aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-11-27 11:58:58 +0000
committerMatt Fleming <matt.fleming@intel.com>2012-11-27 11:58:58 +0000
commitb2eadc35e99caa2a6aba2fae99031c1073bc6cf5 (patch)
tree39bac97efd4a9f60a9e60b6ea01aec06caed2029
parent13bdb6b05cd0d4bb4eb853a74b71f80dc892491e (diff)
downloadsyslinux-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.c28
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;
}