123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666 |
- 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
|