LLVM 18.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.str());
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
100 if (std::error_code EC = MB.getError()) {
101 llvm::errs() << "cannot open file " << Path << ": " << EC.message() << "\n";
102 return nullptr;
103 }
104
105 return std::move(*MB);
106}
107
108static std::string findInputFile(StringRef File, ArrayRef<StringRef> Paths) {
109 for (StringRef Dir : Paths) {
110 SmallString<128> Path = Dir;
111 sys::path::append(Path, File);
112 if (sys::fs::exists(Path))
113 return std::string(Path);
114 }
115 return "";
116}
117
118static void fatalOpenError(llvm::Error E, Twine File) {
119 if (!E)
120 return;
121 handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) {
122 llvm::errs() << "error opening '" << File << "': " << EIB.message() << '\n';
123 exit(1);
124 });
125}
126
127static void doList(opt::InputArgList &Args) {
128 // lib.exe prints the contents of the first archive file.
129 std::unique_ptr<MemoryBuffer> B;
130 for (auto *Arg : Args.filtered(OPT_INPUT)) {
131 // Create or open the archive object.
133 Arg->getValue(), /*IsText=*/false, /*RequiresNullTerminator=*/false);
135
136 if (identify_magic(MaybeBuf.get()->getBuffer()) == file_magic::archive) {
137 B = std::move(MaybeBuf.get());
138 break;
139 }
140 }
141
142 // lib.exe doesn't print an error if no .lib files are passed.
143 if (!B)
144 return;
145
146 Error Err = Error::success();
147 object::Archive Archive(B.get()->getMemBufferRef(), Err);
148 fatalOpenError(std::move(Err), B->getBufferIdentifier());
149
150 std::vector<StringRef> Names;
151 for (auto &C : Archive.children(Err)) {
152 Expected<StringRef> NameOrErr = C.getName();
153 fatalOpenError(NameOrErr.takeError(), B->getBufferIdentifier());
154 Names.push_back(NameOrErr.get());
155 }
156 for (auto Name : reverse(Names))
157 llvm::outs() << Name << '\n';
158 fatalOpenError(std::move(Err), B->getBufferIdentifier());
159}
160
162 std::error_code EC;
163 auto Obj = object::COFFObjectFile::create(MB);
164 if (!Obj)
165 return Obj.takeError();
166
167 uint16_t Machine = (*Obj)->getMachine();
168 if (Machine != COFF::IMAGE_FILE_MACHINE_I386 &&
170 Machine != COFF::IMAGE_FILE_MACHINE_ARMNT && !COFF::isAnyArm64(Machine)) {
172 "unknown machine: " + std::to_string(Machine));
173 }
174
175 return static_cast<COFF::MachineTypes>(Machine);
176}
177
180 if (!TripleStr)
181 return TripleStr.takeError();
182
183 Triple T(*TripleStr);
184 switch (T.getArch()) {
185 case Triple::x86:
187 case Triple::x86_64:
189 case Triple::arm:
191 case Triple::aarch64:
192 return T.isWindowsArm64EC() ? COFF::IMAGE_FILE_MACHINE_ARM64EC
194 default:
196 "unknown arch in target triple: " + *TripleStr);
197 }
198}
199
200static bool machineMatches(COFF::MachineTypes LibMachine,
201 COFF::MachineTypes FileMachine) {
202 if (LibMachine == FileMachine)
203 return true;
204 // ARM64EC mode allows both pure ARM64, ARM64EC and X64 objects to be mixed in
205 // the archive.
206 switch (LibMachine) {
208 return FileMachine == COFF::IMAGE_FILE_MACHINE_ARM64X;
211 return COFF::isAnyArm64(FileMachine) ||
212 FileMachine == COFF::IMAGE_FILE_MACHINE_AMD64;
213 default:
214 return false;
215 }
216}
217
218static void appendFile(std::vector<NewArchiveMember> &Members,
219 COFF::MachineTypes &LibMachine,
220 std::string &LibMachineSource, MemoryBufferRef MB) {
221 file_magic Magic = identify_magic(MB.getBuffer());
222
223 if (Magic != file_magic::coff_object && Magic != file_magic::bitcode &&
227 << ": not a COFF object, bitcode, archive, import library or "
228 "resource file\n";
229 exit(1);
230 }
231
232 // If a user attempts to add an archive to another archive, llvm-lib doesn't
233 // handle the first archive file as a single file. Instead, it extracts all
234 // members from the archive and add them to the second archive. This behavior
235 // is for compatibility with Microsoft's lib command.
236 if (Magic == file_magic::archive) {
237 Error Err = Error::success();
238 object::Archive Archive(MB, Err);
239 fatalOpenError(std::move(Err), MB.getBufferIdentifier());
240
241 for (auto &C : Archive.children(Err)) {
242 Expected<MemoryBufferRef> ChildMB = C.getMemoryBufferRef();
243 if (!ChildMB) {
244 handleAllErrors(ChildMB.takeError(), [&](const ErrorInfoBase &EIB) {
245 llvm::errs() << MB.getBufferIdentifier() << ": " << EIB.message()
246 << "\n";
247 });
248 exit(1);
249 }
250
251 appendFile(Members, LibMachine, LibMachineSource, *ChildMB);
252 }
253
254 fatalOpenError(std::move(Err), MB.getBufferIdentifier());
255 return;
256 }
257
258 // Check that all input files have the same machine type.
259 // Mixing normal objects and LTO bitcode files is fine as long as they
260 // have the same machine type.
261 // Doing this here duplicates the header parsing work that writeArchive()
262 // below does, but it's not a lot of work and it's a bit awkward to do
263 // in writeArchive() which needs to support many tools, can't assume the
264 // input is COFF, and doesn't have a good way to report errors.
265 if (Magic == file_magic::coff_object || Magic == file_magic::bitcode) {
266 Expected<COFF::MachineTypes> MaybeFileMachine =
269 if (!MaybeFileMachine) {
270 handleAllErrors(MaybeFileMachine.takeError(),
271 [&](const ErrorInfoBase &EIB) {
272 llvm::errs() << MB.getBufferIdentifier() << ": "
273 << EIB.message() << "\n";
274 });
275 exit(1);
276 }
277 COFF::MachineTypes FileMachine = *MaybeFileMachine;
278
279 // FIXME: Once lld-link rejects multiple resource .obj files:
280 // Call convertResToCOFF() on .res files and add the resulting
281 // COFF file to the .lib output instead of adding the .res file, and remove
282 // this check. See PR42180.
283 if (FileMachine != COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
284 if (LibMachine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
285 if (FileMachine == COFF::IMAGE_FILE_MACHINE_ARM64EC) {
286 llvm::errs() << MB.getBufferIdentifier() << ": file machine type "
287 << machineToStr(FileMachine)
288 << " conflicts with inferred library machine type,"
289 << " use /machine:arm64ec or /machine:arm64x\n";
290 exit(1);
291 }
292 LibMachine = FileMachine;
293 LibMachineSource =
294 (" (inferred from earlier file '" + MB.getBufferIdentifier() + "')")
295 .str();
296 } else if (!machineMatches(LibMachine, FileMachine)) {
297 llvm::errs() << MB.getBufferIdentifier() << ": file machine type "
298 << machineToStr(FileMachine)
299 << " conflicts with library machine type "
300 << machineToStr(LibMachine) << LibMachineSource << '\n';
301 exit(1);
302 }
303 }
304 }
305
306 Members.emplace_back(MB);
307}
308
310 BumpPtrAllocator Alloc;
311 StringSaver Saver(Alloc);
312
313 // Parse command line arguments.
314 SmallVector<const char *, 20> NewArgs(ArgsArr.begin(), ArgsArr.end());
316 ArgsArr = NewArgs;
317
318 LibOptTable Table;
319 unsigned MissingIndex;
320 unsigned MissingCount;
321 opt::InputArgList Args =
322 Table.ParseArgs(ArgsArr.slice(1), MissingIndex, MissingCount);
323 if (MissingCount) {
324 llvm::errs() << "missing arg value for \""
325 << Args.getArgString(MissingIndex) << "\", expected "
326 << MissingCount
327 << (MissingCount == 1 ? " argument.\n" : " arguments.\n");
328 return 1;
329 }
330 for (auto *Arg : Args.filtered(OPT_UNKNOWN))
331 llvm::errs() << "ignoring unknown argument: " << Arg->getAsString(Args)
332 << "\n";
333
334 // Handle /help
335 if (Args.hasArg(OPT_help)) {
336 Table.printHelp(outs(), "llvm-lib [options] file...", "LLVM Lib");
337 return 0;
338 }
339
340 // Parse /ignore:
341 llvm::StringSet<> IgnoredWarnings;
342 for (auto *Arg : Args.filtered(OPT_ignore))
343 IgnoredWarnings.insert(Arg->getValue());
344
345 // get output library path, if any
346 std::string OutputPath;
347 if (auto *Arg = Args.getLastArg(OPT_out)) {
348 OutputPath = Arg->getValue();
349 }
350
352 std::string LibMachineSource;
353 if (auto *Arg = Args.getLastArg(OPT_machine)) {
354 LibMachine = getMachineType(Arg->getValue());
355 if (LibMachine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
356 llvm::errs() << "unknown /machine: arg " << Arg->getValue() << '\n';
357 return 1;
358 }
359 LibMachineSource =
360 std::string(" (from '/machine:") + Arg->getValue() + "' flag)";
361 }
362
363 // create an import library
364 if (Args.hasArg(OPT_deffile)) {
365
366 if (OutputPath.empty()) {
367 llvm::errs() << "no output path given\n";
368 return 1;
369 }
370
371 if (LibMachine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
372 llvm::errs() << "/def option requires /machine to be specified" << '\n';
373 return 1;
374 }
375
376 std::unique_ptr<MemoryBuffer> MB =
377 openFile(Args.getLastArg(OPT_deffile)->getValue());
378 if (!MB)
379 return 1;
380
381 if (!MB->getBufferSize()) {
382 llvm::errs() << "definition file empty\n";
383 return 1;
384 }
385
387 parseCOFFModuleDefinition(*MB, LibMachine, /*MingwDef=*/false);
388
389 if (!Def) {
390 llvm::errs() << "error parsing definition\n"
391 << errorToErrorCode(Def.takeError()).message();
392 return 1;
393 }
394
395 return writeImportLibrary(Def->OutputFile, OutputPath, Def->Exports,
396 LibMachine,
397 /*MinGW=*/false)
398 ? 1
399 : 0;
400 }
401
402 // If no input files and not told otherwise, silently do nothing to match
403 // lib.exe
404 if (!Args.hasArgNoClaim(OPT_INPUT) && !Args.hasArg(OPT_llvmlibempty)) {
405 if (!IgnoredWarnings.contains("emptyoutput")) {
406 llvm::errs() << "warning: no input files, not writing output file\n";
407 llvm::errs() << " pass /llvmlibempty to write empty .lib file,\n";
408 llvm::errs() << " pass /ignore:emptyoutput to suppress warning\n";
409 if (Args.hasFlag(OPT_WX, OPT_WX_no, false)) {
410 llvm::errs() << "treating warning as error due to /WX\n";
411 return 1;
412 }
413 }
414 return 0;
415 }
416
417 if (Args.hasArg(OPT_lst)) {
418 doList(Args);
419 return 0;
420 }
421
422 std::vector<StringRef> SearchPaths = getSearchPaths(&Args, Saver);
423
424 std::vector<std::unique_ptr<MemoryBuffer>> MBs;
425 StringSet<> Seen;
426 std::vector<NewArchiveMember> Members;
427
428 // Create a NewArchiveMember for each input file.
429 for (auto *Arg : Args.filtered(OPT_INPUT)) {
430 // Find a file
431 std::string Path = findInputFile(Arg->getValue(), SearchPaths);
432 if (Path.empty()) {
433 llvm::errs() << Arg->getValue() << ": no such file or directory\n";
434 return 1;
435 }
436
437 // Input files are uniquified by pathname. If you specify the exact same
438 // path more than once, all but the first one are ignored.
439 //
440 // Note that there's a loophole in the rule; you can prepend `.\` or
441 // something like that to a path to make it look different, and they are
442 // handled as if they were different files. This behavior is compatible with
443 // Microsoft lib.exe.
444 if (!Seen.insert(Path).second)
445 continue;
446
447 // Open a file.
449 Path, /*IsText=*/false, /*RequiresNullTerminator=*/false);
451 MemoryBufferRef MBRef = (*MOrErr)->getMemBufferRef();
452
453 // Append a file.
454 appendFile(Members, LibMachine, LibMachineSource, MBRef);
455
456 // Take the ownership of the file buffer to keep the file open.
457 MBs.push_back(std::move(*MOrErr));
458 }
459
460 // Create an archive file.
461 if (OutputPath.empty()) {
462 if (!Members.empty()) {
463 OutputPath = getDefaultOutputPath(Members[0]);
464 } else {
465 llvm::errs() << "no output path given, and cannot infer with no inputs\n";
466 return 1;
467 }
468 }
469 // llvm-lib uses relative paths for both regular and thin archives, unlike
470 // standard GNU ar, which only uses relative paths for thin archives and
471 // basenames for regular archives.
472 for (NewArchiveMember &Member : Members) {
473 if (sys::path::is_relative(Member.MemberName)) {
474 Expected<std::string> PathOrErr =
475 computeArchiveRelativePath(OutputPath, Member.MemberName);
476 if (PathOrErr)
477 Member.MemberName = Saver.save(*PathOrErr);
478 }
479 }
480
481 // For compatibility with MSVC, reverse member vector after de-duplication.
482 std::reverse(Members.begin(), Members.end());
483
484 bool Thin = Args.hasArg(OPT_llvmlibthin);
485 if (Error E = writeArchive(
486 OutputPath, Members, SymtabWritingMode::NormalSymtab,
488 /*Deterministic=*/true, Thin, nullptr, COFF::isArm64EC(LibMachine))) {
489 handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
490 llvm::errs() << OutputPath << ": " << EI.message() << "\n";
491 });
492 return 1;
493 }
494
495 return 0;
496}
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")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::string Name
static bool machineMatches(COFF::MachineTypes LibMachine, COFF::MachineTypes FileMachine)
Definition: LibDriver.cpp:200
static Expected< COFF::MachineTypes > getBitcodeFileMachine(MemoryBufferRef MB)
Definition: LibDriver.cpp:178
static Expected< COFF::MachineTypes > getCOFFFileMachine(MemoryBufferRef MB)
Definition: LibDriver.cpp:161
static std::string getDefaultOutputPath(const NewArchiveMember &FirstMember)
Definition: LibDriver.cpp:67
static std::string findInputFile(StringRef File, ArrayRef< StringRef > Paths)
Definition: LibDriver.cpp:108
static void doList(opt::InputArgList &Args)
Definition: LibDriver.cpp:127
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:218
static void fatalOpenError(llvm::Error E, Twine File)
Definition: LibDriver.cpp:118
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
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:261
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
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:704
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:51
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition: StringSet.h:34
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:345
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:330
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.
Expected< COFFModuleDefinition > parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine, bool MingwDef=false, bool AddUnderscores=true)
Error writeImportLibrary(StringRef ImportName, StringRef Path, ArrayRef< COFFShortExport > Exports, COFF::MachineTypes Machine, bool MinGW)
Definition: Arg.h:26
bool exists(const basic_file_status &status)
Does file exist?
Definition: Path.cpp:1079
void replace_extension(SmallVectorImpl< char > &path, const Twine &extension, Style style=Style::native)
Replace the file extension of path with extension.
Definition: Path.cpp:482
bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
Definition: Path.cpp:701
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:458
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:309
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
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:1244
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:429
StringRef machineToStr(COFF::MachineTypes MT)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Error writeArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr, bool IsEC=false)
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:47
@ archive
ar style archive file
Definition: Magic.h:24
@ bitcode
Bitcode file.
Definition: Magic.h:23
@ windows_resource
Windows compiled resource file (.res)
Definition: Magic.h:49
@ coff_object
COFF object file.
Definition: Magic.h:46
Entry for a single option instance in the option data table.
Definition: OptTable.h:55