64bit elf support
enable parsing 64bit elf files Change-Id: I7981f4769cf1b822f288fe2e32166254e4394bab
This commit is contained in:
Родитель
e6948bf0f9
Коммит
ddd260eb62
|
@ -218,7 +218,7 @@ bail:
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
#else
|
||||
#elif defined(__ELF__)
|
||||
#include "elf.h"
|
||||
|
||||
#define COPY_STRUCT(dst, buf, ofst, sz) do {\
|
||||
|
@ -237,212 +237,420 @@ bail:
|
|||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *buf; /* Buffer containing ELF data */
|
||||
size_t sz; /* Buffer size */
|
||||
int le_data; /* Data is little-endian */
|
||||
Elf32_Ehdr hdr;
|
||||
uint8_t *buf; /* Buffer containing ELF data */
|
||||
size_t sz; /* Buffer size */
|
||||
int le_data; /* Data is little-endian */
|
||||
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
|
||||
int bits; /* 32 or 64 */
|
||||
Elf32_Ehdr hdr32;
|
||||
Elf64_Ehdr hdr64;
|
||||
} elf_obj_t;
|
||||
|
||||
int parse_elf32_header(elf_obj_t *elf)
|
||||
int parse_elf_header(elf_obj_t *elf)
|
||||
{
|
||||
int res;
|
||||
/* Verify ELF32 header */
|
||||
COPY_STRUCT(&elf->hdr, elf->buf, 0, elf->sz);
|
||||
res = elf->hdr.e_ident[EI_MAG0] == ELFMAG0;
|
||||
res &= elf->hdr.e_ident[EI_MAG1] == ELFMAG1;
|
||||
res &= elf->hdr.e_ident[EI_MAG2] == ELFMAG2;
|
||||
res &= elf->hdr.e_ident[EI_MAG3] == ELFMAG3;
|
||||
res &= elf->hdr.e_ident[EI_CLASS] == ELFCLASS32;
|
||||
res &= elf->hdr.e_ident[EI_DATA] == ELFDATA2LSB
|
||||
|| elf->hdr.e_ident[EI_DATA] == ELFDATA2MSB;
|
||||
/* Verify ELF Magic numbers */
|
||||
COPY_STRUCT(&elf->e_ident, elf->buf, 0, elf->sz);
|
||||
res = elf->e_ident[EI_MAG0] == ELFMAG0;
|
||||
res &= elf->e_ident[EI_MAG1] == ELFMAG1;
|
||||
res &= elf->e_ident[EI_MAG2] == ELFMAG2;
|
||||
res &= elf->e_ident[EI_MAG3] == ELFMAG3;
|
||||
res &= elf->e_ident[EI_CLASS] == ELFCLASS32
|
||||
|| elf->e_ident[EI_CLASS] == ELFCLASS64;
|
||||
res &= elf->e_ident[EI_DATA] == ELFDATA2LSB;
|
||||
|
||||
if (!res) goto bail;
|
||||
|
||||
elf->le_data = elf->hdr.e_ident[EI_DATA] == ELFDATA2LSB;
|
||||
elf->le_data = elf->e_ident[EI_DATA] == ELFDATA2LSB;
|
||||
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_type);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_machine);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_version);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_entry);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_phoff);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shoff);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_flags);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_ehsize);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_phentsize);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_phnum);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shentsize);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shnum);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shstrndx);
|
||||
return 0;
|
||||
bail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parse_elf32_section(elf_obj_t *elf, int idx, Elf32_Shdr *hdr)
|
||||
{
|
||||
if (idx >= elf->hdr.e_shnum)
|
||||
goto bail;
|
||||
|
||||
COPY_STRUCT(hdr, elf->buf, elf->hdr.e_shoff + idx * elf->hdr.e_shentsize,
|
||||
elf->sz);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr->sh_name);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr->sh_type);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr->sh_flags);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr->sh_addr);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr->sh_offset);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr->sh_size);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr->sh_link);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr->sh_info);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr->sh_addralign);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr->sh_entsize);
|
||||
return 0;
|
||||
bail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *parse_elf32_string_table(elf_obj_t *elf, int s_idx, int idx)
|
||||
{
|
||||
Elf32_Shdr shdr;
|
||||
|
||||
if (parse_elf32_section(elf, s_idx, &shdr))
|
||||
/* Read in relevant values */
|
||||
if (elf->e_ident[EI_CLASS] == ELFCLASS32)
|
||||
{
|
||||
log_msg("Failed to parse ELF string table: section %d, index %d\n",
|
||||
s_idx, idx);
|
||||
return "";
|
||||
elf->bits = 32;
|
||||
COPY_STRUCT(&elf->hdr32, elf->buf, 0, elf->sz);
|
||||
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_type);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_machine);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_version);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_entry);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phoff);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shoff);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_flags);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_ehsize);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phentsize);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phnum);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shentsize);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shnum);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shstrndx);
|
||||
}
|
||||
else /* if (elf->e_ident[EI_CLASS] == ELFCLASS64) */
|
||||
{
|
||||
elf->bits = 64;
|
||||
COPY_STRUCT(&elf->hdr64, elf->buf, 0, elf->sz);
|
||||
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_type);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_machine);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_version);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_entry);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phoff);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shoff);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_flags);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_ehsize);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phentsize);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phnum);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shentsize);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shnum);
|
||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shstrndx);
|
||||
}
|
||||
|
||||
return (char *)(elf->buf + shdr.sh_offset + idx);
|
||||
return 0;
|
||||
bail:
|
||||
log_msg("Failed to parse ELF file header");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parse_elf32_symbol(elf_obj_t *elf, unsigned int ofst, Elf32_Sym *sym)
|
||||
int parse_elf_section(elf_obj_t *elf, int idx, Elf32_Shdr *hdr32, Elf64_Shdr *hdr64)
|
||||
{
|
||||
COPY_STRUCT(sym, elf->buf, ofst, elf->sz);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym->st_name);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym->st_value);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym->st_size);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym->st_info);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym->st_other);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym->st_shndx);
|
||||
if (hdr32)
|
||||
{
|
||||
if (idx >= elf->hdr32.e_shnum)
|
||||
goto bail;
|
||||
|
||||
COPY_STRUCT(hdr32, elf->buf, elf->hdr32.e_shoff + idx * elf->hdr32.e_shentsize,
|
||||
elf->sz);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_name);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_type);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_flags);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_addr);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_offset);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_size);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_link);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_info);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_addralign);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_entsize);
|
||||
}
|
||||
else /* if (hdr64) */
|
||||
{
|
||||
if (idx >= elf->hdr64.e_shnum)
|
||||
goto bail;
|
||||
|
||||
COPY_STRUCT(hdr64, elf->buf, elf->hdr64.e_shoff + idx * elf->hdr64.e_shentsize,
|
||||
elf->sz);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_name);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_type);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_flags);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_addr);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_offset);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_size);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_link);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_info);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_addralign);
|
||||
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_entsize);
|
||||
}
|
||||
|
||||
return 0;
|
||||
bail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parse_elf32(uint8_t *buf, size_t sz, output_fmt_t mode)
|
||||
char *parse_elf_string_table(elf_obj_t *elf, int s_idx, int idx)
|
||||
{
|
||||
elf_obj_t elf;
|
||||
Elf32_Shdr shdr;
|
||||
if (elf->bits == 32)
|
||||
{
|
||||
Elf32_Shdr shdr;
|
||||
|
||||
if (parse_elf_section(elf, s_idx, &shdr, NULL))
|
||||
{
|
||||
log_msg("Failed to parse ELF string table: section %d, index %d\n",
|
||||
s_idx, idx);
|
||||
return "";
|
||||
}
|
||||
|
||||
return (char *)(elf->buf + shdr.sh_offset + idx);
|
||||
}
|
||||
else /* if (elf->bits == 64) */
|
||||
{
|
||||
Elf64_Shdr shdr;
|
||||
|
||||
if (parse_elf_section(elf, s_idx, NULL, &shdr))
|
||||
{
|
||||
log_msg("Failed to parse ELF string table: section %d, index %d\n",
|
||||
s_idx, idx);
|
||||
return "";
|
||||
}
|
||||
|
||||
return (char *)(elf->buf + shdr.sh_offset + idx);
|
||||
}
|
||||
}
|
||||
|
||||
int parse_elf_symbol(elf_obj_t *elf, unsigned int ofst, Elf32_Sym *sym32, Elf64_Sym *sym64)
|
||||
{
|
||||
if (sym32)
|
||||
{
|
||||
COPY_STRUCT(sym32, elf->buf, ofst, elf->sz);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym32->st_name);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym32->st_value);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym32->st_size);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym32->st_info);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym32->st_other);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym32->st_shndx);
|
||||
}
|
||||
else /* if (sym64) */
|
||||
{
|
||||
COPY_STRUCT(sym64, elf->buf, ofst, elf->sz);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym64->st_name);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym64->st_value);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym64->st_size);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym64->st_info);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym64->st_other);
|
||||
ENDIAN_ASSIGN_IN_PLACE(sym64->st_shndx);
|
||||
}
|
||||
return 0;
|
||||
bail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parse_elf(uint8_t *buf, size_t sz, output_fmt_t mode)
|
||||
{
|
||||
elf_obj_t elf;
|
||||
unsigned int ofst;
|
||||
int i;
|
||||
Elf32_Off strtab_off; /* save String Table offset for later use */
|
||||
int i;
|
||||
Elf32_Off strtab_off32;
|
||||
Elf64_Off strtab_off64; /* save String Table offset for later use */
|
||||
|
||||
memset(&elf, 0, sizeof(elf));
|
||||
elf.buf = buf;
|
||||
elf.sz = sz;
|
||||
|
||||
/* Parse Header */
|
||||
if (parse_elf32_header(&elf))
|
||||
{
|
||||
log_msg("Parse error: File does not appear to be valid ELF32\n");
|
||||
return 1;
|
||||
}
|
||||
if (parse_elf_header(&elf))
|
||||
goto bail;
|
||||
|
||||
for (i = 0; i < elf.hdr.e_shnum; i++)
|
||||
if (elf.bits == 32)
|
||||
{
|
||||
parse_elf32_section(&elf, i, &shdr);
|
||||
|
||||
if (shdr.sh_type == SHT_STRTAB)
|
||||
Elf32_Shdr shdr;
|
||||
for (i = 0; i < elf.hdr32.e_shnum; i++)
|
||||
{
|
||||
char strtsb_name[128];
|
||||
parse_elf_section(&elf, i, &shdr, NULL);
|
||||
|
||||
strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name));
|
||||
|
||||
if (!(strcmp(strtsb_name, ".shstrtab")))
|
||||
if (shdr.sh_type == SHT_STRTAB)
|
||||
{
|
||||
log_msg("found section: %s\n", strtsb_name);
|
||||
strtab_off = shdr.sh_offset;
|
||||
break;
|
||||
char strtsb_name[128];
|
||||
|
||||
strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name));
|
||||
|
||||
if (!(strcmp(strtsb_name, ".shstrtab")))
|
||||
{
|
||||
/* log_msg("found section: %s\n", strtsb_name); */
|
||||
strtab_off32 = shdr.sh_offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* if (elf.bits == 64) */
|
||||
{
|
||||
Elf64_Shdr shdr;
|
||||
for (i = 0; i < elf.hdr64.e_shnum; i++)
|
||||
{
|
||||
parse_elf_section(&elf, i, NULL, &shdr);
|
||||
|
||||
if (shdr.sh_type == SHT_STRTAB)
|
||||
{
|
||||
char strtsb_name[128];
|
||||
|
||||
strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name));
|
||||
|
||||
if (!(strcmp(strtsb_name, ".shstrtab")))
|
||||
{
|
||||
/* log_msg("found section: %s\n", strtsb_name); */
|
||||
strtab_off64 = shdr.sh_offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse all Symbol Tables */
|
||||
for (i = 0; i < elf.hdr.e_shnum; i++)
|
||||
if (elf.bits == 32)
|
||||
{
|
||||
|
||||
parse_elf32_section(&elf, i, &shdr);
|
||||
|
||||
if (shdr.sh_type == SHT_SYMTAB)
|
||||
Elf32_Shdr shdr;
|
||||
for (i = 0; i < elf.hdr32.e_shnum; i++)
|
||||
{
|
||||
for (ofst = shdr.sh_offset;
|
||||
ofst < shdr.sh_offset + shdr.sh_size;
|
||||
ofst += shdr.sh_entsize)
|
||||
parse_elf_section(&elf, i, &shdr, NULL);
|
||||
|
||||
if (shdr.sh_type == SHT_SYMTAB)
|
||||
{
|
||||
Elf32_Sym sym;
|
||||
|
||||
parse_elf32_symbol(&elf, ofst, &sym);
|
||||
|
||||
/* For all OBJECTS (data objects), extract the value from the
|
||||
* proper data segment.
|
||||
*/
|
||||
if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name)
|
||||
log_msg("found data object %s\n",
|
||||
parse_elf32_string_table(&elf,
|
||||
shdr.sh_link,
|
||||
sym.st_name));
|
||||
|
||||
if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT
|
||||
&& sym.st_size == 4)
|
||||
for (ofst = shdr.sh_offset;
|
||||
ofst < shdr.sh_offset + shdr.sh_size;
|
||||
ofst += shdr.sh_entsize)
|
||||
{
|
||||
Elf32_Shdr dhdr;
|
||||
int32_t val;
|
||||
char section_name[128];
|
||||
Elf32_Sym sym;
|
||||
|
||||
parse_elf32_section(&elf, sym.st_shndx, &dhdr);
|
||||
parse_elf_symbol(&elf, ofst, &sym, NULL);
|
||||
|
||||
/* For explanition - refer to _MSC_VER version of code */
|
||||
strcpy(section_name, (char *)(elf.buf + strtab_off + dhdr.sh_name));
|
||||
log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type);
|
||||
/* For all OBJECTS (data objects), extract the value from the
|
||||
* proper data segment.
|
||||
*/
|
||||
/* if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name)
|
||||
log_msg("found data object %s\n",
|
||||
parse_elf_string_table(&elf,
|
||||
shdr.sh_link,
|
||||
sym.st_name));
|
||||
*/
|
||||
|
||||
if (!(strcmp(section_name, ".bss")))
|
||||
if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT
|
||||
&& sym.st_size == 4)
|
||||
{
|
||||
val = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&val,
|
||||
elf.buf + dhdr.sh_offset + sym.st_value,
|
||||
sizeof(val));
|
||||
Elf32_Shdr dhdr;
|
||||
int val = 0;
|
||||
char section_name[128];
|
||||
|
||||
parse_elf_section(&elf, sym.st_shndx, &dhdr, NULL);
|
||||
|
||||
/* For explanition - refer to _MSC_VER version of code */
|
||||
strcpy(section_name, (char *)(elf.buf + strtab_off32 + dhdr.sh_name));
|
||||
/* log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type); */
|
||||
|
||||
if (strcmp(section_name, ".bss"))
|
||||
{
|
||||
if (sizeof(val) != sym.st_size)
|
||||
{
|
||||
/* The target value is declared as an int in
|
||||
* asm_*_offsets.c, which is 4 bytes on all
|
||||
* targets we currently use. Complain loudly if
|
||||
* this is not true.
|
||||
*/
|
||||
log_msg("Symbol size is wrong\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
memcpy(&val,
|
||||
elf.buf + dhdr.sh_offset + sym.st_value,
|
||||
sym.st_size);
|
||||
}
|
||||
|
||||
if (!elf.le_data)
|
||||
{
|
||||
log_msg("Big Endian data not supported yet!\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case OUTPUT_FMT_RVDS:
|
||||
printf("%-40s EQU %5d\n",
|
||||
parse_elf_string_table(&elf,
|
||||
shdr.sh_link,
|
||||
sym.st_name),
|
||||
val);
|
||||
break;
|
||||
case OUTPUT_FMT_GAS:
|
||||
printf(".equ %-40s, %5d\n",
|
||||
parse_elf_string_table(&elf,
|
||||
shdr.sh_link,
|
||||
sym.st_name),
|
||||
val);
|
||||
break;
|
||||
default:
|
||||
printf("%s = %d\n",
|
||||
parse_elf_string_table(&elf,
|
||||
shdr.sh_link,
|
||||
sym.st_name),
|
||||
val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* if (elf.bits == 64) */
|
||||
{
|
||||
Elf64_Shdr shdr;
|
||||
for (i = 0; i < elf.hdr64.e_shnum; i++)
|
||||
{
|
||||
parse_elf_section(&elf, i, NULL, &shdr);
|
||||
|
||||
if (!elf.le_data)
|
||||
{
|
||||
log_msg("Big Endian data not supported yet!\n");
|
||||
goto bail;
|
||||
}\
|
||||
if (shdr.sh_type == SHT_SYMTAB)
|
||||
{
|
||||
for (ofst = shdr.sh_offset;
|
||||
ofst < shdr.sh_offset + shdr.sh_size;
|
||||
ofst += shdr.sh_entsize)
|
||||
{
|
||||
Elf64_Sym sym;
|
||||
|
||||
switch (mode)
|
||||
parse_elf_symbol(&elf, ofst, NULL, &sym);
|
||||
|
||||
/* For all OBJECTS (data objects), extract the value from the
|
||||
* proper data segment.
|
||||
*/
|
||||
/* if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name)
|
||||
log_msg("found data object %s\n",
|
||||
parse_elf_string_table(&elf,
|
||||
shdr.sh_link,
|
||||
sym.st_name));
|
||||
*/
|
||||
|
||||
if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT
|
||||
&& sym.st_size == 4)
|
||||
{
|
||||
case OUTPUT_FMT_RVDS:
|
||||
printf("%-40s EQU %5d\n",
|
||||
parse_elf32_string_table(&elf,
|
||||
shdr.sh_link,
|
||||
sym.st_name),
|
||||
val);
|
||||
break;
|
||||
case OUTPUT_FMT_GAS:
|
||||
printf(".equ %-40s, %5d\n",
|
||||
parse_elf32_string_table(&elf,
|
||||
shdr.sh_link,
|
||||
sym.st_name),
|
||||
val);
|
||||
break;
|
||||
default:
|
||||
printf("%s = %d\n",
|
||||
parse_elf32_string_table(&elf,
|
||||
shdr.sh_link,
|
||||
sym.st_name),
|
||||
val);
|
||||
Elf64_Shdr dhdr;
|
||||
int val = 0;
|
||||
char section_name[128];
|
||||
|
||||
parse_elf_section(&elf, sym.st_shndx, NULL, &dhdr);
|
||||
|
||||
/* For explanition - refer to _MSC_VER version of code */
|
||||
strcpy(section_name, (char *)(elf.buf + strtab_off64 + dhdr.sh_name));
|
||||
/* log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type); */
|
||||
|
||||
if ((strcmp(section_name, ".bss")))
|
||||
{
|
||||
if (sizeof(val) != sym.st_size)
|
||||
{
|
||||
/* The target value is declared as an int in
|
||||
* asm_*_offsets.c, which is 4 bytes on all
|
||||
* targets we currently use. Complain loudly if
|
||||
* this is not true.
|
||||
*/
|
||||
log_msg("Symbol size is wrong\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
memcpy(&val,
|
||||
elf.buf + dhdr.sh_offset + sym.st_value,
|
||||
sym.st_size);
|
||||
}
|
||||
|
||||
if (!elf.le_data)
|
||||
{
|
||||
log_msg("Big Endian data not supported yet!\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case OUTPUT_FMT_RVDS:
|
||||
printf("%-40s EQU %5d\n",
|
||||
parse_elf_string_table(&elf,
|
||||
shdr.sh_link,
|
||||
sym.st_name),
|
||||
val);
|
||||
break;
|
||||
case OUTPUT_FMT_GAS:
|
||||
printf(".equ %-40s, %5d\n",
|
||||
parse_elf_string_table(&elf,
|
||||
shdr.sh_link,
|
||||
sym.st_name),
|
||||
val);
|
||||
break;
|
||||
default:
|
||||
printf("%s = %d\n",
|
||||
parse_elf_string_table(&elf,
|
||||
shdr.sh_link,
|
||||
sym.st_name),
|
||||
val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -454,7 +662,7 @@ int parse_elf32(uint8_t *buf, size_t sz, output_fmt_t mode)
|
|||
|
||||
return 0;
|
||||
bail:
|
||||
log_msg("Parse error: File does not appear to be valid ELF32\n");
|
||||
log_msg("Parse error: File does not appear to be valid ELF32 or ELF64\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -521,8 +729,7 @@ int main(int argc, char **argv)
|
|||
goto bail;
|
||||
}
|
||||
|
||||
res = parse_elf32(file_buf, stat_buf.st_size, mode);
|
||||
//res = parse_coff(file_buf, stat_buf.st_size);
|
||||
res = parse_elf(file_buf, stat_buf.st_size, mode);
|
||||
free(file_buf);
|
||||
|
||||
if (!res)
|
||||
|
|
Загрузка…
Ссылка в новой задаче