LLVM  14.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/Object/Archive.h"
17 #include "llvm/Object/COFF.h"
18 #include "llvm/Support/Error.h"
19 #include "llvm/Support/Path.h"
20 
21 #include <cstdint>
22 #include <string>
23 #include <vector>
24 
25 using namespace llvm::COFF;
26 using namespace llvm::object;
27 using namespace llvm;
28 
29 namespace llvm {
30 namespace object {
31 
33  switch (Machine) {
34  default:
35  llvm_unreachable("unsupported machine");
38  return false;
41  return true;
42  }
43 }
44 
46  switch (Machine) {
47  default:
48  llvm_unreachable("unsupported machine");
57  }
58 }
59 
60 template <class T> static void append(std::vector<uint8_t> &B, const T &Data) {
61  size_t S = B.size();
62  B.resize(S + sizeof(T));
63  memcpy(&B[S], &Data, sizeof(T));
64 }
65 
66 static void writeStringTable(std::vector<uint8_t> &B,
68  // The COFF string table consists of a 4-byte value which is the size of the
69  // table, including the length field itself. This value is followed by the
70  // string content itself, which is an array of null-terminated C-style
71  // strings. The termination is important as they are referenced to by offset
72  // by the symbol entity in the file format.
73 
74  size_t Pos = B.size();
75  size_t Offset = B.size();
76 
77  // Skip over the length field, we will fill it in later as we will have
78  // computed the length while emitting the string content itself.
79  Pos += sizeof(uint32_t);
80 
81  for (const auto &S : Strings) {
82  B.resize(Pos + S.length() + 1);
83  strcpy(reinterpret_cast<char *>(&B[Pos]), S.c_str());
84  Pos += S.length() + 1;
85  }
86 
87  // Backfill the length of the table now that it has been computed.
88  support::ulittle32_t Length(B.size() - Offset);
90 }
91 
93  MachineTypes Machine, bool MinGW) {
94  // A decorated stdcall function in MSVC is exported with the
95  // type IMPORT_NAME, and the exported function name includes the
96  // the leading underscore. In MinGW on the other hand, a decorated
97  // stdcall function still omits the underscore (IMPORT_NAME_NOPREFIX).
98  // See the comment in isDecorated in COFFModuleDefinition.cpp for more
99  // details.
100  if (ExtName.startswith("_") && ExtName.contains('@') && !MinGW)
101  return IMPORT_NAME;
102  if (Sym != ExtName)
103  return IMPORT_NAME_UNDECORATE;
104  if (Machine == IMAGE_FILE_MACHINE_I386 && Sym.startswith("_"))
105  return IMPORT_NAME_NOPREFIX;
106  return IMPORT_NAME;
107 }
108 
110  StringRef To) {
111  size_t Pos = S.find(From);
112 
113  // From and To may be mangled, but substrings in S may not.
114  if (Pos == StringRef::npos && From.startswith("_") && To.startswith("_")) {
115  From = From.substr(1);
116  To = To.substr(1);
117  Pos = S.find(From);
118  }
119 
120  if (Pos == StringRef::npos) {
121  return make_error<StringError>(
122  StringRef(Twine(S + ": replacing '" + From +
123  "' with '" + To + "' failed").str()), object_error::parse_failed);
124  }
125 
126  return (Twine(S.substr(0, Pos)) + To + S.substr(Pos + From.size())).str();
127 }
128 
129 static const std::string NullImportDescriptorSymbolName =
130  "__NULL_IMPORT_DESCRIPTOR";
131 
132 namespace {
133 // This class constructs various small object files necessary to support linking
134 // symbols imported from a DLL. The contents are pretty strictly defined and
135 // nearly entirely static. The details of the structures files are defined in
136 // WINNT.h and the PE/COFF specification.
137 class ObjectFactory {
138  using u16 = support::ulittle16_t;
139  using u32 = support::ulittle32_t;
141  BumpPtrAllocator Alloc;
142  StringRef ImportName;
144  std::string ImportDescriptorSymbolName;
145  std::string NullThunkSymbolName;
146 
147 public:
148  ObjectFactory(StringRef S, MachineTypes M)
149  : Machine(M), ImportName(S), Library(S.drop_back(4)),
150  ImportDescriptorSymbolName(("__IMPORT_DESCRIPTOR_" + Library).str()),
151  NullThunkSymbolName(("\x7f" + Library + "_NULL_THUNK_DATA").str()) {}
152 
153  // Creates an Import Descriptor. This is a small object file which contains a
154  // reference to the terminators and contains the library name (entry) for the
155  // import name table. It will force the linker to construct the necessary
156  // structure to import symbols from the DLL.
157  NewArchiveMember createImportDescriptor(std::vector<uint8_t> &Buffer);
158 
159  // Creates a NULL import descriptor. This is a small object file whcih
160  // contains a NULL import descriptor. It is used to terminate the imports
161  // from a specific DLL.
162  NewArchiveMember createNullImportDescriptor(std::vector<uint8_t> &Buffer);
163 
164  // Create a NULL Thunk Entry. This is a small object file which contains a
165  // NULL Import Address Table entry and a NULL Import Lookup Table Entry. It
166  // is used to terminate the IAT and ILT.
167  NewArchiveMember createNullThunk(std::vector<uint8_t> &Buffer);
168 
169  // Create a short import file which is described in PE/COFF spec 7. Import
170  // Library Format.
171  NewArchiveMember createShortImport(StringRef Sym, uint16_t Ordinal,
173 
174  // Create a weak external file which is described in PE/COFF Aux Format 3.
175  NewArchiveMember createWeakExternal(StringRef Sym, StringRef Weak, bool Imp);
176 };
177 } // namespace
178 
180 ObjectFactory::createImportDescriptor(std::vector<uint8_t> &Buffer) {
181  const uint32_t NumberOfSections = 2;
182  const uint32_t NumberOfSymbols = 7;
183  const uint32_t NumberOfRelocations = 3;
184 
185  // COFF Header
186  coff_file_header Header{
187  u16(Machine),
188  u16(NumberOfSections),
189  u32(0),
190  u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
191  // .idata$2
193  NumberOfRelocations * sizeof(coff_relocation) +
194  // .idata$4
195  (ImportName.size() + 1)),
196  u32(NumberOfSymbols),
197  u16(0),
199  };
200  append(Buffer, Header);
201 
202  // Section Header Table
203  const coff_section SectionTable[NumberOfSections] = {
204  {{'.', 'i', 'd', 'a', 't', 'a', '$', '2'},
205  u32(0),
206  u32(0),
208  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section)),
209  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
211  u32(0),
212  u16(NumberOfRelocations),
213  u16(0),
216  {{'.', 'i', 'd', 'a', 't', 'a', '$', '6'},
217  u32(0),
218  u32(0),
219  u32(ImportName.size() + 1),
220  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
222  NumberOfRelocations * sizeof(coff_relocation)),
223  u32(0),
224  u32(0),
225  u16(0),
226  u16(0),
229  };
230  append(Buffer, SectionTable);
231 
232  // .idata$2
233  const coff_import_directory_table_entry ImportDescriptor{
234  u32(0), u32(0), u32(0), u32(0), u32(0),
235  };
236  append(Buffer, ImportDescriptor);
237 
238  const coff_relocation RelocationTable[NumberOfRelocations] = {
239  {u32(offsetof(coff_import_directory_table_entry, NameRVA)), u32(2),
241  {u32(offsetof(coff_import_directory_table_entry, ImportLookupTableRVA)),
242  u32(3), u16(getImgRelRelocation(Machine))},
243  {u32(offsetof(coff_import_directory_table_entry, ImportAddressTableRVA)),
244  u32(4), u16(getImgRelRelocation(Machine))},
245  };
246  append(Buffer, RelocationTable);
247 
248  // .idata$6
249  auto S = Buffer.size();
250  Buffer.resize(S + ImportName.size() + 1);
251  memcpy(&Buffer[S], ImportName.data(), ImportName.size());
252  Buffer[S + ImportName.size()] = '\0';
253 
254  // Symbol Table
255  coff_symbol16 SymbolTable[NumberOfSymbols] = {
256  {{{0, 0, 0, 0, 0, 0, 0, 0}},
257  u32(0),
258  u16(1),
259  u16(0),
261  0},
262  {{{'.', 'i', 'd', 'a', 't', 'a', '$', '2'}},
263  u32(0),
264  u16(1),
265  u16(0),
267  0},
268  {{{'.', 'i', 'd', 'a', 't', 'a', '$', '6'}},
269  u32(0),
270  u16(2),
271  u16(0),
273  0},
274  {{{'.', 'i', 'd', 'a', 't', 'a', '$', '4'}},
275  u32(0),
276  u16(0),
277  u16(0),
279  0},
280  {{{'.', 'i', 'd', 'a', 't', 'a', '$', '5'}},
281  u32(0),
282  u16(0),
283  u16(0),
285  0},
286  {{{0, 0, 0, 0, 0, 0, 0, 0}},
287  u32(0),
288  u16(0),
289  u16(0),
291  0},
292  {{{0, 0, 0, 0, 0, 0, 0, 0}},
293  u32(0),
294  u16(0),
295  u16(0),
297  0},
298  };
299  // TODO: Name.Offset.Offset here and in the all similar places below
300  // suggests a names refactoring. Maybe StringTableOffset.Value?
301  SymbolTable[0].Name.Offset.Offset =
302  sizeof(uint32_t);
303  SymbolTable[5].Name.Offset.Offset =
304  sizeof(uint32_t) + ImportDescriptorSymbolName.length() + 1;
305  SymbolTable[6].Name.Offset.Offset =
306  sizeof(uint32_t) + ImportDescriptorSymbolName.length() + 1 +
307  NullImportDescriptorSymbolName.length() + 1;
308  append(Buffer, SymbolTable);
309 
310  // String Table
311  writeStringTable(Buffer,
312  {ImportDescriptorSymbolName, NullImportDescriptorSymbolName,
313  NullThunkSymbolName});
314 
315  StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
316  return {MemoryBufferRef(F, ImportName)};
317 }
318 
320 ObjectFactory::createNullImportDescriptor(std::vector<uint8_t> &Buffer) {
321  const uint32_t NumberOfSections = 1;
322  const uint32_t NumberOfSymbols = 1;
323 
324  // COFF Header
325  coff_file_header Header{
326  u16(Machine),
327  u16(NumberOfSections),
328  u32(0),
329  u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
330  // .idata$3
332  u32(NumberOfSymbols),
333  u16(0),
335  };
336  append(Buffer, Header);
337 
338  // Section Header Table
339  const coff_section SectionTable[NumberOfSections] = {
340  {{'.', 'i', 'd', 'a', 't', 'a', '$', '3'},
341  u32(0),
342  u32(0),
344  u32(sizeof(coff_file_header) +
345  (NumberOfSections * sizeof(coff_section))),
346  u32(0),
347  u32(0),
348  u16(0),
349  u16(0),
352  };
353  append(Buffer, SectionTable);
354 
355  // .idata$3
356  const coff_import_directory_table_entry ImportDescriptor{
357  u32(0), u32(0), u32(0), u32(0), u32(0),
358  };
359  append(Buffer, ImportDescriptor);
360 
361  // Symbol Table
362  coff_symbol16 SymbolTable[NumberOfSymbols] = {
363  {{{0, 0, 0, 0, 0, 0, 0, 0}},
364  u32(0),
365  u16(1),
366  u16(0),
368  0},
369  };
370  SymbolTable[0].Name.Offset.Offset = sizeof(uint32_t);
371  append(Buffer, SymbolTable);
372 
373  // String Table
375 
376  StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
377  return {MemoryBufferRef(F, ImportName)};
378 }
379 
380 NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
381  const uint32_t NumberOfSections = 2;
382  const uint32_t NumberOfSymbols = 1;
383  uint32_t VASize = is32bit(Machine) ? 4 : 8;
384 
385  // COFF Header
386  coff_file_header Header{
387  u16(Machine),
388  u16(NumberOfSections),
389  u32(0),
390  u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
391  // .idata$5
392  VASize +
393  // .idata$4
394  VASize),
395  u32(NumberOfSymbols),
396  u16(0),
398  };
399  append(Buffer, Header);
400 
401  // Section Header Table
402  const coff_section SectionTable[NumberOfSections] = {
403  {{'.', 'i', 'd', 'a', 't', 'a', '$', '5'},
404  u32(0),
405  u32(0),
406  u32(VASize),
407  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section)),
408  u32(0),
409  u32(0),
410  u16(0),
411  u16(0),
416  {{'.', 'i', 'd', 'a', 't', 'a', '$', '4'},
417  u32(0),
418  u32(0),
419  u32(VASize),
420  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
421  VASize),
422  u32(0),
423  u32(0),
424  u16(0),
425  u16(0),
430  };
431  append(Buffer, SectionTable);
432 
433  // .idata$5, ILT
434  append(Buffer, u32(0));
435  if (!is32bit(Machine))
436  append(Buffer, u32(0));
437 
438  // .idata$4, IAT
439  append(Buffer, u32(0));
440  if (!is32bit(Machine))
441  append(Buffer, u32(0));
442 
443  // Symbol Table
444  coff_symbol16 SymbolTable[NumberOfSymbols] = {
445  {{{0, 0, 0, 0, 0, 0, 0, 0}},
446  u32(0),
447  u16(1),
448  u16(0),
450  0},
451  };
452  SymbolTable[0].Name.Offset.Offset = sizeof(uint32_t);
453  append(Buffer, SymbolTable);
454 
455  // String Table
456  writeStringTable(Buffer, {NullThunkSymbolName});
457 
458  StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
459  return {MemoryBufferRef{F, ImportName}};
460 }
461 
462 NewArchiveMember ObjectFactory::createShortImport(StringRef Sym,
463  uint16_t Ordinal,
466  size_t ImpSize = ImportName.size() + Sym.size() + 2; // +2 for NULs
467  size_t Size = sizeof(coff_import_header) + ImpSize;
468  char *Buf = Alloc.Allocate<char>(Size);
469  memset(Buf, 0, Size);
470  char *P = Buf;
471 
472  // Write short import library.
473  auto *Imp = reinterpret_cast<coff_import_header *>(P);
474  P += sizeof(*Imp);
475  Imp->Sig2 = 0xFFFF;
476  Imp->Machine = Machine;
477  Imp->SizeOfData = ImpSize;
478  if (Ordinal > 0)
479  Imp->OrdinalHint = Ordinal;
480  Imp->TypeInfo = (NameType << 2) | ImportType;
481 
482  // Write symbol name and DLL name.
483  memcpy(P, Sym.data(), Sym.size());
484  P += Sym.size() + 1;
485  memcpy(P, ImportName.data(), ImportName.size());
486 
487  return {MemoryBufferRef(StringRef(Buf, Size), ImportName)};
488 }
489 
490 NewArchiveMember ObjectFactory::createWeakExternal(StringRef Sym,
491  StringRef Weak, bool Imp) {
492  std::vector<uint8_t> Buffer;
493  const uint32_t NumberOfSections = 1;
494  const uint32_t NumberOfSymbols = 5;
495 
496  // COFF Header
497  coff_file_header Header{
498  u16(Machine),
499  u16(NumberOfSections),
500  u32(0),
501  u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section))),
502  u32(NumberOfSymbols),
503  u16(0),
504  u16(0),
505  };
506  append(Buffer, Header);
507 
508  // Section Header Table
509  const coff_section SectionTable[NumberOfSections] = {
510  {{'.', 'd', 'r', 'e', 'c', 't', 'v', 'e'},
511  u32(0),
512  u32(0),
513  u32(0),
514  u32(0),
515  u32(0),
516  u32(0),
517  u16(0),
518  u16(0),
520  append(Buffer, SectionTable);
521 
522  // Symbol Table
523  coff_symbol16 SymbolTable[NumberOfSymbols] = {
524  {{{'@', 'c', 'o', 'm', 'p', '.', 'i', 'd'}},
525  u32(0),
526  u16(0xFFFF),
527  u16(0),
529  0},
530  {{{'@', 'f', 'e', 'a', 't', '.', '0', '0'}},
531  u32(0),
532  u16(0xFFFF),
533  u16(0),
535  0},
536  {{{0, 0, 0, 0, 0, 0, 0, 0}},
537  u32(0),
538  u16(0),
539  u16(0),
541  0},
542  {{{0, 0, 0, 0, 0, 0, 0, 0}},
543  u32(0),
544  u16(0),
545  u16(0),
547  1},
548  {{{2, 0, 0, 0, IMAGE_WEAK_EXTERN_SEARCH_ALIAS, 0, 0, 0}},
549  u32(0),
550  u16(0),
551  u16(0),
553  0},
554  };
555  SymbolTable[2].Name.Offset.Offset = sizeof(uint32_t);
556 
557  //__imp_ String Table
558  StringRef Prefix = Imp ? "__imp_" : "";
559  SymbolTable[3].Name.Offset.Offset =
560  sizeof(uint32_t) + Sym.size() + Prefix.size() + 1;
561  append(Buffer, SymbolTable);
562  writeStringTable(Buffer, {(Prefix + Sym).str(),
563  (Prefix + Weak).str()});
564 
565  // Copied here so we can still use writeStringTable
566  char *Buf = Alloc.Allocate<char>(Buffer.size());
567  memcpy(Buf, Buffer.data(), Buffer.size());
568  return {MemoryBufferRef(StringRef(Buf, Buffer.size()), ImportName)};
569 }
570 
573  MachineTypes Machine, bool MinGW) {
574 
575  std::vector<NewArchiveMember> Members;
576  ObjectFactory OF(llvm::sys::path::filename(ImportName), Machine);
577 
578  std::vector<uint8_t> ImportDescriptor;
579  Members.push_back(OF.createImportDescriptor(ImportDescriptor));
580 
581  std::vector<uint8_t> NullImportDescriptor;
582  Members.push_back(OF.createNullImportDescriptor(NullImportDescriptor));
583 
584  std::vector<uint8_t> NullThunk;
585  Members.push_back(OF.createNullThunk(NullThunk));
586 
587  for (COFFShortExport E : Exports) {
588  if (E.Private)
589  continue;
590 
592  if (E.Data)
594  if (E.Constant)
596 
597  StringRef SymbolName = E.SymbolName.empty() ? E.Name : E.SymbolName;
598  ImportNameType NameType = E.Noname
600  : getNameType(SymbolName, E.Name,
601  Machine, MinGW);
602  Expected<std::string> Name = E.ExtName.empty()
603  ? std::string(SymbolName)
604  : replace(SymbolName, E.Name, E.ExtName);
605 
606  if (!Name)
607  return Name.takeError();
608 
609  if (!E.AliasTarget.empty() && *Name != E.AliasTarget) {
610  Members.push_back(OF.createWeakExternal(E.AliasTarget, *Name, false));
611  Members.push_back(OF.createWeakExternal(E.AliasTarget, *Name, true));
612  continue;
613  }
614 
615  Members.push_back(
616  OF.createShortImport(*Name, E.Ordinal, ImportType, NameType));
617  }
618 
619  return writeArchive(Path, Members, /*WriteSymtab*/ true,
621  /*Deterministic*/ true, /*Thin*/ false);
622 }
623 
624 } // namespace object
625 } // namespace llvm
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
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:699
llvm::COFF::IMPORT_ORDINAL
@ IMPORT_ORDINAL
Import is by ordinal.
Definition: COFF.h:697
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:705
llvm::object::COFFShortExport
Definition: COFFImportFile.h:71
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
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:302
llvm::COFF::IMAGE_REL_ARM64_ADDR32NB
@ IMAGE_REL_ARM64_ADDR32NB
Definition: COFF.h:388
llvm::object::is32bit
static bool is32bit(MachineTypes Machine)
Definition: COFFImportFile.cpp:32
llvm::COFF::IMAGE_SYM_CLASS_STATIC
@ IMAGE_SYM_CLASS_STATIC
Static.
Definition: COFF.h:210
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:164
llvm::support::detail::packed_endian_specific_integral
Definition: Endian.h:206
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:129
llvm::COFF::IMAGE_SYM_CLASS_EXTERNAL
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
Definition: COFF.h:209
llvm::COFF::IMAGE_FILE_MACHINE_AMD64
@ IMAGE_FILE_MACHINE_AMD64
Definition: COFF.h:98
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:221
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:336
llvm::COFF::IMAGE_FILE_MACHINE_ARMNT
@ IMAGE_FILE_MACHINE_ARMNT
Definition: COFF.h:100
T
#define T
Definition: Mips16ISelLowering.cpp:341
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS
@ IMAGE_WEAK_EXTERN_SEARCH_ALIAS
Definition: COFF.h:442
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
F
#define F(x, y, z)
Definition: MD5.cpp:56
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:207
llvm::COFF::IMAGE_SCN_LNK_INFO
@ IMAGE_SCN_LNK_INFO
Definition: COFF.h:292
llvm::COFF::IMAGE_FILE_MACHINE_I386
@ IMAGE_FILE_MACHINE_I386
Definition: COFF.h:103
llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
@ IMAGE_SCN_CNT_INITIALIZED_DATA
Definition: COFF.h:289
llvm::object
Definition: ObjectFileTransformer.h:18
ArchiveWriter.h
llvm::BumpPtrAllocatorImpl::Allocate
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
Definition: Allocator.h:145
llvm::COFF::IMAGE_SCN_LNK_REMOVE
@ IMAGE_SCN_LNK_REMOVE
Definition: COFF.h:293
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::COFF::IMAGE_SCN_MEM_READ
@ IMAGE_SCN_MEM_READ
Definition: COFF.h:321
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:655
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:1751
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:368
llvm::COFF::IMPORT_CONST
@ IMPORT_CONST
Definition: COFF.h:689
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:66
NameType
Definition: ItaniumDemangle.h:508
llvm::COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL
@ IMAGE_SYM_CLASS_WEAK_EXTERNAL
Duplicate tag.
Definition: COFF.h:234
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:145
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:702
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:301
llvm::BumpPtrAllocatorImpl
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:67
Archive.h
ArrayRef.h
llvm::object::writeImportLibrary
Error writeImportLibrary(StringRef ImportName, StringRef Path, ArrayRef< COFFShortExport > Exports, COFF::MachineTypes Machine, bool MinGW)
Definition: COFFImportFile.cpp:571
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:692
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:124
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:136
llvm::COFF::IMAGE_SCN_ALIGN_8BYTES
@ IMAGE_SCN_ALIGN_8BYTES
Definition: COFF.h:303
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
llvm::object::getImgRelRelocation
static uint16_t getImgRelRelocation(MachineTypes Machine)
Definition: COFFImportFile.cpp:45
llvm::object::coff_symbol::Name
union llvm::object::coff_symbol::@311 Name
llvm::COFF::IMAGE_FILE_MACHINE_ARM64
@ IMAGE_FILE_MACHINE_ARM64
Definition: COFF.h:101
llvm::object::coff_import_directory_table_entry
Definition: COFF.h:555
llvm::AMDGPU::HSAMD::Kernel::Key::SymbolName
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Definition: AMDGPUMetadata.h:381
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:52
uint16_t
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::object::coff_section
Definition: COFF.h:440
llvm::COFF::IMAGE_REL_AMD64_ADDR32NB
@ IMAGE_REL_AMD64_ADDR32NB
Definition: COFF.h:349
llvm::COFF::ImportType
ImportType
Definition: COFF.h:686
llvm::COFF::IMPORT_CODE
@ IMPORT_CODE
Definition: COFF.h:687
llvm::COFF::MachineTypes
MachineTypes
Definition: COFF.h:93
llvm::COFF::IMAGE_SYM_CLASS_SECTION
@ IMAGE_SYM_CLASS_SECTION
Line number, reformatted as symbol.
Definition: COFF.h:233
llvm::COFF::IMPORT_DATA
@ IMPORT_DATA
Definition: COFF.h:688
llvm::sys::path::filename
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
Definition: Path.cpp:575
Machine
COFF::MachineTypes Machine
Definition: COFFYAML.cpp:366
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:60
llvm::object::coff_import_header
Definition: COFF.h:541
From
BlockVerifier::State From
Definition: BlockVerifier.cpp:55
llvm::COFF
Definition: COFF.h:30
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::object::getNameType
static ImportNameType getNameType(StringRef Sym, StringRef ExtName, MachineTypes Machine, bool MinGW)
Definition: COFFImportFile.cpp:92
llvm::COFF::IMAGE_SCN_MEM_WRITE
@ IMAGE_SCN_MEM_WRITE
Definition: COFF.h:322