[PATCH] D59989: [llvm-objcopy]Allow llvm-objcopy to be used on an ELF file with no section headers

James Henderson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 2 06:14:21 PDT 2019


jhenderson updated this revision to Diff 193266.
jhenderson added a comment.

Rebase and address comment.

Unfortunately, this build fails on Linux. Somehow MSVC is able to handle the incomplete type of Object in the ELFWriter constructor, whereas the version of GCC that I'm using doesn't. The Writer classes aren't really part of the Object interface, so I'm going to move them into a separate header.


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59989/new/

https://reviews.llvm.org/D59989

Files:
  test/tools/llvm-objcopy/ELF/copy-after-strip-sections.test
  tools/llvm-objcopy/ELF/Object.cpp
  tools/llvm-objcopy/ELF/Object.h


Index: tools/llvm-objcopy/ELF/Object.h
===================================================================
--- tools/llvm-objcopy/ELF/Object.h
+++ tools/llvm-objcopy/ELF/Object.h
@@ -226,12 +226,12 @@
 
 public:
   virtual ~ELFWriter() {}
-  bool WriteSectionHeaders = true;
+  bool WriteSectionHeaders;
 
   Error finalize() override;
   Error write() override;
   ELFWriter(Object &Obj, Buffer &Buf, bool WSH)
-      : Writer(Obj, Buf), WriteSectionHeaders(WSH) {}
+      : Writer(Obj, Buf), WriteSectionHeaders(WSH && Obj.HadShdrs) {}
 };
 
 class BinaryWriter : public Writer {
@@ -810,6 +810,7 @@
   uint32_t Version;
   uint32_t Flags;
 
+  bool HadShdrs = true;
   StringTableSection *SectionNames = nullptr;
   SymbolTableSection *SymbolTable = nullptr;
   SectionIndexSection *SectionIndexTable = nullptr;
Index: tools/llvm-objcopy/ELF/Object.cpp
===================================================================
--- tools/llvm-objcopy/ELF/Object.cpp
+++ tools/llvm-objcopy/ELF/Object.cpp
@@ -1212,13 +1212,16 @@
   if (ShstrIndex == SHN_XINDEX)
     ShstrIndex = unwrapOrError(ElfFile.getSection(0))->sh_link;
 
-  Obj.SectionNames =
-      Obj.sections().template getSectionOfType<StringTableSection>(
-          ShstrIndex,
-          "e_shstrndx field value " + Twine(Ehdr.e_shstrndx) +
-              " in elf header " + " is invalid",
-          "e_shstrndx field value " + Twine(Ehdr.e_shstrndx) +
-              " in elf header " + " is not a string table");
+  if (ShstrIndex == SHN_UNDEF)
+    Obj.HadShdrs = false;
+  else
+    Obj.SectionNames =
+        Obj.sections().template getSectionOfType<StringTableSection>(
+            ShstrIndex,
+            "e_shstrndx field value " + Twine(Ehdr.e_shstrndx) +
+                " in elf header is invalid",
+            "e_shstrndx field value " + Twine(Ehdr.e_shstrndx) +
+                " in elf header is not a string table");
 }
 
 Writer::~Writer() {}
@@ -1558,9 +1561,10 @@
 template <class ELFT> size_t ELFWriter<ELFT>::totalSize() const {
   // We already have the section header offset so we can calculate the total
   // size by just adding up the size of each section header.
-  auto NullSectionSize = WriteSectionHeaders ? sizeof(Elf_Shdr) : 0;
-  return Obj.SHOffset + Obj.sections().size() * sizeof(Elf_Shdr) +
-         NullSectionSize;
+  if (!WriteSectionHeaders)
+    return Obj.SHOffset;
+  size_t ShdrCount = Obj.sections().size() + 1; // Includes null shdr.
+  return Obj.SHOffset + ShdrCount * sizeof(Elf_Shdr);
 }
 
 template <class ELFT> Error ELFWriter<ELFT>::write() {
Index: test/tools/llvm-objcopy/ELF/copy-after-strip-sections.test
===================================================================
--- test/tools/llvm-objcopy/ELF/copy-after-strip-sections.test
+++ test/tools/llvm-objcopy/ELF/copy-after-strip-sections.test
@@ -0,0 +1,26 @@
+# llvm-objcopy's --strip-sections removes the section headers. It should be
+# possible to run the tool on the output after this operation. Performing any
+# subsequent stripping operation, or copying the object, should produce
+# identical output.
+
+# RUN: yaml2obj %s -o %t.in
+# RUN: llvm-objcopy %t.in %t.stripped --strip-sections
+# RUN: llvm-objcopy %t.stripped %t.stripped2 --strip-sections
+# RUN: llvm-objcopy %t.stripped2 %t.out
+# RUN: cmp %t.stripped %t.stripped2
+# RUN: cmp %t.stripped %t.out
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_X86_64
+Sections:
+  - Name: .text
+    Type: SHT_PROGBITS
+    Content: 'facefeed'
+ProgramHeaders:
+  - Type: PT_LOAD
+    Sections:
+      - Section: .text


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D59989.193266.patch
Type: text/x-patch
Size: 3618 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190402/a4d5785e/attachment.bin>


More information about the llvm-commits mailing list