[all-commits] [llvm/llvm-project] ef2837: [llvm-objcopy] Fix file offsets when PT_INTERP/PT_...
Fangrui Song via All-commits
all-commits at lists.llvm.org
Tue Feb 20 09:26:16 PST 2024
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: ef28379022121ce32cf93d7c3a7571a73ab5f801
https://github.com/llvm/llvm-project/commit/ef28379022121ce32cf93d7c3a7571a73ab5f801
Author: Fangrui Song <i at maskray.me>
Date: 2024-02-20 (Tue, 20 Feb 2024)
Changed paths:
M llvm/lib/ObjCopy/ELF/ELFObject.cpp
A llvm/test/tools/llvm-objcopy/ELF/non-load-at-load-start.test
Log Message:
-----------
[llvm-objcopy] Fix file offsets when PT_INTERP/PT_LOAD offsets are equal (#80562)
(#79887) When the offset of a PT_INTERP segment equals the offset of a
PT_LOAD segment, we consider that the parent of the PT_LOAD segment is
the PT_INTERP segment. In `layoutSegments`, we place both segments to be
after the current `Offset`, ignoring the PT_LOAD alignment.
This scenario is possible with fixed section addresses, but doesn't
happen with default linker layouts (.interp precedes other sections and
is part of a PT_LOAD segment containing the ELF header and program
headers).
```
% cat a.s
.globl _start; _start: ret
.rodata; .byte 0
.tdata; .balign 4096; .byte 0
% clang -fuse-ld=lld a.s -o a -nostdlib -no-pie -z separate-loadable-segments -Wl,-Ttext=0x201000,--section-start=.interp=0x202000,--section-start=.rodata=0x202020,-z,nognustack
% llvm-objcopy a a2
% llvm-readelf -l a2 # incorrect offset(PT_LOAD)
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000200040 0x0000000000200040 0x0001c0 0x0001c0 R 0x8
INTERP 0x001001 0x0000000000202000 0x0000000000202000 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000200000 0x0000000000200000 0x000200 0x000200 R 0x1000
LOAD 0x001000 0x0000000000201000 0x0000000000201000 0x000001 0x000001 R E 0x1000
//// incorrect offset
LOAD 0x001001 0x0000000000202000 0x0000000000202000 0x000021 0x000021 R 0x1000
LOAD 0x002000 0x0000000000203000 0x0000000000203000 0x000001 0x001000 RW 0x1000
TLS 0x002000 0x0000000000203000 0x0000000000203000 0x000001 0x000001 R 0x1000
GNU_RELRO 0x002000 0x0000000000203000 0x0000000000203000 0x000001 0x001000 R 0x1000
```
The same issue occurs for PT_TLS/PT_GNU_RELRO if we PT_TLS's alignment
is smaller and we place the PT_LOAD after PT_TLS/PT_GNU_RELRO segments
(not linker default, but possible with a `PHDRS` linker script command).
Fix #79887: when two segments have the same offset, order the one with a
larger alignment first. In the previous case, the PT_LOAD segment will
go before the PT_INTERP segment. In case of equal alignments, it doesn't
matter which segment is treated as the parent segment.
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list