Skip to content

Commit

Permalink
[llvm][llvm-objcopy] When outputting to binary don't output segments …
Browse files Browse the repository at this point in the history
…that cover no sections

Sometimes LLD will produce a PT_LOAD segment that only covers the
headers (and covers no sections). GNU objcopy does not output the
segment contents for these sections. In particular this is an issue in
building magenta because the final link step for the kernel would
produce just such a PT_LOAD segment. This change is to support this case
and to match what GNU objcopy does in this case.

Patch by Jake Ehrlich

Differential Revision: https://reviews.llvm.org/D36196

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310149 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
petrhosek committed Aug 4, 2017
1 parent 0b67c73 commit fdd2cc8
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 2 deletions.
Binary file added test/tools/llvm-objcopy/Inputs/pt-phdr.elf
Binary file not shown.
4 changes: 4 additions & 0 deletions test/tools/llvm-objcopy/sectionless-segment.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# RUN: llvm-objcopy -O binary %p/Inputs/pt-phdr.elf %t
# RUN: wc -c < %t | FileCheck %s

# CHECK: 4110
8 changes: 6 additions & 2 deletions tools/llvm-objcopy/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,10 @@ template <class ELFT> size_t BinaryObject<ELFT>::totalSize() const {
template <class ELFT>
void BinaryObject<ELFT>::write(FileOutputBuffer &Out) const {
for (auto &Segment : this->Segments) {
if (Segment->Type == llvm::ELF::PT_LOAD) {
// GNU objcopy does not output segments that do not cover a section. Such
// segments can sometimes be produced by LLD due to how LLD handles PT_PHDR.
if (Segment->Type == llvm::ELF::PT_LOAD &&
Segment->firstSection() != nullptr) {
Segment->writeSegment(Out);
}
}
Expand All @@ -373,7 +376,8 @@ template <class ELFT> void BinaryObject<ELFT>::finalize() {

uint64_t Offset = 0;
for (auto &Segment : this->Segments) {
if (Segment->Type == llvm::ELF::PT_LOAD) {
if (Segment->Type == llvm::ELF::PT_LOAD &&
Segment->firstSection() != nullptr) {
Offset = alignTo(Offset, Segment->Align);
Segment->Offset = Offset;
Offset += Segment->FileSize;
Expand Down

0 comments on commit fdd2cc8

Please sign in to comment.