Bug 674888 - Allow elfhack to move .interp sections. r=tglek

This commit is contained in:
Mike Hommey 2011-08-03 10:28:47 +02:00
parent d05c6783df
commit a20e153d7b
2 changed files with 29 additions and 2 deletions

View File

@ -566,6 +566,7 @@ void ElfSegment::addSection(ElfSection *section)
if ((*i)->getAddr() > section->getAddr()) if ((*i)->getAddr() > section->getAddr())
break; break;
sections.insert(i, section); sections.insert(i, section);
section->addToSegment(this);
} }
unsigned int ElfSegment::getFileSize() unsigned int ElfSegment::getFileSize()
@ -636,8 +637,10 @@ ElfSegment *ElfSegment::splitBefore(ElfSection *section)
phdr.p_memsz = (unsigned int)-1; phdr.p_memsz = (unsigned int)-1;
ElfSegment *segment = new ElfSegment(&phdr); ElfSegment *segment = new ElfSegment(&phdr);
for (rm = i; i != sections.end(); ++i) for (rm = i; i != sections.end(); ++i) {
(*i)->removeFromSegment(this);
segment->addSection(*i); segment->addSection(*i);
}
sections.erase(rm, sections.end()); sections.erase(rm, sections.end());
return segment; return segment;

View File

@ -41,6 +41,7 @@
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <algorithm>
#include <elf.h> #include <elf.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
@ -370,7 +371,8 @@ public:
(getType() == SHT_GNU_HASH) || (getType() == SHT_GNU_HASH) ||
(getType() == SHT_GNU_verdef) || (getType() == SHT_GNU_verdef) ||
(getType() == SHT_GNU_verneed) || (getType() == SHT_GNU_verneed) ||
(getType() == SHT_GNU_versym)) && (getType() == SHT_GNU_versym) ||
isInSegmentType(PT_INTERP)) &&
(getFlags() & SHF_ALLOC); (getFlags() & SHF_ALLOC);
} }
@ -410,6 +412,20 @@ public:
file.seekp(getOffset()); file.seekp(getOffset());
file.write(data, getSize()); file.write(data, getSize());
} }
private:
friend class ElfSegment;
void addToSegment(ElfSegment *segment) {
segments.push_back(segment);
}
void removeFromSegment(ElfSegment *segment) {
std::vector<ElfSegment *>::iterator i = std::find(segments.begin(), segments.end(), segment);
segments.erase(i, i + 1);
}
bool isInSegmentType(unsigned int type);
protected: protected:
Elf_Shdr shdr; Elf_Shdr shdr;
char *data; char *data;
@ -419,6 +435,7 @@ private:
SectionInfo info; SectionInfo info;
ElfSection *next, *previous; ElfSection *next, *previous;
int index; int index;
std::vector<ElfSegment *> segments;
}; };
class ElfSegment { class ElfSegment {
@ -636,6 +653,13 @@ inline unsigned int Elf::getSize() {
return section->getOffset() + section->getSize(); return section->getOffset() + section->getSize();
} }
inline bool ElfSection::isInSegmentType(unsigned int type) {
for (std::vector<ElfSegment *>::iterator seg = segments.begin(); seg != segments.end(); seg++)
if ((*seg)->getType() == type)
return true;
return false;
}
inline ElfLocation::ElfLocation(ElfSection *section, unsigned int off, enum position pos) inline ElfLocation::ElfLocation(ElfSection *section, unsigned int off, enum position pos)
: section(section) { : section(section) {
if ((pos == ABSOLUTE) && section) if ((pos == ABSOLUTE) && section)