From 472deb37084dc269c2a9ad42579bfa762c032984 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 21 Aug 2012 15:21:39 -0400 Subject: Rewrite the st_shndx field in symbol tables The st_shndx field in symbol tables specifies the index of the section that contains the symbol. Since we reorder sections, we need to update this field as well. Otherwise programs like gdb won't be able to resolve addresses to symbol names (and will print "?? ()" instead). --- src/patchelf.cc | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/patchelf.cc b/src/patchelf.cc index cf79310..e1520a8 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -40,8 +40,8 @@ off_t fileSize, maxSize; unsigned char * contents = 0; -#define ElfFileParams class Elf_Ehdr, class Elf_Phdr, class Elf_Shdr, class Elf_Addr, class Elf_Off, class Elf_Dyn -#define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn +#define ElfFileParams class Elf_Ehdr, class Elf_Phdr, class Elf_Shdr, class Elf_Addr, class Elf_Off, class Elf_Dyn, class Elf_Sym +#define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym template @@ -68,6 +68,8 @@ class ElfFile respectively. */ unsigned int sectionAlignment; + vector sectionsByOldIndex; + public: ElfFile() @@ -293,6 +295,10 @@ void ElfFile::parse() assert(shstrtab[shstrtabSize - 1] == 0); sectionNames = string(shstrtab, shstrtabSize); + + sectionsByOldIndex.resize(hdr->e_shnum); + for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) + sectionsByOldIndex[i] = getSectionName(shdrs[i]); } @@ -816,6 +822,25 @@ void ElfFile::rewriteHeaders(Elf_Addr phdrAddress) else if (d_tag == DT_VERSYM) dyn->d_un.d_ptr = findSection(".gnu.version").sh_addr; } + + + /* Rewrite the .dynsym section. It contains the indices of the + sections in which symbols appear, so these need to be + remapped. */ + for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) { + if (rdi(shdrs[i].sh_type) != SHT_SYMTAB && rdi(shdrs[i].sh_type) != SHT_DYNSYM) continue; + debug("rewriting symbol table section %d\n", i); + for (size_t entry = 0; (entry + 1) * sizeof(Elf_Sym) <= rdi(shdrs[i].sh_size); entry++) { + Elf_Sym * sym = (Elf_Sym *) (contents + rdi(shdrs[i].sh_offset) + entry * sizeof(Elf_Sym)); + if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) { + string section = sectionsByOldIndex[rdi(sym->st_shndx)]; + assert(!section.empty()); + unsigned int newIndex = findSection3(section); // inefficient + debug("rewriting symbol %d: index = %d (%s) -> %d\n", entry, rdi(sym->st_shndx), section.c_str(), newIndex); + wri(sym->st_shndx, newIndex); + } + } + } } @@ -1079,13 +1104,13 @@ static void patchElf() if (contents[EI_CLASS] == ELFCLASS32 && contents[EI_VERSION] == EV_CURRENT) { - ElfFile elfFile; + ElfFile elfFile; patchElf2(elfFile, fileMode); } else if (contents[EI_CLASS] == ELFCLASS64 && contents[EI_VERSION] == EV_CURRENT) { - ElfFile elfFile; + ElfFile elfFile; patchElf2(elfFile, fileMode); } else { -- cgit v0.12