зеркало из https://github.com/mozilla/gecko-dev.git
Bug 725284 - Preserve PT_LOAD alignment, except when it's the default on x86-64. r=tglek
This commit is contained in:
Родитель
a7583a7dcc
Коммит
c3d9ce8c6d
|
@ -95,7 +95,7 @@ test$(DLL_SUFFIX): test.$(OBJ_SUFFIX) elfhack $(CSRCS:.c=.$(OBJ_SUFFIX))
|
|||
@echo === --disable-elf-hack until this is fixed.
|
||||
@echo ===
|
||||
@rm -f $@.bak
|
||||
$(CURDIR)/elfhack -b $@
|
||||
$(CURDIR)/elfhack -b -f $@
|
||||
# Fail if the backup file doesn't exist
|
||||
[ -f "$@.bak" ]
|
||||
# Fail if the new library doesn't contain less relocations
|
||||
|
|
|
@ -265,6 +265,15 @@ Elf::Elf(std::ifstream &file)
|
|||
file.seekg(ehdr->e_phoff);
|
||||
for (int i = 0; i < ehdr->e_phnum; i++) {
|
||||
Elf_Phdr phdr(file, e_ident[EI_CLASS], e_ident[EI_DATA]);
|
||||
if (phdr.p_type == PT_LOAD) {
|
||||
// Default alignment for PT_LOAD on x86-64 prevents elfhack from
|
||||
// doing anything useful. However, the system doesn't actually
|
||||
// require such a big alignment, so in order for elfhack to work
|
||||
// efficiently, reduce alignment when it's originally the default
|
||||
// one.
|
||||
if ((ehdr->e_machine == EM_X86_64) && (phdr.p_align == 0x200000))
|
||||
phdr.p_align = 0x1000;
|
||||
}
|
||||
ElfSegment *segment = new ElfSegment(&phdr);
|
||||
// Some segments aren't entirely filled (if at all) by sections
|
||||
// For those, we use fake sections
|
||||
|
@ -503,12 +512,17 @@ unsigned int ElfSection::getOffset()
|
|||
if (previous->getType() != SHT_NOBITS)
|
||||
offset += previous->getSize();
|
||||
|
||||
Elf32_Word align = 0x1000;
|
||||
for (std::vector<ElfSegment *>::iterator seg = segments.begin(); seg != segments.end(); seg++)
|
||||
align = std::max(align, (*seg)->getAlign());
|
||||
|
||||
Elf32_Word mask = align - 1;
|
||||
// SHF_TLS is used for .tbss which is some kind of special case.
|
||||
if (((getType() != SHT_NOBITS) || (getFlags() & SHF_TLS)) && (getFlags() & SHF_ALLOC)) {
|
||||
if ((getAddr() & 4095) < (offset & 4095))
|
||||
offset = (offset | 4095) + (getAddr() & 4095) + 1;
|
||||
if ((getAddr() & mask) < (offset & mask))
|
||||
offset = (offset | mask) + (getAddr() & mask) + 1;
|
||||
else
|
||||
offset = (offset & ~4095) + (getAddr() & 4095);
|
||||
offset = (offset & ~mask) + (getAddr() & mask);
|
||||
}
|
||||
if ((getType() != SHT_NOBITS) && (offset & (getAddrAlign() - 1)))
|
||||
offset = (offset | (getAddrAlign() - 1)) + 1;
|
||||
|
@ -632,7 +646,7 @@ ElfSegment *ElfSegment::splitBefore(ElfSection *section)
|
|||
phdr.p_vaddr = 0;
|
||||
phdr.p_paddr = phdr.p_vaddr + v_p_diff;
|
||||
phdr.p_flags = flags;
|
||||
phdr.p_align = 0x1000;
|
||||
phdr.p_align = getAlign();
|
||||
phdr.p_filesz = (unsigned int)-1;
|
||||
phdr.p_memsz = (unsigned int)-1;
|
||||
ElfSegment *segment = new ElfSegment(&phdr);
|
||||
|
|
|
@ -501,7 +501,7 @@ static inline int backup_file(const char *name)
|
|||
return rename(name, fname.c_str());
|
||||
}
|
||||
|
||||
void do_file(const char *name, bool backup = false)
|
||||
void do_file(const char *name, bool backup = false, bool force = false)
|
||||
{
|
||||
std::ifstream file(name, std::ios::in|std::ios::binary);
|
||||
Elf *elf = new Elf(file);
|
||||
|
@ -531,7 +531,7 @@ void do_file(const char *name, bool backup = false)
|
|||
break;
|
||||
}
|
||||
if (exit == 0) {
|
||||
if (elf->getSize() >= size) {
|
||||
if (!force && (elf->getSize() >= size)) {
|
||||
fprintf(stderr, "No gain. Skipping\n");
|
||||
} else if (backup && backup_file(name) != 0) {
|
||||
fprintf(stderr, "Couln't create backup file\n");
|
||||
|
@ -548,14 +548,17 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
int arg;
|
||||
bool backup = false;
|
||||
bool force = false;
|
||||
char *lastSlash = rindex(argv[0], '/');
|
||||
if (lastSlash != NULL)
|
||||
rundir = strndup(argv[0], lastSlash - argv[0]);
|
||||
for (arg = 1; arg < argc; arg++) {
|
||||
if (strcmp(argv[arg], "-b") == 0)
|
||||
if (strcmp(argv[arg], "-f") == 0)
|
||||
force = true;
|
||||
else if (strcmp(argv[arg], "-b") == 0)
|
||||
backup = true;
|
||||
else
|
||||
do_file(argv[arg], backup);
|
||||
do_file(argv[arg], backup, force);
|
||||
}
|
||||
|
||||
free(rundir);
|
||||
|
|
|
@ -444,7 +444,7 @@ public:
|
|||
|
||||
unsigned int getType() { return type; }
|
||||
unsigned int getFlags() { return flags; }
|
||||
unsigned int getAlign() { return type == PT_LOAD ? 0x1000 : align; /* TODO: remove this gross hack */ }
|
||||
unsigned int getAlign() { return align; }
|
||||
|
||||
ElfSection *getFirstSection() { return sections.empty() ? NULL : sections.front(); }
|
||||
int getVPDiff() { return v_p_diff; }
|
||||
|
|
Загрузка…
Ссылка в новой задаче