39#define DEBUG_TYPE "orc-scanner"
45 dbgs() <<
"LLVM Error";
47 dbgs() <<
" [" << context <<
"]";
54 Triple ObjTriple = Obj.makeTriple();
57 dbgs() <<
"Host triple: " << HostTriple.
str()
58 <<
", Object triple: " << ObjTriple.
str() <<
"\n";
78ObjectFileLoader::loadObjectFileWithOwnership(
StringRef FilePath) {
79 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Attempting to open file " << FilePath
83 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Failed to open file " << FilePath
85 return BinOrErr.takeError();
88 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Successfully opened file " << FilePath
91 auto OwningBin = BinOrErr->takeBinary();
94 if (
Bin->isArchive()) {
95 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: File is an archive, not supported: "
96 << FilePath <<
"\n";);
98 "Archive files are not supported: %s",
99 FilePath.
str().c_str());
102#if defined(__APPLE__)
104 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Detected Mach-O universal binary: "
105 << FilePath <<
"\n";);
106 for (
auto ObjForArch : UB->objects()) {
107 auto ObjOrErr = ObjForArch.getAsObjectFile();
111 <<
"ObjectFileLoader: Skipping invalid architecture slice\n";);
117 std::unique_ptr<object::ObjectFile> Obj = std::move(ObjOrErr.get());
120 dbgs() <<
"ObjectFileLoader: Found compatible object slice\n";);
122 return object::OwningBinary<object::ObjectFile>(
123 std::move(Obj), std::move(OwningBin.second));
126 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Incompatible architecture "
130 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: No compatible slices found in "
131 "universal binary\n";);
133 "No compatible object found in fat binary: %s",
134 FilePath.
str().c_str());
141 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Failed to create object file\n";);
142 return ObjOrErr.takeError();
144 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Detected object file\n";);
146 std::unique_ptr<object::ObjectFile> Obj = std::move(*ObjOrErr);
148 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Incompatible architecture: "
149 << FilePath <<
"\n";);
151 "Incompatible object file: %s",
152 FilePath.
str().c_str());
155 LLVM_DEBUG(
dbgs() <<
"ObjectFileLoader: Object file is compatible\n";);
157 return object::OwningBinary<object::ObjectFile>(std::move(Obj),
158 std::move(OwningBin.second));
172 for (
auto Phdr : *PHOrErr) {
200 dbgs() <<
"Mach-O filetype: " <<
MachO->getHeader().filetype
202 <<
"), shared: " <<
Result <<
"\n";
206 }
else if (Obj.
isCOFF()) {
219 LLVM_DEBUG(
dbgs() <<
"Checking if path is a shared library: " << Path
224 LLVM_DEBUG(
dbgs() <<
"File type is not a regular file for path: " << Path
237#if defined(__APPLE__)
250 bool NeedsObjectInspection =
253#elif defined(__APPLE__)
257#elif defined(LLVM_ON_UNIX)
264#error "Unsupported platform."
267 if (NeedsObjectInspection) {
277 LLVM_DEBUG(
dbgs() <<
"Path is not identified as a shared library: " << Path
287 if (LoaderPath.
empty()) {
288 LoaderDir = ExecPath;
290 LoaderDir = LoaderPath.
str();
296 Placeholders[
"@loader_path"] = std::string(LoaderDir);
297 Placeholders[
"@executable_path"] = std::string(ExecPath);
299 Placeholders[
"$origin"] = std::string(LoaderDir);
303std::optional<std::string>
306 for (
const auto &SP : Paths) {
310 if (!PlaceholderPrefix.empty() &&
316 LLVM_DEBUG(
dbgs() <<
"SearchPathResolver::resolve FullPath = " << FullPath
319 if (
auto Valid = Validator.
validate(FullPath.
str()))
326std::optional<std::string>
327DylibResolverImpl::tryWithExtensions(
StringRef LibStem)
const {
328 LLVM_DEBUG(
dbgs() <<
"tryWithExtensions: baseName = " << LibStem <<
"\n";);
332#if defined(__APPLE__)
334 Candidates.back() +=
".dylib";
336 Candidates.emplace_back(LibStem);
337 Candidates.back() +=
".dll";
339 Candidates.emplace_back(LibStem);
340 Candidates.back() +=
".so";
348 if (!WithPrefix.empty())
351 WithPrefix += FileName;
353#if defined(__APPLE__)
354 WithPrefix +=
".dylib";
356 WithPrefix +=
".dll";
361 Candidates.push_back(std::move(WithPrefix));
365 dbgs() <<
" Candidates to try:\n";
366 for (
const auto &
C : Candidates)
367 dbgs() <<
" " <<
C <<
"\n";
371 for (
const auto &Name : Candidates) {
375 for (
const auto &R : Resolvers) {
376 if (
auto Res = R.resolve(Name, Substitutor, Validator))
386std::optional<std::string>
388 LLVM_DEBUG(
dbgs() <<
"Resolving library stem: " << LibStem <<
"\n";);
393 return Validator.validate(LibStem);
397 if (
auto norm = Validator.validate(Substitutor.substitute(LibStem))) {
405 for (
const auto &R : Resolvers) {
407 if (
auto Result = R.resolve(LibStem, Substitutor, Validator)) {
417 if (VariateLibStem) {
420 if (
auto Norm = tryWithExtensions(LibStem)) {
421 LLVM_DEBUG(
dbgs() <<
" -> Resolved via tryWithExtensions: " << *Norm
428 LLVM_DEBUG(
dbgs() <<
" -> Could not resolve: " << LibStem <<
"\n";);
436 if (
auto Cache = LibPathCache->read_lstat(Path))
441 mode_t st_mode = (lstat(Path.str().c_str(), &buf) == -1) ? 0 : buf.st_mode;
443 LibPathCache->insert_lstat(Path, st_mode);
450 if (
auto Cache = LibPathCache->read_link(Path))
456 if ((len = readlink(Path.str().c_str(), buf,
sizeof(buf))) != -1) {
459 LibPathCache->insert_link(Path, s);
468 if (!BaseIsResolved) {
469 if (Path[0] ==
'~' &&
476 }
else if (BasePath.
empty()) {
481 .
split(Component, Separator, -1,
false);
483 BasePath.
split(Component, Separator, -1,
488 Path.split(Component, Separator, -1,
false);
493 for (
auto &Part : PathParts) {
496 }
else if (Part ==
"..") {
497 if (!NormalizedPath.
empty() && NormalizedPath.
back() !=
"..") {
506 PathParts.
swap(NormalizedPath);
518 EC = std::make_error_code(std::errc::no_such_file_or_directory);
519 LLVM_DEBUG(
dbgs() <<
"PathResolver::realpathCached: Empty path\n";);
524 if (SymLoopLevel <= 0) {
525 EC = std::make_error_code(std::errc::too_many_symbolic_link_levels);
527 dbgs() <<
"PathResolver::realpathCached: Too many Symlink levels: "
536 if (
auto Cached = LibPathCache->read_realpath(Path)) {
537 EC = Cached->ErrnoCode;
539 LLVM_DEBUG(
dbgs() <<
"PathResolver::realpathCached: Cached (error) for "
543 dbgs() <<
"PathResolver::realpathCached: Cached (success) for "
544 << Path <<
" => " << Cached->canonicalPath <<
"\n";);
546 return Cached->canonicalPath.empty()
548 : std::make_optional(Cached->canonicalPath);
552 LLVM_DEBUG(
dbgs() <<
"PathResolver::realpathCached: Resolving path: " << Path
563 if (BaseIsResolved) {
569 Path.split(Components, Separator, -1,
false);
574 for (
auto &
C : Components)
575 dbgs() <<
" " <<
C <<
" ";
581 for (
const auto &Component : Components) {
582 if (Component ==
".")
584 if (Component ==
"..") {
586 size_t S =
Resolved.rfind(Separator);
596 const char *ResolvedPath =
Resolved.c_str();
597 LLVM_DEBUG(
dbgs() <<
" Processing Component: " << Component <<
" => "
598 << ResolvedPath <<
"\n";);
601 if (S_ISLNK(st_mode)) {
602 LLVM_DEBUG(
dbgs() <<
" Found symlink: " << ResolvedPath <<
"\n";);
606 EC = std::make_error_code(std::errc::no_such_file_or_directory);
607 LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{
"", EC});
617 std::string resolvedBase =
"";
620 resolvedBase =
Resolved.str().str();
625 true, SymLoopLevel - 1);
627 LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{
"", EC});
628 LLVM_DEBUG(
dbgs() <<
" Failed to resolve symlink target: " << Symlink
637 }
else if (st_mode == 0) {
638 EC = std::make_error_code(std::errc::no_such_file_or_directory);
639 LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{
"", EC});
640 LLVM_DEBUG(
dbgs() <<
" Component does not exist: " << ResolvedPath
650 std::string Canonical =
Resolved.str().str();
652 LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{
657 LLVM_DEBUG(
dbgs() <<
"PathResolver::realpathCached: Final Resolved: " << Path
658 <<
" => " << Canonical <<
"\n";);
664 std::string Canon = resolveCanonical(Path, EC);
668 <<
"LibraryScanHelper::addBasePath: Failed to canonicalize path: "
672 std::unique_lock<std::shared_mutex> Lock(Mtx);
673 if (LibSearchPaths.count(Canon)) {
674 LLVM_DEBUG(
dbgs() <<
"LibraryScanHelper::addBasePath: Already added: "
678 K = K == PathType::Unknown ? classifyKind(Canon) : K;
679 auto SP = std::make_shared<LibrarySearchPath>(Canon, K);
680 LibSearchPaths[Canon] = SP;
682 if (K == PathType::User) {
683 LLVM_DEBUG(
dbgs() <<
"LibraryScanHelper::addBasePath: Added User path: "
685 UnscannedUsr.push_back(
StringRef(SP->BasePath));
687 LLVM_DEBUG(
dbgs() <<
"LibraryScanHelper::addBasePath: Added System path: "
689 UnscannedSys.push_back(
StringRef(SP->BasePath));
693std::vector<std::shared_ptr<LibrarySearchPath>>
695 std::vector<std::shared_ptr<LibrarySearchPath>>
Result;
696 auto &Queue = (K == PathType::User) ? UnscannedUsr : UnscannedSys;
698 std::unique_lock<std::shared_mutex> Lock(Mtx);
700 while (!Queue.empty() && (BatchSize == 0 ||
Result.size() < BatchSize)) {
702 auto It = LibSearchPaths.find(
Base);
703 if (It != LibSearchPaths.end()) {
704 auto &SP = It->second;
718 std::string Canon = resolveCanonical(Path, EC);
722 std::shared_lock<std::shared_mutex> Lock(Mtx);
723 return LibSearchPaths.count(Canon) > 0;
727 std::shared_lock<std::shared_mutex> Lock(Mtx);
728 for (
const auto &KV : LibSearchPaths) {
729 const auto &SP = KV.second;
737 std::shared_lock<std::shared_mutex> Lock(Mtx);
739 for (
auto &[
_, SP] : LibSearchPaths) {
746 (SP->Kind == PathType::User) ? UnscannedUsr : UnscannedSys;
751std::vector<std::shared_ptr<LibrarySearchPath>>
753 std::shared_lock<std::shared_mutex> Lock(Mtx);
754 std::vector<std::shared_ptr<LibrarySearchPath>>
Result;
755 Result.reserve(LibSearchPaths.size());
756 for (
const auto &[
_, SP] : LibSearchPaths) {
762std::string LibraryScanHelper::resolveCanonical(
StringRef Path,
763 std::error_code &EC)
const {
764 auto Canon = LibPathResolver->resolve(Path, EC);
765 return EC ? Path.str() : *Canon;
770 const char *Home = getenv(
"HOME");
771 if (Home && Path.find(Home) == 0)
772 return PathType::User;
774 static const std::array<std::string, 5> UserPrefixes = {
782 for (
const auto &Prefix : UserPrefixes) {
783 if (Path.find(Prefix) == 0)
784 return PathType::User;
787 return PathType::System;
794 switch (Command.C.cmd) {
795 case MachO::LC_LOAD_DYLIB: {
801 case MachO::LC_LOAD_WEAK_DYLIB:
802 case MachO::LC_REEXPORT_DYLIB:
803 case MachO::LC_LOAD_UPWARD_DYLIB:
804 case MachO::LC_LAZY_LOAD_DYLIB:
806 case MachO::LC_RPATH: {
809 const char *rpath = Command.Ptr + rpathCmd.
path;
816 for (
const auto &raw : RawPaths) {
831 if (!DynamicEntriesOrError)
832 return DynamicEntriesOrError.takeError();
834 for (
const typename ELFT::Dyn &Dyn : *DynamicEntriesOrError) {
835 if (Dyn.d_tag == ELF::DT_STRTAB) {
836 auto MappedAddrOrError = Elf.
toMappedAddr(Dyn.getPtr());
837 if (!MappedAddrOrError)
838 return MappedAddrOrError.takeError();
839 return StringRef(
reinterpret_cast<const char *
>(*MappedAddrOrError));
844 auto SectionsOrError = Elf.
sections();
845 if (!SectionsOrError)
846 return SectionsOrError.takeError();
848 for (
const typename ELFT::Shdr &Sec : *SectionsOrError) {
857template <
typename ELFT>
864 const char *
Data = StrTabOrErr->data();
867 if (!DynamicEntriesOrError) {
868 return DynamicEntriesOrError.takeError();
871 for (
const typename ELFT::Dyn &Dyn : *DynamicEntriesOrError) {
876 case ELF::DT_RPATH: {
880 for (
const auto &raw : RawPaths)
884 case ELF::DT_RUNPATH: {
888 for (
const auto &raw : RawPaths)
892 case ELF::DT_FLAGS_1:
924 LLVM_DEBUG(
dbgs() <<
"extractDeps: Attempting to open file " << FilePath
927 ObjectFileLoader ObjLoader(FilePath);
928 auto ObjOrErr = ObjLoader.getObjectFile();
930 LLVM_DEBUG(
dbgs() <<
"extractDeps: Failed to open " << FilePath <<
"\n";);
931 return ObjOrErr.takeError();
934 object::ObjectFile *Obj = &ObjOrErr.get();
938 <<
" is an ELF object\n";);
945 <<
" is a Mach-O object\n";);
954 LLVM_DEBUG(
dbgs() <<
"extractDeps: Unsupported binary format for file "
955 << FilePath <<
"\n";);
957 "Unsupported binary format: %s",
958 FilePath.
str().c_str());
961std::optional<std::string> LibraryScanner::shouldScan(StringRef FilePath) {
964 LLVM_DEBUG(
dbgs() <<
"[shouldScan] Checking: " << FilePath <<
"\n";);
974 auto CanonicalPathOpt = ScanHelper.resolve(FilePath, EC);
975 if (EC || !CanonicalPathOpt) {
977 <<
EC.message() <<
").\n";);
982 const std::string &CanonicalPath = *CanonicalPathOpt;
983 LLVM_DEBUG(
dbgs() <<
" -> Canonical path: " << CanonicalPath <<
"\n");
999 if (ScanHelper.hasSeenOrMark(CanonicalPath)) {
1002 return std::nullopt;
1006 if (LibMgr.hasLibrary(CanonicalPath)) {
1007 LLVM_DEBUG(
dbgs() <<
" -> Skipped: already tracked by LibraryManager.\n";);
1009 return std::nullopt;
1013 if (!ShouldScanCall(CanonicalPath)) {
1014 LLVM_DEBUG(
dbgs() <<
" -> Skipped: user-defined hook rejected.\n";);
1016 return std::nullopt;
1019 LLVM_DEBUG(
dbgs() <<
" -> Accepted: ready to scan " << CanonicalPath
1021 return CanonicalPath;
1024void LibraryScanner::handleLibrary(StringRef FilePath,
PathType K,
int level) {
1025 LLVM_DEBUG(
dbgs() <<
"LibraryScanner::handleLibrary: Scanning: " << FilePath
1026 <<
", level=" << level <<
"\n";);
1027 auto CanonPathOpt = shouldScan(FilePath);
1028 if (!CanonPathOpt) {
1029 LLVM_DEBUG(
dbgs() <<
" Skipped (shouldScan returned false): " << FilePath
1034 const std::string CanonicalPath = *CanonPathOpt;
1036 auto DepsOrErr = extractDeps(CanonicalPath);
1038 LLVM_DEBUG(
dbgs() <<
" Failed to extract deps for: " << CanonicalPath
1047 dbgs() <<
" Found deps : \n";
1048 for (
const auto &dep : Deps.deps)
1049 dbgs() <<
" : " << dep <<
"\n";
1050 dbgs() <<
" Found @rpath : " << Deps.rpath.size() <<
"\n";
1051 for (
const auto &r : Deps.rpath)
1052 dbgs() <<
" : " << r <<
"\n";
1053 dbgs() <<
" Found @runpath : \n";
1054 for (
const auto &r : Deps.runPath)
1055 dbgs() <<
" : " << r <<
"\n";
1058 if (Deps.isPIE && level == 0) {
1060 << CanonicalPath <<
"\n";);
1065 bool Added = LibMgr.addLibrary(CanonicalPath, K);
1067 LLVM_DEBUG(
dbgs() <<
" Already added: " << CanonicalPath <<
"\n";);
1072 if (Deps.rpath.empty() && Deps.runPath.empty()) {
1074 dbgs() <<
"LibraryScanner::handleLibrary: Skipping deps (Heuristic1): "
1075 << CanonicalPath <<
"\n";);
1080 auto allTracked = [&](
const auto &Paths) {
1082 return std::all_of(Paths.begin(), Paths.end(), [&](StringRef
P) {
1083 LLVM_DEBUG(dbgs() <<
" Checking isTrackedBasePath : " << P <<
"\n";);
1084 return ScanHelper.isTrackedBasePath(
1085 DylibResolver::resolvelinkerFlag(P, CanonicalPath));
1089 if (allTracked(Deps.rpath) && allTracked(Deps.runPath)) {
1091 dbgs() <<
"LibraryScanner::handleLibrary: Skipping deps (Heuristic2): "
1092 << CanonicalPath <<
"\n";);
1096 DylibPathValidator Validator(ScanHelper.getPathResolver());
1097 DylibResolver Resolver(Validator);
1098 Resolver.configure(CanonicalPath,
1102 for (StringRef Dep : Deps.deps) {
1104 auto DepFullOpt = Resolver.resolve(Dep);
1106 LLVM_DEBUG(
dbgs() <<
" Failed to resolve dep: " << Dep <<
"\n";);
1110 LLVM_DEBUG(
dbgs() <<
" Resolved dep to: " << *DepFullOpt <<
"\n";);
1112 handleLibrary(*DepFullOpt, K, level + 1);
1116void LibraryScanner::scanBaseDir(std::shared_ptr<LibrarySearchPath> SP) {
1119 dbgs() <<
"LibraryScanner::scanBaseDir: Invalid or empty basePath: "
1120 <<
SP->BasePath <<
"\n";);
1124 LLVM_DEBUG(
dbgs() <<
"LibraryScanner::scanBaseDir: Scanning directory: "
1125 <<
SP->BasePath <<
"\n";);
1130 for (sys::fs::directory_iterator It(
SP->BasePath, EC), end; It != end && !EC;
1133 if (!
Entry.status())
1136 auto Status = *
Entry.status();
1140 handleLibrary(
Entry.path(),
SP->Kind);
1148 LLVM_DEBUG(
dbgs() <<
"LibraryScanner::scanNext: Scanning next batch of size "
1149 << BatchSize <<
" for kind "
1150 << (K == PathType::User ?
"User" :
"System") <<
"\n";);
1152 auto SearchPaths = ScanHelper.getNextBatch(K, BatchSize);
1153 for (
auto &SP : SearchPaths) {
1154 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.
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.
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.
static constexpr size_t npos
Triple - Helper class for working with autoconf configuration names.
OSType getOS() const
Get the parsed operating system type of this triple.
ArchType getArch() const
Get the parsed architecture type of this triple.
const std::string & str() const
EnvironmentType getEnvironment() const
Get the parsed environment 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
MachO::rpath_command getRpathCommand(const LoadCommandInfo &L) const
iterator_range< load_command_iterator > load_commands() const
MachO::dylib_command getDylibIDLoadCommand(const LoadCommandInfo &L) 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.
static bool isSharedLibrary(StringRef Path)
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)
std::vector< std::shared_ptr< LibrarySearchPath > > getNextBatch(PathType Kind, size_t batchSize)
bool isTrackedBasePath(StringRef P) const
bool leftToScan(PathType K) const
std::vector< std::shared_ptr< LibrarySearchPath > > getAllUnits() const
void addBasePath(const std::string &P, PathType Kind=PathType::Unknown)
void scanNext(PathType Kind, size_t batchSize=1)
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.
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 bool exists(const basic_file_status &status)
Does file exist?
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 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.
LLVM_ABI std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
const char EnvPathSeparator
This is the OS-specific separator for PATH like environment variables:
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)