diff --git a/src/relf/relf.c b/src/relf/relf.c index 97dc8d1..25b7a46 100644 --- a/src/relf/relf.c +++ b/src/relf/relf.c @@ -252,6 +252,61 @@ relf_value_t relf_open(relf_t* relf, const char* path) break; } } + + // load symbol info + relf->symbol_num = symtab->f_size / symtab->entsize; + relf->symbols = (relf_symbol_t*)calloc(sizeof(relf_symbol_t), relf->symbol_num); + + if (relf->type == RELF_64BIT) + { + for (unsigned i = 0; i < relf->symbol_num; i++) + { + const Elf64_Sym* hdr = (const Elf64_Sym*)((char*)relf->image + + symtab->f_offset + i*symtab->entsize); + relf_symbol_t* symbol = &relf->symbols[i]; + + if (hdr->st_name) + symbol->name = (const char*)relf->image + strtab->f_offset + hdr->st_name; + else symbol->name = NULL; + + symbol->value = hdr->st_value; + symbol->size = hdr->st_size; + + symbol->info = hdr->st_info; + symbol->other = hdr->st_other; + + if (hdr->st_shndx < relf->section_num) + symbol->section = &relf->sections[hdr->st_shndx]; + else symbol->section = NULL; + + TRACE_SYMBOL(symbol); + } + } + else + { + for (unsigned i = 0; i < relf->symbol_num; i++) + { + const Elf32_Sym* hdr = (const Elf32_Sym*)((char*)relf->image + + symtab->f_offset + i*symtab->entsize); + relf_symbol_t* symbol = &relf->symbols[i]; + + if (hdr->st_name) + symbol->name = (const char*)relf->image + strtab->f_offset + hdr->st_name; + else symbol->name = NULL; + + symbol->value = hdr->st_value; + symbol->size = hdr->st_size; + + symbol->info = hdr->st_info; + symbol->other = hdr->st_other; + + if (hdr->st_shndx < relf->section_num) + symbol->section = &relf->sections[hdr->st_shndx]; + else symbol->section = NULL; + + TRACE_SYMBOL(symbol); + } + } return RELF_ERROR(RELF_OK); } @@ -261,4 +316,5 @@ void relf_close(relf_t* relf) relf_unmap(relf); free(relf->segments); free(relf->sections); + free(relf->symbols); } diff --git a/src/relf/relf.h b/src/relf/relf.h index ce81dde..56e8ac8 100644 --- a/src/relf/relf.h +++ b/src/relf/relf.h @@ -75,6 +75,19 @@ typedef struct { uint64_t entsize; } relf_section_t; +// ELF symbol +typedef struct { + const char* name; + + uint64_t value; + uint64_t size; + + unsigned info; + unsigned other; + + const relf_section_t* section; +} relf_symbol_t; + // relf instance typedef struct { void* image; @@ -88,6 +101,9 @@ typedef struct { relf_section_t* sections; unsigned section_num; + + relf_symbol_t* symbols; + unsigned symbol_num; } relf_t; // opens ELF file, checks ELF magic and maps it into memory diff --git a/src/relf/relf_debug.h b/src/relf/relf_debug.h index 05607f8..febbde6 100644 --- a/src/relf/relf_debug.h +++ b/src/relf/relf_debug.h @@ -20,9 +20,17 @@ section->link, section->info, \ section->entsize \ ) + +#define TRACE_SYMBOL(symbol) \ + TRACE("symbol name %s value 0x%lx size %lu info %x other %x\n", \ + symbol->name, \ + symbol->value, symbol->size, \ + symbol->info, symbol->other \ + ) #else #define TRACE_SEGMENT(segment) #define TRACE_SECTION(section) +#define TRACE_SYMBOL(symbol) #endif #endif \ No newline at end of file