[llvm-objcopy] [COFF] Add support for removing sections
[llvm-core.git] / tools / llvm-objcopy / COFF / Object.h
bloba73e93620d334f85bbd6ddd41ea49983327964be
1 //===- Object.h -------------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H
10 #define LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ADT/iterator_range.h"
16 #include "llvm/BinaryFormat/COFF.h"
17 #include "llvm/Object/COFF.h"
18 #include <cstddef>
19 #include <cstdint>
20 #include <vector>
22 namespace llvm {
23 namespace objcopy {
24 namespace coff {
26 struct Relocation {
27 Relocation() {}
28 Relocation(const object::coff_relocation& R) : Reloc(R) {}
30 object::coff_relocation Reloc;
31 size_t Target;
32 StringRef TargetName; // Used for diagnostics only
35 struct Section {
36 object::coff_section Header;
37 ArrayRef<uint8_t> Contents;
38 std::vector<Relocation> Relocs;
39 StringRef Name;
40 ssize_t UniqueId;
41 size_t Index;
44 struct Symbol {
45 object::coff_symbol32 Sym;
46 StringRef Name;
47 std::vector<uint8_t> AuxData;
48 ssize_t TargetSectionId;
49 ssize_t AssociativeComdatTargetSectionId = 0;
50 size_t UniqueId;
51 size_t RawIndex;
52 bool Referenced;
55 struct Object {
56 bool IsPE = false;
58 object::dos_header DosHeader;
59 ArrayRef<uint8_t> DosStub;
61 object::coff_file_header CoffFileHeader;
63 bool Is64 = false;
64 object::pe32plus_header PeHeader;
65 uint32_t BaseOfData = 0; // pe32plus_header lacks this field.
67 std::vector<object::data_directory> DataDirectories;
69 ArrayRef<Symbol> getSymbols() const { return Symbols; }
70 // This allows mutating individual Symbols, but not mutating the list
71 // of symbols itself.
72 iterator_range<std::vector<Symbol>::iterator> getMutableSymbols() {
73 return make_range(Symbols.begin(), Symbols.end());
76 const Symbol *findSymbol(size_t UniqueId) const;
78 void addSymbols(ArrayRef<Symbol> NewSymbols);
79 void removeSymbols(function_ref<bool(const Symbol &)> ToRemove);
81 // Set the Referenced field on all Symbols, based on relocations in
82 // all sections.
83 Error markSymbols();
85 ArrayRef<Section> getSections() const { return Sections; }
86 // This allows mutating individual Sections, but not mutating the list
87 // of symbols itself.
88 iterator_range<std::vector<Section>::iterator> getMutableSections() {
89 return make_range(Sections.begin(), Sections.end());
92 const Section *findSection(ssize_t UniqueId) const;
94 void addSections(ArrayRef<Section> NewSections);
95 void removeSections(function_ref<bool(const Section &)> ToRemove);
97 private:
98 std::vector<Symbol> Symbols;
99 DenseMap<size_t, Symbol *> SymbolMap;
101 size_t NextSymbolUniqueId = 0;
103 std::vector<Section> Sections;
104 DenseMap<ssize_t, Section *> SectionMap;
106 ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined.
108 // Update SymbolMap and RawIndex in each Symbol.
109 void updateSymbols();
111 // Update SectionMap and Index in each Section.
112 void updateSections();
115 // Copy between coff_symbol16 and coff_symbol32.
116 // The source and destination files can use either coff_symbol16 or
117 // coff_symbol32, while we always store them as coff_symbol32 in the
118 // intermediate data structure.
119 template <class Symbol1Ty, class Symbol2Ty>
120 void copySymbol(Symbol1Ty &Dest, const Symbol2Ty &Src) {
121 static_assert(sizeof(Dest.Name.ShortName) == sizeof(Src.Name.ShortName),
122 "Mismatched name sizes");
123 memcpy(Dest.Name.ShortName, Src.Name.ShortName, sizeof(Dest.Name.ShortName));
124 Dest.Value = Src.Value;
125 Dest.SectionNumber = Src.SectionNumber;
126 Dest.Type = Src.Type;
127 Dest.StorageClass = Src.StorageClass;
128 Dest.NumberOfAuxSymbols = Src.NumberOfAuxSymbols;
131 // Copy between pe32_header and pe32plus_header.
132 // We store the intermediate state in a pe32plus_header.
133 template <class PeHeader1Ty, class PeHeader2Ty>
134 void copyPeHeader(PeHeader1Ty &Dest, const PeHeader2Ty &Src) {
135 Dest.Magic = Src.Magic;
136 Dest.MajorLinkerVersion = Src.MajorLinkerVersion;
137 Dest.MinorLinkerVersion = Src.MinorLinkerVersion;
138 Dest.SizeOfCode = Src.SizeOfCode;
139 Dest.SizeOfInitializedData = Src.SizeOfInitializedData;
140 Dest.SizeOfUninitializedData = Src.SizeOfUninitializedData;
141 Dest.AddressOfEntryPoint = Src.AddressOfEntryPoint;
142 Dest.BaseOfCode = Src.BaseOfCode;
143 Dest.ImageBase = Src.ImageBase;
144 Dest.SectionAlignment = Src.SectionAlignment;
145 Dest.FileAlignment = Src.FileAlignment;
146 Dest.MajorOperatingSystemVersion = Src.MajorOperatingSystemVersion;
147 Dest.MinorOperatingSystemVersion = Src.MinorOperatingSystemVersion;
148 Dest.MajorImageVersion = Src.MajorImageVersion;
149 Dest.MinorImageVersion = Src.MinorImageVersion;
150 Dest.MajorSubsystemVersion = Src.MajorSubsystemVersion;
151 Dest.MinorSubsystemVersion = Src.MinorSubsystemVersion;
152 Dest.Win32VersionValue = Src.Win32VersionValue;
153 Dest.SizeOfImage = Src.SizeOfImage;
154 Dest.SizeOfHeaders = Src.SizeOfHeaders;
155 Dest.CheckSum = Src.CheckSum;
156 Dest.Subsystem = Src.Subsystem;
157 Dest.DLLCharacteristics = Src.DLLCharacteristics;
158 Dest.SizeOfStackReserve = Src.SizeOfStackReserve;
159 Dest.SizeOfStackCommit = Src.SizeOfStackCommit;
160 Dest.SizeOfHeapReserve = Src.SizeOfHeapReserve;
161 Dest.SizeOfHeapCommit = Src.SizeOfHeapCommit;
162 Dest.LoaderFlags = Src.LoaderFlags;
163 Dest.NumberOfRvaAndSize = Src.NumberOfRvaAndSize;
166 } // end namespace coff
167 } // end namespace objcopy
168 } // end namespace llvm
170 #endif // LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H