-
-
Notifications
You must be signed in to change notification settings - Fork 477
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Split segment size fix #447
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -436,7 +436,7 @@ static uint64_t roundUp(uint64_t n, uint64_t m) | |
|
||
|
||
template<ElfFileParams> | ||
void ElfFile<ElfFileParamNames>::shiftFile(unsigned int extraPages, size_t startOffset) | ||
void ElfFile<ElfFileParamNames>::shiftFile(unsigned int extraPages, size_t startOffset, size_t extraBytes) | ||
{ | ||
assert(startOffset >= sizeof(Elf_Ehdr)); | ||
|
||
|
@@ -463,6 +463,9 @@ void ElfFile<ElfFileParamNames>::shiftFile(unsigned int extraPages, size_t start | |
|
||
int splitIndex = -1; | ||
size_t splitShift = 0; | ||
/* Save off the flags from the segment that we are splitting so we can apply the same value | ||
to both of the resulting segments. */ | ||
decltype(phdrs.at(0).p_flags) splitFlags = 0; | ||
|
||
/* Update the offsets in the program headers. */ | ||
for (int i = 0; i < rdi(hdr()->e_phnum); ++i) { | ||
|
@@ -473,6 +476,7 @@ void ElfFile<ElfFileParamNames>::shiftFile(unsigned int extraPages, size_t start | |
|
||
splitIndex = i; | ||
splitShift = startOffset - p_start; | ||
splitFlags = rdi(phdrs.at(i).p_flags); | ||
|
||
/* This is the load segment we're currently extending within, so we split it. */ | ||
wri(phdrs.at(i).p_offset, startOffset); | ||
|
@@ -512,8 +516,8 @@ void ElfFile<ElfFileParamNames>::shiftFile(unsigned int extraPages, size_t start | |
wri(phdr.p_offset, phdrs.at(splitIndex).p_offset - splitShift - shift); | ||
wri(phdr.p_paddr, phdrs.at(splitIndex).p_paddr - splitShift - shift); | ||
wri(phdr.p_vaddr, phdrs.at(splitIndex).p_vaddr - splitShift - shift); | ||
wri(phdr.p_filesz, wri(phdr.p_memsz, splitShift + shift)); | ||
wri(phdr.p_flags, PF_R | PF_W); | ||
wri(phdr.p_filesz, wri(phdr.p_memsz, splitShift + extraBytes)); | ||
wri(phdr.p_flags, splitFlags); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This flags change made sense to me initially too but can be incorrect, since we can move a This change might be the cause of some CI failures. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, that makes sense. I am admittedly not an expert in the intricacies of the ELF format, so I wasn't aware of this. When I'm able to look at this again (maybe not until next week), I will back out the change to the flags. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I reverted the change to how the segment flags are handled. I'm not sure how to re-run the CI build though. |
||
wri(phdr.p_align, getPageSize()); | ||
} | ||
|
||
|
@@ -912,12 +916,14 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable() | |
neededSpace += sizeof(Elf_Phdr); | ||
debug("needed space is %d\n", neededSpace); | ||
|
||
unsigned int neededPages = roundUp(neededSpace - startOffset, getPageSize()) / getPageSize(); | ||
/* Calculate how many bytes are needed out of the additional pages. */ | ||
size_t extraSpace = neededSpace - startOffset; | ||
unsigned int neededPages = roundUp(extraSpace, getPageSize()) / getPageSize(); | ||
debug("needed pages is %d\n", neededPages); | ||
if (neededPages * getPageSize() > firstPage) | ||
error("virtual address space underrun!"); | ||
|
||
shiftFile(neededPages, startOffset); | ||
shiftFile(neededPages, startOffset, extraSpace); | ||
|
||
firstPage -= neededPages * getPageSize(); | ||
startOffset += neededPages * getPageSize(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to check: can you post what the sections look like for you after this change?
In particular, my head says the address of the moved section needs adjusting too, but I might not be reading this correctly so comparing the output before & after would be useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I should have made that more clear in the beginning. Here is the output of
readelf -l <file>
for the three cases (again, from a Python 3.10 executable that I built from source)Unmodified executable used as input to
patchelf
Output of
patchelf
master branchThis is the version that segfaults upon execution.
Output of
patchelf
from this branch