summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2007-02-01 00:25:29 (GMT)
committerEelco Dolstra <e.dolstra@tudelft.nl>2007-02-01 00:25:29 (GMT)
commitefa2a7ee24c2dfd7865427991040af4a1a868606 (patch)
treef5d8cc1f48215fd833baf4f0bb36bf5377af9c29 /src
parent5cc8d9c439d6134a640e913ad72ae74352052606 (diff)
downloadpatchelf-efa2a7ee24c2dfd7865427991040af4a1a868606.zip
patchelf-efa2a7ee24c2dfd7865427991040af4a1a868606.tar.gz
patchelf-efa2a7ee24c2dfd7865427991040af4a1a868606.tar.bz2
* When sorting the sections, make sure that we maintain the sh_link
and sh_info fields. Tricky.
Diffstat (limited to 'src')
-rw-r--r--src/patchelf.cc59
1 files changed, 49 insertions, 10 deletions
diff --git a/src/patchelf.cc b/src/patchelf.cc
index d6a9449..e290475 100644
--- a/src/patchelf.cc
+++ b/src/patchelf.cc
@@ -86,10 +86,12 @@ private:
string getSectionName(const Elf_Shdr & shdr);
- Elf_Shdr * findSection2(const SectionName & sectionName);
-
Elf_Shdr & findSection(const SectionName & sectionName);
+ Elf_Shdr * findSection2(const SectionName & sectionName);
+
+ unsigned int findSection3(const SectionName & sectionName);
+
string & replaceSection(const SectionName & sectionName,
unsigned int size);
@@ -242,9 +244,38 @@ void ElfFile<ElfFileParamNames>::parse()
template<ElfFileParams>
void ElfFile<ElfFileParamNames>::sortShdrs()
{
+ /* Translate sh_link mappings to section names, since sorting the
+ sections will invalidate the sh_link fields. */
+ map<SectionName, SectionName> linkage;
+ for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i)
+ if (rdi(shdrs[i].sh_link) != 0)
+ linkage[getSectionName(shdrs[i])] = getSectionName(shdrs[rdi(shdrs[i].sh_link)]);
+
+ /* Idem for sh_info on certain sections. */
+ map<SectionName, SectionName> info;
+ for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i)
+ if (rdi(shdrs[i].sh_info) != 0 &&
+ (rdi(shdrs[i].sh_type) == SHT_REL || rdi(shdrs[i].sh_type) == SHT_RELA))
+ info[getSectionName(shdrs[i])] = getSectionName(shdrs[rdi(shdrs[i].sh_info)]);
+
+ /* Sort the sections by offset. */
CompShdr comp;
comp.elfFile = this;
sort(shdrs.begin(), shdrs.end(), comp);
+
+ /* Restore the sh_link mappings. */
+ for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i)
+ if (rdi(shdrs[i].sh_link) != 0)
+ wri(shdrs[i].sh_link,
+ findSection3(linkage[getSectionName(shdrs[i])]));
+
+ /* And the st_info mappings. */
+ for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i)
+ if (rdi(shdrs[i].sh_info) != 0 &&
+ (rdi(shdrs[i].sh_type) == SHT_REL || rdi(shdrs[i].sh_type) == SHT_RELA))
+ wri(shdrs[i].sh_info,
+ findSection3(info[getSectionName(shdrs[i])]));
+
}
@@ -317,21 +348,29 @@ string ElfFile<ElfFileParamNames>::getSectionName(const Elf_Shdr & shdr)
template<ElfFileParams>
+Elf_Shdr & ElfFile<ElfFileParamNames>::findSection(const SectionName & sectionName)
+{
+ Elf_Shdr * shdr = findSection2(sectionName);
+ if (!shdr)
+ error("cannot find section " + sectionName);
+ return *shdr;
+}
+
+
+template<ElfFileParams>
Elf_Shdr * ElfFile<ElfFileParamNames>::findSection2(const SectionName & sectionName)
{
- for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i)
- if (getSectionName(shdrs[i]) == sectionName) return &shdrs[i];
- return 0;
+ unsigned int i = findSection3(sectionName);
+ return i ? &shdrs[i] : 0;
}
template<ElfFileParams>
-Elf_Shdr & ElfFile<ElfFileParamNames>::findSection(const SectionName & sectionName)
+unsigned int ElfFile<ElfFileParamNames>::findSection3(const SectionName & sectionName)
{
- Elf_Shdr * shdr = findSection2(sectionName);
- if (!shdr)
- error("cannot find section " + sectionName);
- return *shdr;
+ for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i)
+ if (getSectionName(shdrs[i]) == sectionName) return i;
+ return 0;
}