Index: test/tools/llvm-objcopy/COFF/remove-section.yaml =================================================================== --- /dev/null +++ test/tools/llvm-objcopy/COFF/remove-section.yaml @@ -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 +... Index: tools/llvm-objcopy/COFF/COFFObjcopy.cpp =================================================================== --- tools/llvm-objcopy/COFF/COFFObjcopy.cpp +++ tools/llvm-objcopy/COFF/COFFObjcopy.cpp @@ -28,9 +28,17 @@ 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. Index: tools/llvm-objcopy/COFF/Object.h =================================================================== --- tools/llvm-objcopy/COFF/Object.h +++ tools/llvm-objcopy/COFF/Object.h @@ -38,12 +38,16 @@ ArrayRef Contents; std::vector Relocs; StringRef Name; + ssize_t UniqueId; + size_t Index; }; struct Symbol { object::coff_symbol32 Sym; StringRef Name; - ArrayRef AuxData; + std::vector AuxData; + ssize_t TargetSectionId; + ssize_t AssociativeComdatTargetSectionId = 0; size_t UniqueId; size_t RawIndex; bool Referenced; @@ -62,7 +66,6 @@ uint32_t BaseOfData = 0; // pe32plus_header lacks this field. std::vector DataDirectories; - std::vector
Sections; ArrayRef getSymbols() const { return Symbols; } // This allows mutating individual Symbols, but not mutating the list @@ -80,14 +83,34 @@ // all sections. Error markSymbols(); + ArrayRef
getSections() const { return Sections; } + // This allows mutating individual Sections, but not mutating the list + // of symbols itself. + iterator_range::iterator> getMutableSections() { + return make_range(Sections.begin(), Sections.end()); + } + + const Section *findSection(ssize_t UniqueId) const; + + void addSections(ArrayRef
NewSections); + void removeSections(function_ref ToRemove); + private: std::vector Symbols; DenseMap SymbolMap; size_t NextSymbolUniqueId = 0; + std::vector
Sections; + DenseMap 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. Index: tools/llvm-objcopy/COFF/Object.cpp =================================================================== --- tools/llvm-objcopy/COFF/Object.cpp +++ tools/llvm-objcopy/COFF/Object.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "Object.h" +#include "llvm/ADT/DenseSet.h" #include namespace llvm { @@ -65,6 +66,68 @@ return Error::success(); } +void Object::addSections(ArrayRef
NewSections) { + for (Section S : NewSections) { + S.UniqueId = NextSectionUniqueId++; + Sections.emplace_back(S); + } + updateSections(); +} + +void Object::updateSections() { + SectionMap = DenseMap(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 ToRemove) { + DenseSet AssociatedSections; + auto RemoveAssociated = [&AssociatedSections](const Section &Sec) { + return AssociatedSections.count(Sec.UniqueId) == 1; + }; + do { + DenseSet 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 Index: tools/llvm-objcopy/COFF/Reader.cpp =================================================================== --- tools/llvm-objcopy/COFF/Reader.cpp +++ tools/llvm-objcopy/COFF/Reader.cpp @@ -12,6 +12,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 @@ -22,6 +23,7 @@ namespace coff { using namespace object; +using namespace COFF; Error COFFReader::readExecutableHeaders(Object &Obj) const { const dos_header *DH = COFFObj.getDOSHeader(); @@ -59,13 +61,14 @@ } Error COFFReader::readSections(Object &Obj) const { + std::vector
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); @@ -78,12 +81,14 @@ return make_error("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 Symbols; Symbols.reserve(COFFObj.getRawNumberOfSymbols()); + ArrayRef
Sections = Obj.getSections(); for (uint32_t I = 0, E = COFFObj.getRawNumberOfSymbols(); I < E;) { Expected SymOrErr = COFFObj.getSymbol(I); if (!SymOrErr) @@ -104,6 +109,26 @@ 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(SymRef.getSectionNumber() - 1) < + Sections.size()) + Sym.TargetSectionId = Sections[SymRef.getSectionNumber() - 1].UniqueId; + else + return make_error("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(Index - 1) >= Sections.size()) + return make_error("Unexpected associative section index", + object_error::parse_failed); + Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId; + } I += 1 + SymRef.getNumberOfAuxSymbols(); } Obj.addSymbols(Symbols); @@ -117,7 +142,7 @@ 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("SymbolTableIndex out of range", Index: tools/llvm-objcopy/COFF/Writer.h =================================================================== --- tools/llvm-objcopy/COFF/Writer.h +++ tools/llvm-objcopy/COFF/Writer.h @@ -32,6 +32,7 @@ StringTableBuilder StrTabBuilder; Error finalizeRelocTargets(); + Error finalizeSectionNumbers(); void layoutSections(); size_t finalizeStringTable(); template std::pair finalizeSymbolTable(); Index: tools/llvm-objcopy/COFF/Writer.cpp =================================================================== --- tools/llvm-objcopy/COFF/Writer.cpp +++ tools/llvm-objcopy/COFF/Writer.cpp @@ -26,7 +26,7 @@ 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) @@ -40,8 +40,48 @@ 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(Sym.TargetSectionId); + } else { + const Section *Sec = Obj.findSection(Sym.TargetSectionId); + if (Sec == nullptr) + return make_error("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(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( + "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(SDSectionNumber); + SD->NumberHighPart = static_cast(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 @@ -58,7 +98,7 @@ } 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); @@ -68,7 +108,7 @@ 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)); @@ -98,6 +138,8 @@ Error COFFWriter::finalize(bool IsBigObj) { if (Error E = finalizeRelocTargets()) return E; + if (Error E = finalizeSectionNumbers()) + return E; size_t SizeOfHeaders = 0; FileAlignment = 1; @@ -114,10 +156,10 @@ 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 = @@ -132,8 +174,8 @@ 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); @@ -199,7 +241,7 @@ 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; @@ -224,14 +266,14 @@ 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); @@ -296,7 +338,7 @@ 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) { @@ -325,7 +367,7 @@ } Error COFFWriter::write() { - bool IsBigObj = Obj.Sections.size() > MaxNumberOfSections16; + bool IsBigObj = Obj.getSections().size() > MaxNumberOfSections16; if (IsBigObj && Obj.IsPE) return make_error("Too many sections for executable", object_error::parse_failed);