summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/test/tools/llvm-objcopy/ELF/copy-after-strip-sections.test26
-rw-r--r--llvm/tools/llvm-objcopy/ELF/Object.cpp28
-rw-r--r--llvm/tools/llvm-objcopy/ELF/Object.h6
3 files changed, 47 insertions, 13 deletions
diff --git a/llvm/test/tools/llvm-objcopy/ELF/copy-after-strip-sections.test b/llvm/test/tools/llvm-objcopy/ELF/copy-after-strip-sections.test
new file mode 100644
index 00000000000..3b61649b263
--- /dev/null
+++ b/llvm/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
diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp
index 321adf6fff0..de51851ecfe 100644
--- a/llvm/tools/llvm-objcopy/ELF/Object.cpp
+++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp
@@ -1212,13 +1212,16 @@ template <class ELFT> void ELFBuilder<ELFT>::build() {
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() {}
@@ -1372,6 +1375,10 @@ template <class ELFT> void ELFWriter<ELFT>::writeSegmentData() {
}
}
+template <class ELFT>
+ELFWriter<ELFT>::ELFWriter(Object &Obj, Buffer &Buf, bool WSH)
+ : Writer(Obj, Buf), WriteSectionHeaders(WSH && Obj.HadShdrs) {}
+
Error Object::removeSections(
std::function<bool(const SectionBase &)> ToRemove) {
@@ -1558,9 +1565,10 @@ template <class ELFT> void ELFWriter<ELFT>::assignOffsets() {
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() {
diff --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/tools/llvm-objcopy/ELF/Object.h
index f85d4b70018..4e0e23e5f49 100644
--- a/llvm/tools/llvm-objcopy/ELF/Object.h
+++ b/llvm/tools/llvm-objcopy/ELF/Object.h
@@ -226,12 +226,11 @@ private:
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) {}
+ ELFWriter(Object &Obj, Buffer &Buf, bool WSH);
};
class BinaryWriter : public Writer {
@@ -810,6 +809,7 @@ public:
uint32_t Version;
uint32_t Flags;
+ bool HadShdrs = true;
StringTableSection *SectionNames = nullptr;
SymbolTableSection *SymbolTable = nullptr;
SectionIndexSection *SectionIndexTable = nullptr;
OpenPOWER on IntegriCloud