OSDN Git Service

[llvm][llvm-objcopy] When outputting to binary don't output segments that cover no...
authorPetr Hosek <phosek@chromium.org>
Fri, 4 Aug 2017 23:18:18 +0000 (23:18 +0000)
committerPetr Hosek <phosek@chromium.org>
Fri, 4 Aug 2017 23:18:18 +0000 (23:18 +0000)
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

test/tools/llvm-objcopy/Inputs/pt-phdr.elf [new file with mode: 0644]
test/tools/llvm-objcopy/sectionless-segment.test [new file with mode: 0644]
tools/llvm-objcopy/Object.cpp

diff --git a/test/tools/llvm-objcopy/Inputs/pt-phdr.elf b/test/tools/llvm-objcopy/Inputs/pt-phdr.elf
new file mode 100644 (file)
index 0000000..cede0e7
Binary files /dev/null and b/test/tools/llvm-objcopy/Inputs/pt-phdr.elf differ
diff --git a/test/tools/llvm-objcopy/sectionless-segment.test b/test/tools/llvm-objcopy/sectionless-segment.test
new file mode 100644 (file)
index 0000000..054e84f
--- /dev/null
@@ -0,0 +1,4 @@
+# RUN: llvm-objcopy -O binary %p/Inputs/pt-phdr.elf %t
+# RUN: wc -c < %t | FileCheck %s
+
+# CHECK: 4110
index 576f660..adb2543 100644 (file)
@@ -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);
     }
   }
@@ -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;