LLVM  9.0.0svn
Magic.cpp
Go to the documentation of this file.
1 //===- llvm/BinaryFormat/Magic.cpp - File magic identification --*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
11 #include "llvm/BinaryFormat/COFF.h"
12 #include "llvm/BinaryFormat/ELF.h"
14 #include "llvm/Support/Endian.h"
17 
18 #if !defined(_MSC_VER) && !defined(__MINGW32__)
19 #include <unistd.h>
20 #else
21 #include <io.h>
22 #endif
23 
24 using namespace llvm;
25 using namespace llvm::support::endian;
26 using namespace llvm::sys::fs;
27 
28 template <size_t N>
29 static bool startswith(StringRef Magic, const char (&S)[N]) {
30  return Magic.startswith(StringRef(S, N - 1));
31 }
32 
33 /// Identify the magic in magic.
35  if (Magic.size() < 4)
36  return file_magic::unknown;
37  switch ((unsigned char)Magic[0]) {
38  case 0x00: {
39  // COFF bigobj, CL.exe's LTO object file, or short import library file
40  if (startswith(Magic, "\0\0\xFF\xFF")) {
41  size_t MinSize =
43  if (Magic.size() < MinSize)
45 
46  const char *Start = Magic.data() + offsetof(COFF::BigObjHeader, UUID);
47  if (memcmp(Start, COFF::BigObjMagic, sizeof(COFF::BigObjMagic)) == 0)
49  if (memcmp(Start, COFF::ClGlObjMagic, sizeof(COFF::BigObjMagic)) == 0)
52  }
53  // Windows resource file
54  if (Magic.size() >= sizeof(COFF::WinResMagic) &&
55  memcmp(Magic.data(), COFF::WinResMagic, sizeof(COFF::WinResMagic)) == 0)
57  // 0x0000 = COFF unknown machine type
58  if (Magic[1] == 0)
60  if (startswith(Magic, "\0asm"))
62  break;
63  }
64 
65  case 0x01:
66  // XCOFF format
67  if (startswith(Magic, "\x01\xDF"))
69  break;
70 
71  case 0xDE: // 0x0B17C0DE = BC wraper
72  if (startswith(Magic, "\xDE\xC0\x17\x0B"))
73  return file_magic::bitcode;
74  break;
75  case 'B':
76  if (startswith(Magic, "BC\xC0\xDE"))
77  return file_magic::bitcode;
78  break;
79  case '!':
80  if (startswith(Magic, "!<arch>\n") || startswith(Magic, "!<thin>\n"))
81  return file_magic::archive;
82  break;
83 
84  case '\177':
85  if (startswith(Magic, "\177ELF") && Magic.size() >= 18) {
86  bool Data2MSB = Magic[5] == 2;
87  unsigned high = Data2MSB ? 16 : 17;
88  unsigned low = Data2MSB ? 17 : 16;
89  if (Magic[high] == 0) {
90  switch (Magic[low]) {
91  default:
92  return file_magic::elf;
93  case 1:
95  case 2:
97  case 3:
99  case 4:
100  return file_magic::elf_core;
101  }
102  }
103  // It's still some type of ELF file.
104  return file_magic::elf;
105  }
106  break;
107 
108  case 0xCA:
109  if (startswith(Magic, "\xCA\xFE\xBA\xBE") ||
110  startswith(Magic, "\xCA\xFE\xBA\xBF")) {
111  // This is complicated by an overlap with Java class files.
112  // See the Mach-O section in /usr/share/file/magic for details.
113  if (Magic.size() >= 8 && Magic[7] < 43)
115  }
116  break;
117 
118  // The two magic numbers for mach-o are:
119  // 0xfeedface - 32-bit mach-o
120  // 0xfeedfacf - 64-bit mach-o
121  case 0xFE:
122  case 0xCE:
123  case 0xCF: {
124  uint16_t type = 0;
125  if (startswith(Magic, "\xFE\xED\xFA\xCE") ||
126  startswith(Magic, "\xFE\xED\xFA\xCF")) {
127  /* Native endian */
128  size_t MinSize;
129  if (Magic[3] == char(0xCE))
130  MinSize = sizeof(MachO::mach_header);
131  else
132  MinSize = sizeof(MachO::mach_header_64);
133  if (Magic.size() >= MinSize)
134  type = Magic[12] << 24 | Magic[13] << 12 | Magic[14] << 8 | Magic[15];
135  } else if (startswith(Magic, "\xCE\xFA\xED\xFE") ||
136  startswith(Magic, "\xCF\xFA\xED\xFE")) {
137  /* Reverse endian */
138  size_t MinSize;
139  if (Magic[0] == char(0xCE))
140  MinSize = sizeof(MachO::mach_header);
141  else
142  MinSize = sizeof(MachO::mach_header_64);
143  if (Magic.size() >= MinSize)
144  type = Magic[15] << 24 | Magic[14] << 12 | Magic[13] << 8 | Magic[12];
145  }
146  switch (type) {
147  default:
148  break;
149  case 1:
151  case 2:
153  case 3:
155  case 4:
156  return file_magic::macho_core;
157  case 5:
159  case 6:
161  case 7:
163  case 8:
165  case 9:
167  case 10:
169  case 11:
171  }
172  break;
173  }
174  case 0xF0: // PowerPC Windows
175  case 0x83: // Alpha 32-bit
176  case 0x84: // Alpha 64-bit
177  case 0x66: // MPS R4000 Windows
178  case 0x50: // mc68K
179  case 0x4c: // 80386 Windows
180  case 0xc4: // ARMNT Windows
181  if (Magic[1] == 0x01)
184 
185  case 0x90: // PA-RISC Windows
186  case 0x68: // mc68K Windows
187  if (Magic[1] == 0x02)
189  break;
190 
191  case 'M': // Possible MS-DOS stub on Windows PE file, MSF/PDB file or a
192  // Minidump file.
193  if (startswith(Magic, "MZ") && Magic.size() >= 0x3c + 4) {
194  uint32_t off = read32le(Magic.data() + 0x3c);
195  // PE/COFF file, either EXE or DLL.
196  if (Magic.substr(off).startswith(
199  }
200  if (Magic.startswith("Microsoft C/C++ MSF 7.00\r\n"))
201  return file_magic::pdb;
202  if (startswith(Magic, "MDMP"))
203  return file_magic::minidump;
204  break;
205 
206  case 0x64: // x86-64 or ARM64 Windows.
207  if (Magic[1] == char(0x86) || Magic[1] == char(0xaa))
209  break;
210 
211  default:
212  break;
213  }
214  return file_magic::unknown;
215 }
216 
217 std::error_code llvm::identify_magic(const Twine &Path, file_magic &Result) {
218  auto FileOrError = MemoryBuffer::getFile(Path, -1LL, false);
219  if (!FileOrError)
220  return FileOrError.getError();
221 
222  std::unique_ptr<MemoryBuffer> FileBuffer = std::move(*FileOrError);
223  Result = identify_magic(FileBuffer->getBuffer());
224 
225  return std::error_code();
226 }
32-bit XCOFF object file
Definition: Magic.h:48
Mach-O Object file.
Definition: Magic.h:30
ELF core image.
Definition: Magic.h:29
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Microsoft cl.exe&#39;s intermediate code file.
Definition: Magic.h:43
ELF dynamically linked shared lib.
Definition: Magic.h:28
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:256
Windows compiled resource file (.res)
Definition: Magic.h:47
Mach-O Bundle file.
Definition: Magic.h:37
Mach-O Preloaded Executable.
Definition: Magic.h:34
static const char BigObjMagic[]
Definition: COFF.h:38
Bitcode file.
Definition: Magic.h:23
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
Definition: Magic.cpp:34
The Mach-O dynamic linker.
Definition: Magic.h:36
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:578
ELF Relocatable object file.
Definition: Magic.h:26
static bool startswith(StringRef Magic, const char(&S)[N])
Definition: Magic.cpp:29
Windows minidump file.
Definition: Magic.h:42
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:130
COFF import library.
Definition: Magic.h:45
Mach-O universal binary.
Definition: Magic.h:41
static const char ClGlObjMagic[]
Definition: COFF.h:43
Mach-O Core File.
Definition: Magic.h:33
Mach-O dSYM companion file.
Definition: Magic.h:39
#define offsetof(TYPE, MEMBER)
PECOFF executable file.
Definition: Magic.h:46
std::pair< llvm::MachO::Architecture, std::string > UUID
COFF object file.
Definition: Magic.h:44
static const char *const Magic
Definition: Archive.cpp:41
Mach-O kext bundle file.
Definition: Magic.h:40
ar style archive file
Definition: Magic.h:24
ELF Unknown type.
Definition: Magic.h:25
ELF Executable image.
Definition: Magic.h:27
WebAssembly Object file.
Definition: Magic.h:49
Merge contiguous icmps into a memcmp
Definition: MergeICmps.cpp:927
#define N
uint32_t read32le(const void *P)
Definition: Endian.h:383
static const char PEMagic[]
Definition: COFF.h:36
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatile=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
static const char WinResMagic[]
Definition: COFF.h:49
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:122
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:250
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Mach-O Executable.
Definition: Magic.h:31
Unrecognized file.
Definition: Magic.h:22
Windows PDB debug info file.
Definition: Magic.h:50
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
Definition: Magic.h:20