diff options
author | James Henderson <jh7370@my.bristol.ac.uk> | 2019-04-02 14:11:13 +0000 |
---|---|---|
committer | James Henderson <jh7370@my.bristol.ac.uk> | 2019-04-02 14:11:13 +0000 |
commit | 38cb238f752cefe5fde8bf6cb73dacc3fec8f89d (patch) | |
tree | 44472d3158aeffed95ebcef7854b3c1ef93960ed /llvm/tools/llvm-objcopy/ELF/Object.cpp | |
parent | 68ad5c34e076475cf5691ead29c1ae6515272b75 (diff) | |
download | bcm5719-llvm-38cb238f752cefe5fde8bf6cb73dacc3fec8f89d.tar.gz bcm5719-llvm-38cb238f752cefe5fde8bf6cb73dacc3fec8f89d.zip |
[llvm-objcopy]Allow llvm-objcopy to be used on an ELF file with no section headers
This patch fixes https://bugs.llvm.org/show_bug.cgi?id=41293 and
https://bugs.llvm.org/show_bug.cgi?id=41045. llvm-objcopy assumed that
it could always read a section header string table. This isn't the case
when the sections were previously all stripped, and the e_shstrndx field
was set to 0. This patch fixes this. It also fixes a double space in an
error message relating to this issue, and prevents llvm-objcopy from
adding extra space for non-existent section headers, meaning that
--strip-sections on the output of a previous --strip-sections run
produces identical output, simplifying the test.
Reviewed by: rupprecht, grimar
Differential Revision: https://reviews.llvm.org/D59989
llvm-svn: 357475
Diffstat (limited to 'llvm/tools/llvm-objcopy/ELF/Object.cpp')
-rw-r--r-- | llvm/tools/llvm-objcopy/ELF/Object.cpp | 28 |
1 files changed, 18 insertions, 10 deletions
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() { |