diff options
author | Matt Fleming <matt.fleming@intel.com> | 2012-11-27 11:58:58 +0000 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2012-11-27 11:58:58 +0000 |
commit | b2eadc35e99caa2a6aba2fae99031c1073bc6cf5 (patch) | |
tree | 39bac97efd4a9f60a9e60b6ea01aec06caed2029 | |
parent | 13bdb6b05cd0d4bb4eb853a74b71f80dc892491e (diff) | |
download | syslinux-b2eadc35e99caa2a6aba2fae99031c1073bc6cf5.tar.gz syslinux-b2eadc35e99caa2a6aba2fae99031c1073bc6cf5.tar.xz syslinux-b2eadc35e99caa2a6aba2fae99031c1073bc6cf5.zip |
module: Correct the size of the module symbol table
We were incorrectly grovelling around in the GNU hash table for the
size of the symbol table. Instead we need to map the section headers
and search for the SHT_DYNSYM entry.
This bug caused hdt.c32 to refuse to load as some symbols were never
resolved because not all of the SHT_UNDEF symbols in hdt.c32 were
processed.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r-- | com32/lib/sys/module/elf_module.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/com32/lib/sys/module/elf_module.c b/com32/lib/sys/module/elf_module.c index b220e1ad..c92fe266 100644 --- a/com32/lib/sys/module/elf_module.c +++ b/com32/lib/sys/module/elf_module.c @@ -51,7 +51,9 @@ static int load_segments(struct elf_module *module, Elf32_Ehdr *elf_hdr) { int i; int res = 0; char *pht = NULL; + char *sht = NULL; Elf32_Phdr *cr_pht; + Elf32_Shdr *cr_sht; Elf32_Addr min_addr = 0x00000000; // Min. ELF vaddr Elf32_Addr max_addr = 0x00000000; // Max. ELF vaddr @@ -163,6 +165,25 @@ static int load_segments(struct elf_module *module, Elf32_Ehdr *elf_hdr) { } } + // Get to the SHT + image_seek(elf_hdr->e_shoff, module); + + // Load the SHT + sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize); + image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module); + + // Setup the symtable size + for (i = 0; i < elf_hdr->e_shnum; i++) { + cr_sht = (Elf32_Shdr*)(sht + i * elf_hdr->e_shentsize); + + if (cr_sht->sh_type == SHT_DYNSYM) { + module->symtable_size = cr_sht->sh_size; + break; + } + } + + free(sht); + // Setup dynamic segment location module->dyn_table = module_get_absolute(dyn_addr, module); @@ -229,13 +250,6 @@ static int prepare_dynlinking(struct elf_module *module) { dyn_entry++; } - // Now compute the number of symbols in the symbol table - if (module->ghash_table != NULL) { - module->symtable_size = module->ghash_table[1]; - } else { - module->symtable_size = module->hash_table[1]; - } - return 0; } |