From 0c5f99f90a07381c6d21446532f35372c421fed5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 28 May 2008 14:31:08 +0000 Subject: * Support executables without a .dynamic section (klcc generates 'em). --- src/patchelf.cc | 69 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/src/patchelf.cc b/src/patchelf.cc index 6503894..f0493f6 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -736,39 +736,42 @@ void ElfFile::rewriteHeaders(Elf_Addr phdrAddress) /* Update all those nasty virtual addresses in the .dynamic - section. */ - Elf_Shdr & shdrDynamic = findSection(".dynamic"); - Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset)); - unsigned int d_tag; - for ( ; (d_tag = rdi(dyn->d_tag)) != DT_NULL; dyn++) - if (d_tag == DT_STRTAB) - dyn->d_un.d_ptr = findSection(".dynstr").sh_addr; - else if (d_tag == DT_STRSZ) - dyn->d_un.d_val = findSection(".dynstr").sh_size; - else if (d_tag == DT_SYMTAB) - dyn->d_un.d_ptr = findSection(".dynsym").sh_addr; - else if (d_tag == DT_HASH) - dyn->d_un.d_ptr = findSection(".hash").sh_addr; - else if (d_tag == DT_JMPREL) { - Elf_Shdr * shdr = findSection2(".rel.plt"); - if (!shdr) shdr = findSection2(".rela.plt"); /* 64-bit Linux, x86-64 */ - if (!shdr) shdr = findSection2(".rela.IA_64.pltoff"); /* 64-bit Linux, IA-64 */ - if (!shdr) error("cannot find section corresponding to DT_JMPREL"); - dyn->d_un.d_ptr = shdr->sh_addr; - } - else if (d_tag == DT_REL) { /* !!! hack! */ - Elf_Shdr * shdr = findSection2(".rel.dyn"); - /* no idea if this makes sense, but it was needed for some - program */ - if (!shdr) shdr = findSection2(".rel.got"); - if (!shdr) error("cannot find .rel.dyn or .rel.got"); - dyn->d_un.d_ptr = shdr->sh_addr; - } - /* should probably update DT_RELA */ - else if (d_tag == DT_VERNEED) - dyn->d_un.d_ptr = findSection(".gnu.version_r").sh_addr; - else if (d_tag == DT_VERSYM) - dyn->d_un.d_ptr = findSection(".gnu.version").sh_addr; + section. Note that not all executables have .dynamic sections + (e.g., those produced by klibc's klcc). */ + Elf_Shdr * shdrDynamic = findSection2(".dynamic"); + if (shdrDynamic) { + Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic->sh_offset)); + unsigned int d_tag; + for ( ; (d_tag = rdi(dyn->d_tag)) != DT_NULL; dyn++) + if (d_tag == DT_STRTAB) + dyn->d_un.d_ptr = findSection(".dynstr").sh_addr; + else if (d_tag == DT_STRSZ) + dyn->d_un.d_val = findSection(".dynstr").sh_size; + else if (d_tag == DT_SYMTAB) + dyn->d_un.d_ptr = findSection(".dynsym").sh_addr; + else if (d_tag == DT_HASH) + dyn->d_un.d_ptr = findSection(".hash").sh_addr; + else if (d_tag == DT_JMPREL) { + Elf_Shdr * shdr = findSection2(".rel.plt"); + if (!shdr) shdr = findSection2(".rela.plt"); /* 64-bit Linux, x86-64 */ + if (!shdr) shdr = findSection2(".rela.IA_64.pltoff"); /* 64-bit Linux, IA-64 */ + if (!shdr) error("cannot find section corresponding to DT_JMPREL"); + dyn->d_un.d_ptr = shdr->sh_addr; + } + else if (d_tag == DT_REL) { /* !!! hack! */ + Elf_Shdr * shdr = findSection2(".rel.dyn"); + /* no idea if this makes sense, but it was needed for some + program */ + if (!shdr) shdr = findSection2(".rel.got"); + if (!shdr) error("cannot find .rel.dyn or .rel.got"); + dyn->d_un.d_ptr = shdr->sh_addr; + } + /* should probably update DT_RELA */ + else if (d_tag == DT_VERNEED) + dyn->d_un.d_ptr = findSection(".gnu.version_r").sh_addr; + else if (d_tag == DT_VERSYM) + dyn->d_un.d_ptr = findSection(".gnu.version").sh_addr; + } } -- cgit v0.12