X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSystem%2FPath.cpp;h=ae166a574d1042a87b311b41063d180ed1055a1b;hb=5c0db76cf262bec095c6b52ba0aa6e095f9f8298;hp=e8fd5f29634c91358c02a2c3f3d34a5ab495ffe0;hpb=9b01cc0ede3bfef32ce46159670dedc3e9769a64;p=oota-llvm.git diff --git a/lib/System/Path.cpp b/lib/System/Path.cpp index e8fd5f29634..ae166a574d1 100644 --- a/lib/System/Path.cpp +++ b/lib/System/Path.cpp @@ -24,9 +24,12 @@ using namespace sys; //=== independent code. //===----------------------------------------------------------------------===// -std::ostream& llvm::operator<<(std::ostream &strm, const sys::Path &aPath) { - strm << aPath.toString(); - return strm; +bool Path::operator==(const Path &that) const { + return path == that.path; +} + +bool Path::operator<(const Path& that) const { + return path < that.path; } Path @@ -40,10 +43,15 @@ Path::GetLLVMConfigDir() { } 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]) { + 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; @@ -53,7 +61,7 @@ sys::IdentifyFileType(const char*magic, unsigned length) { if (memcmp(magic,"!\n",8) == 0) return Archive_FileType; break; - + case '\177': if (magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F') { if (length >= 18 && magic[17] == 0) @@ -68,29 +76,43 @@ sys::IdentifyFileType(const char*magic, unsigned length) { break; case 0xCA: - // This is complicated by an overlap with Java class files. - // See the Mach-O section in /usr/share/file/magic for details. - if (magic[1] == char(0xFE) && magic[2] == char(0xBA) && + if (magic[1] == char(0xFE) && magic[2] == char(0xBA) && magic[3] == char(0xBE)) { - return Mach_O_DynamicallyLinkedSharedLib_FileType; - - // FIXME: How does this work? - if (length >= 14 && magic[13] == 0) - switch (magic[12]) { - 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; - } + // 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 @@ -105,6 +127,10 @@ sys::IdentifyFileType(const char*magic, unsigned length) { if (magic[1] == 0x02) return COFF_FileType; break; + case 0x64: // x86-64 Windows. + if (magic[1] == char(0x86)) + return COFF_FileType; + break; default: break; @@ -114,25 +140,37 @@ sys::IdentifyFileType(const char*magic, unsigned length) { bool Path::isArchive() const { - if (canRead()) - return hasMagicNumber("!\012"); - return false; + return hasMagicNumber("!\012"); } bool Path::isDynamicLibrary() const { - if (canRead()) { - std::string Magic; - if (getMagicNumber(Magic, 64)) - switch (IdentifyFileType(Magic.c_str(), 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; - } - } + 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; } @@ -153,7 +191,7 @@ Path::FindLibrary(std::string& name) { return sys::Path(); } -std::string Path::GetDLLSuffix() { +StringRef Path::GetDLLSuffix() { return LTDL_SHLIB_EXT; } @@ -162,21 +200,19 @@ Path::isBitcodeFile() const { std::string actualMagic; if (!getMagicNumber(actualMagic, 4)) return false; - return actualMagic == "BC\xC0\xDE"; + LLVMFileType FT = + IdentifyFileType(actualMagic.c_str(), + static_cast(actualMagic.length())); + return FT == Bitcode_FileType; } -bool Path::hasMagicNumber(const std::string &Magic) const { +bool Path::hasMagicNumber(StringRef Magic) const { std::string actualMagic; - if (getMagicNumber(actualMagic, Magic.size())) + if (getMagicNumber(actualMagic, static_cast(Magic.size()))) return Magic == actualMagic; return false; } -std::string -Path::getSuffix() const { - return path.substr(path.rfind('.') + 1); -} - static void getPathList(const char*path, std::vector& Paths) { const char* at = path; const char* delim = strchr(at, PathSeparator); @@ -196,42 +232,43 @@ static void getPathList(const char*path, std::vector& Paths) { Paths.push_back(tmpPath); } -static std::string getDirnameCharSep(const std::string& path, char Sep) { - +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 = path.size() - 1; - - while (pos >= 0 && path[pos] == Sep) + + signed pos = static_cast(path.size()) - 1; + + while (pos >= 0 && path[pos] == Sep[0]) --pos; - + if (pos < 0) - return path[0] == Sep ? std::string(1, Sep) : std::string("."); - + return path[0] == Sep[0] ? Sep : "."; + // Any slashes left? signed i = 0; - - while (i < pos && path[i] != Sep) + + 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) + + // 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) + while (pos >= 0 && path[pos] == Sep[0]) --pos; - + if (pos < 0) - return path[0] == Sep ? std::string(1, Sep) : std::string("."); - + return path[0] == Sep[0] ? Sep : "."; + return path.substr(0, pos+1); }