#include "llvm/Support/Path.h"
#include "llvm/Config/config.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/FileSystem.h"
#include <cassert>
#include <cstring>
#include <ostream>
using namespace llvm;
using namespace sys;
+namespace {
+using support::ulittle32_t;
+}
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only TRULY operating system
return path < that.path;
}
-Path
-Path::GetLLVMConfigDir() {
- Path result;
-#ifdef LLVM_ETCDIR
- if (result.set(LLVM_ETCDIR))
- return result;
-#endif
- return GetLLVMDefaultConfigDir();
-}
-
LLVMFileType
sys::IdentifyFileType(const char *magic, unsigned length) {
assert(magic && "Invalid magic number string");
case '\177':
if (magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F') {
- if (length >= 18 && magic[17] == 0)
- switch (magic[16]) {
+ bool Data2MSB = magic[5] == 2;
+ unsigned high = Data2MSB ? 16 : 17;
+ unsigned low = Data2MSB ? 17 : 16;
+ if (length >= 18 && magic[high] == 0)
+ switch (magic[low]) {
default: break;
case 1: return ELF_Relocatable_FileType;
case 2: return ELF_Executable_FileType;
}
break;
+ // The two magic numbers for mach-o are:
+ // 0xfeedface - 32-bit mach-o
+ // 0xfeedfacf - 64-bit mach-o
case 0xFE:
- case 0xCE: {
+ case 0xCE:
+ case 0xCF: {
uint16_t type = 0;
if (magic[0] == char(0xFE) && magic[1] == char(0xED) &&
- magic[2] == char(0xFA) && magic[3] == char(0xCE)) {
+ magic[2] == char(0xFA) &&
+ (magic[3] == char(0xCE) || magic[3] == char(0xCF))) {
/* 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)) {
+ } else if ((magic[0] == char(0xCE) || magic[0] == char(0xCF)) &&
+ magic[1] == char(0xFA) && magic[2] == char(0xED) &&
+ magic[3] == char(0xFE)) {
/* Reverse endian */
if (length >= 14) type = magic[13] << 8 | magic[12];
}
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.
+ case 10: return Mach_O_DSYMCompanion_FileType;
}
break;
}
if (magic[1] == 0x02)
return COFF_FileType;
break;
+
+ case 0x4d: // Possible MS-DOS stub on Windows PE file
+ if (magic[1] == 0x5a) {
+ uint32_t off = *reinterpret_cast<const ulittle32_t *>(magic + 0x3c);
+ // PE/COFF file, either EXE or DLL.
+ if (off < length && memcmp(magic + off, "PE\0\0",4) == 0)
+ return COFF_FileType;
+ }
+ break;
+
case 0x64: // x86-64 Windows.
if (magic[1] == char(0x86))
return COFF_FileType;
bool
Path::isArchive() const {
- std::string Magic;
- if (getMagicNumber(Magic, 8))
- if (IdentifyFileType(Magic.c_str(), Magic.length()) == Archive_FileType)
- return true;
- return false;
+ fs::file_magic type;
+ if (fs::identify_magic(str(), type))
+ return false;
+ return type == fs::file_magic::archive;
}
bool
Path::isDynamicLibrary() const {
- std::string Magic;
- if (getMagicNumber(Magic, 64))
- switch (IdentifyFileType(Magic.c_str(),
- static_cast<unsigned>(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;
+ fs::file_magic type;
+ if (fs::identify_magic(str(), type))
+ return false;
+ switch (type) {
+ default: return false;
+ case fs::file_magic::macho_fixed_virtual_memory_shared_lib:
+ case fs::file_magic::macho_dynamically_linked_shared_lib:
+ case fs::file_magic::macho_dynamically_linked_shared_lib_stub:
+ case fs::file_magic::elf_shared_object:
+ case fs::file_magic::pecoff_executable: return true;
+ }
}
bool
Path::isObjectFile() const {
- std::string Magic;
- if (getMagicNumber(Magic, 64))
- if (IdentifyFileType(Magic.c_str(),
- static_cast<unsigned>(Magic.length()))
- != Unknown_FileType) {
- // Everything in LLVMFileType is currently an object file.
- return true;
- }
-
- return false;
+ fs::file_magic type;
+ if (fs::identify_magic(str(), type) || type == fs::file_magic::unknown)
+ return false;
+ return true;
}
Path
bool
Path::isBitcodeFile() const {
- std::string actualMagic;
- if (!getMagicNumber(actualMagic, 4))
+ fs::file_magic type;
+ if (fs::identify_magic(str(), type))
return false;
- LLVMFileType FT =
- IdentifyFileType(actualMagic.c_str(),
- static_cast<unsigned>(actualMagic.length()));
- return FT == Bitcode_FileType;
+ return type == fs::file_magic::bitcode;
}
bool Path::hasMagicNumber(StringRef Magic) const {