LLVM 19.0.0git
LibDriver.cpp
Go to the documentation of this file.
1//===- LibDriver.cpp - lib.exe-compatible driver --------------------------===//
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// Defines an interface to a lib.exe-compatible driver that also understands
10// bitcode files. Used by llvm-lib and lld-link /lib.
11//
12//===----------------------------------------------------------------------===//
13
15#include "llvm/ADT/STLExtras.h"
16#include "llvm/ADT/StringSet.h"
21#include "llvm/Object/COFF.h"
24#include "llvm/Option/Arg.h"
25#include "llvm/Option/ArgList.h"
27#include "llvm/Option/Option.h"
29#include "llvm/Support/Path.h"
33#include <optional>
34
35using namespace llvm;
36using namespace llvm::object;
37
38namespace {
39
40enum {
41 OPT_INVALID = 0,
42#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),
43#include "Options.inc"
44#undef OPTION
45};
46
47#define PREFIX(NAME, VALUE) \
48 static constexpr StringLiteral NAME##_init[] = VALUE; \
49 static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
50 std::size(NAME##_init) - 1);
51#include "Options.inc"
52#undef PREFIX
53
54using namespace llvm::opt;
55static constexpr opt::OptTable::Info InfoTable[] = {
56#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
57#include "Options.inc"
58#undef OPTION
59};
60
61class LibOptTable : public opt::GenericOptTable {
62public:
63 LibOptTable() : opt::GenericOptTable(InfoTable, true) {}
64};
65} // namespace
66
67static std::string getDefaultOutputPath(const NewArchiveMember &FirstMember) {
68 SmallString<128> Val = StringRef(FirstMember.Buf->getBufferIdentifier());
70 return std::string(Val);
71}
72
73static std::vector<StringRef> getSearchPaths(opt::InputArgList *Args,
74 StringSaver &Saver) {
75 std::vector<StringRef> Ret;
76 // Add current directory as first item of the search path.
77 Ret.push_back("");
78
79 // Add /libpath flags.
80 for (auto *Arg : Args->filtered(OPT_libpath))
81 Ret.push_back(Arg->getValue());
82
83 // Add $LIB.
84 std::optional<std::string> EnvOpt = sys::Process::GetEnv("LIB");
85 if (!EnvOpt)
86 return Ret;
87 StringRef Env = Saver.save(*EnvOpt);
88 while (!Env.empty()) {
89 StringRef Path;
90 std::tie(Path, Env) = Env.split(';');
91 Ret.push_back(Path);
92 }
93 return Ret;
94}
95
96// Opens a file. Path has to be resolved already. (used for def file)
97std::unique_ptr<MemoryBuffer> openFile(const Twine &Path) {
99 MemoryBuffer::getFile(Path, /*IsText=*/true);
100
101 if (std::error_code EC = MB.getError()) {
102 llvm::errs() << "cannot open file " << Path << ": " << EC.message() << "\n";
103 return nullptr;
104 }
105
106 return std::move(*MB);
107}
108
109static std::string findInputFile(StringRef File, ArrayRef<StringRef> Paths) {
110 for (StringRef Dir : Paths) {
111 SmallString<128> Path = Dir;
112 sys::path::append(Path, File);
113 if (sys::fs::exists(Path))
114 return std::string(Path);
115 }
116 return "";
117}
118
119static void fatalOpenError(llvm::Error E, Twine File) {
120 if (!E)
121 return;
122 handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) {
123 llvm::errs() << "error opening '" << File << "': " << EIB.message() << '\n';
124 exit(1);
125 });
126}
127
128static void doList(opt::InputArgList &Args) {
129 // lib.exe prints the contents of the first archive file.
130 std::unique_ptr<MemoryBuffer> B;
131 for (auto *Arg : Args.filtered(OPT_INPUT)) {
132 // Create or open the archive object.
134 Arg->getValue(), /*IsText=*/false, /*RequiresNullTerminator=*/false);
136
137 if (identify_magic(MaybeBuf.get()->getBuffer()) == file_magic::archive) {
138 B = std::move(MaybeBuf.get());
139 break;
140 }
141 }
142
143 // lib.exe doesn't print an error if no .lib files are passed.
144 if (!B)
145 return;
146
147 Error Err = Error::success();
148 object::Archive Archive(B.get()->getMemBufferRef(), Err);
149 fatalOpenError(std::move(Err), B->getBufferIdentifier());
150
151 std::vector<StringRef> Names;
152 for (auto &C : Archive.children(Err)) {
153 Expected<StringRef> NameOrErr = C.getName();
154 fatalOpenError(NameOrErr.takeError(), B->getBufferIdentifier());
155 Names.push_back(NameOrErr.get());
156 }
157 for (auto Name : reverse(Names))
158 llvm::outs() << Name << '\n';
159 fatalOpenError(std::move(Err), B->getBufferIdentifier());
160}
161
163 std::error_code EC;
164 auto Obj = object::COFFObjectFile::create(MB);
165 if (!Obj)
166 return Obj.takeError();
167
168 uint16_t Machine = (*Obj)->getMachine();
173 "unknown machine: " + std::to_string(Machine));
174 }
175
176 return static_cast<COFF::MachineTypes>(Machine);
177}
178
181 if (!TripleStr)
182 return TripleStr.takeError();
183
184 Triple T(*TripleStr);
185 switch (T.getArch()) {
186 case Triple::x86:
188 case Triple::x86_64:
190 case Triple::arm:
192 case Triple::aarch64:
193 return T.isWindowsArm64EC() ? COFF::IMAGE_FILE_MACHINE_ARM64EC
195 default:
197 "unknown arch in target triple: " + *TripleStr);
198 }
199}
200
201static bool machineMatches(COFF::MachineTypes LibMachine,
202 COFF::MachineTypes FileMachine) {
203 if (LibMachine == FileMachine)
204 return true;
205 // ARM64EC mode allows both pure ARM64, ARM64EC and X64 objects to be mixed in
206 // the archive.
207 switch (LibMachine) {
209 return FileMachine == COFF::IMAGE_FILE_MACHINE_ARM64X;
212 return COFF::isAnyArm64(FileMachine) ||
213 FileMachine == COFF::IMAGE_FILE_MACHINE_AMD64;
214 default:
215 return false;
216 }
217}
218
219static void appendFile(std::vector<NewArchiveMember> &Members,
220 COFF::MachineTypes &LibMachine,
221 std::string &LibMachineSource, MemoryBufferRef MB) {
222 file_magic Magic = identify_magic(MB.getBuffer());
223
224 if (Magic != file_magic::coff_object && Magic != file_magic::bitcode &&
228 << ": not a COFF object, bitcode, archive, import library or "
229 "resource file\n";
230 exit(1);
231 }
232
233 // If a user attempts to add an archive to another archive, llvm-lib doesn't
234 // handle the first archive file as a single file. Instead, it extracts all
235 // members from the archive and add them to the second archive. This behavior
236 // is for compatibility with Microsoft's lib command.
237 if (Magic == file_magic::archive) {
238 Error Err = Error::success();
239 object::Archive Archive(MB, Err);
240 fatalOpenError(std::move(Err), MB.getBufferIdentifier());
241
242 for (auto &C : Archive.children(Err)) {
243 Expected<MemoryBufferRef> ChildMB = C.getMemoryBufferRef();
244 if (!ChildMB) {
245 handleAllErrors(ChildMB.takeError(), [&](const ErrorInfoBase &EIB) {
246 llvm::errs() << MB.getBufferIdentifier() << ": " << EIB.message()
247 << "\n";
248 });
249 exit(1);
250 }
251
252 appendFile(Members, LibMachine, LibMachineSource, *ChildMB);
253 }
254
255 fatalOpenError(std::move(Err), MB.getBufferIdentifier());
256 return;
257 }
258
259 // Check that all input files have the same machine type.
260 // Mixing normal objects and LTO bitcode files is fine as long as they
261 // have the same machine type.
262 // Doing this here duplicates the header parsing work that writeArchive()
263 // below does, but it's not a lot of work and it's a bit awkward to do
264 // in writeArchive() which needs to support many tools, can't assume the
265 // input is COFF, and doesn't have a good way to report errors.
266 if (Magic == file_magic::coff_object || Magic == file_magic::bitcode) {
267 Expected<COFF::MachineTypes> MaybeFileMachine =
270 if (!MaybeFileMachine) {
271 handleAllErrors(MaybeFileMachine.takeError(),
272 [&](const ErrorInfoBase &EIB) {
273 llvm::errs() << MB.getBufferIdentifier() << ": "
274 << EIB.message() << "\n";
275 });
276 exit(1);
277 }
278 COFF::MachineTypes FileMachine = *MaybeFileMachine;
279
280 // FIXME: Once lld-link rejects multiple resource .obj files:
281 // Call convertResToCOFF() on .res files and add the resulting
282 // COFF file to the .lib output instead of adding the .res file, and remove
283 // this check. See PR42180.
284 if (FileMachine != COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
285 if (LibMachine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
286 if (FileMachine == COFF::IMAGE_FILE_MACHINE_ARM64EC) {
287 llvm::errs() << MB.getBufferIdentifier() << ": file machine type "
288 << machineToStr(FileMachine)
289 << " conflicts with inferred library machine type,"
290 << " use /machine:arm64ec or /machine:arm64x\n";
291 exit(1);
292 }
293 LibMachine = FileMachine;
294 LibMachineSource =
295 (" (inferred from earlier file '" + MB.getBufferIdentifier() + "')")
296 .str();
297 } else if (!machineMatches(LibMachine, FileMachine)) {
298 llvm::errs() << MB.getBufferIdentifier() << ": file machine type "
299 << machineToStr(FileMachine)
300 << " conflicts with library machine type "
301 << machineToStr(LibMachine) << LibMachineSource << '\n';
302 exit(1);
303 }
304 }
305 }
306
307 Members.emplace_back(MB);
308}
309
311 BumpPtrAllocator Alloc;
312 StringSaver Saver(Alloc);
313
314 // Parse command line arguments.
315 SmallVector<const char *, 20> NewArgs(ArgsArr.begin(), ArgsArr.end());
317 ArgsArr = NewArgs;
318
319 LibOptTable Table;
320 unsigned MissingIndex;
321 unsigned MissingCount;
322 opt::InputArgList Args =
323 Table.ParseArgs(ArgsArr.slice(1), MissingIndex, MissingCount);
324 if (MissingCount) {
325 llvm::errs() << "missing arg value for \""
326 << Args.getArgString(MissingIndex) << "\", expected "
327 << MissingCount
328 << (MissingCount == 1 ? " argument.\n" : " arguments.\n");
329 return 1;
330 }
331 for (auto *Arg : Args.filtered(OPT_UNKNOWN))
332 llvm::errs() << "ignoring unknown argument: " << Arg->getAsString(Args)
333 << "\n";
334
335 // Handle /help
336 if (Args.hasArg(OPT_help)) {
337 Table.printHelp(outs(), "llvm-lib [options] file...", "LLVM Lib");
338 return 0;
339 }
340
341 // Parse /ignore:
342 llvm::StringSet<> IgnoredWarnings;
343 for (auto *Arg : Args.filtered(OPT_ignore))
344 IgnoredWarnings.insert(Arg->getValue());
345
346 // get output library path, if any
347 std::string OutputPath;
348 if (auto *Arg = Args.getLastArg(OPT_out)) {
349 OutputPath = Arg->getValue();
350 }
351
353 std::string LibMachineSource;
354 if (auto *Arg = Args.getLastArg(OPT_machine)) {
355 LibMachine = getMachineType(Arg->getValue());
356 if (LibMachine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
357 llvm::errs() << "unknown /machine: arg " << Arg->getValue() << '\n';
358 return 1;
359 }
360 LibMachineSource =
361 std::string(" (from '/machine:") + Arg->getValue() + "' flag)";
362 }
363
364 // create an import library
365 if (Args.hasArg(OPT_deffile)) {
366
367 if (OutputPath.empty()) {
368 llvm::errs() << "no output path given\n";
369 return 1;
370 }
371
372 if (LibMachine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
373 llvm::errs() << "/def option requires /machine to be specified" << '\n';
374 return 1;
375 }
376
377 std::unique_ptr<MemoryBuffer> MB =
378 openFile(Args.getLastArg(OPT_deffile)->getValue());
379 if (!MB)
380 return 1;
381
382 if (!MB->getBufferSize()) {
383 llvm::errs() << "definition file empty\n";
384 return 1;
385 }
386
388 parseCOFFModuleDefinition(*MB, LibMachine, /*MingwDef=*/false);
389
390 if (!Def) {
391 llvm::errs() << "error parsing definition\n"
392 << errorToErrorCode(Def.takeError()).message();
393 return 1;
394 }
395
396 std::vector<COFFShortExport> NativeExports;
397 std::string OutputFile = Def->OutputFile;
398
399 if (isArm64EC(LibMachine) && Args.hasArg(OPT_nativedeffile)) {
400 std::unique_ptr<MemoryBuffer> NativeMB =
401 openFile(Args.getLastArg(OPT_nativedeffile)->getValue());
402 if (!NativeMB)
403 return 1;
404
405 if (!NativeMB->getBufferSize()) {
406 llvm::errs() << "native definition file empty\n";
407 return 1;
408 }
409
412
413 if (!NativeDef) {
414 llvm::errs() << "error parsing native definition\n"
415 << errorToErrorCode(NativeDef.takeError()).message();
416 return 1;
417 }
418 NativeExports = std::move(NativeDef->Exports);
419 OutputFile = std::move(NativeDef->OutputFile);
420 }
421
422 return writeImportLibrary(OutputFile, OutputPath, Def->Exports, LibMachine,
423 /*MinGW=*/false, NativeExports)
424 ? 1
425 : 0;
426 }
427
428 // If no input files and not told otherwise, silently do nothing to match
429 // lib.exe
430 if (!Args.hasArgNoClaim(OPT_INPUT) && !Args.hasArg(OPT_llvmlibempty)) {
431 if (!IgnoredWarnings.contains("emptyoutput")) {
432 llvm::errs() << "warning: no input files, not writing output file\n";
433 llvm::errs() << " pass /llvmlibempty to write empty .lib file,\n";
434 llvm::errs() << " pass /ignore:emptyoutput to suppress warning\n";
435 if (Args.hasFlag(OPT_WX, OPT_WX_no, false)) {
436 llvm::errs() << "treating warning as error due to /WX\n";
437 return 1;
438 }
439 }
440 return 0;
441 }
442
443 if (Args.hasArg(OPT_lst)) {
444 doList(Args);
445 return 0;
446 }
447
448 std::vector<StringRef> SearchPaths = getSearchPaths(&Args, Saver);
449
450 std::vector<std::unique_ptr<MemoryBuffer>> MBs;
451 StringSet<> Seen;
452 std::vector<NewArchiveMember> Members;
453
454 // Create a NewArchiveMember for each input file.
455 for (auto *Arg : Args.filtered(OPT_INPUT)) {
456 // Find a file
457 std::string Path = findInputFile(Arg->getValue(), SearchPaths);
458 if (Path.empty()) {
459 llvm::errs() << Arg->getValue() << ": no such file or directory\n";
460 return 1;
461 }
462
463 // Input files are uniquified by pathname. If you specify the exact same
464 // path more than once, all but the first one are ignored.
465 //
466 // Note that there's a loophole in the rule; you can prepend `.\` or
467 // something like that to a path to make it look different, and they are
468 // handled as if they were different files. This behavior is compatible with
469 // Microsoft lib.exe.
470 if (!Seen.insert(Path).second)
471 continue;
472
473 // Open a file.
475 Path, /*IsText=*/false, /*RequiresNullTerminator=*/false);
477 MemoryBufferRef MBRef = (*MOrErr)->getMemBufferRef();
478
479 // Append a file.
480 appendFile(Members, LibMachine, LibMachineSource, MBRef);
481
482 // Take the ownership of the file buffer to keep the file open.
483 MBs.push_back(std::move(*MOrErr));
484 }
485
486 // Create an archive file.
487 if (OutputPath.empty()) {
488 if (!Members.empty()) {
489 OutputPath = getDefaultOutputPath(Members[0]);
490 } else {
491 llvm::errs() << "no output path given, and cannot infer with no inputs\n";
492 return 1;
493 }
494 }
495 // llvm-lib uses relative paths for both regular and thin archives, unlike
496 // standard GNU ar, which only uses relative paths for thin archives and
497 // basenames for regular archives.
498 for (NewArchiveMember &Member : Members) {
499 if (sys::path::is_relative(Member.MemberName)) {
500 Expected<std::string> PathOrErr =
501 computeArchiveRelativePath(OutputPath, Member.MemberName);
502 if (PathOrErr)
503 Member.MemberName = Saver.save(*PathOrErr);
504 }
505 }
506
507 // For compatibility with MSVC, reverse member vector after de-duplication.
508 std::reverse(Members.begin(), Members.end());
509
510 bool Thin = Args.hasArg(OPT_llvmlibthin);
511 if (Error E = writeArchive(
512 OutputPath, Members, SymtabWritingMode::NormalSymtab,
514 /*Deterministic=*/true, Thin, nullptr, COFF::isArm64EC(LibMachine))) {
515 handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
516 llvm::errs() << OutputPath << ": " << EI.message() << "\n";
517 });
518 return 1;
519 }
520
521 return 0;
522}
arm prera ldst opt
Defines the llvm::Arg class for parsed arguments.
basic Basic Alias true
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
COFF::MachineTypes Machine
Definition: COFFYAML.cpp:371
std::string Name
static bool machineMatches(COFF::MachineTypes LibMachine, COFF::MachineTypes FileMachine)
Definition: LibDriver.cpp:201
static Expected< COFF::MachineTypes > getBitcodeFileMachine(MemoryBufferRef MB)
Definition: LibDriver.cpp:179
static Expected< COFF::MachineTypes > getCOFFFileMachine(MemoryBufferRef MB)
Definition: LibDriver.cpp:162
static std::string getDefaultOutputPath(const NewArchiveMember &FirstMember)
Definition: LibDriver.cpp:67
static std::string findInputFile(StringRef File, ArrayRef< StringRef > Paths)
Definition: LibDriver.cpp:109
static void doList(opt::InputArgList &Args)
Definition: LibDriver.cpp:128
static std::vector< StringRef > getSearchPaths(opt::InputArgList *Args, StringSaver &Saver)
Definition: LibDriver.cpp:73
std::unique_ptr< MemoryBuffer > openFile(const Twine &Path)
Definition: LibDriver.cpp:97
static void appendFile(std::vector< NewArchiveMember > &Members, COFF::MachineTypes &LibMachine, std::string &LibMachineSource, MemoryBufferRef MB)
Definition: LibDriver.cpp:219
static void fatalOpenError(llvm::Error E, Twine File)
Definition: LibDriver.cpp:119
Provides a library for accessing information about this process and other processes on the operating ...
This file contains some templates that are useful if you are working with the STL at all.
StringSet - A set-like wrapper for the StringMap.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
iterator end() const
Definition: ArrayRef.h:154
iterator begin() const
Definition: ArrayRef.h:153
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Definition: ArrayRef.h:195
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
Base class for error info classes.
Definition: Error.h:45
virtual std::string message() const
Return the error message as a string.
Definition: Error.h:53
Represents either an error or a value T.
Definition: ErrorOr.h:56
reference get()
Definition: ErrorOr.h:149
std::error_code getError() const
Definition: ErrorOr.h:152
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:334
Tagged union holding either a T or a Error.
Definition: Error.h:474
Error takeError()
Take ownership of the stored error.
Definition: Error.h:601
reference get()
Returns a reference to the stored T value.
Definition: Error.h:571
StringRef getBufferIdentifier() const
StringRef getBuffer() const
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,...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:692
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
Definition: StringSaver.h:21
StringRef save(const char *S)
Definition: StringSaver.h:30
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:23
bool contains(StringRef key) const
Check if the set contains the given key.
Definition: StringSet.h:55
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition: StringSet.h:38
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const
Definition: Archive.h:346
static Expected< std::unique_ptr< COFFObjectFile > > create(MemoryBufferRef Object)
A concrete instance of a particular driver option.
Definition: Arg.h:34
std::string getAsString(const ArgList &Args) const
Return a formatted version of the argument and its values, for diagnostics.
Definition: Arg.cpp:66
const char * getValue(unsigned N=0) const
Definition: Arg.h:125
Specialization of OptTable.
Definition: OptTable.h:355
static std::optional< std::string > GetEnv(StringRef name)
MachineTypes
Definition: COFF.h:92
@ IMAGE_FILE_MACHINE_ARM64
Definition: COFF.h:100
@ IMAGE_FILE_MACHINE_UNKNOWN
Definition: COFF.h:95
@ IMAGE_FILE_MACHINE_AMD64
Definition: COFF.h:97
@ IMAGE_FILE_MACHINE_ARM64EC
Definition: COFF.h:101
@ IMAGE_FILE_MACHINE_I386
Definition: COFF.h:104
@ IMAGE_FILE_MACHINE_ARM64X
Definition: COFF.h:102
@ IMAGE_FILE_MACHINE_ARMNT
Definition: COFF.h:99
bool isAnyArm64(T Machine)
Definition: COFF.h:129
bool isArm64EC(T Machine)
Definition: COFF.h:124
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl< const char * > &Argv)
A convenience helper which supports the typical use case of expansion function call.
void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver, SmallVectorImpl< const char * > &NewArgv, bool MarkEOLs=false)
Tokenizes a string of Windows command line arguments, which may contain quotes and escaped quotes.
Error writeImportLibrary(StringRef ImportName, StringRef Path, ArrayRef< COFFShortExport > Exports, COFF::MachineTypes Machine, bool MinGW, ArrayRef< COFFShortExport > NativeExports=std::nullopt)
Writes a COFF import library containing entries described by the Exports array.
Expected< COFFModuleDefinition > parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine, bool MingwDef=false, bool AddUnderscores=true)
Definition: Arg.h:26
bool exists(const basic_file_status &status)
Does file exist?
Definition: Path.cpp:1078
void replace_extension(SmallVectorImpl< char > &path, const Twine &extension, Style style=Style::native)
Replace the file extension of path with extension.
Definition: Path.cpp:481
bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
Definition: Path.cpp:700
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:457
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
Definition: Magic.cpp:33
int libDriverMain(ArrayRef< const char * > ARgs)
Definition: LibDriver.cpp:310
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:970
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:90
Error writeArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr, std::optional< bool > IsEC=std::nullopt)
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
Expected< std::string > getBitcodeTargetTriple(MemoryBufferRef Buffer)
Read the header of the specified bitcode buffer and extract just the triple information.
COFF::MachineTypes getMachineType(StringRef S)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1258
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:419
StringRef machineToStr(COFF::MachineTypes MT)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Expected< std::string > computeArchiveRelativePath(StringRef From, StringRef To)
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:103
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
Definition: Error.cpp:109
std::unique_ptr< MemoryBuffer > Buf
Definition: ArchiveWriter.h:21
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
Definition: Magic.h:20
@ coff_import_library
COFF import library.
Definition: Magic.h:48
@ archive
ar style archive file
Definition: Magic.h:25
@ bitcode
Bitcode file.
Definition: Magic.h:23
@ windows_resource
Windows compiled resource file (.res)
Definition: Magic.h:50
@ coff_object
COFF object file.
Definition: Magic.h:47
Entry for a single option instance in the option data table.
Definition: OptTable.h:55