Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ObjCopy/COFF/COFFObject.h
35268 views
1
//===- COFFObject.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
//===----------------------------------------------------------------------===//
8
9
#ifndef LLVM_LIB_OBJCOPY_COFF_COFFOBJECT_H
10
#define LLVM_LIB_OBJCOPY_COFF_COFFOBJECT_H
11
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>
21
22
namespace llvm {
23
namespace objcopy {
24
namespace coff {
25
26
struct Relocation {
27
Relocation() = default;
28
Relocation(const object::coff_relocation &R) : Reloc(R) {}
29
30
object::coff_relocation Reloc;
31
size_t Target = 0;
32
StringRef TargetName; // Used for diagnostics only
33
};
34
35
struct Section {
36
object::coff_section Header;
37
std::vector<Relocation> Relocs;
38
StringRef Name;
39
ssize_t UniqueId;
40
size_t Index;
41
42
ArrayRef<uint8_t> getContents() const {
43
if (!OwnedContents.empty())
44
return OwnedContents;
45
return ContentsRef;
46
}
47
48
void setContentsRef(ArrayRef<uint8_t> Data) {
49
OwnedContents.clear();
50
ContentsRef = Data;
51
}
52
53
void setOwnedContents(std::vector<uint8_t> &&Data) {
54
ContentsRef = ArrayRef<uint8_t>();
55
OwnedContents = std::move(Data);
56
Header.SizeOfRawData = OwnedContents.size();
57
}
58
59
void clearContents() {
60
ContentsRef = ArrayRef<uint8_t>();
61
OwnedContents.clear();
62
}
63
64
private:
65
ArrayRef<uint8_t> ContentsRef;
66
std::vector<uint8_t> OwnedContents;
67
};
68
69
struct AuxSymbol {
70
AuxSymbol(ArrayRef<uint8_t> In) {
71
assert(In.size() == sizeof(Opaque));
72
std::copy(In.begin(), In.end(), Opaque);
73
}
74
75
ArrayRef<uint8_t> getRef() const {
76
return ArrayRef<uint8_t>(Opaque, sizeof(Opaque));
77
}
78
79
uint8_t Opaque[sizeof(object::coff_symbol16)];
80
};
81
82
struct Symbol {
83
object::coff_symbol32 Sym;
84
StringRef Name;
85
std::vector<AuxSymbol> AuxData;
86
StringRef AuxFile;
87
ssize_t TargetSectionId;
88
ssize_t AssociativeComdatTargetSectionId = 0;
89
std::optional<size_t> WeakTargetSymbolId;
90
size_t UniqueId;
91
size_t RawIndex;
92
bool Referenced;
93
};
94
95
struct Object {
96
bool IsPE = false;
97
98
object::dos_header DosHeader;
99
ArrayRef<uint8_t> DosStub;
100
101
object::coff_file_header CoffFileHeader;
102
103
bool Is64 = false;
104
object::pe32plus_header PeHeader;
105
uint32_t BaseOfData = 0; // pe32plus_header lacks this field.
106
107
std::vector<object::data_directory> DataDirectories;
108
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());
114
}
115
116
const Symbol *findSymbol(size_t UniqueId) const;
117
118
void addSymbols(ArrayRef<Symbol> NewSymbols);
119
Error removeSymbols(function_ref<Expected<bool>(const Symbol &)> ToRemove);
120
121
// Set the Referenced field on all Symbols, based on relocations in
122
// all sections.
123
Error markSymbols();
124
125
ArrayRef<Section> getSections() const { return Sections; }
126
// This allows mutating individual Sections, but not mutating the list
127
// of sections itself.
128
iterator_range<std::vector<Section>::iterator> getMutableSections() {
129
return make_range(Sections.begin(), Sections.end());
130
}
131
132
const Section *findSection(ssize_t UniqueId) const;
133
134
void addSections(ArrayRef<Section> NewSections);
135
void removeSections(function_ref<bool(const Section &)> ToRemove);
136
void truncateSections(function_ref<bool(const Section &)> ToTruncate);
137
138
private:
139
std::vector<Symbol> Symbols;
140
DenseMap<size_t, Symbol *> SymbolMap;
141
142
size_t NextSymbolUniqueId = 0;
143
144
std::vector<Section> Sections;
145
DenseMap<ssize_t, Section *> SectionMap;
146
147
ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined.
148
149
// Update SymbolMap.
150
void updateSymbols();
151
152
// Update SectionMap and Index in each Section.
153
void updateSections();
154
};
155
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;
170
}
171
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;
205
}
206
207
} // end namespace coff
208
} // end namespace objcopy
209
} // end namespace llvm
210
211
#endif // LLVM_LIB_OBJCOPY_COFF_COFFOBJECT_H
212
213