Skip to content

Commit fd624e6

Browse files
committed
[llvm-objcopy] Don't specialize the all zero p_paddr case
Spotted by https://reviews.llvm.org/D74755#1998673 > it looks like OrderedSegments in the function is only used to set the physical address to the virtual address when there are no physical addresses set amongst these sections. I believe this behavior was copied from https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=6ffd79000b45e77b3625143932ffbf781b6aecab (2008-05) The commit was made for some corner cases of very old linkers. This special rule does not seem useful and remove it can allow us to delete a large chunk of code. Reviewed By: jhenderson, jakehehrlich Differential Revision: https://reviews.llvm.org/D78786
1 parent dab1326 commit fd624e6

File tree

2 files changed

+17
-46
lines changed

2 files changed

+17
-46
lines changed

llvm/test/tools/llvm-objcopy/ELF/binary-no-paddr.test

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
1-
# RUN: yaml2obj %s -o %t
2-
# RUN: llvm-objcopy -O binary %t %t2
3-
# RUN: od -t x2 -v %t2 | FileCheck %s --ignore-case
4-
# RUN: wc -c < %t2 | FileCheck %s --check-prefix=SIZE
1+
# RUN: yaml2obj -D PADDR=1 %s -o %t1
2+
# RUN: llvm-objcopy -O binary %t1 %t1.out
3+
# RUN: od -t x2 -v %t1.out | FileCheck %s --ignore-case
4+
# RUN: wc -c < %t1.out | FileCheck %s --check-prefix=SIZE
5+
6+
## When all p_paddr fields are 0, GNU objcopy resets LMA to VMA
7+
## and gives a different output.
8+
## https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=6ffd79000b45e77b3625143932ffbf781b6aecab
9+
## We don't implement this special rule. The p_paddr=0 output is the same as
10+
## the p_paddr=1 case.
11+
# RUN: yaml2obj -D PADDR=0 %s -o %t0
12+
# RUN: llvm-objcopy -O binary %t0 %t0.out
13+
# RUN: cmp %t1.out %t0.out
514

615
!ELF
716
FileHeader:
@@ -26,17 +35,15 @@ ProgramHeaders:
2635
- Type: PT_LOAD
2736
Flags: [ PF_X, PF_R ]
2837
VAddr: 0x1000
29-
PAddr: 0x0000
30-
Align: 0x1000
38+
PAddr: [[PADDR]]
3139
Sections:
3240
- Section: .text
3341
- Type: PT_LOAD
3442
Flags: [ PF_R, PF_W ]
3543
VAddr: 0x1004
36-
PAddr: 0x0000
37-
Align: 0x1000
44+
PAddr: [[PADDR]]
3845
Sections:
3946
- Section: .data
4047

41-
# CHECK: 0000000 c3c3 c3c3 3232
42-
# SIZE: 6
48+
# CHECK: 0000000 3232 c3c3
49+
# SIZE: 4

llvm/tools/llvm-objcopy/ELF/Object.cpp

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,14 +1101,6 @@ static bool compareSegmentsByOffset(const Segment *A, const Segment *B) {
11011101
return A->Index < B->Index;
11021102
}
11031103

1104-
static bool compareSegmentsByPAddr(const Segment *A, const Segment *B) {
1105-
if (A->PAddr < B->PAddr)
1106-
return true;
1107-
if (A->PAddr > B->PAddr)
1108-
return false;
1109-
return A->Index < B->Index;
1110-
}
1111-
11121104
void BasicELFBuilder::initFileHeader() {
11131105
Obj->Flags = 0x0;
11141106
Obj->Type = ET_REL;
@@ -2224,34 +2216,6 @@ Error BinaryWriter::write() {
22242216
}
22252217

22262218
Error BinaryWriter::finalize() {
2227-
// We need a temporary list of segments that has a special order to it
2228-
// so that we know that anytime ->ParentSegment is set that segment has
2229-
// already had it's offset properly set. We only want to consider the segments
2230-
// that will affect layout of allocated sections so we only add those.
2231-
std::vector<Segment *> OrderedSegments;
2232-
for (const SectionBase &Sec : Obj.allocSections())
2233-
if (Sec.ParentSegment != nullptr)
2234-
OrderedSegments.push_back(Sec.ParentSegment);
2235-
2236-
// For binary output, we're going to use physical addresses instead of
2237-
// virtual addresses, since a binary output is used for cases like ROM
2238-
// loading and physical addresses are intended for ROM loading.
2239-
// However, if no segment has a physical address, we'll fallback to using
2240-
// virtual addresses for all.
2241-
if (all_of(OrderedSegments,
2242-
[](const Segment *Seg) { return Seg->PAddr == 0; }))
2243-
for (Segment *Seg : OrderedSegments)
2244-
Seg->PAddr = Seg->VAddr;
2245-
2246-
llvm::stable_sort(OrderedSegments, compareSegmentsByPAddr);
2247-
2248-
// Because we add a ParentSegment for each section we might have duplicate
2249-
// segments in OrderedSegments. If there were duplicates then layoutSegments
2250-
// would do very strange things.
2251-
auto End =
2252-
std::unique(std::begin(OrderedSegments), std::end(OrderedSegments));
2253-
OrderedSegments.erase(End, std::end(OrderedSegments));
2254-
22552219
// Compute the section LMA based on its sh_offset and the containing segment's
22562220
// p_offset and p_paddr. Also compute the minimum LMA of all sections as
22572221
// MinAddr. In the output, the contents between address 0 and MinAddr will be

0 commit comments

Comments
 (0)