64bit elf support
enable parsing 64bit elf files Change-Id: I7981f4769cf1b822f288fe2e32166254e4394bab
This commit is contained in:
parent
e6948bf0f9
commit
ddd260eb62
@ -218,7 +218,7 @@ bail:
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#elif defined(__ELF__)
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
|
|
||||||
#define COPY_STRUCT(dst, buf, ofst, sz) do {\
|
#define COPY_STRUCT(dst, buf, ofst, sz) do {\
|
||||||
@ -237,212 +237,420 @@ bail:
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t *buf; /* Buffer containing ELF data */
|
uint8_t *buf; /* Buffer containing ELF data */
|
||||||
size_t sz; /* Buffer size */
|
size_t sz; /* Buffer size */
|
||||||
int le_data; /* Data is little-endian */
|
int le_data; /* Data is little-endian */
|
||||||
Elf32_Ehdr hdr;
|
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;
|
} elf_obj_t;
|
||||||
|
|
||||||
int parse_elf32_header(elf_obj_t *elf)
|
int parse_elf_header(elf_obj_t *elf)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
/* Verify ELF32 header */
|
/* Verify ELF Magic numbers */
|
||||||
COPY_STRUCT(&elf->hdr, elf->buf, 0, elf->sz);
|
COPY_STRUCT(&elf->e_ident, elf->buf, 0, elf->sz);
|
||||||
res = elf->hdr.e_ident[EI_MAG0] == ELFMAG0;
|
res = elf->e_ident[EI_MAG0] == ELFMAG0;
|
||||||
res &= elf->hdr.e_ident[EI_MAG1] == ELFMAG1;
|
res &= elf->e_ident[EI_MAG1] == ELFMAG1;
|
||||||
res &= elf->hdr.e_ident[EI_MAG2] == ELFMAG2;
|
res &= elf->e_ident[EI_MAG2] == ELFMAG2;
|
||||||
res &= elf->hdr.e_ident[EI_MAG3] == ELFMAG3;
|
res &= elf->e_ident[EI_MAG3] == ELFMAG3;
|
||||||
res &= elf->hdr.e_ident[EI_CLASS] == ELFCLASS32;
|
res &= elf->e_ident[EI_CLASS] == ELFCLASS32
|
||||||
res &= elf->hdr.e_ident[EI_DATA] == ELFDATA2LSB
|
|| elf->e_ident[EI_CLASS] == ELFCLASS64;
|
||||||
|| elf->hdr.e_ident[EI_DATA] == ELFDATA2MSB;
|
res &= elf->e_ident[EI_DATA] == ELFDATA2LSB;
|
||||||
|
|
||||||
if (!res) goto bail;
|
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);
|
/* Read in relevant values */
|
||||||
ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_machine);
|
if (elf->e_ident[EI_CLASS] == ELFCLASS32)
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
log_msg("Failed to parse ELF string table: section %d, index %d\n",
|
elf->bits = 32;
|
||||||
s_idx, idx);
|
COPY_STRUCT(&elf->hdr32, elf->buf, 0, elf->sz);
|
||||||
return "";
|
|
||||||
|
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);
|
if (hdr32)
|
||||||
ENDIAN_ASSIGN_IN_PLACE(sym->st_name);
|
{
|
||||||
ENDIAN_ASSIGN_IN_PLACE(sym->st_value);
|
if (idx >= elf->hdr32.e_shnum)
|
||||||
ENDIAN_ASSIGN_IN_PLACE(sym->st_size);
|
goto bail;
|
||||||
ENDIAN_ASSIGN_IN_PLACE(sym->st_info);
|
|
||||||
ENDIAN_ASSIGN_IN_PLACE(sym->st_other);
|
COPY_STRUCT(hdr32, elf->buf, elf->hdr32.e_shoff + idx * elf->hdr32.e_shentsize,
|
||||||
ENDIAN_ASSIGN_IN_PLACE(sym->st_shndx);
|
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;
|
return 0;
|
||||||
bail:
|
bail:
|
||||||
return 1;
|
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;
|
if (elf->bits == 32)
|
||||||
Elf32_Shdr shdr;
|
{
|
||||||
|
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;
|
unsigned int ofst;
|
||||||
int i;
|
int i;
|
||||||
Elf32_Off strtab_off; /* save String Table offset for later use */
|
Elf32_Off strtab_off32;
|
||||||
|
Elf64_Off strtab_off64; /* save String Table offset for later use */
|
||||||
|
|
||||||
memset(&elf, 0, sizeof(elf));
|
memset(&elf, 0, sizeof(elf));
|
||||||
elf.buf = buf;
|
elf.buf = buf;
|
||||||
elf.sz = sz;
|
elf.sz = sz;
|
||||||
|
|
||||||
/* Parse Header */
|
/* Parse Header */
|
||||||
if (parse_elf32_header(&elf))
|
if (parse_elf_header(&elf))
|
||||||
{
|
goto bail;
|
||||||
log_msg("Parse error: File does not appear to be valid ELF32\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < elf.hdr.e_shnum; i++)
|
if (elf.bits == 32)
|
||||||
{
|
{
|
||||||
parse_elf32_section(&elf, i, &shdr);
|
Elf32_Shdr shdr;
|
||||||
|
for (i = 0; i < elf.hdr32.e_shnum; i++)
|
||||||
if (shdr.sh_type == SHT_STRTAB)
|
|
||||||
{
|
{
|
||||||
char strtsb_name[128];
|
parse_elf_section(&elf, i, &shdr, NULL);
|
||||||
|
|
||||||
strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name));
|
if (shdr.sh_type == SHT_STRTAB)
|
||||||
|
|
||||||
if (!(strcmp(strtsb_name, ".shstrtab")))
|
|
||||||
{
|
{
|
||||||
log_msg("found section: %s\n", strtsb_name);
|
char strtsb_name[128];
|
||||||
strtab_off = shdr.sh_offset;
|
|
||||||
break;
|
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 */
|
/* Parse all Symbol Tables */
|
||||||
for (i = 0; i < elf.hdr.e_shnum; i++)
|
if (elf.bits == 32)
|
||||||
{
|
{
|
||||||
|
Elf32_Shdr shdr;
|
||||||
parse_elf32_section(&elf, i, &shdr);
|
for (i = 0; i < elf.hdr32.e_shnum; i++)
|
||||||
|
|
||||||
if (shdr.sh_type == SHT_SYMTAB)
|
|
||||||
{
|
{
|
||||||
for (ofst = shdr.sh_offset;
|
parse_elf_section(&elf, i, &shdr, NULL);
|
||||||
ofst < shdr.sh_offset + shdr.sh_size;
|
|
||||||
ofst += shdr.sh_entsize)
|
if (shdr.sh_type == SHT_SYMTAB)
|
||||||
{
|
{
|
||||||
Elf32_Sym sym;
|
for (ofst = shdr.sh_offset;
|
||||||
|
ofst < shdr.sh_offset + shdr.sh_size;
|
||||||
parse_elf32_symbol(&elf, ofst, &sym);
|
ofst += shdr.sh_entsize)
|
||||||
|
|
||||||
/* 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)
|
|
||||||
{
|
{
|
||||||
Elf32_Shdr dhdr;
|
Elf32_Sym sym;
|
||||||
int32_t val;
|
|
||||||
char section_name[128];
|
|
||||||
|
|
||||||
parse_elf32_section(&elf, sym.st_shndx, &dhdr);
|
parse_elf_symbol(&elf, ofst, &sym, NULL);
|
||||||
|
|
||||||
/* For explanition - refer to _MSC_VER version of code */
|
/* For all OBJECTS (data objects), extract the value from the
|
||||||
strcpy(section_name, (char *)(elf.buf + strtab_off + dhdr.sh_name));
|
* proper data segment.
|
||||||
log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type);
|
*/
|
||||||
|
/* 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;
|
Elf32_Shdr dhdr;
|
||||||
}
|
int val = 0;
|
||||||
else
|
char section_name[128];
|
||||||
{
|
|
||||||
memcpy(&val,
|
parse_elf_section(&elf, sym.st_shndx, &dhdr, NULL);
|
||||||
elf.buf + dhdr.sh_offset + sym.st_value,
|
|
||||||
sizeof(val));
|
/* 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)
|
if (shdr.sh_type == SHT_SYMTAB)
|
||||||
{
|
{
|
||||||
log_msg("Big Endian data not supported yet!\n");
|
for (ofst = shdr.sh_offset;
|
||||||
goto bail;
|
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:
|
Elf64_Shdr dhdr;
|
||||||
printf("%-40s EQU %5d\n",
|
int val = 0;
|
||||||
parse_elf32_string_table(&elf,
|
char section_name[128];
|
||||||
shdr.sh_link,
|
|
||||||
sym.st_name),
|
parse_elf_section(&elf, sym.st_shndx, NULL, &dhdr);
|
||||||
val);
|
|
||||||
break;
|
/* For explanition - refer to _MSC_VER version of code */
|
||||||
case OUTPUT_FMT_GAS:
|
strcpy(section_name, (char *)(elf.buf + strtab_off64 + dhdr.sh_name));
|
||||||
printf(".equ %-40s, %5d\n",
|
/* log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type); */
|
||||||
parse_elf32_string_table(&elf,
|
|
||||||
shdr.sh_link,
|
if ((strcmp(section_name, ".bss")))
|
||||||
sym.st_name),
|
{
|
||||||
val);
|
if (sizeof(val) != sym.st_size)
|
||||||
break;
|
{
|
||||||
default:
|
/* The target value is declared as an int in
|
||||||
printf("%s = %d\n",
|
* asm_*_offsets.c, which is 4 bytes on all
|
||||||
parse_elf32_string_table(&elf,
|
* targets we currently use. Complain loudly if
|
||||||
shdr.sh_link,
|
* this is not true.
|
||||||
sym.st_name),
|
*/
|
||||||
val);
|
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;
|
return 0;
|
||||||
bail:
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,8 +729,7 @@ int main(int argc, char **argv)
|
|||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = parse_elf32(file_buf, stat_buf.st_size, mode);
|
res = parse_elf(file_buf, stat_buf.st_size, mode);
|
||||||
//res = parse_coff(file_buf, stat_buf.st_size);
|
|
||||||
free(file_buf);
|
free(file_buf);
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user