Skip to content

Align startOffset with p_align instead of pagesize for compatibility #510

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

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/patchelf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,13 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
neededSpace += headerTableSpace;
debug("needed space is %d\n", neededSpace);

Elf_Off startOffset = roundUp(fileContents->size(), getPageSize());
/* glibc earlier than 2.35 requires that the LOAD segment satisfies
(p_vaddr mod p_align) == (p_offset mod p_align).
The ELF specification requires that loadable process segments satisfy
(p_vaddr mod pagesize) == (p_offset mod pagesize), so glibc is probably
wrong, but here startOffset is calculated according to p_align for
compatibility. */
Elf_Off startOffset = roundUp(fileContents->size(), alignStartPage);

// In older version of binutils (2.30), readelf would check if the dynamic
// section segment is strictly smaller than the file (and not same size).
Expand Down Expand Up @@ -879,7 +885,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
rdi(lastSeg.p_type) == PT_LOAD &&
rdi(lastSeg.p_flags) == (PF_R | PF_W) &&
rdi(lastSeg.p_align) == alignStartPage) {
auto segEnd = roundUp(rdi(lastSeg.p_offset) + rdi(lastSeg.p_memsz), getPageSize());
auto segEnd = roundUp(rdi(lastSeg.p_offset) + rdi(lastSeg.p_memsz), alignStartPage);
if (segEnd == startOffset) {
auto newSz = startOffset + neededSpace - rdi(lastSeg.p_offset);
wri(lastSeg.p_filesz, wri(lastSeg.p_memsz, newSz));
Expand Down