summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2008-05-28 14:31:08 (GMT)
committerEelco Dolstra <e.dolstra@tudelft.nl>2008-05-28 14:31:08 (GMT)
commit0c5f99f90a07381c6d21446532f35372c421fed5 (patch)
treee982bb996adbe4e98686436f980d0ba1bb79beb0 /src
parent59f7b9a4d0d1ab53a0452da6e14c8dfbdb7cc88b (diff)
downloadpatchelf-0c5f99f90a07381c6d21446532f35372c421fed5.zip
patchelf-0c5f99f90a07381c6d21446532f35372c421fed5.tar.gz
patchelf-0c5f99f90a07381c6d21446532f35372c421fed5.tar.bz2
* Support executables without a .dynamic section (klcc generates
'em).
Diffstat (limited to 'src')
-rw-r--r--src/patchelf.cc69
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;
+ }
}