X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSystem%2FPath.cpp;h=ae166a574d1042a87b311b41063d180ed1055a1b;hb=5c0db76cf262bec095c6b52ba0aa6e095f9f8298;hp=34cbd6d69b7fef691d1ee20de0e176d7fcaf667c;hpb=6b8a63ae583b53a942dca7c681f4cf161c90d35e;p=oota-llvm.git diff --git a/lib/System/Path.cpp b/lib/System/Path.cpp index 34cbd6d69b7..ae166a574d1 100644 --- a/lib/System/Path.cpp +++ b/lib/System/Path.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Reid Spencer and is distributed under the -// University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -14,8 +14,9 @@ #include "llvm/System/Path.h" #include "llvm/Config/config.h" #include - -namespace llvm { +#include +#include +using namespace llvm; using namespace sys; //===----------------------------------------------------------------------===// @@ -23,54 +24,153 @@ using namespace sys; //=== independent code. //===----------------------------------------------------------------------===// +bool Path::operator==(const Path &that) const { + return path == that.path; +} + +bool Path::operator<(const Path& that) const { + return path < that.path; +} + Path Path::GetLLVMConfigDir() { Path result; #ifdef LLVM_ETCDIR - if (result.setDirectory(LLVM_ETCDIR)) + if (result.set(LLVM_ETCDIR)) return result; #endif return GetLLVMDefaultConfigDir(); } LLVMFileType -sys::IdentifyFileType(const char*magic, unsigned length) { +sys::IdentifyFileType(const char *magic, unsigned length) { assert(magic && "Invalid magic number string"); assert(length >=4 && "Invalid magic number length"); - switch (magic[0]) { - case 'l': - if (magic[1] == 'l' && magic[2] == 'v') { - if (magic[3] == 'c') - return CompressedBytecodeFileType; - else if (magic[3] == 'm') - return BytecodeFileType; - } + switch ((unsigned char)magic[0]) { + case 0xDE: // 0x0B17C0DE = BC wraper + if (magic[1] == (char)0xC0 && magic[2] == (char)0x17 && + magic[3] == (char)0x0B) + return Bitcode_FileType; + break; + case 'B': + if (magic[1] == 'C' && magic[2] == (char)0xC0 && magic[3] == (char)0xDE) + return Bitcode_FileType; break; - case '!': - if (length >= 8) { + if (length >= 8) if (memcmp(magic,"!\n",8) == 0) - return ArchiveFileType; + return Archive_FileType; + break; + + case '\177': + if (magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F') { + if (length >= 18 && magic[17] == 0) + switch (magic[16]) { + default: break; + case 1: return ELF_Relocatable_FileType; + case 2: return ELF_Executable_FileType; + case 3: return ELF_SharedObject_FileType; + case 4: return ELF_Core_FileType; + } + } + break; + + case 0xCA: + if (magic[1] == char(0xFE) && magic[2] == char(0xBA) && + magic[3] == char(0xBE)) { + // This is complicated by an overlap with Java class files. + // See the Mach-O section in /usr/share/file/magic for details. + if (length >= 8 && magic[7] < 43) + // FIXME: Universal Binary of any type. + return Mach_O_DynamicallyLinkedSharedLib_FileType; } break; + case 0xFE: + case 0xCE: { + uint16_t type = 0; + if (magic[0] == char(0xFE) && magic[1] == char(0xED) && + magic[2] == char(0xFA) && magic[3] == char(0xCE)) { + /* Native endian */ + if (length >= 16) type = magic[14] << 8 | magic[15]; + } else if (magic[0] == char(0xCE) && magic[1] == char(0xFA) && + magic[2] == char(0xED) && magic[3] == char(0xFE)) { + /* Reverse endian */ + if (length >= 14) type = magic[13] << 8 | magic[12]; + } + switch (type) { + default: break; + case 1: return Mach_O_Object_FileType; + case 2: return Mach_O_Executable_FileType; + case 3: return Mach_O_FixedVirtualMemorySharedLib_FileType; + case 4: return Mach_O_Core_FileType; + case 5: return Mach_O_PreloadExectuable_FileType; + case 6: return Mach_O_DynamicallyLinkedSharedLib_FileType; + case 7: return Mach_O_DynamicLinker_FileType; + case 8: return Mach_O_Bundle_FileType; + case 9: return Mach_O_DynamicallyLinkedSharedLibStub_FileType; + case 10: break; // FIXME: MH_DSYM companion file with only debug. + } + break; + } + case 0xF0: // PowerPC Windows + case 0x83: // Alpha 32-bit + case 0x84: // Alpha 64-bit + case 0x66: // MPS R4000 Windows + case 0x50: // mc68K + case 0x4c: // 80386 Windows + if (magic[1] == 0x01) + return COFF_FileType; + + case 0x90: // PA-RISC Windows + case 0x68: // mc68K Windows + if (magic[1] == 0x02) + return COFF_FileType; + break; + case 0x64: // x86-64 Windows. + if (magic[1] == char(0x86)) + return COFF_FileType; + break; + default: break; } - return UnknownFileType; + return Unknown_FileType; } bool Path::isArchive() const { - if (readable()) - return hasMagicNumber("!\012"); - return false; + return hasMagicNumber("!\012"); } bool Path::isDynamicLibrary() const { - if (readable()) - return hasMagicNumber("\177ELF"); + std::string Magic; + if (getMagicNumber(Magic, 64)) + switch (IdentifyFileType(Magic.c_str(), + static_cast(Magic.length()))) { + default: return false; + case Mach_O_FixedVirtualMemorySharedLib_FileType: + case Mach_O_DynamicallyLinkedSharedLib_FileType: + case Mach_O_DynamicallyLinkedSharedLibStub_FileType: + case ELF_SharedObject_FileType: + case COFF_FileType: return true; + } + + return false; +} + +bool +Path::isObjectFile() const { + std::string Magic; + if (getMagicNumber(Magic, 64)) + if (IdentifyFileType(Magic.c_str(), + static_cast(Magic.length())) + != Unknown_FileType) { + // Everything in LLVMFileType is currently an object file. + return true; + } + return false; } @@ -80,10 +180,10 @@ Path::FindLibrary(std::string& name) { GetSystemLibraryPaths(LibPaths); for (unsigned i = 0; i < LibPaths.size(); ++i) { sys::Path FullPath(LibPaths[i]); - FullPath.appendFile("lib" + name + LTDL_SHLIB_EXT); + FullPath.appendComponent("lib" + name + LTDL_SHLIB_EXT); if (FullPath.isDynamicLibrary()) return FullPath; - FullPath.elideSuffix(); + FullPath.eraseSuffix(); FullPath.appendSuffix("a"); if (FullPath.isArchive()) return FullPath; @@ -91,15 +191,88 @@ Path::FindLibrary(std::string& name) { return sys::Path(); } -std::string -Path::GetDLLSuffix() { +StringRef Path::GetDLLSuffix() { return LTDL_SHLIB_EXT; } +bool +Path::isBitcodeFile() const { + std::string actualMagic; + if (!getMagicNumber(actualMagic, 4)) + return false; + LLVMFileType FT = + IdentifyFileType(actualMagic.c_str(), + static_cast(actualMagic.length())); + return FT == Bitcode_FileType; } -// Include the truly platform-specific parts of this class. +bool Path::hasMagicNumber(StringRef Magic) const { + std::string actualMagic; + if (getMagicNumber(actualMagic, static_cast(Magic.size()))) + return Magic == actualMagic; + return false; +} + +static void getPathList(const char*path, std::vector& Paths) { + const char* at = path; + const char* delim = strchr(at, PathSeparator); + Path tmpPath; + while (delim != 0) { + std::string tmp(at, size_t(delim-at)); + if (tmpPath.set(tmp)) + if (tmpPath.canRead()) + Paths.push_back(tmpPath); + at = delim + 1; + delim = strchr(at, PathSeparator); + } + + if (*at != 0) + if (tmpPath.set(std::string(at))) + if (tmpPath.canRead()) + Paths.push_back(tmpPath); +} + +static StringRef getDirnameCharSep(StringRef path, const char *Sep) { + assert(Sep[0] != '\0' && Sep[1] == '\0' && + "Sep must be a 1-character string literal."); + if (path.empty()) + return "."; + + // If the path is all slashes, return a single slash. + // Otherwise, remove all trailing slashes. + signed pos = static_cast(path.size()) - 1; + + while (pos >= 0 && path[pos] == Sep[0]) + --pos; + + if (pos < 0) + return path[0] == Sep[0] ? Sep : "."; + + // Any slashes left? + signed i = 0; + + while (i < pos && path[i] != Sep[0]) + ++i; + + if (i == pos) // No slashes? Return "." + return "."; + + // There is at least one slash left. Remove all trailing non-slashes. + while (pos >= 0 && path[pos] != Sep[0]) + --pos; + + // Remove any trailing slashes. + while (pos >= 0 && path[pos] == Sep[0]) + --pos; + + if (pos < 0) + return path[0] == Sep[0] ? Sep : "."; + + return path.substr(0, pos+1); +} + +// Include the truly platform-specific parts of this class. #if defined(LLVM_ON_UNIX) #include "Unix/Path.inc" #endif