LLVM  15.0.0git
COFFImportFile.cpp
Go to the documentation of this file.
1 //===- COFFImportFile.cpp - COFF short import file implementation ---------===//
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 //
9 // This file defines the writeImportLibrary function.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/Twine.h"
16 #include "llvm/Object/Archive.h"
18 #include "llvm/Object/COFF.h"
19 #include "llvm/Support/Allocator.h"
20 #include "llvm/Support/Endian.h"
21 #include "llvm/Support/Error.h"
23 #include "llvm/Support/Path.h"
24 
25 #include <cstdint>
26 #include <string>
27 #include <vector>
28 
29 using namespace llvm::COFF;
30 using namespace llvm::object;
31 using namespace llvm;
32 
33 namespace llvm {
34 namespace object {
35 
37  switch (Machine) {
38  default:
39  llvm_unreachable("unsupported machine");
42  return false;
45  return true;
46  }
47 }
48 
50  switch (Machine) {
51  default:
52  llvm_unreachable("unsupported machine");
61  }
62 }
63 
64 template <class T> static void append(std::vector<uint8_t> &B, const T &Data) {
65  size_t S = B.size();
66  B.resize(S + sizeof(T));
67  memcpy(&B[S], &Data, sizeof(T));
68 }
69 
70 static void writeStringTable(std::vector<uint8_t> &B,
72  // The COFF string table consists of a 4-byte value which is the size of the
73  // table, including the length field itself. This value is followed by the
74  // string content itself, which is an array of null-terminated C-style
75  // strings. The termination is important as they are referenced to by offset
76  // by the symbol entity in the file format.
77 
78  size_t Pos = B.size();
79  size_t Offset = B.size();
80 
81  // Skip over the length field, we will fill it in later as we will have
82  // computed the length while emitting the string content itself.
83  Pos += sizeof(uint32_t);
84 
85  for (const auto &S : Strings) {
86  B.resize(Pos + S.length() + 1);
87  strcpy(reinterpret_cast<char *>(&B[Pos]), S.c_str());
88  Pos += S.length() + 1;
89  }
90 
91  // Backfill the length of the table now that it has been computed.
92  support::ulittle32_t Length(B.size() - Offset);
93  support::endian::write32le(&B[Offset], Length);
94 }
95 
97  MachineTypes Machine, bool MinGW) {
98  // A decorated stdcall function in MSVC is exported with the
99  // type IMPORT_NAME, and the exported function name includes the
100  // the leading underscore. In MinGW on the other hand, a decorated
101  // stdcall function still omits the underscore (IMPORT_NAME_NOPREFIX).
102  // See the comment in isDecorated in COFFModuleDefinition.cpp for more
103  // details.
104  if (ExtName.startswith("_") && ExtName.contains('@') && !MinGW)
105  return IMPORT_NAME;
106  if (Sym != ExtName)
107  return IMPORT_NAME_UNDECORATE;
108  if (Machine == IMAGE_FILE_MACHINE_I386 && Sym.startswith("_"))
109  return IMPORT_NAME_NOPREFIX;
110  return IMPORT_NAME;
111 }
112 
114  StringRef To) {
115  size_t Pos = S.find(From);
116 
117  // From and To may be mangled, but substrings in S may not.
118  if (Pos == StringRef::npos && From.startswith("_") && To.startswith("_")) {
119  From = From.substr(1);
120  To = To.substr(1);
121  Pos = S.find(From);
122  }
123 
124  if (Pos == StringRef::npos) {
125  return make_error<StringError>(
126  StringRef(Twine(S + ": replacing '" + From +
127  "' with '" + To + "' failed").str()), object_error::parse_failed);
128  }
129 
130  return (Twine(S.substr(0, Pos)) + To + S.substr(Pos + From.size())).str();
131 }
132 
133 static const std::string NullImportDescriptorSymbolName =
134  "__NULL_IMPORT_DESCRIPTOR";
135 
136 namespace {
137 // This class constructs various small object files necessary to support linking
138 // symbols imported from a DLL. The contents are pretty strictly defined and
139 // nearly entirely static. The details of the structures files are defined in
140 // WINNT.h and the PE/COFF specification.
141 class ObjectFactory {
142  using u16 = support::ulittle16_t;
143  using u32 = support::ulittle32_t;
145  BumpPtrAllocator Alloc;
146  StringRef ImportName;
148  std::string ImportDescriptorSymbolName;
149  std::string NullThunkSymbolName;
150 
151 public:
152  ObjectFactory(StringRef S, MachineTypes M)
153  : Machine(M), ImportName(S), Library(S.drop_back(4)),
154  ImportDescriptorSymbolName(("__IMPORT_DESCRIPTOR_" + Library).str()),
155  NullThunkSymbolName(("\x7f" + Library + "_NULL_THUNK_DATA").str()) {}
156 
157  // Creates an Import Descriptor. This is a small object file which contains a
158  // reference to the terminators and contains the library name (entry) for the
159  // import name table. It will force the linker to construct the necessary
160  // structure to import symbols from the DLL.
161  NewArchiveMember createImportDescriptor(std::vector<uint8_t> &Buffer);
162 
163  // Creates a NULL import descriptor. This is a small object file whcih
164  // contains a NULL import descriptor. It is used to terminate the imports
165  // from a specific DLL.
166  NewArchiveMember createNullImportDescriptor(std::vector<uint8_t> &Buffer);
167 
168  // Create a NULL Thunk Entry. This is a small object file which contains a
169  // NULL Import Address Table entry and a NULL Import Lookup Table Entry. It
170  // is used to terminate the IAT and ILT.
171  NewArchiveMember createNullThunk(std::vector<uint8_t> &Buffer);
172 
173  // Create a short import file which is described in PE/COFF spec 7. Import
174  // Library Format.
175  NewArchiveMember createShortImport(StringRef Sym, uint16_t Ordinal,
177 
178  // Create a weak external file which is described in PE/COFF Aux Format 3.
179  NewArchiveMember createWeakExternal(StringRef Sym, StringRef Weak, bool Imp);
180 };
181 } // namespace
182 
184 ObjectFactory::createImportDescriptor(std::vector<uint8_t> &Buffer) {
185  const uint32_t NumberOfSections = 2;
186  const uint32_t NumberOfSymbols = 7;
187  const uint32_t NumberOfRelocations = 3;
188 
189  // COFF Header
190  coff_file_header Header{
191  u16(Machine),
192  u16(NumberOfSections),
193  u32(0),
194  u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
195  // .idata$2
197  NumberOfRelocations * sizeof(coff_relocation) +
198  // .idata$4
199  (ImportName.size() + 1)),
200  u32(NumberOfSymbols),
201  u16(0),
203  };
204  append(Buffer, Header);
205 
206  // Section Header Table
207  const coff_section SectionTable[NumberOfSections] = {
208  {{'.', 'i', 'd', 'a', 't', 'a', '$', '2'},
209  u32(0),
210  u32(0),
212  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section)),
213  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
215  u32(0),
216  u16(NumberOfRelocations),
217  u16(0),
220  {{'.', 'i', 'd', 'a', 't', 'a', '$', '6'},
221  u32(0),
222  u32(0),
223  u32(ImportName.size() + 1),
224  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
226  NumberOfRelocations * sizeof(coff_relocation)),
227  u32(0),
228  u32(0),
229  u16(0),
230  u16(0),
233  };
234  append(Buffer, SectionTable);
235 
236  // .idata$2
237  const coff_import_directory_table_entry ImportDescriptor{
238  u32(0), u32(0), u32(0), u32(0), u32(0),
239  };
240  append(Buffer, ImportDescriptor);
241 
242  const coff_relocation RelocationTable[NumberOfRelocations] = {
243  {u32(offsetof(coff_import_directory_table_entry, NameRVA)), u32(2),
245  {u32(offsetof(coff_import_directory_table_entry, ImportLookupTableRVA)),
246  u32(3), u16(getImgRelRelocation(Machine))},
247  {u32(offsetof(coff_import_directory_table_entry, ImportAddressTableRVA)),
248  u32(4), u16(getImgRelRelocation(Machine))},
249  };
250  append(Buffer, RelocationTable);
251 
252  // .idata$6
253  auto S = Buffer.size();
254  Buffer.resize(S + ImportName.size() + 1);
255  memcpy(&Buffer[S], ImportName.data(), ImportName.size());
256  Buffer[S + ImportName.size()] = '\0';
257 
258  // Symbol Table
259  coff_symbol16 SymbolTable[NumberOfSymbols] = {
260  {{{0, 0, 0, 0, 0, 0, 0, 0}},
261  u32(0),
262  u16(1),
263  u16(0),
265  0},
266  {{{'.', 'i', 'd', 'a', 't', 'a', '$', '2'}},
267  u32(0),
268  u16(1),
269  u16(0),
271  0},
272  {{{'.', 'i', 'd', 'a', 't', 'a', '$', '6'}},
273  u32(0),
274  u16(2),
275  u16(0),
277  0},
278  {{{'.', 'i', 'd', 'a', 't', 'a', '$', '4'}},
279  u32(0),
280  u16(0),
281  u16(0),
283  0},
284  {{{'.', 'i', 'd', 'a', 't', 'a', '$', '5'}},
285  u32(0),
286  u16(0),
287  u16(0),
289  0},
290  {{{0, 0, 0, 0, 0, 0, 0, 0}},
291  u32(0),
292  u16(0),
293  u16(0),
295  0},
296  {{{0, 0, 0, 0, 0, 0, 0, 0}},
297  u32(0),
298  u16(0),
299  u16(0),
301  0},
302  };
303  // TODO: Name.Offset.Offset here and in the all similar places below
304  // suggests a names refactoring. Maybe StringTableOffset.Value?
305  SymbolTable[0].Name.Offset.Offset =
306  sizeof(uint32_t);
307  SymbolTable[5].Name.Offset.Offset =
308  sizeof(uint32_t) + ImportDescriptorSymbolName.length() + 1;
309  SymbolTable[6].Name.Offset.Offset =
310  sizeof(uint32_t) + ImportDescriptorSymbolName.length() + 1 +
311  NullImportDescriptorSymbolName.length() + 1;
312  append(Buffer, SymbolTable);
313 
314  // String Table
315  writeStringTable(Buffer,
316  {ImportDescriptorSymbolName, NullImportDescriptorSymbolName,
317  NullThunkSymbolName});
318 
319  StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
320  return {MemoryBufferRef(F, ImportName)};
321 }
322 
324 ObjectFactory::createNullImportDescriptor(std::vector<uint8_t> &Buffer) {
325  const uint32_t NumberOfSections = 1;
326  const uint32_t NumberOfSymbols = 1;
327 
328  // COFF Header
329  coff_file_header Header{
330  u16(Machine),
331  u16(NumberOfSections),
332  u32(0),
333  u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
334  // .idata$3
336  u32(NumberOfSymbols),
337  u16(0),
339  };
340  append(Buffer, Header);
341 
342  // Section Header Table
343  const coff_section SectionTable[NumberOfSections] = {
344  {{'.', 'i', 'd', 'a', 't', 'a', '$', '3'},
345  u32(0),
346  u32(0),
348  u32(sizeof(coff_file_header) +
349  (NumberOfSections * sizeof(coff_section))),
350  u32(0),
351  u32(0),
352  u16(0),
353  u16(0),
356  };
357  append(Buffer, SectionTable);
358 
359  // .idata$3
360  const coff_import_directory_table_entry ImportDescriptor{
361  u32(0), u32(0), u32(0), u32(0), u32(0),
362  };
363  append(Buffer, ImportDescriptor);
364 
365  // Symbol Table
366  coff_symbol16 SymbolTable[NumberOfSymbols] = {
367  {{{0, 0, 0, 0, 0, 0, 0, 0}},
368  u32(0),
369  u16(1),
370  u16(0),
372  0},
373  };
374  SymbolTable[0].Name.Offset.Offset = sizeof(uint32_t);
375  append(Buffer, SymbolTable);
376 
377  // String Table
379 
380  StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
381  return {MemoryBufferRef(F, ImportName)};
382 }
383 
384 NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
385  const uint32_t NumberOfSections = 2;
386  const uint32_t NumberOfSymbols = 1;
387  uint32_t VASize = is32bit(Machine) ? 4 : 8;
388 
389  // COFF Header
390  coff_file_header Header{
391  u16(Machine),
392  u16(NumberOfSections),
393  u32(0),
394  u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
395  // .idata$5
396  VASize +
397  // .idata$4
398  VASize),
399  u32(NumberOfSymbols),
400  u16(0),
402  };
403  append(Buffer, Header);
404 
405  // Section Header Table
406  const coff_section SectionTable[NumberOfSections] = {
407  {{'.', 'i', 'd', 'a', 't', 'a', '$', '5'},
408  u32(0),
409  u32(0),
410  u32(VASize),
411  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section)),
412  u32(0),
413  u32(0),
414  u16(0),
415  u16(0),
420  {{'.', 'i', 'd', 'a', 't', 'a', '$', '4'},
421  u32(0),
422  u32(0),
423  u32(VASize),
424  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
425  VASize),
426  u32(0),
427  u32(0),
428  u16(0),
429  u16(0),
434  };
435  append(Buffer, SectionTable);
436 
437  // .idata$5, ILT
438  append(Buffer, u32(0));
439  if (!is32bit(Machine))
440  append(Buffer, u32(0));
441 
442  // .idata$4, IAT
443  append(Buffer, u32(0));
444  if (!is32bit(Machine))
445  append(Buffer, u32(0));
446 
447  // Symbol Table
448  coff_symbol16 SymbolTable[NumberOfSymbols] = {
449  {{{0, 0, 0, 0, 0, 0, 0, 0}},
450  u32(0),
451  u16(1),
452  u16(0),
454  0},
455  };
456  SymbolTable[0].Name.Offset.Offset = sizeof(uint32_t);
457  append(Buffer, SymbolTable);
458 
459  // String Table
460  writeStringTable(Buffer, {NullThunkSymbolName});
461 
462  StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
463  return {MemoryBufferRef{F, ImportName}};
464 }
465 
466 NewArchiveMember ObjectFactory::createShortImport(StringRef Sym,
467  uint16_t Ordinal,
470  size_t ImpSize = ImportName.size() + Sym.size() + 2; // +2 for NULs
471  size_t Size = sizeof(coff_import_header) + ImpSize;
472  char *Buf = Alloc.Allocate<char>(Size);
473  memset(Buf, 0, Size);
474  char *P = Buf;
475 
476  // Write short import library.
477  auto *Imp = reinterpret_cast<coff_import_header *>(P);
478  P += sizeof(*Imp);
479  Imp->Sig2 = 0xFFFF;
480  Imp->Machine = Machine;
481  Imp->SizeOfData = ImpSize;
482  if (Ordinal > 0)
483  Imp->OrdinalHint = Ordinal;
484  Imp->TypeInfo = (NameType << 2) | ImportType;
485 
486  // Write symbol name and DLL name.
487  memcpy(P, Sym.data(), Sym.size());
488  P += Sym.size() + 1;
489  memcpy(P, ImportName.data(), ImportName.size());
490 
491  return {MemoryBufferRef(StringRef(Buf, Size), ImportName)};
492 }
493 
494 NewArchiveMember ObjectFactory::createWeakExternal(StringRef Sym,
495  StringRef Weak, bool Imp) {
496  std::vector<uint8_t> Buffer;
497  const uint32_t NumberOfSections = 1;
498  const uint32_t NumberOfSymbols = 5;
499 
500  // COFF Header
501  coff_file_header Header{
502  u16(Machine),
503  u16(NumberOfSections),
504  u32(0),
505  u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section))),
506  u32(NumberOfSymbols),
507  u16(0),
508  u16(0),
509  };
510  append(Buffer, Header);
511 
512  // Section Header Table
513  const coff_section SectionTable[NumberOfSections] = {
514  {{'.', 'd', 'r', 'e', 'c', 't', 'v', 'e'},
515  u32(0),
516  u32(0),
517  u32(0),
518  u32(0),
519  u32(0),
520  u32(0),
521  u16(0),
522  u16(0),
524  append(Buffer, SectionTable);
525 
526  // Symbol Table
527  coff_symbol16 SymbolTable[NumberOfSymbols] = {
528  {{{'@', 'c', 'o', 'm', 'p', '.', 'i', 'd'}},
529  u32(0),
530  u16(0xFFFF),
531  u16(0),
533  0},
534  {{{'@', 'f', 'e', 'a', 't', '.', '0', '0'}},
535  u32(0),
536  u16(0xFFFF),
537  u16(0),
539  0},
540  {{{0, 0, 0, 0, 0, 0, 0, 0}},
541  u32(0),
542  u16(0),
543  u16(0),
545  0},
546  {{{0, 0, 0, 0, 0, 0, 0, 0}},
547  u32(0),
548  u16(0),
549  u16(0),
551  1},
552  {{{2, 0, 0, 0, IMAGE_WEAK_EXTERN_SEARCH_ALIAS, 0, 0, 0}},
553  u32(0),
554  u16(0),
555  u16(0),
557  0},
558  };
559  SymbolTable[2].Name.Offset.Offset = sizeof(uint32_t);
560 
561  //__imp_ String Table
562  StringRef Prefix = Imp ? "__imp_" : "";
563  SymbolTable[3].Name.Offset.Offset =
564  sizeof(uint32_t) + Sym.size() + Prefix.size() + 1;
565  append(Buffer, SymbolTable);
566  writeStringTable(Buffer, {(Prefix + Sym).str(),
567  (Prefix + Weak).str()});
568 
569  // Copied here so we can still use writeStringTable
570  char *Buf = Alloc.Allocate<char>(Buffer.size());
571  memcpy(Buf, Buffer.data(), Buffer.size());
572  return {MemoryBufferRef(StringRef(Buf, Buffer.size()), ImportName)};
573 }
574 
577  MachineTypes Machine, bool MinGW) {
578 
579  std::vector<NewArchiveMember> Members;
580  ObjectFactory OF(llvm::sys::path::filename(ImportName), Machine);
581 
582  std::vector<uint8_t> ImportDescriptor;
583  Members.push_back(OF.createImportDescriptor(ImportDescriptor));
584 
585  std::vector<uint8_t> NullImportDescriptor;
586  Members.push_back(OF.createNullImportDescriptor(NullImportDescriptor));
587 
588  std::vector<uint8_t> NullThunk;
589  Members.push_back(OF.createNullThunk(NullThunk));
590 
591  for (COFFShortExport E : Exports) {
592  if (E.Private)
593  continue;
594 
596  if (E.Data)
598  if (E.Constant)
600 
601  StringRef SymbolName = E.SymbolName.empty() ? E.Name : E.SymbolName;
602  ImportNameType NameType = E.Noname
604  : getNameType(SymbolName, E.Name,
605  Machine, MinGW);
606  Expected<std::string> Name = E.ExtName.empty()
607  ? std::string(SymbolName)
608  : replace(SymbolName, E.Name, E.ExtName);
609 
610  if (!Name)
611  return Name.takeError();
612 
613  if (!E.AliasTarget.empty() && *Name != E.AliasTarget) {
614  Members.push_back(OF.createWeakExternal(E.AliasTarget, *Name, false));
615  Members.push_back(OF.createWeakExternal(E.AliasTarget, *Name, true));
616  continue;
617  }
618 
619  Members.push_back(
620  OF.createShortImport(*Name, E.Ordinal, ImportType, NameType));
621  }
622 
623  return writeArchive(Path, Members, /*WriteSymtab*/ true,
625  /*Deterministic*/ true, /*Thin*/ false);
626 }
627 
628 } // namespace object
629 } // namespace llvm
llvm::Check::Size
@ Size
Definition: FileCheck.h:76
llvm::NewArchiveMember
Definition: ArchiveWriter.h:20
llvm::COFF::IMPORT_NAME
@ IMPORT_NAME
The import name is identical to the public symbol name.
Definition: COFF.h:698
llvm::COFF::IMPORT_ORDINAL
@ IMPORT_ORDINAL
Import is by ordinal.
Definition: COFF.h:696
llvm::StringRef::startswith
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:286
llvm::COFF::IMPORT_NAME_UNDECORATE
@ IMPORT_NAME_UNDECORATE
The import name is the public symbol name, but skipping the leading ?, @, or optionally _,...
Definition: COFF.h:704
llvm::object::COFFShortExport
Definition: COFFImportFile.h:70
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::COFF::IMAGE_SCN_ALIGN_4BYTES
@ IMAGE_SCN_ALIGN_4BYTES
Definition: COFF.h:301
llvm::COFF::IMAGE_REL_ARM64_ADDR32NB
@ IMAGE_REL_ARM64_ADDR32NB
Definition: COFF.h:387
llvm::object::is32bit
static bool is32bit(MachineTypes Machine)
Definition: COFFImportFile.cpp:36
llvm::COFF::IMAGE_SYM_CLASS_STATIC
@ IMAGE_SYM_CLASS_STATIC
Static.
Definition: COFF.h:209
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:160
llvm::support::detail::packed_endian_specific_integral
Definition: Endian.h:206
T
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::StringRef::npos
static constexpr size_t npos
Definition: StringRef.h:60
offsetof
#define offsetof(TYPE, MEMBER)
Definition: AMDHSAKernelDescriptor.h:23
Path.h
llvm::support::endian::write32le
void write32le(void *P, uint32_t V)
Definition: Endian.h:416
llvm::object::NullImportDescriptorSymbolName
static const std::string NullImportDescriptorSymbolName
Definition: COFFImportFile.cpp:133
llvm::COFF::IMAGE_SYM_CLASS_EXTERNAL
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
Definition: COFF.h:208
ErrorHandling.h
Allocator.h
llvm::COFF::IMAGE_FILE_MACHINE_AMD64
@ IMAGE_FILE_MACHINE_AMD64
Definition: COFF.h:97
Error.h
llvm::object::StringTableOffset::Offset
support::ulittle32_t Offset
Definition: COFF.h:246
Library
Itanium Name Demangler Library
Definition: README.txt:2
llvm::object::Archive::K_GNU
@ K_GNU
Definition: Archive.h:339
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
COFFImportFile.h
llvm::COFF::IMAGE_REL_I386_DIR32NB
@ IMAGE_REL_I386_DIR32NB
Definition: COFF.h:335
llvm::COFF::IMAGE_FILE_MACHINE_ARMNT
@ IMAGE_FILE_MACHINE_ARMNT
Definition: COFF.h:99
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS
@ IMAGE_WEAK_EXTERN_SEARCH_ALIAS
Definition: COFF.h:441
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::object::coff_file_header
Definition: COFF.h:75
llvm::StringRef::substr
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:611
llvm::COFF::IMAGE_SYM_CLASS_NULL
@ IMAGE_SYM_CLASS_NULL
No symbol.
Definition: COFF.h:206
llvm::COFF::IMAGE_SCN_LNK_INFO
@ IMAGE_SCN_LNK_INFO
Definition: COFF.h:291
llvm::COFF::IMAGE_FILE_MACHINE_I386
@ IMAGE_FILE_MACHINE_I386
Definition: COFF.h:102
llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
@ IMAGE_SCN_CNT_INITIALIZED_DATA
Definition: COFF.h:288
llvm::object
Definition: DWARFDebugLoc.h:25
ArchiveWriter.h
llvm::COFF::IMAGE_SCN_LNK_REMOVE
@ IMAGE_SCN_LNK_REMOVE
Definition: COFF.h:292
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Twine.h
llvm::COFF::IMAGE_SCN_MEM_READ
@ IMAGE_SCN_MEM_READ
Definition: COFF.h:320
llvm::writeArchive
Error writeArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr)
Definition: ArchiveWriter.cpp:823
llvm::replace
void replace(Container &Cont, typename Container::iterator ContIt, typename Container::iterator ContEnd, RandomAccessIterator ValIt, RandomAccessIterator ValEnd)
Given a sequence container Cont, replace the range [ContIt, ContEnd) with the range [ValIt,...
Definition: STLExtras.h:1820
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::COFF::IMAGE_REL_ARM_ADDR32NB
@ IMAGE_REL_ARM_ADDR32NB
Definition: COFF.h:367
llvm::COFF::IMPORT_CONST
@ IMPORT_CONST
Definition: COFF.h:688
llvm::StringRef::contains
LLVM_NODISCARD bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:462
llvm::object::writeStringTable
static void writeStringTable(std::vector< uint8_t > &B, ArrayRef< const std::string > Strings)
Definition: COFFImportFile.cpp:70
NameType
Definition: ItaniumDemangle.h:471
llvm::COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL
@ IMAGE_SYM_CLASS_WEAK_EXTERNAL
Duplicate tag.
Definition: COFF.h:233
llvm::object::coff_symbol
Definition: COFF.h:250
llvm::object::coff_relocation
Definition: COFF.h:474
llvm::object::coff_symbol::Offset
StringTableOffset Offset
Definition: COFF.h:253
llvm::support::ulittle32_t
detail::packed_endian_specific_integral< uint32_t, little, unaligned > ulittle32_t
Definition: Endian.h:272
llvm::COFF::IMAGE_FILE_32BIT_MACHINE
@ IMAGE_FILE_32BIT_MACHINE
Machine is based on a 32bit word architecture.
Definition: COFF.h:144
llvm::COFF::IMPORT_NAME_NOPREFIX
@ IMPORT_NAME_NOPREFIX
The import name is the public symbol name, but skipping the leading ?, @, or optionally _.
Definition: COFF.h:701
llvm::support::ulittle16_t
detail::packed_endian_specific_integral< uint16_t, little, unaligned > ulittle16_t
Definition: Endian.h:270
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
llvm::COFF::IMAGE_SCN_ALIGN_2BYTES
@ IMAGE_SCN_ALIGN_2BYTES
Definition: COFF.h:300
llvm::BumpPtrAllocatorImpl
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:63
ArrayRef.h
llvm::object::writeImportLibrary
Error writeImportLibrary(StringRef ImportName, StringRef Path, ArrayRef< COFFShortExport > Exports, COFF::MachineTypes Machine, bool MinGW)
Definition: COFFImportFile.cpp:575
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::COFF::ImportNameType
ImportNameType
Definition: COFF.h:691
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::COFF::C_Invalid
@ C_Invalid
Definition: COFF.h:123
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::COFF::IMAGE_SCN_ALIGN_8BYTES
@ IMAGE_SCN_ALIGN_8BYTES
Definition: COFF.h:302
uint32_t
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
Archive.h
llvm::object::getImgRelRelocation
static uint16_t getImgRelRelocation(MachineTypes Machine)
Definition: COFFImportFile.cpp:49
llvm::COFF::IMAGE_FILE_MACHINE_ARM64
@ IMAGE_FILE_MACHINE_ARM64
Definition: COFF.h:100
llvm::object::coff_import_directory_table_entry
Definition: COFF.h:555
llvm::StringRef::size
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::AMDGPU::HSAMD::Kernel::Key::SymbolName
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Definition: AMDGPUMetadata.h:386
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::object::coff_symbol::Name
union llvm::object::coff_symbol::@322 Name
uint16_t
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::object::coff_section
Definition: COFF.h:440
llvm::BumpPtrAllocatorImpl::Allocate
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
Definition: Allocator.h:146
llvm::COFF::IMAGE_REL_AMD64_ADDR32NB
@ IMAGE_REL_AMD64_ADDR32NB
Definition: COFF.h:348
llvm::COFF::ImportType
ImportType
Definition: COFF.h:685
llvm::COFF::IMPORT_CODE
@ IMPORT_CODE
Definition: COFF.h:686
llvm::COFF::MachineTypes
MachineTypes
Definition: COFF.h:92
llvm::COFF::IMAGE_SYM_CLASS_SECTION
@ IMAGE_SYM_CLASS_SECTION
Line number, reformatted as symbol.
Definition: COFF.h:232
llvm::COFF::IMPORT_DATA
@ IMPORT_DATA
Definition: COFF.h:687
llvm::sys::path::filename
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
Definition: Path.cpp:577
Machine
COFF::MachineTypes Machine
Definition: COFFYAML.cpp:369
COFF.h
llvm::StringRef::data
const LLVM_NODISCARD char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:149
llvm::object::append
static void append(std::vector< uint8_t > &B, const T &Data)
Definition: COFFImportFile.cpp:64
llvm::object::coff_import_header
Definition: COFF.h:541
From
BlockVerifier::State From
Definition: BlockVerifier.cpp:55
llvm::COFF
Definition: COFF.h:29
Endian.h
llvm::object::getNameType
static ImportNameType getNameType(StringRef Sym, StringRef ExtName, MachineTypes Machine, bool MinGW)
Definition: COFFImportFile.cpp:96
llvm::COFF::IMAGE_SCN_MEM_WRITE
@ IMAGE_SCN_MEM_WRITE
Definition: COFF.h:321