LLVM: lib/ObjCopy/COFF/COFFObjcopy.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
15
22#include
23
24namespace llvm {
25namespace objcopy {
26namespace coff {
27
28using namespace object;
29using namespace COFF;
30
33}
34
37 return 0;
39 return alignTo(Last.Header.VirtualAddress + Last.Header.VirtualSize,
41}
42
47 if (!LinkTargetOrErr)
49 auto LinkTarget = std::move(*LinkTargetOrErr);
50 uint32_t CRC32 = llvm::crc32(arrayRefFromStringRef(LinkTarget->getBuffer()));
51
53 size_t CRCPos = alignTo(FileName.size() + 1, 4);
54 std::vector<uint8_t> Data(CRCPos + 4);
55 memcpy(Data.data(), FileName.data(), FileName.size());
58}
59
60
65
68 Sec.Name = Name;
69 Sec.Header.VirtualSize = NeedVA ? Sec.getContents().size() : 0u;
70 Sec.Header.VirtualAddress = NeedVA ? getNextRVA(Obj) : 0u;
71 Sec.Header.SizeOfRawData =
72 NeedVA ? alignTo(Sec.Header.VirtualSize,
74 : Sec.getContents().size();
75
76 Sec.Header.PointerToRelocations = 0;
77 Sec.Header.PointerToLinenumbers = 0;
78
79 Sec.Header.NumberOfLinenumbers = 0;
81
83}
84
88 if (!Contents)
90
91 addSection(Obj, ".gnu_debuglink", *Contents,
94
96}
97
99
100 const uint32_t PreserveMask =
108
109
110
112
120 NewCharacteristics |=
130
131 return NewCharacteristics;
132}
133
137 continue;
138
140
141 std::unique_ptr Buffer;
143 Buffer = std::move(*B);
144 else
145 return B.takeError();
146
147 llvm::copy(Contents, Buffer->getBufferStart());
148 if (Error E = Buffer->commit())
149 return E;
150
152 }
153 return createStringError(object_error::parse_failed, "section '%s' not found",
155}
156
162 return E;
163 }
164
165
167
168
169 if (.OnlySection.empty() &&
.OnlySection.matches(Sec.Name))
170 return true;
171
174 if (isDebugSection(Sec) &&
175 (Sec.Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0)
176 return true;
177 }
178
180 return true;
181
182 return false;
183 });
184
185 if (Config.OnlyKeepDebug) {
189 : nullptr;
190
191
194 !(DebugDir && DebugDir->Size > 0 &&
200 });
201 }
202
203
207
208
210 .SymbolsToRemove.empty())
212 return E;
213
216 if (I != Config.SymbolsToRename.end())
218 }
219
221
222
224 return true;
225
227
231 "'" + Config.OutputFilename + "': not stripping symbol '" +
232 Sym.Name.str() + "' because it is named in a relocation");
233 return true;
234 }
235
237
238
239
240
243 if (Config.StripUnneeded ||
244 Config.UnneededSymbolsToRemove.matches(Sym.Name))
245 return true;
246
247
248
249
253 return true;
254 }
255
256 return false;
257 };
258
259
261 return Err;
262
263 if (.SetSectionFlags.empty())
265 const auto It = Config.SetSectionFlags.find(Sec.Name);
266 if (It != Config.SetSectionFlags.end())
269 }
270
273 const auto It = Config.SetSectionFlags.find(NewSection.SectionName);
274 if (It != Config.SetSectionFlags.end())
276 else
278
281 NewSection.SectionData->getBufferStart()),
282 NewSection.SectionData->getBufferSize()),
284 }
285
288 return Sec.Name == NewSection.SectionName;
289 });
292 "could not find section with name '%s'",
294 size_t ContentSize = It->getContents().size();
295 if (!ContentSize)
298 "section '%s' cannot be updated because it does not have contents",
300 if (ContentSize < NewSection.SectionData->getBufferSize())
303 "new section cannot be larger than previous section");
304 It->setOwnedContents({NewSection.SectionData->getBufferStart(),
305 NewSection.SectionData->getBufferEnd()});
306 }
307
308 if (.AddGnuDebugLink.empty())
310 return E;
311
314 if (!Obj.IsPE)
317 "'" + Config.OutputFilename +
318 "': unable to set subsystem on a relocatable object file");
325 }
326
328}
329
335 if (!ObjOrErr)
338 assert(Obj && "Unable to deserialize COFF object");
342 if (Error E = Writer.write())
345}
346
347}
348}
349}
ReachingDefAnalysis InstSet & ToRemove
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
This class represents an Operation in the Expression.
Represents either an error or a value T.
std::error_code getError() const
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
static Expected< std::unique_ptr< FileOutputBuffer > > create(StringRef FilePath, size_t Size, unsigned Flags=0)
Factory method to create an OutputBuffer object which manages a read/write buffer of the specified si...
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Expected< std::unique_ptr< Object > > create() const
This class implements an extremely fast bulk output stream that can only output to a stream.
@ IMAGE_SCN_ALIGN_64BYTES
@ IMAGE_SCN_ALIGN_128BYTES
@ IMAGE_SCN_ALIGN_256BYTES
@ IMAGE_SCN_ALIGN_1024BYTES
@ IMAGE_SCN_ALIGN_512BYTES
@ IMAGE_SCN_CNT_UNINITIALIZED_DATA
@ IMAGE_SCN_MEM_DISCARDABLE
@ IMAGE_SCN_ALIGN_4096BYTES
@ IMAGE_SCN_CNT_INITIALIZED_DATA
@ IMAGE_SCN_ALIGN_8192BYTES
@ IMAGE_SCN_ALIGN_16BYTES
@ IMAGE_SCN_ALIGN_32BYTES
@ IMAGE_SCN_ALIGN_2048BYTES
@ IMAGE_SYM_CLASS_STATIC
Static.
static bool isDebugSection(const Section &Sec)
Error executeObjcopyOnBinary(const CommonConfig &Config, const COFFConfig &, object::COFFObjectFile &In, raw_ostream &Out)
Apply the transformations described by Config and COFFConfig to In and writes the result into Out.
static void addSection(Object &Obj, StringRef Name, ArrayRef< uint8_t > Contents, uint32_t Characteristics)
static uint32_t flagsToCharacteristics(SectionFlag AllFlags, uint32_t OldChar)
static Error dumpSection(Object &O, StringRef SectionName, StringRef FileName)
static uint64_t getNextRVA(const Object &Obj)
static Error handleArgs(const CommonConfig &Config, const COFFConfig &COFFConfig, Object &Obj)
static Error addGnuDebugLink(Object &Obj, StringRef DebugLinkFile)
static Expected< std::vector< uint8_t > > createGnuDebugLinkSectionContents(StringRef File)
void write32le(void *P, uint32_t V)
StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
This is an optimization pass for GlobalISel generic memory operations.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
uint32_t crc32(ArrayRef< uint8_t > Data)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
OutputIt copy(R &&Range, OutputIt Out)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
std::optional< unsigned > MinorSubsystemVersion
std::optional< unsigned > Subsystem
std::optional< unsigned > MajorSubsystemVersion
std::shared_ptr< MemoryBuffer > SectionData
iterator_range< std::vector< Symbol >::iterator > getMutableSymbols()
void truncateSections(function_ref< bool(const Section &)> ToTruncate)
std::vector< object::data_directory > DataDirectories
void addSections(ArrayRef< Section > NewSections)
object::pe32plus_header PeHeader
void removeSections(function_ref< bool(const Section &)> ToRemove)
iterator_range< std::vector< Section >::iterator > getMutableSections()
ArrayRef< Section > getSections() const
Error removeSymbols(function_ref< Expected< bool >(const Symbol &)> ToRemove)
void setOwnedContents(std::vector< uint8_t > &&Data)
object::coff_section Header
std::vector< Relocation > Relocs
ArrayRef< uint8_t > getContents() const
object::coff_symbol32 Sym
support::ulittle32_t Characteristics
support::ulittle32_t SizeOfRawData
support::ulittle32_t VirtualAddress
SectionNumberType SectionNumber
support::ulittle32_t RelativeVirtualAddress
support::ulittle32_t Size