diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2008-05-28 14:31:08 (GMT) |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2008-05-28 14:31:08 (GMT) |
commit | 0c5f99f90a07381c6d21446532f35372c421fed5 (patch) | |
tree | e982bb996adbe4e98686436f980d0ba1bb79beb0 /src/patchelf.cc | |
parent | 59f7b9a4d0d1ab53a0452da6e14c8dfbdb7cc88b (diff) | |
download | patchelf-0c5f99f90a07381c6d21446532f35372c421fed5.zip patchelf-0c5f99f90a07381c6d21446532f35372c421fed5.tar.gz patchelf-0c5f99f90a07381c6d21446532f35372c421fed5.tar.bz2 |
* Support executables without a .dynamic section (klcc generates
'em).
Diffstat (limited to 'src/patchelf.cc')
-rw-r--r-- | src/patchelf.cc | 69 |
1 files 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<ElfFileParamNames>::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; + } } |