author | David Major <dmajor@mozilla.com> |
Thu, 16 Jan 2020 21:04:49 +0000 | |
changeset 510529 | 088590c7630c2d1d84905494abbd2c82830244dd |
parent 510528 | 4153f03aa6ab82f6ab8d430cca47ebe6236fb3ae |
child 510530 | 62b38d54dfb44330e92ce29186ebbbf6c431a797 |
push id | 37025 |
push user | opoprus@mozilla.com |
push date | Fri, 17 Jan 2020 09:44:53 +0000 |
treeherder | mozilla-central@cb06fe24fb3e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | tjr |
bugs | 1609780, 1590624 |
milestone | 74.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
deleted file mode 100644 --- a/build/build-clang/mingwclang-llvm-objcopy-COFF-Add-support-for-removing-sections.patch +++ /dev/null @@ -1,665 +0,0 @@ -From 2ccafacb7ddd740054dbee06655749ebc55a4d86 Mon Sep 17 00:00:00 2001 -From: Martin Storsjo <martin@martin.st> -Date: Sat, 19 Jan 2019 19:42:35 +0000 -Subject: [PATCH] [llvm-objcopy] [COFF] Add support for removing sections - -Differential Revision: https://reviews.llvm.org/D56683 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351660 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - .../llvm-objcopy/COFF/remove-section.test | 210 ++++++++++++++++++ - tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 10 +- - tools/llvm-objcopy/COFF/Object.cpp | 63 ++++++ - tools/llvm-objcopy/COFF/Object.h | 27 ++- - tools/llvm-objcopy/COFF/Reader.cpp | 31 ++- - tools/llvm-objcopy/COFF/Writer.cpp | 68 ++++-- - tools/llvm-objcopy/COFF/Writer.h | 1 + - 7 files changed, 391 insertions(+), 19 deletions(-) - create mode 100644 test/tools/llvm-objcopy/COFF/remove-section.test - -diff --git a/llvm/test/tools/llvm-objcopy/COFF/remove-section.test b/llvm/test/tools/llvm-objcopy/COFF/remove-section.test -new file mode 100644 -index 00000000000..b3dfb0b98cb ---- /dev/null -+++ b/llvm/test/tools/llvm-objcopy/COFF/remove-section.test -@@ -0,0 +1,210 @@ -+# RUN: yaml2obj %s > %t.in.o -+# -+# RUN: llvm-objdump -section-headers %t.in.o | FileCheck %s --check-prefixes=SECTIONS-PRE -+# RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS-PRE -+# -+# RUN: llvm-objcopy -R .bss %t.in.o %t.remove-bss.o -+# RUN: llvm-objdump -section-headers %t.remove-bss.o | FileCheck %s --check-prefix=SECTIONS-REMOVE-BSS -+# RUN: llvm-objdump -t %t.remove-bss.o | FileCheck %s --check-prefix=SYMBOLS-REMOVE-BSS -+# -+# RUN: llvm-objcopy --remove-section .bss %t.in.o %t.cmp.o -+# RUN: cmp %t.remove-bss.o %t.cmp.o -+# -+# RUN: llvm-objcopy -R .text %t.in.o %t.remove-text.o -+# RUN: llvm-objdump -section-headers %t.remove-text.o | FileCheck %s --check-prefix=SECTIONS-REMOVE-TEXT -+# RUN: llvm-objdump -t %t.remove-text.o | FileCheck %s --check-prefix=SYMBOLS-REMOVE-TEXT -+# -+# RUN: not llvm-objcopy -R .comdat %t.in.o %t.remove-comdat.o 2>&1 | FileCheck %s --check-prefix=ERROR-RELOC -+# -+# RUN: llvm-objcopy -R .text -R .comdat %t.in.o %t.remove-text-comdat.o -+# RUN: llvm-objdump -section-headers %t.remove-text-comdat.o | FileCheck %s --check-prefix=SECTIONS-REMOVE-TEXT-COMDAT -+# RUN: llvm-objdump -t %t.remove-text-comdat.o | FileCheck %s --check-prefix=SYMBOLS-REMOVE-TEXT-COMDAT -+# -+# -+# SECTIONS-PRE: Sections: -+# SECTIONS-PRE-NEXT: Idx Name -+# SECTIONS-PRE-NEXT: 0 .text -+# SECTIONS-PRE-NEXT: 1 .bss -+# SECTIONS-PRE-NEXT: 2 .comdat -+# SECTIONS-PRE-NEXT: 3 .associative -+# SECTIONS-PRE-EMPTY: -+# -+# SYMBOLS-PRE: SYMBOL TABLE: -+# SYMBOLS-PRE-NEXT: {{.*}}(sec -1){{.*}} @feat.00 -+# SYMBOLS-PRE-NEXT: {{.*}}(sec 1){{.*}} .text -+# SYMBOLS-PRE-NEXT: AUX scnlen {{.*}} assoc 1 comdat 0 -+# SYMBOLS-PRE-NEXT: {{.*}}(sec 2){{.*}} .bss -+# SYMBOLS-PRE-NEXT: AUX scnlen {{.*}} assoc 2 comdat 0 -+# SYMBOLS-PRE-NEXT: {{.*}}(sec 4){{.*}} .associative -+# SYMBOLS-PRE-NEXT: AUX scnlen {{.*}} assoc 3 comdat 5 -+# SYMBOLS-PRE-NEXT: {{.*}}(sec 3){{.*}} .comdat -+# SYMBOLS-PRE-NEXT: AUX scnlen {{.*}} assoc 3 comdat 2 -+# SYMBOLS-PRE-NEXT: {{.*}}(sec 3){{.*}} foo -+# SYMBOLS-PRE-NEXT: {{.*}}(sec 1){{.*}} main -+# SYMBOLS-PRE-EMPTY: -+# -+# -+# Removing the .bss section removes one symbol and its aux symbol, -+# and updates the section indices in symbols pointing to later -+# symbols, including the aux section defintitions. -+# -+# Testing that the absolute symbol @feat.00 survives the section number -+# mangling. -+# -+# SECTIONS-REMOVE-BSS: Sections: -+# SECTIONS-REMOVE-BSS-NEXT: Idx Name -+# SECTIONS-REMOVE-BSS-NEXT: 0 .text -+# SECTIONS-REMOVE-BSS-NEXT: 1 .comdat -+# SECTIONS-REMOVE-BSS-NEXT: 2 .associative -+# SECTIONS-REMOVE-BSS-EMPTY: -+# -+# SYMBOLS-REMOVE-BSS: SYMBOL TABLE: -+# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec -1){{.*}} @feat.00 -+# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 1){{.*}} .text -+# SYMBOLS-REMOVE-BSS-NEXT: AUX scnlen {{.*}} assoc 1 comdat 0 -+# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 3){{.*}} .associative -+# SYMBOLS-REMOVE-BSS-NEXT: AUX scnlen {{.*}} assoc 2 comdat 5 -+# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 2){{.*}} .comdat -+# SYMBOLS-REMOVE-BSS-NEXT: AUX scnlen {{.*}} assoc 2 comdat 2 -+# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 2){{.*}} foo -+# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 1){{.*}} main -+# SYMBOLS-REMOVE-BSS-EMPTY: -+# -+# -+# Removing the .text section is ok and just removes the external symbol -+# referring to it. -+# -+# SECTIONS-REMOVE-TEXT: Sections: -+# SECTIONS-REMOVE-TEXT-NEXT: Idx Name -+# SECTIONS-REMOVE-TEXT-NEXT: 0 .bss -+# SECTIONS-REMOVE-TEXT-NEXT: 1 .comdat -+# SECTIONS-REMOVE-TEXT-NEXT: 2 .associative -+# SECTIONS-REMOVE-TEXT-EMPTY: -+# -+# SYMBOLS-REMOVE-TEXT: SYMBOL TABLE: -+# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec -1){{.*}} @feat.00 -+# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec 1){{.*}} .bss -+# SYMBOLS-REMOVE-TEXT-NEXT: AUX scnlen {{.*}} assoc 1 comdat 0 -+# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec 3){{.*}} .associative -+# SYMBOLS-REMOVE-TEXT-NEXT: AUX scnlen {{.*}} assoc 2 comdat 5 -+# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec 2){{.*}} .comdat -+# SYMBOLS-REMOVE-TEXT-NEXT: AUX scnlen {{.*}} assoc 2 comdat 2 -+# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec 2){{.*}} foo -+# SYMBOLS-REMOVE-TEXT-EMPTY: -+# -+# -+# Removing the .comdat section fails, since the .text section has relocations -+# against it. -+# -+# ERROR-RELOC: Relocation target foo ({{.*}}) not found -+# -+# -+# Removing the .comdat section and .text (with a relocation against .comdat) -+# works, as it also removes the .associative section transitively. -+# -+# SECTIONS-REMOVE-TEXT-COMDAT: Sections: -+# SECTIONS-REMOVE-TEXT-COMDAT-NEXT: Idx Name -+# SECTIONS-REMOVE-TEXT-COMDAT-NEXT: 0 .bss -+# SECTIONS-REMOVE-TEXT-COMDAT-EMPTY: -+# -+# SYMBOLS-REMOVE-TEXT-COMDAT: SYMBOL TABLE: -+# SYMBOLS-REMOVE-TEXT-COMDAT-NEXT: {{.*}}(sec -1){{.*}} @feat.00 -+# SYMBOLS-REMOVE-TEXT-COMDAT-NEXT: {{.*}}(sec 1){{.*}} .bss -+# SYMBOLS-REMOVE-TEXT-COMDAT-NEXT: AUX scnlen {{.*}} assoc 1 comdat 0 -+# SYMBOLS-REMOVE-TEXT-COMDAT-EMPTY: -+ -+--- !COFF -+header: -+ Machine: IMAGE_FILE_MACHINE_AMD64 -+ Characteristics: [ ] -+sections: -+ - Name: .text -+ Characteristics: [ ] -+ Alignment: 4 -+ SectionData: 488B0500000000C3 -+ Relocations: -+ - VirtualAddress: 3 -+ SymbolName: foo -+ Type: IMAGE_REL_AMD64_REL32 -+ - Name: .bss -+ Characteristics: [ ] -+ Alignment: 4 -+ SectionData: '' -+ - Name: .comdat -+ Characteristics: [ IMAGE_SCN_LNK_COMDAT ] -+ Alignment: 1 -+ SectionData: '2A000000' -+ - Name: .associative -+ Characteristics: [ IMAGE_SCN_LNK_COMDAT ] -+ Alignment: 1 -+ SectionData: '0000000000000000' -+symbols: -+ - Name: '@feat.00' -+ Value: 0 -+ SectionNumber: -1 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_NULL -+ StorageClass: IMAGE_SYM_CLASS_STATIC -+ - Name: .text -+ Value: 0 -+ SectionNumber: 1 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_NULL -+ StorageClass: IMAGE_SYM_CLASS_STATIC -+ SectionDefinition: -+ Length: 8 -+ NumberOfRelocations: 1 -+ NumberOfLinenumbers: 0 -+ CheckSum: 583624169 -+ Number: 1 -+ - Name: .bss -+ Value: 0 -+ SectionNumber: 2 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_NULL -+ StorageClass: IMAGE_SYM_CLASS_STATIC -+ SectionDefinition: -+ Length: 0 -+ NumberOfRelocations: 0 -+ NumberOfLinenumbers: 0 -+ CheckSum: 0 -+ Number: 2 -+ - Name: .associative -+ Value: 0 -+ SectionNumber: 4 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_NULL -+ StorageClass: IMAGE_SYM_CLASS_STATIC -+ SectionDefinition: -+ Length: 8 -+ NumberOfRelocations: 0 -+ NumberOfLinenumbers: 0 -+ CheckSum: 0 -+ Number: 3 -+ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE -+ - Name: .comdat -+ Value: 0 -+ SectionNumber: 3 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_NULL -+ StorageClass: IMAGE_SYM_CLASS_STATIC -+ SectionDefinition: -+ Length: 4 -+ NumberOfRelocations: 0 -+ NumberOfLinenumbers: 0 -+ CheckSum: 3482275674 -+ Number: 3 -+ Selection: IMAGE_COMDAT_SELECT_ANY -+ - Name: foo -+ Value: 0 -+ SectionNumber: 3 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_NULL -+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL -+ - Name: main -+ Value: 0 -+ SectionNumber: 1 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_NULL -+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL -+... -diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -index 437dccbd3d5..dd2e4829218 100644 ---- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -@@ -27,9 +27,17 @@ using namespace object; - using namespace COFF; - - static Error handleArgs(const CopyConfig &Config, Object &Obj) { -+ // Perform the actual section removals. -+ Obj.removeSections([&Config](const Section &Sec) { -+ if (is_contained(Config.ToRemove, Sec.Name)) -+ return true; -+ -+ return false; -+ }); -+ - // StripAll removes all symbols and thus also removes all relocations. - if (Config.StripAll || Config.StripAllGNU) -- for (Section &Sec : Obj.Sections) -+ for (Section &Sec : Obj.getMutableSections()) - Sec.Relocs.clear(); - - // If we need to do per-symbol removals, initialize the Referenced field. -diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp -index e58e161e7d2..e19cea6aa9d 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Object.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp -@@ -7,6 +7,7 @@ - //===----------------------------------------------------------------------===// - - #include "Object.h" -+#include "llvm/ADT/DenseSet.h" - #include <algorithm> - - namespace llvm { -@@ -64,6 +65,68 @@ Error Object::markSymbols() { - return Error::success(); - } - -+void Object::addSections(ArrayRef<Section> NewSections) { -+ for (Section S : NewSections) { -+ S.UniqueId = NextSectionUniqueId++; -+ Sections.emplace_back(S); -+ } -+ updateSections(); -+} -+ -+void Object::updateSections() { -+ SectionMap = DenseMap<ssize_t, Section *>(Sections.size()); -+ size_t Index = 1; -+ for (Section &S : Sections) { -+ SectionMap[S.UniqueId] = &S; -+ S.Index = Index++; -+ } -+} -+ -+const Section *Object::findSection(ssize_t UniqueId) const { -+ auto It = SectionMap.find(UniqueId); -+ if (It == SectionMap.end()) -+ return nullptr; -+ return It->second; -+} -+ -+void Object::removeSections(function_ref<bool(const Section &)> ToRemove) { -+ DenseSet<ssize_t> AssociatedSections; -+ auto RemoveAssociated = [&AssociatedSections](const Section &Sec) { -+ return AssociatedSections.count(Sec.UniqueId) == 1; -+ }; -+ do { -+ DenseSet<ssize_t> RemovedSections; -+ Sections.erase( -+ std::remove_if(std::begin(Sections), std::end(Sections), -+ [ToRemove, &RemovedSections](const Section &Sec) { -+ bool Remove = ToRemove(Sec); -+ if (Remove) -+ RemovedSections.insert(Sec.UniqueId); -+ return Remove; -+ }), -+ std::end(Sections)); -+ // Remove all symbols referring to the removed sections. -+ AssociatedSections.clear(); -+ Symbols.erase( -+ std::remove_if( -+ std::begin(Symbols), std::end(Symbols), -+ [&RemovedSections, &AssociatedSections](const Symbol &Sym) { -+ // If there are sections that are associative to a removed -+ // section, -+ // remove those as well as nothing will include them (and we can't -+ // leave them dangling). -+ if (RemovedSections.count(Sym.AssociativeComdatTargetSectionId) == -+ 1) -+ AssociatedSections.insert(Sym.TargetSectionId); -+ return RemovedSections.count(Sym.TargetSectionId) == 1; -+ }), -+ std::end(Symbols)); -+ ToRemove = RemoveAssociated; -+ } while (!AssociatedSections.empty()); -+ updateSections(); -+ updateSymbols(); -+} -+ - } // end namespace coff - } // end namespace objcopy - } // end namespace llvm -diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h -index e6147c40b7c..a73e93620d3 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Object.h -+++ b/llvm/tools/llvm-objcopy/COFF/Object.h -@@ -37,12 +37,16 @@ struct Section { - ArrayRef<uint8_t> Contents; - std::vector<Relocation> Relocs; - StringRef Name; -+ ssize_t UniqueId; -+ size_t Index; - }; - - struct Symbol { - object::coff_symbol32 Sym; - StringRef Name; -- ArrayRef<uint8_t> AuxData; -+ std::vector<uint8_t> AuxData; -+ ssize_t TargetSectionId; -+ ssize_t AssociativeComdatTargetSectionId = 0; - size_t UniqueId; - size_t RawIndex; - bool Referenced; -@@ -61,7 +65,6 @@ struct Object { - uint32_t BaseOfData = 0; // pe32plus_header lacks this field. - - std::vector<object::data_directory> DataDirectories; -- std::vector<Section> Sections; - - ArrayRef<Symbol> getSymbols() const { return Symbols; } - // This allows mutating individual Symbols, but not mutating the list -@@ -79,14 +82,34 @@ struct Object { - // all sections. - Error markSymbols(); - -+ ArrayRef<Section> getSections() const { return Sections; } -+ // This allows mutating individual Sections, but not mutating the list -+ // of symbols itself. -+ iterator_range<std::vector<Section>::iterator> getMutableSections() { -+ return make_range(Sections.begin(), Sections.end()); -+ } -+ -+ const Section *findSection(ssize_t UniqueId) const; -+ -+ void addSections(ArrayRef<Section> NewSections); -+ void removeSections(function_ref<bool(const Section &)> ToRemove); -+ - private: - std::vector<Symbol> Symbols; - DenseMap<size_t, Symbol *> SymbolMap; - - size_t NextSymbolUniqueId = 0; - -+ std::vector<Section> Sections; -+ DenseMap<ssize_t, Section *> SectionMap; -+ -+ ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined. -+ - // Update SymbolMap and RawIndex in each Symbol. - void updateSymbols(); -+ -+ // Update SectionMap and Index in each Section. -+ void updateSections(); - }; - - // Copy between coff_symbol16 and coff_symbol32. -diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp -index d794042ae24..c8abe2913a2 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp -@@ -11,6 +11,7 @@ - #include "llvm-objcopy.h" - #include "llvm/ADT/ArrayRef.h" - #include "llvm/ADT/StringRef.h" -+#include "llvm/BinaryFormat/COFF.h" - #include "llvm/Object/COFF.h" - #include "llvm/Support/ErrorHandling.h" - #include <cstddef> -@@ -21,6 +22,7 @@ namespace objcopy { - namespace coff { - - using namespace object; -+using namespace COFF; - - Error COFFReader::readExecutableHeaders(Object &Obj) const { - const dos_header *DH = COFFObj.getDOSHeader(); -@@ -58,13 +60,14 @@ Error COFFReader::readExecutableHeaders(Object &Obj) const { - } - - Error COFFReader::readSections(Object &Obj) const { -+ std::vector<Section> Sections; - // Section indexing starts from 1. - for (size_t I = 1, E = COFFObj.getNumberOfSections(); I <= E; I++) { - const coff_section *Sec; - if (auto EC = COFFObj.getSection(I, Sec)) - return errorCodeToError(EC); -- Obj.Sections.push_back(Section()); -- Section &S = Obj.Sections.back(); -+ Sections.push_back(Section()); -+ Section &S = Sections.back(); - S.Header = *Sec; - if (auto EC = COFFObj.getSectionContents(Sec, S.Contents)) - return errorCodeToError(EC); -@@ -77,12 +80,14 @@ Error COFFReader::readSections(Object &Obj) const { - return make_error<StringError>("Extended relocations not supported yet", - object_error::parse_failed); - } -+ Obj.addSections(Sections); - return Error::success(); - } - - Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const { - std::vector<Symbol> Symbols; - Symbols.reserve(COFFObj.getRawNumberOfSymbols()); -+ ArrayRef<Section> Sections = Obj.getSections(); - for (uint32_t I = 0, E = COFFObj.getRawNumberOfSymbols(); I < E;) { - Expected<COFFSymbolRef> SymOrErr = COFFObj.getSymbol(I); - if (!SymOrErr) -@@ -103,6 +108,26 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const { - Sym.AuxData = COFFObj.getSymbolAuxData(SymRef); - assert((Sym.AuxData.size() % - (IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16))) == 0); -+ // Find the unique id of the section -+ if (SymRef.getSectionNumber() <= -+ 0) // Special symbol (undefined/absolute/debug) -+ Sym.TargetSectionId = SymRef.getSectionNumber(); -+ else if (static_cast<uint32_t>(SymRef.getSectionNumber() - 1) < -+ Sections.size()) -+ Sym.TargetSectionId = Sections[SymRef.getSectionNumber() - 1].UniqueId; -+ else -+ return make_error<StringError>("Section number out of range", -+ object_error::parse_failed); -+ // For section definitions, check if it is comdat associative, and if -+ // it is, find the target section unique id. -+ const coff_aux_section_definition *SD = SymRef.getSectionDefinition(); -+ if (SD && SD->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) { -+ int32_t Index = SD->getNumber(IsBigObj); -+ if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size()) -+ return make_error<StringError>("Unexpected associative section index", -+ object_error::parse_failed); -+ Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId; -+ } - I += 1 + SymRef.getNumberOfAuxSymbols(); - } - Obj.addSymbols(Symbols); -@@ -116,7 +141,7 @@ Error COFFReader::setRelocTargets(Object &Obj) const { - for (size_t I = 0; I < Sym.Sym.NumberOfAuxSymbols; I++) - RawSymbolTable.push_back(nullptr); - } -- for (Section &Sec : Obj.Sections) { -+ for (Section &Sec : Obj.getMutableSections()) { - for (Relocation &R : Sec.Relocs) { - if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size()) - return make_error<StringError>("SymbolTableIndex out of range", -diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp -index c347810dd24..9fb7812672b 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp -@@ -25,7 +25,7 @@ using namespace object; - using namespace COFF; - - Error COFFWriter::finalizeRelocTargets() { -- for (Section &Sec : Obj.Sections) { -+ for (Section &Sec : Obj.getMutableSections()) { - for (Relocation &R : Sec.Relocs) { - const Symbol *Sym = Obj.findSymbol(R.Target); - if (Sym == nullptr) -@@ -39,8 +39,48 @@ Error COFFWriter::finalizeRelocTargets() { - return Error::success(); - } - -+Error COFFWriter::finalizeSectionNumbers() { -+ for (Symbol &Sym : Obj.getMutableSymbols()) { -+ if (Sym.TargetSectionId <= 0) { -+ // Undefined, or a special kind of symbol. These negative values -+ // are stored in the SectionNumber field which is unsigned. -+ Sym.Sym.SectionNumber = static_cast<uint32_t>(Sym.TargetSectionId); -+ } else { -+ const Section *Sec = Obj.findSection(Sym.TargetSectionId); -+ if (Sec == nullptr) -+ return make_error<StringError>("Symbol " + Sym.Name + -+ " points to a removed section", -+ object_error::invalid_symbol_index); -+ Sym.Sym.SectionNumber = Sec->Index; -+ -+ if (Sym.Sym.NumberOfAuxSymbols == 1 && -+ Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC) { -+ coff_aux_section_definition *SD = -+ reinterpret_cast<coff_aux_section_definition *>(Sym.AuxData.data()); -+ uint32_t SDSectionNumber; -+ if (Sym.AssociativeComdatTargetSectionId == 0) { -+ // Not a comdat associative section; just set the Number field to -+ // the number of the section itself. -+ SDSectionNumber = Sec->Index; -+ } else { -+ Sec = Obj.findSection(Sym.AssociativeComdatTargetSectionId); -+ if (Sec == nullptr) -+ return make_error<StringError>( -+ "Symbol " + Sym.Name + " is associative to a removed section", -+ object_error::invalid_symbol_index); -+ SDSectionNumber = Sec->Index; -+ } -+ // Update the section definition with the new section number. -+ SD->NumberLowPart = static_cast<uint16_t>(SDSectionNumber); -+ SD->NumberHighPart = static_cast<uint16_t>(SDSectionNumber >> 16); -+ } -+ } -+ } -+ return Error::success(); -+} -+ - void COFFWriter::layoutSections() { -- for (auto &S : Obj.Sections) { -+ for (auto &S : Obj.getMutableSections()) { - if (S.Header.SizeOfRawData > 0) - S.Header.PointerToRawData = FileSize; - FileSize += S.Header.SizeOfRawData; // For executables, this is already -@@ -57,7 +97,7 @@ void COFFWriter::layoutSections() { - } - - size_t COFFWriter::finalizeStringTable() { -- for (auto &S : Obj.Sections) -+ for (const auto &S : Obj.getSections()) - if (S.Name.size() > COFF::NameSize) - StrTabBuilder.add(S.Name); - -@@ -67,7 +107,7 @@ size_t COFFWriter::finalizeStringTable() { - - StrTabBuilder.finalize(); - -- for (auto &S : Obj.Sections) { -+ for (auto &S : Obj.getMutableSections()) { - if (S.Name.size() > COFF::NameSize) { - snprintf(S.Header.Name, sizeof(S.Header.Name), "/%d", - (int)StrTabBuilder.getOffset(S.Name)); -@@ -97,6 +137,8 @@ std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() { - Error COFFWriter::finalize(bool IsBigObj) { - if (Error E = finalizeRelocTargets()) - return E; -+ if (Error E = finalizeSectionNumbers()) -+ return E; - - size_t SizeOfHeaders = 0; - FileAlignment = 1; -@@ -113,10 +155,10 @@ Error COFFWriter::finalize(bool IsBigObj) { - SizeOfHeaders += - PeHeaderSize + sizeof(data_directory) * Obj.DataDirectories.size(); - } -- Obj.CoffFileHeader.NumberOfSections = Obj.Sections.size(); -+ Obj.CoffFileHeader.NumberOfSections = Obj.getSections().size(); - SizeOfHeaders += - IsBigObj ? sizeof(coff_bigobj_file_header) : sizeof(coff_file_header); -- SizeOfHeaders += sizeof(coff_section) * Obj.Sections.size(); -+ SizeOfHeaders += sizeof(coff_section) * Obj.getSections().size(); - SizeOfHeaders = alignTo(SizeOfHeaders, FileAlignment); - - Obj.CoffFileHeader.SizeOfOptionalHeader = -@@ -131,8 +173,8 @@ Error COFFWriter::finalize(bool IsBigObj) { - Obj.PeHeader.SizeOfHeaders = SizeOfHeaders; - Obj.PeHeader.SizeOfInitializedData = SizeOfInitializedData; - -- if (!Obj.Sections.empty()) { -- const Section &S = Obj.Sections.back(); -+ if (!Obj.getSections().empty()) { -+ const Section &S = Obj.getSections().back(); - Obj.PeHeader.SizeOfImage = - alignTo(S.Header.VirtualAddress + S.Header.VirtualSize, - Obj.PeHeader.SectionAlignment); -@@ -198,7 +240,7 @@ void COFFWriter::writeHeaders(bool IsBigObj) { - BigObjHeader.unused4 = 0; - // The value in Obj.CoffFileHeader.NumberOfSections is truncated, thus - // get the original one instead. -- BigObjHeader.NumberOfSections = Obj.Sections.size(); -+ BigObjHeader.NumberOfSections = Obj.getSections().size(); - BigObjHeader.PointerToSymbolTable = Obj.CoffFileHeader.PointerToSymbolTable; - BigObjHeader.NumberOfSymbols = Obj.CoffFileHeader.NumberOfSymbols; - -@@ -223,14 +265,14 @@ void COFFWriter::writeHeaders(bool IsBigObj) { - Ptr += sizeof(DD); - } - } -- for (const auto &S : Obj.Sections) { -+ for (const auto &S : Obj.getSections()) { - memcpy(Ptr, &S.Header, sizeof(S.Header)); - Ptr += sizeof(S.Header); - } - } - - void COFFWriter::writeSections() { -- for (const auto &S : Obj.Sections) { -+ for (const auto &S : Obj.getSections()) { - uint8_t *Ptr = Buf.getBufferStart() + S.Header.PointerToRawData; - std::copy(S.Contents.begin(), S.Contents.end(), Ptr); - -@@ -295,7 +337,7 @@ Error COFFWriter::patchDebugDirectory() { - const data_directory *Dir = &Obj.DataDirectories[DEBUG_DIRECTORY]; - if (Dir->Size <= 0) - return Error::success(); -- for (const auto &S : Obj.Sections) { -+ for (const auto &S : Obj.getSections()) { - if (Dir->RelativeVirtualAddress >= S.Header.VirtualAddress && - Dir->RelativeVirtualAddress < - S.Header.VirtualAddress + S.Header.SizeOfRawData) { -@@ -324,7 +366,7 @@ Error COFFWriter::patchDebugDirectory() { - } - - Error COFFWriter::write() { -- bool IsBigObj = Obj.Sections.size() > MaxNumberOfSections16; -+ bool IsBigObj = Obj.getSections().size() > MaxNumberOfSections16; - if (IsBigObj && Obj.IsPE) - return make_error<StringError>("Too many sections for executable", - object_error::parse_failed); -diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/tools/llvm-objcopy/COFF/Writer.h -index 52fef385926..a967a103df9 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Writer.h -+++ b/llvm/tools/llvm-objcopy/COFF/Writer.h -@@ -31,6 +31,7 @@ class COFFWriter { - StringTableBuilder StrTabBuilder; - - Error finalizeRelocTargets(); -+ Error finalizeSectionNumbers(); - void layoutSections(); - size_t finalizeStringTable(); - template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable(); --- -2.17.1 -
deleted file mode 100644 --- a/build/build-clang/mingwclang-llvm-objcopy-COFF-Clear-the-unwritten-tail-of-coff_s.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 1284ee3c47bab17ec081b5169633aea4f8abfd30 Mon Sep 17 00:00:00 2001 -From: Martin Storsjo <martin@martin.st> -Date: Wed, 23 Jan 2019 09:12:53 +0000 -Subject: [PATCH] [llvm-objcopy] [COFF] Clear the unwritten tail of - coff_section::Header::Name - -This should fix the add-gnu-debuglink test on all buildbots. - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351934 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - tools/llvm-objcopy/COFF/Writer.cpp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp -index 05e46291c39..db897e2ff33 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp -@@ -121,6 +121,7 @@ size_t COFFWriter::finalizeStringTable() { - - for (auto &S : Obj.getMutableSections()) { - if (S.Name.size() > COFF::NameSize) { -+ memset(S.Header.Name, 0, sizeof(S.Header.Name)); - snprintf(S.Header.Name, sizeof(S.Header.Name), "/%d", - (int)StrTabBuilder.getOffset(S.Name)); - } else { --- -2.17.1 -
deleted file mode 100644 --- a/build/build-clang/mingwclang-llvm-objcopy-COFF-Error-out-on-use-of-unhandled-opti.patch +++ /dev/null @@ -1,43 +0,0 @@ -From abacd83232acf69d7cbacd53fc2f9aae66c1a32e Mon Sep 17 00:00:00 2001 -From: Martin Storsjo <martin@martin.st> -Date: Wed, 23 Jan 2019 11:54:55 +0000 -Subject: [PATCH] [llvm-objcopy] [COFF] Error out on use of unhandled options - -Prefer erroring out than silently not doing what was requested. - -Differential Revision: https://reviews.llvm.org/D57045 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351948 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -index 64b4e79a4e0..b7b3d3cb629 100644 ---- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -@@ -170,6 +170,21 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) { - if (!Config.AddGnuDebugLink.empty()) - addGnuDebugLink(Obj, Config.AddGnuDebugLink); - -+ if (!Config.BuildIdLinkDir.empty() || Config.BuildIdLinkInput || -+ Config.BuildIdLinkOutput || !Config.SplitDWO.empty() || -+ !Config.SymbolsPrefix.empty() || !Config.AddSection.empty() || -+ !Config.DumpSection.empty() || !Config.KeepSection.empty() || -+ !Config.SymbolsToGlobalize.empty() || !Config.SymbolsToKeep.empty() || -+ !Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() || -+ !Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() || -+ !Config.SymbolsToRename.empty() || Config.ExtractDWO || -+ Config.KeepFileSymbols || Config.LocalizeHidden || Config.PreserveDates || -+ Config.StripDWO || Config.StripNonAlloc || Config.StripSections || -+ Config.Weaken || Config.DecompressDebugSections) { -+ return createStringError(llvm::errc::invalid_argument, -+ "Option not supported by llvm-objcopy for COFF"); -+ } -+ - return Error::success(); - } - --- -2.17.1 -
deleted file mode 100644 --- a/build/build-clang/mingwclang-llvm-objcopy-COFF-Fix-handling-of-aux-symbols-for-bi.patch +++ /dev/null @@ -1,377 +0,0 @@ -From 74c7d422cba163635394ec32f2b243b1de502a18 Mon Sep 17 00:00:00 2001 -From: Martin Storsjo <martin@martin.st> -Date: Wed, 23 Jan 2019 11:54:51 +0000 -Subject: [PATCH] [llvm-objcopy] [COFF] Fix handling of aux symbols for big - objects - -The aux symbols were stored in an opaque std::vector<uint8_t>, -with contents interpreted according to the rest of the symbol. - -All aux symbol types but one fit in 18 bytes (sizeof(coff_symbol16)), -and if written to a bigobj, two extra padding bytes are written (as -sizeof(coff_symbol32) is 20). In the storage agnostic intermediate -representation, store the aux symbols as a series of coff_symbol16 -sized opaque blobs. (In practice, all such aux symbols only consist -of one aux symbol, so this is more flexible than what reality needs.) - -The special case is the file aux symbols, which are written in -potentially more than one aux symbol slot, without any padding, -as one single long string. This can't be stored in the same opaque -vector of fixed sized aux symbol entries. The file aux symbols will -occupy a different number of aux symbol slots depending on the type -of output object file. As nothing in the intermediate process needs -to have accurate raw symbol indices, updating that is moved into the -writer class. - -Differential Revision: https://reviews.llvm.org/D57009 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351947 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - .../llvm-objcopy/COFF/Inputs/bigobj.o.gz | Bin 0 -> 7841 bytes - test/tools/llvm-objcopy/COFF/bigobj.test | 35 +++++++++++++ - .../llvm-objcopy/ELF/auto-remove-shndx.test | 2 +- - .../tools/llvm-objcopy/ELF/many-sections.test | 2 +- - test/tools/llvm-objcopy/ELF/remove-shndx.test | 2 +- - .../tools/llvm-objcopy/ELF/strict-no-add.test | 2 +- - .../llvm-objcopy/{ELF => }/Inputs/ungzip.py | 0 - tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 6 +-- - tools/llvm-objcopy/COFF/Object.cpp | 6 +-- - tools/llvm-objcopy/COFF/Object.h | 18 ++++++- - tools/llvm-objcopy/COFF/Reader.cpp | 21 ++++++-- - tools/llvm-objcopy/COFF/Writer.cpp | 49 +++++++++++++----- - tools/llvm-objcopy/COFF/Writer.h | 2 +- - 13 files changed, 115 insertions(+), 30 deletions(-) - create mode 100644 test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz - create mode 100644 test/tools/llvm-objcopy/COFF/bigobj.test - rename test/tools/llvm-objcopy/{ELF => }/Inputs/ungzip.py (100%) - -diff --git a/llvm/test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz b/llvm/test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz -new file mode 100644 -index 0000000000000000000000000000000000000000..6435f4785ff76e0c6bca12f3e57bc6ad8888bece -GIT binary patch -literal 7841 -zcmb2|=3r3v^@w3&etUMmo^zoH`-kGKM_vfJsF<z%6+Sz#g6qq)pf0Hj#_r`4B7DML -zW(h1l`+!x)t@&W-R@I~lyKmU3Ti&1Z=iKur;uBMy1MR!_ywlsouYY&-*4H1mU!Qw= -z`RpIDkw;!V4(WOF_)B3`(Vt|~S>?L-b)Wx@^wig`HIMAw|N8V<v65oeyETs611{)_ -zm27RwTe)ENN|7SLgM~83N6}~qjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk -zz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRokHNw|D97mKRo|%+Z6Ym -z*X{Ku$4#4*Vqm}gyYR^b^Sc?_E*<<cFE#Q=*rt6OBmJeLZ=aoe_u9R>-w!^l5biDe -p{d@nvw*mU6<NG83=jxn4_wt_G?yUy#YeOF~KhH^=cj<;Y0{~9Br>p<~ - -literal 0 -HcmV?d00001 - -diff --git a/llvm/test/tools/llvm-objcopy/COFF/bigobj.test b/llvm/test/tools/llvm-objcopy/COFF/bigobj.test -new file mode 100644 -index 00000000000..17968f12b8a ---- /dev/null -+++ b/llvm/test/tools/llvm-objcopy/COFF/bigobj.test -@@ -0,0 +1,35 @@ -+RUN: %python %p/../Inputs/ungzip.py %p/Inputs/bigobj.o.gz > %t.in.o -+ -+RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-ORIG -+ -+# Do a plain copy, to check that section numbers in symbols referring -+# to sections outside of the small object format are handled correctly. -+RUN: llvm-objcopy -R '.text$4' %t.in.o %t.small.o -+RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-ORIG -+ -+# Remove a section, making the section count fit into a small object. -+RUN: llvm-objcopy -R '.text$4' %t.in.o %t.small.o -+RUN: llvm-objdump -t %t.small.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-SMALL,SYMBOLS-REMOVED-SMALL -+ -+# Add a .gnu_debuglink section, forcing the object back to big format. -+RUN: llvm-objcopy --add-gnu-debuglink=%t.in.o %t.small.o %t.big.o -+ llvm-objdump -t %t.big.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-REMOVED-BIG -+ -+# In big object format, the .file symbol occupies one symbol table entry for -+# the auxillary data, but needs two entries in the small format, forcing the -+# raw symbol indices of later symbols to change. -+SYMBOLS: SYMBOL TABLE: -+SYMBOLS-NEXT: [ 0]{{.*}} (nx 1) {{.*}} .text -+SYMBOLS-NEXT: AUX scnlen -+SYMBOLS-SMALL-NEXT: [ 2]{{.*}} (nx 2) {{.*}} .file -+SYMBOLS-BIG-NEXT: [ 2]{{.*}} (nx 1) {{.*}} .file -+SYMBOLS-NEXT: AUX abcdefghijklmnopqrs -+SYMBOLS-SMALL-NEXT: [ 5]{{.*}} (nx 0) {{.*}} foo -+SYMBOLS-BIG-NEXT: [ 4]{{.*}} (nx 0) {{.*}} foo -+ -+# Check that the section numbers outside of signed 16 bit int range -+# are represented properly. After removing one section, the section -+# numbers decrease. -+SYMBOLS-ORIG: [ 5](sec 65280){{.*}} symbol65280 -+SYMBOLS-REMOVED-SMALL: [ 6](sec 65279){{.*}} symbol65280 -+SYMBOLS-REMOVED-BIG: [ 5](sec 65279){{.*}} symbol65280 -diff --git a/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test b/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test -index 5a23493fa94..8e6c788bf48 100644 ---- a/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test -+++ b/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test -@@ -1,4 +1,4 @@ --# RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t -+# RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t - # RUN: llvm-objcopy -R .text -R s0 -R s1 -R s2 -R s3 -R s4 -R s5 -R s6 %t %t2 - # RUN: llvm-readobj --sections %t2 | FileCheck --check-prefix=SECS %s - -diff --git a/llvm/test/tools/llvm-objcopy/ELF/many-sections.test b/llvm/test/tools/llvm-objcopy/ELF/many-sections.test -index 57239f32e4a..1dd41cfb10c 100644 ---- a/llvm/test/tools/llvm-objcopy/ELF/many-sections.test -+++ b/llvm/test/tools/llvm-objcopy/ELF/many-sections.test -@@ -1,4 +1,4 @@ --RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t -+RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t - RUN: llvm-objcopy %t %t2 - RUN: llvm-readobj --file-headers %t2 | FileCheck --check-prefix=EHDR %s - RUN: llvm-readobj --sections %t2 | FileCheck --check-prefix=SECS %s -diff --git a/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test b/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test -index 6cc3a1a291f..53ca8e7f220 100644 ---- a/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test -+++ b/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test -@@ -1,6 +1,6 @@ - # This test checks to see that a .symtab_shndx section is added to any binary - # that needs it, even if the original was removed. --RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t -+RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t - RUN: llvm-objcopy -R .symtab_shndx %t %t2 - RUN: llvm-readobj --sections %t2 | FileCheck %s - -diff --git a/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test b/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test -index 4f24df31bf9..348ab7c4fbd 100644 ---- a/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test -+++ b/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test -@@ -1,7 +1,7 @@ - # This test makes sure that sections added at the end that don't have symbols - # defined in them don't trigger the creation of a large index table. - --RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t.0 -+RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t.0 - RUN: cat %p/Inputs/alloc-symtab.o > %t - RUN: llvm-objcopy -R .text -R s0 -R s1 -R s2 -R s3 -R s4 -R s5 -R s6 %t.0 %t2 - RUN: llvm-objcopy --add-section=.s0=%t --add-section=.s1=%t --add-section=.s2=%t %t2 %t2 -diff --git a/llvm/test/tools/llvm-objcopy/ELF/Inputs/ungzip.py b/llvm/test/tools/llvm-objcopy/Inputs/ungzip.py -similarity index 100% -rename from test/tools/llvm-objcopy/ELF/Inputs/ungzip.py -rename to test/tools/llvm-objcopy/Inputs/ungzip.py -diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -index 20adbe11e7a..64b4e79a4e0 100644 ---- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -@@ -37,7 +37,7 @@ static uint64_t getNextRVA(const Object &Obj) { - return 0; - const Section &Last = Obj.getSections().back(); - return alignTo(Last.Header.VirtualAddress + Last.Header.VirtualSize, -- Obj.PeHeader.SectionAlignment); -+ Obj.IsPE ? Obj.PeHeader.SectionAlignment : 1); - } - - static uint32_t getCRC32(StringRef Data) { -@@ -74,8 +74,8 @@ static void addGnuDebugLink(Object &Obj, StringRef DebugLinkFile) { - Sec.Name = ".gnu_debuglink"; - Sec.Header.VirtualSize = Sec.getContents().size(); - Sec.Header.VirtualAddress = StartRVA; -- Sec.Header.SizeOfRawData = -- alignTo(Sec.Header.VirtualSize, Obj.PeHeader.FileAlignment); -+ Sec.Header.SizeOfRawData = alignTo(Sec.Header.VirtualSize, -+ Obj.IsPE ? Obj.PeHeader.FileAlignment : 1); - // Sec.Header.PointerToRawData is filled in by the writer. - Sec.Header.PointerToRelocations = 0; - Sec.Header.PointerToLinenumbers = 0; -diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp -index 8c382c1faef..0ad5a05a144 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Object.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp -@@ -26,12 +26,8 @@ void Object::addSymbols(ArrayRef<Symbol> NewSymbols) { - - void Object::updateSymbols() { - SymbolMap = DenseMap<size_t, Symbol *>(Symbols.size()); -- size_t RawSymIndex = 0; -- for (Symbol &Sym : Symbols) { -+ for (Symbol &Sym : Symbols) - SymbolMap[Sym.UniqueId] = &Sym; -- Sym.RawIndex = RawSymIndex; -- RawSymIndex += 1 + Sym.Sym.NumberOfAuxSymbols; -- } - } - - const Symbol *Object::findSymbol(size_t UniqueId) const { -diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h -index afa272286ef..21475b06862 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Object.h -+++ b/llvm/tools/llvm-objcopy/COFF/Object.h -@@ -66,10 +66,24 @@ private: - std::vector<uint8_t> OwnedContents; - }; - -+struct AuxSymbol { -+ AuxSymbol(ArrayRef<uint8_t> In) { -+ assert(In.size() == sizeof(Opaque)); -+ std::copy(In.begin(), In.end(), Opaque); -+ } -+ -+ ArrayRef<uint8_t> getRef() const { -+ return ArrayRef<uint8_t>(Opaque, sizeof(Opaque)); -+ } -+ -+ uint8_t Opaque[sizeof(object::coff_symbol16)]; -+}; -+ - struct Symbol { - object::coff_symbol32 Sym; - StringRef Name; -- std::vector<uint8_t> AuxData; -+ std::vector<AuxSymbol> AuxData; -+ StringRef AuxFile; - ssize_t TargetSectionId; - ssize_t AssociativeComdatTargetSectionId = 0; - Optional<size_t> WeakTargetSymbolId; -@@ -132,7 +146,7 @@ private: - - ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined. - -- // Update SymbolMap and RawIndex in each Symbol. -+ // Update SymbolMap. - void updateSymbols(); - - // Update SectionMap and Index in each Section. -diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp -index 87dd60a43cf..7270bbf94de 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp -@@ -107,9 +107,24 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const { - *reinterpret_cast<const coff_symbol16 *>(SymRef.getRawPtr())); - if (auto EC = COFFObj.getSymbolName(SymRef, Sym.Name)) - return errorCodeToError(EC); -- Sym.AuxData = COFFObj.getSymbolAuxData(SymRef); -- assert((Sym.AuxData.size() % -- (IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16))) == 0); -+ -+ ArrayRef<uint8_t> AuxData = COFFObj.getSymbolAuxData(SymRef); -+ size_t SymSize = IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16); -+ assert(AuxData.size() == SymSize * SymRef.getNumberOfAuxSymbols()); -+ // The auxillary symbols are structs of sizeof(coff_symbol16) each. -+ // In the big object format (where symbols are coff_symbol32), each -+ // auxillary symbol is padded with 2 bytes at the end. Copy each -+ // auxillary symbol to the Sym.AuxData vector. For file symbols, -+ // the whole range of aux symbols are interpreted as one null padded -+ // string instead. -+ if (SymRef.isFileRecord()) -+ Sym.AuxFile = StringRef(reinterpret_cast<const char *>(AuxData.data()), -+ AuxData.size()) -+ .rtrim('\0'); -+ else -+ for (size_t I = 0; I < SymRef.getNumberOfAuxSymbols(); I++) -+ Sym.AuxData.push_back(AuxData.slice(I * SymSize, sizeof(AuxSymbol))); -+ - // Find the unique id of the section - if (SymRef.getSectionNumber() <= - 0) // Special symbol (undefined/absolute/debug) -diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp -index db897e2ff33..6e69c597217 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp -@@ -55,7 +55,8 @@ Error COFFWriter::finalizeSymbolContents() { - if (Sym.Sym.NumberOfAuxSymbols == 1 && - Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC) { - coff_aux_section_definition *SD = -- reinterpret_cast<coff_aux_section_definition *>(Sym.AuxData.data()); -+ reinterpret_cast<coff_aux_section_definition *>( -+ Sym.AuxData[0].Opaque); - uint32_t SDSectionNumber; - if (Sym.AssociativeComdatTargetSectionId == 0) { - // Not a comdat associative section; just set the Number field to -@@ -79,7 +80,7 @@ Error COFFWriter::finalizeSymbolContents() { - // we want to set. Only >= 1 would be required, but only == 1 makes sense. - if (Sym.WeakTargetSymbolId && Sym.Sym.NumberOfAuxSymbols == 1) { - coff_aux_weak_external *WE = -- reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData.data()); -+ reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData[0].Opaque); - const Symbol *Target = Obj.findSymbol(*Sym.WeakTargetSymbolId); - if (Target == nullptr) - return createStringError(object_error::invalid_symbol_index, -@@ -141,13 +142,26 @@ size_t COFFWriter::finalizeStringTable() { - - template <class SymbolTy> - std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() { -- size_t SymTabSize = Obj.getSymbols().size() * sizeof(SymbolTy); -- for (const auto &S : Obj.getSymbols()) -- SymTabSize += S.AuxData.size(); -- return std::make_pair(SymTabSize, sizeof(SymbolTy)); -+ size_t RawSymIndex = 0; -+ for (auto &S : Obj.getMutableSymbols()) { -+ // Symbols normally have NumberOfAuxSymbols set correctly all the time. -+ // For file symbols, we need to know the output file's symbol size to be -+ // able to calculate the number of slots it occupies. -+ if (!S.AuxFile.empty()) -+ S.Sym.NumberOfAuxSymbols = -+ alignTo(S.AuxFile.size(), sizeof(SymbolTy)) / sizeof(SymbolTy); -+ S.RawIndex = RawSymIndex; -+ RawSymIndex += 1 + S.Sym.NumberOfAuxSymbols; -+ } -+ return std::make_pair(RawSymIndex * sizeof(SymbolTy), sizeof(SymbolTy)); - } - - Error COFFWriter::finalize(bool IsBigObj) { -+ size_t SymTabSize, SymbolSize; -+ std::tie(SymTabSize, SymbolSize) = IsBigObj -+ ? finalizeSymbolTable<coff_symbol32>() -+ : finalizeSymbolTable<coff_symbol16>(); -+ - if (Error E = finalizeRelocTargets()) - return E; - if (Error E = finalizeSymbolContents()) -@@ -199,10 +213,6 @@ Error COFFWriter::finalize(bool IsBigObj) { - } - - size_t StrTabSize = finalizeStringTable(); -- size_t SymTabSize, SymbolSize; -- std::tie(SymTabSize, SymbolSize) = IsBigObj -- ? finalizeSymbolTable<coff_symbol32>() -- : finalizeSymbolTable<coff_symbol16>(); - - size_t PointerToSymbolTable = FileSize; - // StrTabSize <= 4 is the size of an empty string table, only consisting -@@ -312,8 +322,23 @@ template <class SymbolTy> void COFFWriter::writeSymbolStringTables() { - copySymbol<SymbolTy, coff_symbol32>(*reinterpret_cast<SymbolTy *>(Ptr), - S.Sym); - Ptr += sizeof(SymbolTy); -- std::copy(S.AuxData.begin(), S.AuxData.end(), Ptr); -- Ptr += S.AuxData.size(); -+ if (!S.AuxFile.empty()) { -+ // For file symbols, just write the string into the aux symbol slots, -+ // assuming that the unwritten parts are initialized to zero in the memory -+ // mapped file. -+ std::copy(S.AuxFile.begin(), S.AuxFile.end(), Ptr); -+ Ptr += S.Sym.NumberOfAuxSymbols * sizeof(SymbolTy); -+ } else { -+ // For other auxillary symbols, write their opaque payload into one symbol -+ // table slot each. For big object files, the symbols are larger than the -+ // opaque auxillary symbol struct and we leave padding at the end of each -+ // entry. -+ for (const AuxSymbol &AuxSym : S.AuxData) { -+ ArrayRef<uint8_t> Ref = AuxSym.getRef(); -+ std::copy(Ref.begin(), Ref.end(), Ptr); -+ Ptr += sizeof(SymbolTy); -+ } -+ } - } - if (StrTabBuilder.getSize() > 4 || !Obj.IsPE) { - // Always write a string table in object files, even an empty one. -diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/tools/llvm-objcopy/COFF/Writer.h -index 9b1cfa91d00..681a8d5e4a6 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Writer.h -+++ b/llvm/tools/llvm-objcopy/COFF/Writer.h -@@ -30,11 +30,11 @@ class COFFWriter { - size_t SizeOfInitializedData; - StringTableBuilder StrTabBuilder; - -+ template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable(); - Error finalizeRelocTargets(); - Error finalizeSymbolContents(); - void layoutSections(); - size_t finalizeStringTable(); -- template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable(); - - Error finalize(bool IsBigObj); - --- -2.17.1 -
deleted file mode 100644 --- a/build/build-clang/mingwclang-llvm-objcopy-COFF-Implement-only-keep-debug.patch +++ /dev/null @@ -1,222 +0,0 @@ -From 526aa2e94355b7feb3bf7774a6e1899f68e94ad8 Mon Sep 17 00:00:00 2001 -From: Martin Storsjo <martin@martin.st> -Date: Sat, 19 Jan 2019 19:42:48 +0000 -Subject: [PATCH] [llvm-objcopy] [COFF] Implement --only-keep-debug - -Differential Revision: https://reviews.llvm.org/D56840 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351662 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - .../COFF/Inputs/only-keep-sections.yaml | 77 +++++++++++++++++++ - .../llvm-objcopy/COFF/only-keep-debug.test | 58 ++++++++++++++ - tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 10 +++ - tools/llvm-objcopy/COFF/Object.cpp | 10 +++ - tools/llvm-objcopy/COFF/Object.h | 1 + - 5 files changed, 156 insertions(+) - create mode 100644 test/tools/llvm-objcopy/COFF/Inputs/only-keep-sections.yaml - create mode 100644 test/tools/llvm-objcopy/COFF/only-keep-debug.test - -diff --git a/llvm/test/tools/llvm-objcopy/COFF/Inputs/only-keep-sections.yaml b/llvm/test/tools/llvm-objcopy/COFF/Inputs/only-keep-sections.yaml -new file mode 100644 -index 00000000000..b5437e10763 ---- /dev/null -+++ b/llvm/test/tools/llvm-objcopy/COFF/Inputs/only-keep-sections.yaml -@@ -0,0 +1,77 @@ -+--- !COFF -+OptionalHeader: -+ AddressOfEntryPoint: 4144 -+ ImageBase: 1073741824 -+ SectionAlignment: 4096 -+ FileAlignment: 512 -+ MajorOperatingSystemVersion: 6 -+ MinorOperatingSystemVersion: 0 -+ MajorImageVersion: 0 -+ MinorImageVersion: 0 -+ MajorSubsystemVersion: 6 -+ MinorSubsystemVersion: 0 -+ Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI -+ DLLCharacteristics: [ ] -+ SizeOfStackReserve: 1048576 -+ SizeOfStackCommit: 4096 -+ SizeOfHeapReserve: 1048576 -+ SizeOfHeapCommit: 4096 -+header: -+ Machine: IMAGE_FILE_MACHINE_AMD64 -+ Characteristics: [ ] -+sections: -+ - Name: .text -+ Characteristics: [ IMAGE_SCN_CNT_CODE ] -+ VirtualAddress: 4096 -+ VirtualSize: 4 -+ SectionData: C3C3C3C3 -+ - Name: .rdata -+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA ] -+ VirtualAddress: 8192 -+ VirtualSize: 4 -+ SectionData: 2A000000 -+ - Name: .buildid -+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA ] -+ VirtualAddress: 12288 -+ VirtualSize: 4 -+ SectionData: 2B000000 -+ - Name: .reloc -+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE ] -+ VirtualAddress: 16384 -+ VirtualSize: 4 -+ SectionData: 2C000000 -+ - Name: .debug_discardable -+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE ] -+ VirtualAddress: 20480 -+ VirtualSize: 4 -+ SectionData: 2D000000 -+ - Name: .debug_undiscardable -+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA ] -+ VirtualAddress: 24576 -+ VirtualSize: 4 -+ SectionData: 2E000000 -+ - Name: .unflagged -+ Characteristics: [ ] -+ VirtualAddress: 28672 -+ VirtualSize: 4 -+ SectionData: 2F000000 -+symbols: -+ - Name: main -+ Value: 2 -+ SectionNumber: 1 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION -+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL -+ - Name: debug_discardable_sym -+ Value: 0 -+ SectionNumber: 5 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION -+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL -+ - Name: debug_undiscardable_sym -+ Value: 0 -+ SectionNumber: 6 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION -+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL -+... -diff --git a/llvm/test/tools/llvm-objcopy/COFF/only-keep-debug.test b/llvm/test/tools/llvm-objcopy/COFF/only-keep-debug.test -new file mode 100644 -index 00000000000..5518d4000fc ---- /dev/null -+++ b/llvm/test/tools/llvm-objcopy/COFF/only-keep-debug.test -@@ -0,0 +1,58 @@ -+RUN: yaml2obj %p/Inputs/only-keep-sections.yaml > %t.in.exe -+ -+RUN: llvm-objcopy --only-keep-debug %t.in.exe %t.out.exe -+RUN: llvm-readobj --sections %t.out.exe | FileCheck %s --check-prefix=SECTIONS -+RUN: llvm-objdump -t %t.out.exe | FileCheck %s --check-prefix=SYMBOLS -+ -+Check that all non-debug/buildid sections with IMAGE_SCN_CNT_CODE -+or IMAGE_SCN_CNT_INITIALIZED_DATA are truncated, and no others. -+ -+SECTIONS: Sections [ -+SECTIONS-NEXT: Section { -+SECTIONS-NEXT: Number: 1 -+SECTIONS-NEXT: Name: .text -+SECTIONS-NEXT: VirtualSize: 0x4 -+SECTIONS-NEXT: VirtualAddress: -+SECTIONS-NEXT: RawDataSize: 0 -+SECTIONS: Section { -+SECTIONS-NEXT: Number: 2 -+SECTIONS-NEXT: Name: .rdata -+SECTIONS-NEXT: VirtualSize: 0x4 -+SECTIONS-NEXT: VirtualAddress: -+SECTIONS-NEXT: RawDataSize: 0 -+SECTIONS: Section { -+SECTIONS-NEXT: Number: 3 -+SECTIONS-NEXT: Name: .buildid -+SECTIONS-NEXT: VirtualSize: 0x4 -+SECTIONS-NEXT: VirtualAddress: -+SECTIONS-NEXT: RawDataSize: 512 -+SECTIONS: Section { -+SECTIONS-NEXT: Number: 4 -+SECTIONS-NEXT: Name: .reloc -+SECTIONS-NEXT: VirtualSize: 0x4 -+SECTIONS-NEXT: VirtualAddress: -+SECTIONS-NEXT: RawDataSize: 0 -+SECTIONS: Section { -+SECTIONS-NEXT: Number: 5 -+SECTIONS-NEXT: Name: .debug_discardable -+SECTIONS-NEXT: VirtualSize: 0x4 -+SECTIONS-NEXT: VirtualAddress: -+SECTIONS-NEXT: RawDataSize: 512 -+SECTIONS: Section { -+SECTIONS-NEXT: Number: 6 -+SECTIONS-NEXT: Name: .debug_undiscardable -+SECTIONS-NEXT: VirtualSize: 0x4 -+SECTIONS-NEXT: VirtualAddress: -+SECTIONS-NEXT: RawDataSize: 512 -+SECTIONS: Section { -+SECTIONS-NEXT: Number: 7 -+SECTIONS-NEXT: Name: .unflagged -+SECTIONS-NEXT: VirtualSize: 0x4 -+SECTIONS-NEXT: VirtualAddress: -+SECTIONS-NEXT: RawDataSize: 512 -+ -+SYMBOLS: SYMBOL TABLE: -+SYMBOLS-NEXT: main -+SYMBOLS-NEXT: debug_discardable_sym -+SYMBOLS-NEXT: debug_undiscardable_sym -+SYMBOLS-EMPTY: -diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -index 13d8efde37c..60afbf7bb54 100644 ---- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -@@ -46,6 +46,16 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) { - return false; - }); - -+ if (Config.OnlyKeepDebug) { -+ // For --only-keep-debug, we keep all other sections, but remove their -+ // content. The VirtualSize field in the section header is kept intact. -+ Obj.truncateSections([](const Section &Sec) { -+ return !isDebugSection(Sec) && Sec.Name != ".buildid" && -+ ((Sec.Header.Characteristics & -+ (IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA)) != 0); -+ }); -+ } -+ - // StripAll removes all symbols and thus also removes all relocations. - if (Config.StripAll || Config.StripAllGNU) - for (Section &Sec : Obj.getMutableSections()) -diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp -index e19cea6aa9d..fc87d9e574d 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Object.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp -@@ -127,6 +127,16 @@ void Object::removeSections(function_ref<bool(const Section &)> ToRemove) { - updateSymbols(); - } - -+void Object::truncateSections(function_ref<bool(const Section &)> ToTruncate) { -+ for (Section &Sec : Sections) { -+ if (ToTruncate(Sec)) { -+ Sec.Contents = ArrayRef<uint8_t>(); -+ Sec.Relocs.clear(); -+ Sec.Header.SizeOfRawData = 0; -+ } -+ } -+} -+ - } // end namespace coff - } // end namespace objcopy - } // end namespace llvm -diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h -index a73e93620d3..8e200369f0b 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Object.h -+++ b/llvm/tools/llvm-objcopy/COFF/Object.h -@@ -93,6 +93,7 @@ struct Object { - - void addSections(ArrayRef<Section> NewSections); - void removeSections(function_ref<bool(const Section &)> ToRemove); -+ void truncateSections(function_ref<bool(const Section &)> ToTruncate); - - private: - std::vector<Symbol> Symbols; --- -2.17.1 -
deleted file mode 100644 --- a/build/build-clang/mingwclang-llvm-objcopy-COFF-Implement-only-section.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 17dcf25b3ade15605ca27150e4440bcc75caed65 Mon Sep 17 00:00:00 2001 -From: Martin Storsjo <martin@martin.st> -Date: Sat, 19 Jan 2019 19:42:54 +0000 -Subject: [PATCH] [llvm-objcopy] [COFF] Implement --only-section - -Differential Revision: https://reviews.llvm.org/D56873 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351663 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - .../tools/llvm-objcopy/COFF/only-section.test | 21 +++++++++++++++++++ - tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 6 ++++++ - 2 files changed, 27 insertions(+) - create mode 100644 test/tools/llvm-objcopy/COFF/only-section.test - -diff --git a/llvm/test/tools/llvm-objcopy/COFF/only-section.test b/llvm/test/tools/llvm-objcopy/COFF/only-section.test -new file mode 100644 -index 00000000000..42492ed80ff ---- /dev/null -+++ b/llvm/test/tools/llvm-objcopy/COFF/only-section.test -@@ -0,0 +1,21 @@ -+RUN: yaml2obj %p/Inputs/only-keep-sections.yaml > %t.in.exe -+ -+RUN: llvm-objcopy --only-section .debug_discardable %t.in.exe %t.out.exe -+RUN: llvm-objdump --section-headers -t %t.out.exe | FileCheck %s --check-prefixes=SECTIONS,SECTIONS-DEBUG,SYMBOLS,SYMBOLS-DEBUG -+ -+Adding another section stripping option makes it return the intersection of -+kept sections - in this case keeping only .text. -+ -+RUN: llvm-objcopy --only-section .debug_discardable --only-section .text --strip-debug %t.in.exe %t.combination.exe -+RUN: llvm-objdump --section-headers -t %t.combination.exe | FileCheck %s --check-prefixes=SECTIONS,SECTIONS-TEXT,SYMBOLS,SYMBOLS-TEXT -+ -+SECTIONS: Sections: -+SECTIONS-NEXT: Idx Name -+SECTIONS-DEBUG-NEXT: .debug_discardable -+SECTIONS-TEXT-NEXT: .text -+SECTIONS-EMPTY: -+ -+SYMBOLS: SYMBOL TABLE: -+SYMBOLS-DEBUG-NEXT: debug_discardable_sym -+SYMBOLS-TEXT-NEXT: main -+SYMBOLS-EMPTY: -diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -index 60afbf7bb54..99929d10a1f 100644 ---- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -@@ -33,6 +33,12 @@ static bool isDebugSection(const Section &Sec) { - static Error handleArgs(const CopyConfig &Config, Object &Obj) { - // Perform the actual section removals. - Obj.removeSections([&Config](const Section &Sec) { -+ // Contrary to --only-keep-debug, --only-section fully removes sections that -+ // aren't mentioned. -+ if (!Config.OnlySection.empty() && -+ !is_contained(Config.OnlySection, Sec.Name)) -+ return true; -+ - if (Config.StripDebug || Config.StripAll || Config.StripAllGNU || - Config.DiscardAll || Config.StripUnneeded) { - if (isDebugSection(Sec) && --- -2.17.1 -
deleted file mode 100644 --- a/build/build-clang/mingwclang-llvm-objcopy-COFF-Implement-strip-debug.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 2b6e1b7585d6bd997ea4e4233c904a6d2c11ad33 Mon Sep 17 00:00:00 2001 -From: Martin Storsjo <martin@martin.st> -Date: Sat, 19 Jan 2019 19:42:41 +0000 -Subject: [PATCH] [llvm-objcopy] [COFF] Implement --strip-debug - -Also remove sections similarly for --strip-all, --discard-all, ---strip-unneeded. - -Differential Revision: https://reviews.llvm.org/D56839 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351661 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - test/tools/llvm-objcopy/COFF/strip-debug.test | 109 ++++++++++++++++++ - tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 11 ++ - 2 files changed, 120 insertions(+) - create mode 100644 test/tools/llvm-objcopy/COFF/strip-debug.test - -diff --git a/llvm/test/tools/llvm-objcopy/COFF/strip-debug.test b/llvm/test/tools/llvm-objcopy/COFF/strip-debug.test -new file mode 100644 -index 00000000000..97fa96aac70 ---- /dev/null -+++ b/llvm/test/tools/llvm-objcopy/COFF/strip-debug.test -@@ -0,0 +1,109 @@ -+# RUN: yaml2obj %s > %t.in.o -+# -+# RUN: llvm-objdump --section-headers %t.in.o | FileCheck %s --check-prefixes=SECTIONS,SECTIONS-PRE -+# RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-PRE -+# -+# RUN: llvm-objcopy --strip-debug %t.in.o %t.out.o -+# RUN: llvm-objdump --section-headers %t.out.o | FileCheck %s --check-prefixes=SECTIONS -+# RUN: llvm-objdump -t %t.out.o | FileCheck %s --check-prefixes=SYMBOLS -+# -+# Test that --strip-all, --strip-all-gnu, --discard-all and --strip-unneeded, -+# plus llvm-strip without arguments all produce a similiar set of sections -+# (while they remove symbols differently). -+# -+# RUN: llvm-objcopy --strip-all %t.in.o %t.strip-all.o -+# RUN: llvm-objdump --section-headers %t.strip-all.o | FileCheck %s --check-prefixes=SECTIONS -+# -+# RUN: llvm-objcopy --strip-all-gnu %t.in.o %t.strip-all-gnu.o -+# RUN: llvm-objdump --section-headers %t.strip-all-gnu.o | FileCheck %s --check-prefixes=SECTIONS -+# -+# RUN: llvm-objcopy --discard-all %t.in.o %t.discard-all.o -+# RUN: llvm-objdump --section-headers %t.discard-all.o | FileCheck %s --check-prefixes=SECTIONS -+# -+# RUN: llvm-objcopy --discard-all %t.in.o %t.strip-unneeded.o -+# RUN: llvm-objdump --section-headers %t.strip-unneeded.o | FileCheck %s --check-prefixes=SECTIONS -+# -+# SECTIONS: Sections: -+# SECTIONS-NEXT: Idx Name -+# SECTIONS-NEXT: 0 .text -+# SECTIONS-NEXT: 1 .data -+# SECTIONS-NEXT: 2 .bss -+# SECTIONS-NEXT: 3 .xdata -+# SECTIONS-NEXT: 4 .reloc -+# SECTIONS-PRE-NEXT: 5 .debug_discardable -+# SECTIONS-NEXT: {{.*}} .debug_undiscardable -+# SECTIONS-NEXT: {{.*}} .llvm_addrsig -+# SECTIONS-EMPTY: -+# -+# Test that --strip-debug doesn't remove e.g. unreferenced local symbols. -+# -+# SYMBOLS: SYMBOL TABLE: -+# SYMBOLS-NEXT: external -+# SYMBOLS-NEXT: local_unreferenced -+# SYMBOLS-PRE-NEXT: debug_discardable_sym -+# SYMBOLS-NEXT: debug_undiscardable_sym -+# SYMBOLS-EMPTY: -+ -+--- !COFF -+header: -+ Machine: IMAGE_FILE_MACHINE_AMD64 -+ Characteristics: [ ] -+sections: -+ - Name: .text -+ Characteristics: [ ] -+ Alignment: 4 -+ SectionData: 00000000 -+ - Name: .data -+ Characteristics: [ ] -+ Alignment: 4 -+ SectionData: 00000000 -+ - Name: .bss -+ Characteristics: [ ] -+ Alignment: 4 -+ SectionData: 00000000 -+ - Name: .xdata -+ Characteristics: [ ] -+ Alignment: 4 -+ SectionData: 00000000 -+ - Name: .reloc -+ Characteristics: [ IMAGE_SCN_MEM_DISCARDABLE ] -+ Alignment: 4 -+ SectionData: 00000000 -+ - Name: .debug_discardable -+ Characteristics: [ IMAGE_SCN_MEM_DISCARDABLE ] -+ Alignment: 4 -+ SectionData: 00000000 -+ - Name: .debug_undiscardable -+ Characteristics: [ ] -+ Alignment: 4 -+ SectionData: 00000000 -+ - Name: .llvm_addrsig -+ Characteristics: [ IMAGE_SCN_LNK_REMOVE ] -+ Alignment: 4 -+ SectionData: 00000000 -+symbols: -+ - Name: external -+ Value: 0 -+ SectionNumber: 1 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_NULL -+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL -+ - Name: local_unreferenced -+ Value: 0 -+ SectionNumber: 1 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_NULL -+ StorageClass: IMAGE_SYM_CLASS_STATIC -+ - Name: debug_discardable_sym -+ Value: 0 -+ SectionNumber: 6 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_NULL -+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL -+ - Name: debug_undiscardable_sym -+ Value: 0 -+ SectionNumber: 7 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_NULL -+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL -+... -diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -index dd2e4829218..13d8efde37c 100644 ---- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -@@ -26,9 +26,20 @@ namespace coff { - using namespace object; - using namespace COFF; - -+static bool isDebugSection(const Section &Sec) { -+ return Sec.Name.startswith(".debug"); -+} -+ - static Error handleArgs(const CopyConfig &Config, Object &Obj) { - // Perform the actual section removals. - Obj.removeSections([&Config](const Section &Sec) { -+ if (Config.StripDebug || Config.StripAll || Config.StripAllGNU || -+ Config.DiscardAll || Config.StripUnneeded) { -+ if (isDebugSection(Sec) && -+ (Sec.Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0) -+ return true; -+ } -+ - if (is_contained(Config.ToRemove, Sec.Name)) - return true; - --- -2.17.1 -
deleted file mode 100644 --- a/build/build-clang/mingwclang-llvm-objcopy-COFF-Remove-a-superfluous-namespace-qua.patch +++ /dev/null @@ -1,27 +0,0 @@ -From a495c9ae6fb3367e6b59d8d245273ed3669754f0 Mon Sep 17 00:00:00 2001 -From: Martin Storsjo <martin@martin.st> -Date: Sat, 19 Jan 2019 19:42:23 +0000 -Subject: [PATCH] [llvm-objcopy] [COFF] Remove a superfluous namespace - qualification. NFC. - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351658 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -index ceebf600b3a..437dccbd3d5 100644 ---- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -@@ -78,7 +78,7 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) { - } - - void executeObjcopyOnBinary(const CopyConfig &Config, -- object::COFFObjectFile &In, Buffer &Out) { -+ COFFObjectFile &In, Buffer &Out) { - COFFReader Reader(In); - Expected<std::unique_ptr<Object>> ObjOrErr = Reader.create(); - if (!ObjOrErr) --- -2.17.1 -
deleted file mode 100644 --- a/build/build-clang/mingwclang-llvm-objcopy-COFF-Update-symbol-indices-in-weak-exte.patch +++ /dev/null @@ -1,224 +0,0 @@ -From d37f67c7311cd371d9ff1afd398bc92f309e6baf Mon Sep 17 00:00:00 2001 -From: Martin Storsjo <martin@martin.st> -Date: Tue, 22 Jan 2019 10:58:09 +0000 -Subject: [PATCH] [llvm-objcopy] [COFF] Update symbol indices in weak externals - -Differential Revision: https://reviews.llvm.org/D57006 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351800 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - .../llvm-objcopy/COFF/weak-external.test | 49 +++++++++++++++++++ - tools/llvm-objcopy/COFF/Object.h | 2 + - tools/llvm-objcopy/COFF/Reader.cpp | 24 ++++++++- - tools/llvm-objcopy/COFF/Reader.h | 2 +- - tools/llvm-objcopy/COFF/Writer.cpp | 16 +++++- - tools/llvm-objcopy/COFF/Writer.h | 2 +- - 6 files changed, 89 insertions(+), 6 deletions(-) - create mode 100644 test/tools/llvm-objcopy/COFF/weak-external.test - -diff --git a/llvm/test/tools/llvm-objcopy/COFF/weak-external.test b/llvm/test/tools/llvm-objcopy/COFF/weak-external.test -new file mode 100644 -index 00000000000..d36a53b4eb1 ---- /dev/null -+++ b/llvm/test/tools/llvm-objcopy/COFF/weak-external.test -@@ -0,0 +1,49 @@ -+# RUN: yaml2obj %s > %t.in.o -+ -+# RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-PRE -+ -+# RUN: llvm-objcopy -N func %t.in.o %t.out.o -+# RUN: llvm-objdump -t %t.out.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-POST -+ -+# RUN: not llvm-objcopy -N .weak.foobar.file1 %t.in.o %t.err.o 2>&1 | FileCheck %s --check-prefix=ERROR -+ -+# SYMBOLS: SYMBOL TABLE: -+# SYMBOLS-PRE-NEXT: func -+# SYMBOLS-NEXT: .weak.foobar.file1 -+# SYMBOLS-NEXT: foobar -+# SYMBOLS-PRE-NEXT: AUX indx 1 -+# SYMBOLS-POST-NEXT: AUX indx 0 -+# SYMBOLS-EMPTY: -+ -+# ERROR: Symbol 'foobar' is missing its weak target -+ -+--- !COFF -+header: -+ Machine: IMAGE_FILE_MACHINE_AMD64 -+ Characteristics: [ ] -+sections: -+ - Name: .text -+ Characteristics: [ ] -+symbols: -+ - Name: func -+ Value: 0 -+ SectionNumber: 1 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_NULL -+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL -+ - Name: .weak.foobar.file1 -+ Value: 1 -+ SectionNumber: 1 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_NULL -+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL -+ - Name: foobar -+ Value: 0 -+ SectionNumber: 0 -+ SimpleType: IMAGE_SYM_TYPE_NULL -+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION -+ StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL -+ WeakExternal: -+ TagIndex: 1 -+ Characteristics: IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY -+... -diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h -index 8e200369f0b..0630f9c5ff8 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Object.h -+++ b/llvm/tools/llvm-objcopy/COFF/Object.h -@@ -11,6 +11,7 @@ - - #include "llvm/ADT/ArrayRef.h" - #include "llvm/ADT/DenseMap.h" -+#include "llvm/ADT/Optional.h" - #include "llvm/ADT/StringRef.h" - #include "llvm/ADT/iterator_range.h" - #include "llvm/BinaryFormat/COFF.h" -@@ -47,6 +48,7 @@ struct Symbol { - std::vector<uint8_t> AuxData; - ssize_t TargetSectionId; - ssize_t AssociativeComdatTargetSectionId = 0; -+ Optional<size_t> WeakTargetSymbolId; - size_t UniqueId; - size_t RawIndex; - bool Referenced; -diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp -index 20ff32a59dc..2446277cc2b 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp -@@ -121,12 +121,18 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const { - // For section definitions, check if it is comdat associative, and if - // it is, find the target section unique id. - const coff_aux_section_definition *SD = SymRef.getSectionDefinition(); -+ const coff_aux_weak_external *WE = SymRef.getWeakExternal(); - if (SD && SD->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) { - int32_t Index = SD->getNumber(IsBigObj); - if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size()) - return createStringError(object_error::parse_failed, - "Unexpected associative section index"); - Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId; -+ } else if (WE) { -+ // This is a raw symbol index for now, but store it in the Symbol -+ // until we've added them to the Object, which assigns the final -+ // unique ids. -+ Sym.WeakTargetSymbolId = WE->TagIndex; - } - I += 1 + SymRef.getNumberOfAuxSymbols(); - } -@@ -134,13 +140,27 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const { - return Error::success(); - } - --Error COFFReader::setRelocTargets(Object &Obj) const { -+Error COFFReader::setSymbolTargets(Object &Obj) const { - std::vector<const Symbol *> RawSymbolTable; - for (const Symbol &Sym : Obj.getSymbols()) { - RawSymbolTable.push_back(&Sym); - for (size_t I = 0; I < Sym.Sym.NumberOfAuxSymbols; I++) - RawSymbolTable.push_back(nullptr); - } -+ for (Symbol &Sym : Obj.getMutableSymbols()) { -+ // Convert WeakTargetSymbolId from the original raw symbol index to -+ // a proper unique id. -+ if (Sym.WeakTargetSymbolId) { -+ if (*Sym.WeakTargetSymbolId >= RawSymbolTable.size()) -+ return createStringError(object_error::parse_failed, -+ "Weak external reference out of range"); -+ const Symbol *Target = RawSymbolTable[*Sym.WeakTargetSymbolId]; -+ if (Target == nullptr) -+ return createStringError(object_error::parse_failed, -+ "Invalid SymbolTableIndex"); -+ Sym.WeakTargetSymbolId = Target->UniqueId; -+ } -+ } - for (Section &Sec : Obj.getMutableSections()) { - for (Relocation &R : Sec.Relocs) { - if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size()) -@@ -184,7 +204,7 @@ Expected<std::unique_ptr<Object>> COFFReader::create() const { - return std::move(E); - if (Error E = readSymbols(*Obj, IsBigObj)) - return std::move(E); -- if (Error E = setRelocTargets(*Obj)) -+ if (Error E = setSymbolTargets(*Obj)) - return std::move(E); - - return std::move(Obj); -diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.h b/llvm/tools/llvm-objcopy/COFF/Reader.h -index 4493705e73c..ec15369db0b 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Reader.h -+++ b/llvm/tools/llvm-objcopy/COFF/Reader.h -@@ -28,7 +28,7 @@ class COFFReader { - Error readExecutableHeaders(Object &Obj) const; - Error readSections(Object &Obj) const; - Error readSymbols(Object &Obj, bool IsBigObj) const; -- Error setRelocTargets(Object &Obj) const; -+ Error setSymbolTargets(Object &Obj) const; - - public: - explicit COFFReader(const COFFObjectFile &O) : COFFObj(O) {} -diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp -index 0321f94a896..4f57131d5ab 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp -@@ -38,7 +38,7 @@ Error COFFWriter::finalizeRelocTargets() { - return Error::success(); - } - --Error COFFWriter::finalizeSectionNumbers() { -+Error COFFWriter::finalizeSymbolContents() { - for (Symbol &Sym : Obj.getMutableSymbols()) { - if (Sym.TargetSectionId <= 0) { - // Undefined, or a special kind of symbol. These negative values -@@ -75,6 +75,18 @@ Error COFFWriter::finalizeSectionNumbers() { - SD->NumberHighPart = static_cast<uint16_t>(SDSectionNumber >> 16); - } - } -+ // Check that we actually have got AuxData to match the weak symbol target -+ // we want to set. Only >= 1 would be required, but only == 1 makes sense. -+ if (Sym.WeakTargetSymbolId && Sym.Sym.NumberOfAuxSymbols == 1) { -+ coff_aux_weak_external *WE = -+ reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData.data()); -+ const Symbol *Target = Obj.findSymbol(*Sym.WeakTargetSymbolId); -+ if (Target == nullptr) -+ return createStringError(object_error::invalid_symbol_index, -+ "Symbol '%s' is missing its weak target", -+ Sym.Name.str().c_str()); -+ WE->TagIndex = Target->RawIndex; -+ } - } - return Error::success(); - } -@@ -137,7 +149,7 @@ std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() { - Error COFFWriter::finalize(bool IsBigObj) { - if (Error E = finalizeRelocTargets()) - return E; -- if (Error E = finalizeSectionNumbers()) -+ if (Error E = finalizeSymbolContents()) - return E; - - size_t SizeOfHeaders = 0; -diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/tools/llvm-objcopy/COFF/Writer.h -index a967a103df9..9b1cfa91d00 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Writer.h -+++ b/llvm/tools/llvm-objcopy/COFF/Writer.h -@@ -31,7 +31,7 @@ class COFFWriter { - StringTableBuilder StrTabBuilder; - - Error finalizeRelocTargets(); -- Error finalizeSectionNumbers(); -+ Error finalizeSymbolContents(); - void layoutSections(); - size_t finalizeStringTable(); - template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable(); --- -2.17.1 -
deleted file mode 100644 --- a/build/build-clang/mingwclang-llvm-objcopy-Consistently-use-createStringError-inst.patch +++ /dev/null @@ -1,242 +0,0 @@ -From d3b89a1637cddee1c61e59257cfe92227ead29e5 Mon Sep 17 00:00:00 2001 -From: Martin Storsjo <martin@martin.st> -Date: Tue, 22 Jan 2019 10:57:59 +0000 -Subject: [PATCH] [llvm-objcopy] Consistently use createStringError instead of - make_error<StringError> - -This was requested in the review of D57006. - -Also add missing quotes around symbol names in error messages. - -Differential Revision: https://reviews.llvm.org/D57014 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351799 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - .../llvm-objcopy/COFF/remove-section.test | 2 +- - tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 8 ++--- - tools/llvm-objcopy/COFF/Object.cpp | 5 ++- - tools/llvm-objcopy/COFF/Reader.cpp | 24 +++++++------- - tools/llvm-objcopy/COFF/Writer.cpp | 33 +++++++++---------- - tools/llvm-objcopy/ELF/ELFObjcopy.cpp | 10 +++--- - 6 files changed, 40 insertions(+), 42 deletions(-) - -diff --git a/llvm/test/tools/llvm-objcopy/COFF/remove-section.test b/llvm/test/tools/llvm-objcopy/COFF/remove-section.test -index b3dfb0b98cb..6dc8f6a6c2e 100644 ---- a/test/tools/llvm-objcopy/COFF/remove-section.test -+++ b/llvm/test/tools/llvm-objcopy/COFF/remove-section.test -@@ -96,7 +96,7 @@ - # Removing the .comdat section fails, since the .text section has relocations - # against it. - # --# ERROR-RELOC: Relocation target foo ({{.*}}) not found -+# ERROR-RELOC: Relocation target 'foo' ({{.*}}) not found - # - # - # Removing the .comdat section and .text (with a relocation against .comdat) -diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -index 99929d10a1f..8d8f53d13d8 100644 ---- a/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp -@@ -84,10 +84,10 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) { - // Explicitly removing a referenced symbol is an error. - if (Sym.Referenced) - reportError(Config.OutputFilename, -- make_error<StringError>( -- "not stripping symbol '" + Sym.Name + -- "' because it is named in a relocation.", -- llvm::errc::invalid_argument)); -+ createStringError(llvm::errc::invalid_argument, -+ "not stripping symbol '%s' because it is " -+ "named in a relocation.", -+ Sym.Name.str().c_str())); - return true; - } - -diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp -index fc87d9e574d..83435dffa98 100644 ---- a/tools/llvm-objcopy/COFF/Object.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp -@@ -56,9 +56,8 @@ Error Object::markSymbols() { - for (const Relocation &R : Sec.Relocs) { - auto It = SymbolMap.find(R.Target); - if (It == SymbolMap.end()) -- return make_error<StringError>("Relocation target " + Twine(R.Target) + -- " not found", -- object_error::invalid_symbol_index); -+ return createStringError(object_error::invalid_symbol_index, -+ "Relocation target %zu not found", R.Target); - It->second->Referenced = true; - } - } -diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp -index c8abe2913a2..20ff32a59dc 100644 ---- a/tools/llvm-objcopy/COFF/Reader.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp -@@ -77,8 +77,8 @@ Error COFFReader::readSections(Object &Obj) const { - if (auto EC = COFFObj.getSectionName(Sec, S.Name)) - return errorCodeToError(EC); - if (Sec->hasExtendedRelocations()) -- return make_error<StringError>("Extended relocations not supported yet", -- object_error::parse_failed); -+ return createStringError(object_error::parse_failed, -+ "Extended relocations not supported yet"); - } - Obj.addSections(Sections); - return Error::success(); -@@ -116,16 +116,16 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const { - Sections.size()) - Sym.TargetSectionId = Sections[SymRef.getSectionNumber() - 1].UniqueId; - else -- return make_error<StringError>("Section number out of range", -- object_error::parse_failed); -+ return createStringError(object_error::parse_failed, -+ "Section number out of range"); - // For section definitions, check if it is comdat associative, and if - // it is, find the target section unique id. - const coff_aux_section_definition *SD = SymRef.getSectionDefinition(); - if (SD && SD->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) { - int32_t Index = SD->getNumber(IsBigObj); - if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size()) -- return make_error<StringError>("Unexpected associative section index", -- object_error::parse_failed); -+ return createStringError(object_error::parse_failed, -+ "Unexpected associative section index"); - Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId; - } - I += 1 + SymRef.getNumberOfAuxSymbols(); -@@ -144,12 +144,12 @@ Error COFFReader::setRelocTargets(Object &Obj) const { - for (Section &Sec : Obj.getMutableSections()) { - for (Relocation &R : Sec.Relocs) { - if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size()) -- return make_error<StringError>("SymbolTableIndex out of range", -- object_error::parse_failed); -+ return createStringError(object_error::parse_failed, -+ "SymbolTableIndex out of range"); - const Symbol *Sym = RawSymbolTable[R.Reloc.SymbolTableIndex]; - if (Sym == nullptr) -- return make_error<StringError>("Invalid SymbolTableIndex", -- object_error::parse_failed); -+ return createStringError(object_error::parse_failed, -+ "Invalid SymbolTableIndex"); - R.Target = Sym->UniqueId; - R.TargetName = Sym->Name; - } -@@ -169,8 +169,8 @@ Expected<std::unique_ptr<Object>> COFFReader::create() const { - Obj->CoffFileHeader = *CFH; - } else { - if (!CBFH) -- return make_error<StringError>("No COFF file header returned", -- object_error::parse_failed); -+ return createStringError(object_error::parse_failed, -+ "No COFF file header returned"); - // Only copying the few fields from the bigobj header that we need - // and won't recreate in the end. - Obj->CoffFileHeader.Machine = CBFH->Machine; -diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp -index 9fb7812672b..0321f94a896 100644 ---- a/tools/llvm-objcopy/COFF/Writer.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp -@@ -29,10 +29,9 @@ Error COFFWriter::finalizeRelocTargets() { - for (Relocation &R : Sec.Relocs) { - const Symbol *Sym = Obj.findSymbol(R.Target); - if (Sym == nullptr) -- return make_error<StringError>("Relocation target " + R.TargetName + -- " (" + Twine(R.Target) + -- ") not found", -- object_error::invalid_symbol_index); -+ return createStringError(object_error::invalid_symbol_index, -+ "Relocation target '%s' (%zu) not found", -+ R.TargetName.str().c_str(), R.Target); - R.Reloc.SymbolTableIndex = Sym->RawIndex; - } - } -@@ -48,9 +47,9 @@ Error COFFWriter::finalizeSectionNumbers() { - } else { - const Section *Sec = Obj.findSection(Sym.TargetSectionId); - if (Sec == nullptr) -- return make_error<StringError>("Symbol " + Sym.Name + -- " points to a removed section", -- object_error::invalid_symbol_index); -+ return createStringError(object_error::invalid_symbol_index, -+ "Symbol '%s' points to a removed section", -+ Sym.Name.str().c_str()); - Sym.Sym.SectionNumber = Sec->Index; - - if (Sym.Sym.NumberOfAuxSymbols == 1 && -@@ -65,9 +64,10 @@ Error COFFWriter::finalizeSectionNumbers() { - } else { - Sec = Obj.findSection(Sym.AssociativeComdatTargetSectionId); - if (Sec == nullptr) -- return make_error<StringError>( -- "Symbol " + Sym.Name + " is associative to a removed section", -- object_error::invalid_symbol_index); -+ return createStringError( -+ object_error::invalid_symbol_index, -+ "Symbol '%s' is associative to a removed section", -+ Sym.Name.str().c_str()); - SDSectionNumber = Sec->Index; - } - // Update the section definition with the new section number. -@@ -343,9 +343,8 @@ Error COFFWriter::patchDebugDirectory() { - S.Header.VirtualAddress + S.Header.SizeOfRawData) { - if (Dir->RelativeVirtualAddress + Dir->Size > - S.Header.VirtualAddress + S.Header.SizeOfRawData) -- return make_error<StringError>( -- "Debug directory extends past end of section", -- object_error::parse_failed); -+ return createStringError(object_error::parse_failed, -+ "Debug directory extends past end of section"); - - size_t Offset = Dir->RelativeVirtualAddress - S.Header.VirtualAddress; - uint8_t *Ptr = Buf.getBufferStart() + S.Header.PointerToRawData + Offset; -@@ -361,15 +360,15 @@ Error COFFWriter::patchDebugDirectory() { - return Error::success(); - } - } -- return make_error<StringError>("Debug directory not found", -- object_error::parse_failed); -+ return createStringError(object_error::parse_failed, -+ "Debug directory not found"); - } - - Error COFFWriter::write() { - bool IsBigObj = Obj.getSections().size() > MaxNumberOfSections16; - if (IsBigObj && Obj.IsPE) -- return make_error<StringError>("Too many sections for executable", -- object_error::parse_failed); -+ return createStringError(object_error::parse_failed, -+ "Too many sections for executable"); - return write(IsBigObj); - } - -diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp -index db0cd76ced4..a2996395c1f 100644 ---- a/tools/llvm-objcopy/ELF/ELFObjcopy.cpp -+++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp -@@ -185,9 +185,10 @@ static Error dumpSectionToFile(StringRef SecName, StringRef Filename, - for (auto &Sec : Obj.sections()) { - if (Sec.Name == SecName) { - if (Sec.OriginalData.empty()) -- return make_error<StringError>("Can't dump section \"" + SecName + -- "\": it has no contents", -- object_error::parse_failed); -+ return createStringError( -+ object_error::parse_failed, -+ "Can't dump section \"%s\": it has no contents", -+ SecName.str().c_str()); - Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = - FileOutputBuffer::create(Filename, Sec.OriginalData.size()); - if (!BufferOrErr) -@@ -200,8 +201,7 @@ static Error dumpSectionToFile(StringRef SecName, StringRef Filename, - return Error::success(); - } - } -- return make_error<StringError>("Section not found", -- object_error::parse_failed); -+ return createStringError(object_error::parse_failed, "Section not found"); - } - - static bool isCompressed(const SectionBase &Section) { --- -2.17.1 -
deleted file mode 100644 --- a/build/build-clang/mingwclang-llvm-objcopy-Return-Error-from-Buffer-allocate-ELF-W.patch +++ /dev/null @@ -1,330 +0,0 @@ -From 8cf7aa39d7c9461e2d765f6d4fa7e0925571695f Mon Sep 17 00:00:00 2001 -From: Jordan Rupprecht <rupprecht@google.com> -Date: Tue, 22 Jan 2019 23:49:16 +0000 -Subject: [PATCH] [llvm-objcopy] Return Error from Buffer::allocate(), - [ELF]Writer::finalize(), and [ELF]Writer::commit() - -Summary: -This patch changes a few methods to return Error instead of manually calling error/reportError to abort. This will make it easier to extract into a library. - -Note that error() takes just a string (this patch also adds an overload that takes an Error), while reportError() takes string + [error/code]. To help unify things, use FileError to associate a given filename with an error. Note that this takes some special care (for now), e.g. calling reportError(FileName, <something that could be FileError>) will duplicate the filename. The goal is to eventually remove reportError() and have every error associated with a file to be a FileError, and just one error handling block at the tool level. - -This change was suggested in D56806. I took it a little further than suggested, but completely fixing llvm-objcopy will take a couple more patches. If this approach looks good, I'll commit this and apply similar patche(s) for the rest. - -This change is NFC in terms of non-error related code, although the error message changes in one context. - -Reviewers: alexshap, jhenderson, jakehehrlich, mstorsjo, espindola - -Reviewed By: alexshap, jhenderson - -Subscribers: llvm-commits, emaste, arichardson - -Differential Revision: https://reviews.llvm.org/D56930 - -git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351896 91177308-0d34-0410-b5e6-96231b3b80d8 ---- - .../ELF/fail-no-output-directory.test | 2 +- - tools/llvm-objcopy/Buffer.cpp | 20 ++++++++++++----- - tools/llvm-objcopy/Buffer.h | 6 ++--- - tools/llvm-objcopy/COFF/Writer.cpp | 3 ++- - tools/llvm-objcopy/ELF/ELFObjcopy.cpp | 18 ++++++++++----- - tools/llvm-objcopy/ELF/Object.cpp | 22 ++++++++++--------- - tools/llvm-objcopy/ELF/Object.h | 12 +++++----- - tools/llvm-objcopy/llvm-objcopy.cpp | 15 +++++++++++-- - tools/llvm-objcopy/llvm-objcopy.h | 1 + - 9 files changed, 64 insertions(+), 35 deletions(-) - -diff --git a/llvm/test/tools/llvm-objcopy/ELF/fail-no-output-directory.test b/llvm/test/tools/llvm-objcopy/ELF/fail-no-output-directory.test -index f66b2e09fce..732046fa925 100644 ---- a/llvm/test/tools/llvm-objcopy/ELF/fail-no-output-directory.test -+++ b/llvm/test/tools/llvm-objcopy/ELF/fail-no-output-directory.test -@@ -1,6 +1,6 @@ - # RUN: yaml2obj %s > %t - # RUN: not llvm-objcopy %t no/such/dir 2>&1 | FileCheck %s --# CHECK: failed to open no/such/dir: -+# CHECK: error: 'no/such/dir': No such file or directory - - !ELF - FileHeader: -diff --git a/llvm/tools/llvm-objcopy/Buffer.cpp b/llvm/tools/llvm-objcopy/Buffer.cpp -index 2da03dee1af..1789097f276 100644 ---- a/llvm/tools/llvm-objcopy/Buffer.cpp -+++ b/llvm/tools/llvm-objcopy/Buffer.cpp -@@ -17,23 +17,31 @@ namespace objcopy { - - Buffer::~Buffer() {} - --void FileBuffer::allocate(size_t Size) { -+Error FileBuffer::allocate(size_t Size) { - Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = - FileOutputBuffer::create(getName(), Size, FileOutputBuffer::F_executable); -- handleAllErrors(BufferOrErr.takeError(), [this](const ErrorInfoBase &E) { -- error("failed to open " + getName() + ": " + E.message()); -- }); -+ // FileOutputBuffer::create() returns an Error that is just a wrapper around -+ // std::error_code. Wrap it in FileError to include the actual filename. -+ if (!BufferOrErr) -+ return createFileError(getName(), BufferOrErr.takeError()); - Buf = std::move(*BufferOrErr); -+ return Error::success(); - } - --Error FileBuffer::commit() { return Buf->commit(); } -+Error FileBuffer::commit() { -+ Error Err = Buf->commit(); -+ // FileOutputBuffer::commit() returns an Error that is just a wrapper around -+ // std::error_code. Wrap it in FileError to include the actual filename. -+ return Err ? createFileError(getName(), std::move(Err)) : std::move(Err); -+} - - uint8_t *FileBuffer::getBufferStart() { - return reinterpret_cast<uint8_t *>(Buf->getBufferStart()); - } - --void MemBuffer::allocate(size_t Size) { -+Error MemBuffer::allocate(size_t Size) { - Buf = WritableMemoryBuffer::getNewMemBuffer(Size, getName()); -+ return Error::success(); - } - - Error MemBuffer::commit() { return Error::success(); } -diff --git a/llvm/tools/llvm-objcopy/Buffer.h b/llvm/tools/llvm-objcopy/Buffer.h -index 482777fe05c..40670accac2 100644 ---- a/llvm/tools/llvm-objcopy/Buffer.h -+++ b/llvm/tools/llvm-objcopy/Buffer.h -@@ -27,7 +27,7 @@ class Buffer { - - public: - virtual ~Buffer(); -- virtual void allocate(size_t Size) = 0; -+ virtual Error allocate(size_t Size) = 0; - virtual uint8_t *getBufferStart() = 0; - virtual Error commit() = 0; - -@@ -39,7 +39,7 @@ class FileBuffer : public Buffer { - std::unique_ptr<FileOutputBuffer> Buf; - - public: -- void allocate(size_t Size) override; -+ Error allocate(size_t Size) override; - uint8_t *getBufferStart() override; - Error commit() override; - -@@ -50,7 +50,7 @@ class MemBuffer : public Buffer { - std::unique_ptr<WritableMemoryBuffer> Buf; - - public: -- void allocate(size_t Size) override; -+ Error allocate(size_t Size) override; - uint8_t *getBufferStart() override; - Error commit() override; - -diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp -index 4f57131d5ab..db3589bb119 100644 ---- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp -+++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp -@@ -324,7 +324,8 @@ Error COFFWriter::write(bool IsBigObj) { - if (Error E = finalize(IsBigObj)) - return E; - -- Buf.allocate(FileSize); -+ if (Error E = Buf.allocate(FileSize)) -+ return E; - - writeHeaders(IsBigObj); - writeSections(); -diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp -index a2996395c1f..2a52f1f9951 100644 ---- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp -+++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp -@@ -176,8 +176,10 @@ static void splitDWOToFile(const CopyConfig &Config, const Reader &Reader, - DWOFile->Machine = Config.OutputArch.getValue().EMachine; - FileBuffer FB(File); - auto Writer = createWriter(Config, *DWOFile, FB, OutputElfType); -- Writer->finalize(); -- Writer->write(); -+ if (Error E = Writer->finalize()) -+ error(std::move(E)); -+ if (Error E = Writer->write()) -+ error(std::move(E)); - } - - static Error dumpSectionToFile(StringRef SecName, StringRef Filename, -@@ -542,8 +544,10 @@ void executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In, - handleArgs(Config, *Obj, Reader, OutputElfType); - std::unique_ptr<Writer> Writer = - createWriter(Config, *Obj, Out, OutputElfType); -- Writer->finalize(); -- Writer->write(); -+ if (Error E = Writer->finalize()) -+ error(std::move(E)); -+ if (Error E = Writer->write()) -+ error(std::move(E)); - } - - void executeObjcopyOnBinary(const CopyConfig &Config, -@@ -570,8 +574,10 @@ void executeObjcopyOnBinary(const CopyConfig &Config, - handleArgs(Config, *Obj, Reader, OutputElfType); - std::unique_ptr<Writer> Writer = - createWriter(Config, *Obj, Out, OutputElfType); -- Writer->finalize(); -- Writer->write(); -+ if (Error E = Writer->finalize()) -+ error(std::move(E)); -+ if (Error E = Writer->write()) -+ error(std::move(E)); - if (!Config.BuildIdLinkDir.empty() && Config.BuildIdLinkOutput) { - linkToBuildIdDir(Config, Config.OutputFilename, - Config.BuildIdLinkOutput.getValue(), BuildIdBytes); -diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp -index fecb752a39f..ef5dc5d7951 100644 ---- a/llvm/tools/llvm-objcopy/ELF/Object.cpp -+++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp -@@ -1488,17 +1488,16 @@ template <class ELFT> size_t ELFWriter<ELFT>::totalSize() const { - NullSectionSize; - } - --template <class ELFT> void ELFWriter<ELFT>::write() { -+template <class ELFT> Error ELFWriter<ELFT>::write() { - writeEhdr(); - writePhdrs(); - writeSectionData(); - if (WriteSectionHeaders) - writeShdrs(); -- if (auto E = Buf.commit()) -- reportError(Buf.getName(), errorToErrorCode(std::move(E))); -+ return Buf.commit(); - } - --template <class ELFT> void ELFWriter<ELFT>::finalize() { -+template <class ELFT> Error ELFWriter<ELFT>::finalize() { - // It could happen that SectionNames has been removed and yet the user wants - // a section header table output. We need to throw an error if a user tries - // to do that. -@@ -1582,21 +1581,22 @@ template <class ELFT> void ELFWriter<ELFT>::finalize() { - Section.finalize(); - } - -- Buf.allocate(totalSize()); -+ if (Error E = Buf.allocate(totalSize())) -+ return E; - SecWriter = llvm::make_unique<ELFSectionWriter<ELFT>>(Buf); -+ return Error::success(); - } - --void BinaryWriter::write() { -+Error BinaryWriter::write() { - for (auto &Section : Obj.sections()) { - if ((Section.Flags & SHF_ALLOC) == 0) - continue; - Section.accept(*SecWriter); - } -- if (auto E = Buf.commit()) -- reportError(Buf.getName(), errorToErrorCode(std::move(E))); -+ return Buf.commit(); - } - --void BinaryWriter::finalize() { -+Error BinaryWriter::finalize() { - // TODO: Create a filter range to construct OrderedSegments from so that this - // code can be deduped with assignOffsets above. This should also solve the - // todo below for LayoutSections. -@@ -1675,8 +1675,10 @@ void BinaryWriter::finalize() { - TotalSize = std::max(TotalSize, Section->Offset + Section->Size); - } - -- Buf.allocate(TotalSize); -+ if (Error E = Buf.allocate(TotalSize)) -+ return E; - SecWriter = llvm::make_unique<BinarySectionWriter>(Buf); -+ return Error::success(); - } - - template class ELFBuilder<ELF64LE>; -diff --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/tools/llvm-objcopy/ELF/Object.h -index 0dcb0d888bc..9e2b64be9dc 100644 ---- a/llvm/tools/llvm-objcopy/ELF/Object.h -+++ b/llvm/tools/llvm-objcopy/ELF/Object.h -@@ -193,8 +193,8 @@ protected: - - public: - virtual ~Writer(); -- virtual void finalize() = 0; -- virtual void write() = 0; -+ virtual Error finalize() = 0; -+ virtual Error write() = 0; - - Writer(Object &O, Buffer &B) : Obj(O), Buf(B) {} - }; -@@ -226,8 +226,8 @@ public: - virtual ~ELFWriter() {} - bool WriteSectionHeaders = true; - -- void finalize() override; -- void write() override; -+ Error finalize() override; -+ Error write() override; - ELFWriter(Object &Obj, Buffer &Buf, bool WSH) - : Writer(Obj, Buf), WriteSectionHeaders(WSH) {} - }; -@@ -240,8 +240,8 @@ private: - - public: - ~BinaryWriter() {} -- void finalize() override; -- void write() override; -+ Error finalize() override; -+ Error write() override; - BinaryWriter(Object &Obj, Buffer &Buf) : Writer(Obj, Buf) {} - }; - -diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp -index d27395f2ae0..75d513546b7 100644 ---- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp -+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp -@@ -56,6 +56,16 @@ LLVM_ATTRIBUTE_NORETURN void error(Twine Message) { - exit(1); - } - -+LLVM_ATTRIBUTE_NORETURN void error(Error E) { -+ assert(E); -+ std::string Buf; -+ raw_string_ostream OS(Buf); -+ logAllUnhandledErrors(std::move(E), OS); -+ OS.flush(); -+ WithColor::error(errs(), ToolName) << Buf; -+ exit(1); -+} -+ - LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, std::error_code EC) { - assert(EC); - WithColor::error(errs(), ToolName) -@@ -100,10 +110,11 @@ static Error deepWriteArchive(StringRef ArcName, - // NewArchiveMember still requires them even though writeArchive does not - // write them on disk. - FileBuffer FB(Member.MemberName); -- FB.allocate(Member.Buf->getBufferSize()); -+ if (Error E = FB.allocate(Member.Buf->getBufferSize())) -+ return E; - std::copy(Member.Buf->getBufferStart(), Member.Buf->getBufferEnd(), - FB.getBufferStart()); -- if (auto E = FB.commit()) -+ if (Error E = FB.commit()) - return E; - } - return Error::success(); -diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.h b/llvm/tools/llvm-objcopy/llvm-objcopy.h -index 46d8339576c..18a789ca1f8 100644 ---- a/llvm/tools/llvm-objcopy/llvm-objcopy.h -+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.h -@@ -19,6 +19,7 @@ namespace llvm { - namespace objcopy { - - LLVM_ATTRIBUTE_NORETURN extern void error(Twine Message); -+LLVM_ATTRIBUTE_NORETURN extern void error(Error E); - LLVM_ATTRIBUTE_NORETURN extern void reportError(StringRef File, Error E); - LLVM_ATTRIBUTE_NORETURN extern void reportError(StringRef File, - std::error_code EC); --- -2.17.1 -