39#define DEBUG_TYPE "orc-scanner"
45 dbgs() <<
"LLVM Error";
47 dbgs() <<
" [" << context <<
"]";
55 if (HostTriple.
getArch() != Obj.getArch())
65ObjectFileLoader::loadObjectFileWithOwnership(
StringRef FilePath) {
66 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Attempting to open file " << FilePath
72 auto OwningBin = std::move(*ObjOrErr);
75 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Incompatible architecture: "
76 << FilePath <<
"\n";);
78 "Incompatible object file: %s",
79 FilePath.
str().c_str());
82 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Object file is compatible\n";);
84 return std::move(OwningBin);
90 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Failed to open file " << FilePath
92 return BinOrErr.takeError();
96 << FilePath <<
"\n";);
98 auto OwningBin = BinOrErr->takeBinary();
99 object::Binary *
Bin = OwningBin.first.get();
101 if (
Bin->isArchive()) {
103 dbgs() <<
"ObjectFileLoader: File is an archive, not supported: "
104 << FilePath <<
"\n";);
106 "Archive files are not supported: %s",
107 FilePath.
str().c_str());
112 dbgs() <<
"ObjectFileLoader: Detected Mach-O universal binary: "
113 << FilePath <<
"\n";);
114 for (
auto ObjForArch : UB->objects()) {
115 auto ObjOrErr = ObjForArch.getAsObjectFile();
118 "architecture slice\n";);
124 std::unique_ptr<object::ObjectFile> Obj = std::move(ObjOrErr.get());
127 dbgs() <<
"ObjectFileLoader: Found compatible object slice\n";);
129 return object::OwningBinary<object::ObjectFile>(
130 std::move(Obj), std::move(OwningBin.second));
133 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Incompatible architecture "
137 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: No compatible slices found in "
138 "universal binary\n";);
140 "No compatible object found in fat binary: %s",
141 FilePath.
str().c_str());
143 return ObjOrErr.takeError();
145 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Failed to open file " << FilePath
147 return ObjOrErr.takeError();
152 "Not a compatible object file : %s",
153 FilePath.
str().c_str());
167 for (
auto Phdr : *PHOrErr) {
185 }
else if (Obj.isMachO()) {
195 dbgs() <<
"Mach-O filetype: " <<
MachO->getHeader().filetype
197 <<
"), shared: " <<
Result <<
"\n";
201 }
else if (Obj.isCOFF()) {
214 LLVM_DEBUG(
dbgs() <<
"Checking if path is a shared library: " << Path
219 LLVM_DEBUG(
dbgs() <<
"File type is not a regular file for path: " << Path
232 bool NeedsObjectInspection =
235#elif defined(__APPLE__)
240#elif defined(LLVM_ON_UNIX)
247#error "Unsupported platform."
250 if (!NeedsObjectInspection) {
251 LLVM_DEBUG(
dbgs() <<
"Path is not identified as a shared library: " << Path
265 if (IsShared && ObjCache)
266 ObjCache->insert(Path, std::move(ObjLoader));
276 if (LoaderPath.
empty()) {
277 LoaderDir = ExecPath;
279 LoaderDir = LoaderPath.
str();
285 Placeholders.
push_back({
"@loader_path", std::string(LoaderDir)});
286 Placeholders.push_back({
"@executable_path", std::string(ExecPath)});
288 Placeholders.push_back({
"$origin", std::string(LoaderDir)});
292std::optional<std::string>
295 for (
const auto &SP : Paths) {
299 if (!PlaceholderPrefix.empty() &&
305 LLVM_DEBUG(
dbgs() <<
"SearchPathResolver::resolve FullPath = " << FullPath
308 if (
auto Valid = Validator.
validate(FullPath.
str()))
315std::optional<std::string>
316DylibResolverImpl::tryWithExtensions(
StringRef LibStem)
const {
317 LLVM_DEBUG(
dbgs() <<
"tryWithExtensions: baseName = " << LibStem <<
"\n";);
321#if defined(__APPLE__)
323 Candidates.back() +=
".dylib";
325 Candidates.emplace_back(LibStem);
326 Candidates.back() +=
".dll";
328 Candidates.emplace_back(LibStem);
329 Candidates.back() +=
".so";
337 if (!WithPrefix.empty())
340 WithPrefix += FileName;
342#if defined(__APPLE__)
343 WithPrefix +=
".dylib";
345 WithPrefix +=
".dll";
350 Candidates.push_back(std::move(WithPrefix));
354 dbgs() <<
" Candidates to try:\n";
355 for (
const auto &
C : Candidates)
356 dbgs() <<
" " <<
C <<
"\n";
360 for (
const auto &Name : Candidates) {
364 for (
const auto &R : Resolvers) {
365 if (
auto Res = R.resolve(Name, Substitutor, Validator))
375std::optional<std::string>
377 LLVM_DEBUG(
dbgs() <<
"Resolving library stem: " << LibStem <<
"\n";);
382 return Validator.validate(LibStem);
386 if (
auto norm = Validator.validate(Substitutor.substitute(LibStem))) {
394 for (
const auto &R : Resolvers) {
396 if (
auto Result = R.resolve(LibStem, Substitutor, Validator)) {
406 if (VariateLibStem) {
409 if (
auto Norm = tryWithExtensions(LibStem)) {
410 LLVM_DEBUG(
dbgs() <<
" -> Resolved via tryWithExtensions: " << *Norm
416 LLVM_DEBUG(
dbgs() <<
" -> Could not resolve: " << LibStem <<
"\n";);
424 if (
auto Cache = LibPathCache->read_lstat(Path))
429 mode_t st_mode = (lstat(Path.str().c_str(), &buf) == -1) ? 0 : buf.st_mode;
431 LibPathCache->insert_lstat(Path, st_mode);
438 if (
auto Cache = LibPathCache->read_link(Path))
444 if ((len = readlink(Path.str().c_str(), buf,
sizeof(buf))) != -1) {
447 LibPathCache->insert_link(Path, s);
456 if (!BaseIsResolved) {
457 if (Path[0] ==
'~' &&
464 }
else if (BasePath.
empty()) {
469 .
split(Component, Separator, -1,
false);
471 BasePath.
split(Component, Separator, -1,
476 Path.split(Component, Separator, -1,
false);
481 for (
auto &Part : PathParts) {
484 }
else if (Part ==
"..") {
485 if (!NormalizedPath.
empty() && NormalizedPath.
back() !=
"..") {
494 PathParts.
swap(NormalizedPath);
506 EC = std::make_error_code(std::errc::no_such_file_or_directory);
507 LLVM_DEBUG(
dbgs() <<
"PathResolver::realpathCached: Empty path\n";);
512 if (SymLoopLevel <= 0) {
513 EC = std::make_error_code(std::errc::too_many_symbolic_link_levels);
515 dbgs() <<
"PathResolver::realpathCached: Too many Symlink levels: "
524 if (
auto Cached = LibPathCache->read_realpath(Path)) {
525 EC = Cached->ErrnoCode;
527 LLVM_DEBUG(
dbgs() <<
"PathResolver::realpathCached: Cached (error) for "
531 dbgs() <<
"PathResolver::realpathCached: Cached (success) for "
532 << Path <<
" => " << Cached->canonicalPath <<
"\n";);
534 return Cached->canonicalPath.empty()
536 : std::make_optional(Cached->canonicalPath);
540 LLVM_DEBUG(
dbgs() <<
"PathResolver::realpathCached: Resolving path: " << Path
551 if (BaseIsResolved) {
557 Path.split(Components, Separator, -1,
false);
562 for (
auto &
C : Components)
563 dbgs() <<
" " <<
C <<
" ";
569 for (
const auto &Component : Components) {
570 if (Component ==
".")
572 if (Component ==
"..") {
574 size_t S =
Resolved.rfind(Separator);
584 const char *ResolvedPath =
Resolved.c_str();
585 LLVM_DEBUG(
dbgs() <<
" Processing Component: " << Component <<
" => "
586 << ResolvedPath <<
"\n";);
589 if (S_ISLNK(st_mode)) {
590 LLVM_DEBUG(
dbgs() <<
" Found symlink: " << ResolvedPath <<
"\n";);
594 EC = std::make_error_code(std::errc::no_such_file_or_directory);
595 LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{
"", EC});
605 std::string resolvedBase =
"";
608 resolvedBase =
Resolved.str().str();
613 true, SymLoopLevel - 1);
615 LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{
"", EC});
616 LLVM_DEBUG(
dbgs() <<
" Failed to resolve symlink target: " << Symlink
625 }
else if (st_mode == 0) {
626 EC = std::make_error_code(std::errc::no_such_file_or_directory);
627 LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{
"", EC});
628 LLVM_DEBUG(
dbgs() <<
" Component does not exist: " << ResolvedPath
638 std::string Canonical =
Resolved.str().str();
640 LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{
645 LLVM_DEBUG(
dbgs() <<
"PathResolver::realpathCached: Final Resolved: " << Path
646 <<
" => " << Canonical <<
"\n";);
652 std::string Canon = resolveCanonical(Path, EC);
656 <<
"LibraryScanHelper::addBasePath: Failed to canonicalize path: "
660 std::unique_lock<std::shared_mutex> Lock(Mtx);
661 if (LibSearchPaths.count(Canon)) {
662 LLVM_DEBUG(
dbgs() <<
"LibraryScanHelper::addBasePath: Already added: "
666 K = K == PathType::Unknown ? classifyKind(Canon) : K;
667 LibSearchPaths[Canon] = std::make_unique<LibrarySearchPath>(Canon, K);
668 auto &SP = LibSearchPaths[Canon];
670 if (K == PathType::User) {
671 LLVM_DEBUG(
dbgs() <<
"LibraryScanHelper::addBasePath: Added User path: "
673 UnscannedUsr.push_back(
StringRef(SP->BasePath));
675 LLVM_DEBUG(
dbgs() <<
"LibraryScanHelper::addBasePath: Added System path: "
677 UnscannedSys.push_back(
StringRef(SP->BasePath));
684 auto &Queue = (K == PathType::User) ? UnscannedUsr : UnscannedSys;
686 std::unique_lock<std::shared_mutex> Lock(Mtx);
688 while (!Queue.empty() && (BatchSize == 0 ||
Result.size() < BatchSize)) {
690 auto It = LibSearchPaths.find(
Base);
691 if (It != LibSearchPaths.end()) {
692 auto &SP = It->second;
695 Result.push_back(SP.get());
704 std::string Canon = resolveCanonical(Path, EC);
708 std::shared_lock<std::shared_mutex> Lock(Mtx);
709 return LibSearchPaths.count(Canon) > 0;
713 std::shared_lock<std::shared_mutex> Lock(Mtx);
714 for (
const auto &KV : LibSearchPaths) {
715 const auto &SP = KV.second;
723 std::shared_lock<std::shared_mutex> Lock(Mtx);
725 for (
auto &[
_, SP] : LibSearchPaths) {
732 (SP->Kind == PathType::User) ? UnscannedUsr : UnscannedSys;
737std::string LibraryScanHelper::resolveCanonical(
StringRef Path,
738 std::error_code &EC)
const {
739 auto Canon = LibPathResolver->resolve(Path, EC);
740 return EC ? Path.str() : *Canon;
745 const char *Home = getenv(
"HOME");
746 if (Home && Path.starts_with(Home))
747 return PathType::User;
749 static const std::array<std::string, 5> UserPrefixes = {
757 for (
const auto &Prefix : UserPrefixes) {
758 if (Path.starts_with(Prefix))
759 return PathType::User;
762 return PathType::System;
768 for (
const auto &Command : Obj.load_commands()) {
769 switch (Command.C.cmd) {
770 case MachO::LC_LOAD_DYLIB: {
776 case MachO::LC_LOAD_WEAK_DYLIB:
777 case MachO::LC_REEXPORT_DYLIB:
778 case MachO::LC_LOAD_UPWARD_DYLIB:
779 case MachO::LC_LAZY_LOAD_DYLIB:
781 case MachO::LC_RPATH: {
784 const char *rpath = Command.Ptr + rpathCmd.
path;
791 for (
const auto &raw : RawPaths) {
806 if (!DynamicEntriesOrError)
807 return DynamicEntriesOrError.takeError();
809 for (
const typename ELFT::Dyn &Dyn : *DynamicEntriesOrError) {
810 if (Dyn.d_tag == ELF::DT_STRTAB) {
811 auto MappedAddrOrError = Elf.
toMappedAddr(Dyn.getPtr());
812 if (!MappedAddrOrError)
813 return MappedAddrOrError.takeError();
814 return StringRef(
reinterpret_cast<const char *
>(*MappedAddrOrError));
819 auto SectionsOrError = Elf.
sections();
820 if (!SectionsOrError)
821 return SectionsOrError.takeError();
823 for (
const typename ELFT::Shdr &Sec : *SectionsOrError) {
832template <
typename ELFT>
839 const char *
Data = StrTabOrErr->data();
842 if (!DynamicEntriesOrError) {
843 return DynamicEntriesOrError.takeError();
846 for (
const typename ELFT::Dyn &Dyn : *DynamicEntriesOrError) {
851 case ELF::DT_RPATH: {
855 for (
const auto &raw : RawPaths)
859 case ELF::DT_RUNPATH: {
863 for (
const auto &raw : RawPaths)
867 case ELF::DT_FLAGS_1:
903 <<
" is an ELF object\n";);
910 <<
" is a Mach-O object\n";);
919 LLVM_DEBUG(
dbgs() <<
"extractDeps: Unsupported binary format for file "
920 << FilePath <<
"\n";);
922 "Unsupported binary format: %s",
923 FilePath.
str().c_str());
927 LLVM_DEBUG(
dbgs() <<
"extractDeps: Attempting to open file " << FilePath
930 if (
auto Cached = ObjCache.
take(FilePath)) {
931 auto ObjOrErr = Cached->getObjectFile();
933 return ObjOrErr.takeError();
938 ObjectFileLoader ObjLoader(FilePath);
939 auto ObjOrErr = ObjLoader.getObjectFile();
941 LLVM_DEBUG(
dbgs() <<
"extractDeps: Failed to open " << FilePath <<
"\n";);
942 return ObjOrErr.takeError();
948bool LibraryScanner::shouldScan(StringRef FilePath,
bool IsResolvingDep) {
949 LLVM_DEBUG(
dbgs() <<
"[shouldScan] Checking: " << FilePath <<
"\n";);
951 LibraryPathCache &Cache = ScanHelper.getCache();
953 if (Cache.hasSeen(FilePath)) {
965 if (!IsResolvingDep && !Validator.isSharedLibrary(FilePath)) {
971 Cache.markSeen(FilePath.str());
974 if (!ShouldScanCall(FilePath)) {
975 LLVM_DEBUG(
dbgs() <<
" -> Skipped: user-defined hook rejected.\n";);
979 LLVM_DEBUG(
dbgs() <<
" -> Accepted: ready to scan " << FilePath <<
"\n";);
983void LibraryScanner::handleLibrary(StringRef FilePath,
PathType K,
int level) {
984 LLVM_DEBUG(
dbgs() <<
"LibraryScanner::handleLibrary: Scanning: " << FilePath
985 <<
", level=" << level <<
"\n";);
986 if (!shouldScan(FilePath, level > 0)) {
987 LLVM_DEBUG(
dbgs() <<
" Skipped (shouldScan returned false): " << FilePath
992 auto DepsOrErr = extractDeps(FilePath);
994 LLVM_DEBUG(
dbgs() <<
" Failed to extract deps for: " << FilePath <<
"\n";);
1002 dbgs() <<
" Found deps : \n";
1003 for (
const auto &dep : Deps.deps)
1004 dbgs() <<
" : " << dep <<
"\n";
1005 dbgs() <<
" Found @rpath : " << Deps.rpath.size() <<
"\n";
1006 for (
const auto &r : Deps.rpath)
1007 dbgs() <<
" : " << r <<
"\n";
1008 dbgs() <<
" Found @runpath : \n";
1009 for (
const auto &r : Deps.runPath)
1010 dbgs() <<
" : " << r <<
"\n";
1013 if (Deps.isPIE && level == 0) {
1014 LLVM_DEBUG(
dbgs() <<
" Skipped PIE executable at top level: " << FilePath
1020 bool Added = LibMgr.addLibrary(FilePath.str(), K);
1027 if (Deps.rpath.empty() && Deps.runPath.empty()) {
1029 dbgs() <<
"LibraryScanner::handleLibrary: Skipping deps (Heuristic1): "
1030 << FilePath <<
"\n";);
1035 auto allTracked = [&](
const auto &Paths) {
1037 return std::all_of(Paths.begin(), Paths.end(), [&](StringRef
P) {
1038 LLVM_DEBUG(dbgs() <<
" Checking isTrackedBasePath : " << P <<
"\n";);
1039 return ScanHelper.isTrackedBasePath(
1040 DylibResolver::resolvelinkerFlag(P, FilePath));
1044 if (allTracked(Deps.rpath) && allTracked(Deps.runPath)) {
1046 dbgs() <<
"LibraryScanner::handleLibrary: Skipping deps (Heuristic2): "
1047 << FilePath <<
"\n";);
1051 DylibResolver Resolver(Validator);
1052 Resolver.configure(FilePath,
1056 for (StringRef Dep : Deps.deps) {
1058 auto DepFullOpt = Resolver.resolve(Dep);
1060 LLVM_DEBUG(
dbgs() <<
" Failed to resolve dep: " << Dep <<
"\n";);
1063 LLVM_DEBUG(
dbgs() <<
" Resolved dep to: " << *DepFullOpt <<
"\n";);
1065 handleLibrary(*DepFullOpt, K, level + 1);
1072 dbgs() <<
"LibraryScanner::scanBaseDir: Invalid or empty basePath: "
1073 <<
SP->BasePath <<
"\n";);
1077 LLVM_DEBUG(
dbgs() <<
"LibraryScanner::scanBaseDir: Scanning directory: "
1078 <<
SP->BasePath <<
"\n";);
1083 for (sys::fs::directory_iterator It(
SP->BasePath, EC), end; It != end && !EC;
1086 if (!
Entry.status())
1089 auto Status = *
Entry.status();
1093 std::string FinalPath;
1100 auto CanonicalOpt = ScanHelper.resolve(
Entry.path(), EC);
1101 if (EC || !CanonicalOpt) {
1103 <<
EC.message() <<
")\n");
1107 FinalPath = std::move(*CanonicalOpt);
1113 SmallString<256> Abs(
Entry.path());
1115 FinalPath = Abs.str().str();
1117 LLVM_DEBUG(
dbgs() <<
" Regular: absolute = " << FinalPath <<
"\n");
1127 handleLibrary(FinalPath,
SP->Kind);
1135 LLVM_DEBUG(
dbgs() <<
"LibraryScanner::scanNext: Scanning next batch of size "
1136 << BatchSize <<
" for kind "
1137 << (K == PathType::User ?
"User" :
"System") <<
"\n";);
1140 ScanHelper.getNextBatch(K, BatchSize, SearchPaths);
1141 for (
const auto *SP : SearchPaths) {
1142 LLVM_DEBUG(
dbgs() <<
" Scanning unit with basePath: " << SP->BasePath
std::deque< BasicBlock * > PathType
Base class for error info classes.
virtual std::string message() const
Return the error message as a string.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void append(StringRef RHS)
Append from a StringRef.
StringRef str() const
Explicit conversion to StringRef.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void swap(SmallVectorImpl &RHS)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
static constexpr size_t npos
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 bool empty() const
empty - Check if the string is empty.
LLVM_ABI bool starts_with_insensitive(StringRef Prefix) const
Check if this string starts with the given Prefix, ignoring case.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Triple - Helper class for working with autoconf configuration names.
ObjectFormatType getObjectFormat() const
Get the object format for this triple.
ArchType getArch() const
Get the parsed architecture type of this triple.
uint16_t getCharacteristics() const
const Elf_Ehdr & getHeader() const
Expected< Elf_Phdr_Range > program_headers() const
Iterate over program header table.
Expected< StringRef > getStringTableForSymtab(const Elf_Shdr &Section) const
Expected< Elf_Dyn_Range > dynamicEntries() const
Expected< Elf_Shdr_Range > sections() const
Expected< const uint8_t * > toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler=&defaultWarningHandler) const
This class is the base class for all object file types.
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Validates and normalizes dynamic library paths.
bool isSharedLibrary(StringRef Path) const
std::optional< std::string > validate(StringRef Path) const
Validate the given path as a shared library.
std::optional< std::string > resolve(StringRef Stem, bool VariateLibStem=false) const
Performs placeholder substitution in dynamic library paths.
std::string substitute(StringRef input) const
void configure(StringRef loaderPath)
bool isTrackedBasePath(StringRef P) const
void getNextBatch(PathType Kind, size_t batchSize, SmallVectorImpl< const LibrarySearchPath * > &Out)
bool leftToScan(PathType K) const
void addBasePath(const std::string &P, PathType Kind=PathType::Unknown)
void scanNext(PathType Kind, size_t batchSize=1)
std::optional< ObjectFileLoader > take(StringRef Path)
Loads an object file and provides access to it.
static bool isArchitectureCompatible(const object::ObjectFile &Obj)
Expected< object::ObjectFile & > getObjectFile()
Get the loaded object file, or return an error if loading failed.
std::optional< std::string > readlinkCached(StringRef Path)
mode_t lstatCached(StringRef Path)
std::optional< std::string > realpathCached(StringRef Path, std::error_code &ec, StringRef base="", bool baseIsResolved=false, long symloopLevel=40)
std::optional< std::string > resolve(StringRef libStem, const DylibSubstitutor &Subst, DylibPathValidator &Validator) const
@ IMAGE_FILE_DLL
The image file is a DLL.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
Expected< LibraryDepsInfo > parseELF(const object::ELFFile< ELFT > &Elf)
LibraryScanner::LibraryDepsInfo LibraryDepsInfo
Expected< LibraryDepsInfo > parseMachODeps(const object::MachOObjectFile &Obj)
void createComponent(StringRef Path, StringRef BasePath, bool BaseIsResolved, SmallVector< StringRef, 16 > &Component)
void handleError(Error Err, StringRef context="")
void normalizePathSegments(SmallVector< StringRef, 16 > &PathParts)
bool isELFSharedLibrary(const object::ELFFile< ELFT > &ELFObj)
@ Resolved
Queried, materialization begun.
Expected< LibraryDepsInfo > parseDependencies(StringRef FilePath, object::ObjectFile *Obj)
bool isSharedLibraryObject(object::ObjectFile &Obj)
Expected< LibraryDepsInfo > parseELFDeps(const object::ELFObjectFileBase &Obj)
static Expected< StringRef > getDynamicStrTab(const object::ELFFile< ELFT > &Elf)
LLVM_ABI bool is_regular_file(const basic_file_status &status)
Does status represent a regular file?
LLVM_ABI bool is_symlink_file(const basic_file_status &status)
Does status represent a symlink file?
LLVM_ABI std::error_code real_path(const Twine &path, SmallVectorImpl< char > &output, bool expand_tilde=false)
Collapse all .
LLVM_ABI std::string getMainExecutable(const char *argv0, void *MainExecAddr)
Return the path to the main executable, given the value of argv[0] from program startup and the addre...
LLVM_ABI file_type get_file_type(const Twine &Path, bool Follow=true)
Does status represent a directory?
LLVM_ABI std::error_code make_absolute(SmallVectorImpl< char > &path)
Make path an absolute path.
LLVM_ABI std::error_code current_path(SmallVectorImpl< char > &result)
Get the current path.
LLVM_ABI bool is_directory(const basic_file_status &status)
Does status represent a directory?
LLVM_ABI StringRef get_separator(Style style=Style::native)
Return the preferred separator for this platform.
LLVM_ABI void remove_filename(SmallVectorImpl< char > &path, Style style=Style::native)
Remove the last component from path unless it is the root dir.
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
LLVM_ABI bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
LLVM_ABI bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
LLVM_ABI bool home_directory(SmallVectorImpl< char > &result)
Get the user's home directory.
LLVM_ABI bool is_separator(char value, Style style=Style::native)
Check whether the given char is a path separator on the host OS.
const char EnvPathSeparator
This is the OS-specific separator for PATH like environment variables:
LLVM_ABI std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
LLVM_ABI file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
LLVM_ABI void SplitString(StringRef Source, SmallVectorImpl< StringRef > &OutFragments, StringRef Delimiters=" \t\n\v\f\r")
SplitString - Split up the specified string according to the specified delimiters,...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
void consumeError(Error Err)
Consume a Error without doing anything.
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
@ archive
ar style archive file
@ elf_shared_object
ELF dynamically linked shared lib.
@ macho_dynamically_linked_shared_lib
Mach-O dynlinked shared lib.
@ macho_dynamically_linked_shared_lib_stub
Mach-O Shared lib stub.
@ pecoff_executable
PECOFF executable file.
@ macho_universal_binary
Mach-O universal binary.
@ macho_fixed_virtual_memory_shared_lib
Mach-O Shared Lib, FVM.
Dependency info for a library.
void addRunPath(StringRef s)
void addRPath(StringRef s)