1 //===- Object.h -------------------------------------------------*- C++ -*-===//
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
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/Optional.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ADT/iterator_range.h"
17 #include "llvm/BinaryFormat/COFF.h"
18 #include "llvm/Object/COFF.h"
29 Relocation(const object::coff_relocation
& R
) : Reloc(R
) {}
31 object::coff_relocation Reloc
;
33 StringRef TargetName
; // Used for diagnostics only
37 object::coff_section Header
;
38 std::vector
<Relocation
> Relocs
;
43 ArrayRef
<uint8_t> getContents() const {
44 if (!OwnedContents
.empty())
49 void setContentsRef(ArrayRef
<uint8_t> Data
) {
50 OwnedContents
.clear();
54 void setOwnedContents(std::vector
<uint8_t> &&Data
) {
55 ContentsRef
= ArrayRef
<uint8_t>();
56 OwnedContents
= std::move(Data
);
59 void clearContents() {
60 ContentsRef
= ArrayRef
<uint8_t>();
61 OwnedContents
.clear();
65 ArrayRef
<uint8_t> ContentsRef
;
66 std::vector
<uint8_t> OwnedContents
;
70 AuxSymbol(ArrayRef
<uint8_t> In
) {
71 assert(In
.size() == sizeof(Opaque
));
72 std::copy(In
.begin(), In
.end(), Opaque
);
75 ArrayRef
<uint8_t> getRef() const {
76 return ArrayRef
<uint8_t>(Opaque
, sizeof(Opaque
));
79 uint8_t Opaque
[sizeof(object::coff_symbol16
)];
83 object::coff_symbol32 Sym
;
85 std::vector
<AuxSymbol
> AuxData
;
87 ssize_t TargetSectionId
;
88 ssize_t AssociativeComdatTargetSectionId
= 0;
89 Optional
<size_t> WeakTargetSymbolId
;
98 object::dos_header DosHeader
;
99 ArrayRef
<uint8_t> DosStub
;
101 object::coff_file_header CoffFileHeader
;
104 object::pe32plus_header PeHeader
;
105 uint32_t BaseOfData
= 0; // pe32plus_header lacks this field.
107 std::vector
<object::data_directory
> DataDirectories
;
109 ArrayRef
<Symbol
> getSymbols() const { return Symbols
; }
110 // This allows mutating individual Symbols, but not mutating the list
111 // of symbols itself.
112 iterator_range
<std::vector
<Symbol
>::iterator
> getMutableSymbols() {
113 return make_range(Symbols
.begin(), Symbols
.end());
116 const Symbol
*findSymbol(size_t UniqueId
) const;
118 void addSymbols(ArrayRef
<Symbol
> NewSymbols
);
119 void removeSymbols(function_ref
<bool(const Symbol
&)> ToRemove
);
121 // Set the Referenced field on all Symbols, based on relocations in
125 ArrayRef
<Section
> getSections() const { return Sections
; }
126 // This allows mutating individual Sections, but not mutating the list
127 // of symbols itself.
128 iterator_range
<std::vector
<Section
>::iterator
> getMutableSections() {
129 return make_range(Sections
.begin(), Sections
.end());
132 const Section
*findSection(ssize_t UniqueId
) const;
134 void addSections(ArrayRef
<Section
> NewSections
);
135 void removeSections(function_ref
<bool(const Section
&)> ToRemove
);
136 void truncateSections(function_ref
<bool(const Section
&)> ToTruncate
);
139 std::vector
<Symbol
> Symbols
;
140 DenseMap
<size_t, Symbol
*> SymbolMap
;
142 size_t NextSymbolUniqueId
= 0;
144 std::vector
<Section
> Sections
;
145 DenseMap
<ssize_t
, Section
*> SectionMap
;
147 ssize_t NextSectionUniqueId
= 1; // Allow a UniqueId 0 to mean undefined.
150 void updateSymbols();
152 // Update SectionMap and Index in each Section.
153 void updateSections();
156 // Copy between coff_symbol16 and coff_symbol32.
157 // The source and destination files can use either coff_symbol16 or
158 // coff_symbol32, while we always store them as coff_symbol32 in the
159 // intermediate data structure.
160 template <class Symbol1Ty
, class Symbol2Ty
>
161 void copySymbol(Symbol1Ty
&Dest
, const Symbol2Ty
&Src
) {
162 static_assert(sizeof(Dest
.Name
.ShortName
) == sizeof(Src
.Name
.ShortName
),
163 "Mismatched name sizes");
164 memcpy(Dest
.Name
.ShortName
, Src
.Name
.ShortName
, sizeof(Dest
.Name
.ShortName
));
165 Dest
.Value
= Src
.Value
;
166 Dest
.SectionNumber
= Src
.SectionNumber
;
167 Dest
.Type
= Src
.Type
;
168 Dest
.StorageClass
= Src
.StorageClass
;
169 Dest
.NumberOfAuxSymbols
= Src
.NumberOfAuxSymbols
;
172 // Copy between pe32_header and pe32plus_header.
173 // We store the intermediate state in a pe32plus_header.
174 template <class PeHeader1Ty
, class PeHeader2Ty
>
175 void copyPeHeader(PeHeader1Ty
&Dest
, const PeHeader2Ty
&Src
) {
176 Dest
.Magic
= Src
.Magic
;
177 Dest
.MajorLinkerVersion
= Src
.MajorLinkerVersion
;
178 Dest
.MinorLinkerVersion
= Src
.MinorLinkerVersion
;
179 Dest
.SizeOfCode
= Src
.SizeOfCode
;
180 Dest
.SizeOfInitializedData
= Src
.SizeOfInitializedData
;
181 Dest
.SizeOfUninitializedData
= Src
.SizeOfUninitializedData
;
182 Dest
.AddressOfEntryPoint
= Src
.AddressOfEntryPoint
;
183 Dest
.BaseOfCode
= Src
.BaseOfCode
;
184 Dest
.ImageBase
= Src
.ImageBase
;
185 Dest
.SectionAlignment
= Src
.SectionAlignment
;
186 Dest
.FileAlignment
= Src
.FileAlignment
;
187 Dest
.MajorOperatingSystemVersion
= Src
.MajorOperatingSystemVersion
;
188 Dest
.MinorOperatingSystemVersion
= Src
.MinorOperatingSystemVersion
;
189 Dest
.MajorImageVersion
= Src
.MajorImageVersion
;
190 Dest
.MinorImageVersion
= Src
.MinorImageVersion
;
191 Dest
.MajorSubsystemVersion
= Src
.MajorSubsystemVersion
;
192 Dest
.MinorSubsystemVersion
= Src
.MinorSubsystemVersion
;
193 Dest
.Win32VersionValue
= Src
.Win32VersionValue
;
194 Dest
.SizeOfImage
= Src
.SizeOfImage
;
195 Dest
.SizeOfHeaders
= Src
.SizeOfHeaders
;
196 Dest
.CheckSum
= Src
.CheckSum
;
197 Dest
.Subsystem
= Src
.Subsystem
;
198 Dest
.DLLCharacteristics
= Src
.DLLCharacteristics
;
199 Dest
.SizeOfStackReserve
= Src
.SizeOfStackReserve
;
200 Dest
.SizeOfStackCommit
= Src
.SizeOfStackCommit
;
201 Dest
.SizeOfHeapReserve
= Src
.SizeOfHeapReserve
;
202 Dest
.SizeOfHeapCommit
= Src
.SizeOfHeapCommit
;
203 Dest
.LoaderFlags
= Src
.LoaderFlags
;
204 Dest
.NumberOfRvaAndSize
= Src
.NumberOfRvaAndSize
;
207 } // end namespace coff
208 } // end namespace objcopy
209 } // end namespace llvm
211 #endif // LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H