diff options
author | Magnus Damm <magnus@valinux.co.jp> | 2006-08-23 12:51:21 +0900 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2006-10-06 12:44:15 +0900 |
commit | 0c7eda010fe8122f340e470cfc8273a0975945a3 (patch) | |
tree | c7b77435f6141cd0bbf5014410e7b5a2f5f00738 /kexec | |
parent | 64c27ee85138921a38a958f21478eb2aad5e7b75 (diff) | |
download | kexec-tools-0c7eda010fe8122f340e470cfc8273a0975945a3.tar.gz |
teach elf_rel_load() about section names
The patch extends elf_rel_load() to handle section names correctly.
Signed-off-by: Magnus Damm <magnus@valinux.co.jp>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'kexec')
-rw-r--r-- | kexec/kexec-elf-rel.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/kexec/kexec-elf-rel.c b/kexec/kexec-elf-rel.c index 8f7433c..ae78a09 100644 --- a/kexec/kexec-elf-rel.c +++ b/kexec/kexec-elf-rel.c @@ -338,6 +338,7 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info, struct mem_rela rel; struct mem_sym sym; const void *location; + const char *name; unsigned long address, value, sec_base; if (shdr->sh_type == SHT_REL) { rel = elf_rel(ehdr, ptr); @@ -353,9 +354,17 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info, /* The relevant symbol */ sym = elf_sym(ehdr, symtab->sh_data + (rel.r_sym * elf_sym_size(ehdr))); + + if (sym.st_name) { + name = strtab + sym.st_name; + } + else { + name = ehdr->e_shdr[ehdr->e_shstrndx].sh_data; + name += ehdr->e_shdr[sym.st_shndx].sh_name; + } #ifdef DEBUG fprintf(stderr, "sym: %10s info: %02x other: %02x shndx: %lx value: %lx size: %lx\n", - strtab + sym.st_name, + name, sym.st_info, sym.st_other, sym.st_shndx, @@ -373,30 +382,28 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info, * So, is this really an error condition to flag die? */ /* - die("Undefined symbol: %s\n", - strtab + sym.st_name); + die("Undefined symbol: %s\n", name); */ continue; } sec_base = 0; if (sym.st_shndx == SHN_COMMON) { die("symbol: '%s' in common section\n", - strtab + sym.st_name); + name); } else if (sym.st_shndx == SHN_ABS) { sec_base = 0; } else if (sym.st_shndx > ehdr->e_shnum) { die("Invalid section: %d for symbol %s\n", - sym.st_shndx, - strtab + sym.st_name); + sym.st_shndx, name); } else { sec_base = ehdr->e_shdr[sym.st_shndx].sh_addr; } #ifdef DEBUG fprintf(stderr, "sym: %s value: %lx addr: %lx\n", - strtab + sym.st_name, value, address); + name, value, address); #endif value = sym.st_value; value += sec_base; |