LLVM  16.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");
43  return false;
46  return true;
47  }
48 }
49 
51  switch (Machine) {
52  default:
53  llvm_unreachable("unsupported machine");
63  }
64 }
65 
66 template <class T> static void append(std::vector<uint8_t> &B, const T &Data) {
67  size_t S = B.size();
68  B.resize(S + sizeof(T));
69  memcpy(&B[S], &Data, sizeof(T));
70 }
71 
72 static void writeStringTable(std::vector<uint8_t> &B,
74  // The COFF string table consists of a 4-byte value which is the size of the
75  // table, including the length field itself. This value is followed by the
76  // string content itself, which is an array of null-terminated C-style
77  // strings. The termination is important as they are referenced to by offset
78  // by the symbol entity in the file format.
79 
80  size_t Pos = B.size();
81  size_t Offset = B.size();
82 
83  // Skip over the length field, we will fill it in later as we will have
84  // computed the length while emitting the string content itself.
85  Pos += sizeof(uint32_t);
86 
87  for (const auto &S : Strings) {
88  B.resize(Pos + S.length() + 1);
89  strcpy(reinterpret_cast<char *>(&B[Pos]), S.c_str());
90  Pos += S.length() + 1;
91  }
92 
93  // Backfill the length of the table now that it has been computed.
94  support::ulittle32_t Length(B.size() - Offset);
95  support::endian::write32le(&B[Offset], Length);
96 }
97 
99  MachineTypes Machine, bool MinGW) {
100  // A decorated stdcall function in MSVC is exported with the
101  // type IMPORT_NAME, and the exported function name includes the
102  // the leading underscore. In MinGW on the other hand, a decorated
103  // stdcall function still omits the underscore (IMPORT_NAME_NOPREFIX).
104  // See the comment in isDecorated in COFFModuleDefinition.cpp for more
105  // details.
106  if (ExtName.startswith("_") && ExtName.contains('@') && !MinGW)
107  return IMPORT_NAME;
108  if (Sym != ExtName)
109  return IMPORT_NAME_UNDECORATE;
110  if (Machine == IMAGE_FILE_MACHINE_I386 && Sym.startswith("_"))
111  return IMPORT_NAME_NOPREFIX;
112  return IMPORT_NAME;
113 }
114 
116  StringRef To) {
117  size_t Pos = S.find(From);
118 
119  // From and To may be mangled, but substrings in S may not.
120  if (Pos == StringRef::npos && From.startswith("_") && To.startswith("_")) {
121  From = From.substr(1);
122  To = To.substr(1);
123  Pos = S.find(From);
124  }
125 
126  if (Pos == StringRef::npos) {
127  return make_error<StringError>(
128  StringRef(Twine(S + ": replacing '" + From +
129  "' with '" + To + "' failed").str()), object_error::parse_failed);
130  }
131 
132  return (Twine(S.substr(0, Pos)) + To + S.substr(Pos + From.size())).str();
133 }
134 
135 static const std::string NullImportDescriptorSymbolName =
136  "__NULL_IMPORT_DESCRIPTOR";
137 
138 namespace {
139 // This class constructs various small object files necessary to support linking
140 // symbols imported from a DLL. The contents are pretty strictly defined and
141 // nearly entirely static. The details of the structures files are defined in
142 // WINNT.h and the PE/COFF specification.
143 class ObjectFactory {
144  using u16 = support::ulittle16_t;
145  using u32 = support::ulittle32_t;
147  BumpPtrAllocator Alloc;
148  StringRef ImportName;
150  std::string ImportDescriptorSymbolName;
151  std::string NullThunkSymbolName;
152 
153 public:
154  ObjectFactory(StringRef S, MachineTypes M)
155  : Machine(M), ImportName(S), Library(S.drop_back(4)),
156  ImportDescriptorSymbolName(("__IMPORT_DESCRIPTOR_" + Library).str()),
157  NullThunkSymbolName(("\x7f" + Library + "_NULL_THUNK_DATA").str()) {}
158 
159  // Creates an Import Descriptor. This is a small object file which contains a
160  // reference to the terminators and contains the library name (entry) for the
161  // import name table. It will force the linker to construct the necessary
162  // structure to import symbols from the DLL.
163  NewArchiveMember createImportDescriptor(std::vector<uint8_t> &Buffer);
164 
165  // Creates a NULL import descriptor. This is a small object file whcih
166  // contains a NULL import descriptor. It is used to terminate the imports
167  // from a specific DLL.
168  NewArchiveMember createNullImportDescriptor(std::vector<uint8_t> &Buffer);
169 
170  // Create a NULL Thunk Entry. This is a small object file which contains a
171  // NULL Import Address Table entry and a NULL Import Lookup Table Entry. It
172  // is used to terminate the IAT and ILT.
173  NewArchiveMember createNullThunk(std::vector<uint8_t> &Buffer);
174 
175  // Create a short import file which is described in PE/COFF spec 7. Import
176  // Library Format.
177  NewArchiveMember createShortImport(StringRef Sym, uint16_t Ordinal,
179 
180  // Create a weak external file which is described in PE/COFF Aux Format 3.
181  NewArchiveMember createWeakExternal(StringRef Sym, StringRef Weak, bool Imp);
182 };
183 } // namespace
184 
186 ObjectFactory::createImportDescriptor(std::vector<uint8_t> &Buffer) {
187  const uint32_t NumberOfSections = 2;
188  const uint32_t NumberOfSymbols = 7;
189  const uint32_t NumberOfRelocations = 3;
190 
191  // COFF Header
192  coff_file_header Header{
193  u16(Machine),
194  u16(NumberOfSections),
195  u32(0),
196  u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
197  // .idata$2
199  NumberOfRelocations * sizeof(coff_relocation) +
200  // .idata$4
201  (ImportName.size() + 1)),
202  u32(NumberOfSymbols),
203  u16(0),
205  };
206  append(Buffer, Header);
207 
208  // Section Header Table
209  const coff_section SectionTable[NumberOfSections] = {
210  {{'.', 'i', 'd', 'a', 't', 'a', '$', '2'},
211  u32(0),
212  u32(0),
214  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section)),
215  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
217  u32(0),
218  u16(NumberOfRelocations),
219  u16(0),
222  {{'.', 'i', 'd', 'a', 't', 'a', '$', '6'},
223  u32(0),
224  u32(0),
225  u32(ImportName.size() + 1),
226  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
228  NumberOfRelocations * sizeof(coff_relocation)),
229  u32(0),
230  u32(0),
231  u16(0),
232  u16(0),
235  };
236  append(Buffer, SectionTable);
237 
238  // .idata$2
239  const coff_import_directory_table_entry ImportDescriptor{
240  u32(0), u32(0), u32(0), u32(0), u32(0),
241  };
242  append(Buffer, ImportDescriptor);
243 
244  const coff_relocation RelocationTable[NumberOfRelocations] = {
245  {u32(offsetof(coff_import_directory_table_entry, NameRVA)), u32(2),
247  {u32(offsetof(coff_import_directory_table_entry, ImportLookupTableRVA)),
248  u32(3), u16(getImgRelRelocation(Machine))},
249  {u32(offsetof(coff_import_directory_table_entry, ImportAddressTableRVA)),
250  u32(4), u16(getImgRelRelocation(Machine))},
251  };
252  append(Buffer, RelocationTable);
253 
254  // .idata$6
255  auto S = Buffer.size();
256  Buffer.resize(S + ImportName.size() + 1);
257  memcpy(&Buffer[S], ImportName.data(), ImportName.size());
258  Buffer[S + ImportName.size()] = '\0';
259 
260  // Symbol Table
261  coff_symbol16 SymbolTable[NumberOfSymbols] = {
262  {{{0, 0, 0, 0, 0, 0, 0, 0}},
263  u32(0),
264  u16(1),
265  u16(0),
267  0},
268  {{{'.', 'i', 'd', 'a', 't', 'a', '$', '2'}},
269  u32(0),
270  u16(1),
271  u16(0),
273  0},
274  {{{'.', 'i', 'd', 'a', 't', 'a', '$', '6'}},
275  u32(0),
276  u16(2),
277  u16(0),
279  0},
280  {{{'.', 'i', 'd', 'a', 't', 'a', '$', '4'}},
281  u32(0),
282  u16(0),
283  u16(0),
285  0},
286  {{{'.', 'i', 'd', 'a', 't', 'a', '$', '5'}},
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  {{{0, 0, 0, 0, 0, 0, 0, 0}},
299  u32(0),
300  u16(0),
301  u16(0),
303  0},
304  };
305  // TODO: Name.Offset.Offset here and in the all similar places below
306  // suggests a names refactoring. Maybe StringTableOffset.Value?
307  SymbolTable[0].Name.Offset.Offset =
308  sizeof(uint32_t);
309  SymbolTable[5].Name.Offset.Offset =
310  sizeof(uint32_t) + ImportDescriptorSymbolName.length() + 1;
311  SymbolTable[6].Name.Offset.Offset =
312  sizeof(uint32_t) + ImportDescriptorSymbolName.length() + 1 +
313  NullImportDescriptorSymbolName.length() + 1;
314  append(Buffer, SymbolTable);
315 
316  // String Table
317  writeStringTable(Buffer,
318  {ImportDescriptorSymbolName, NullImportDescriptorSymbolName,
319  NullThunkSymbolName});
320 
321  StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
322  return {MemoryBufferRef(F, ImportName)};
323 }
324 
326 ObjectFactory::createNullImportDescriptor(std::vector<uint8_t> &Buffer) {
327  const uint32_t NumberOfSections = 1;
328  const uint32_t NumberOfSymbols = 1;
329 
330  // COFF Header
331  coff_file_header Header{
332  u16(Machine),
333  u16(NumberOfSections),
334  u32(0),
335  u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
336  // .idata$3
338  u32(NumberOfSymbols),
339  u16(0),
341  };
342  append(Buffer, Header);
343 
344  // Section Header Table
345  const coff_section SectionTable[NumberOfSections] = {
346  {{'.', 'i', 'd', 'a', 't', 'a', '$', '3'},
347  u32(0),
348  u32(0),
350  u32(sizeof(coff_file_header) +
351  (NumberOfSections * sizeof(coff_section))),
352  u32(0),
353  u32(0),
354  u16(0),
355  u16(0),
358  };
359  append(Buffer, SectionTable);
360 
361  // .idata$3
362  const coff_import_directory_table_entry ImportDescriptor{
363  u32(0), u32(0), u32(0), u32(0), u32(0),
364  };
365  append(Buffer, ImportDescriptor);
366 
367  // Symbol Table
368  coff_symbol16 SymbolTable[NumberOfSymbols] = {
369  {{{0, 0, 0, 0, 0, 0, 0, 0}},
370  u32(0),
371  u16(1),
372  u16(0),
374  0},
375  };
376  SymbolTable[0].Name.Offset.Offset = sizeof(uint32_t);
377  append(Buffer, SymbolTable);
378 
379  // String Table
381 
382  StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
383  return {MemoryBufferRef(F, ImportName)};
384 }
385 
386 NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
387  const uint32_t NumberOfSections = 2;
388  const uint32_t NumberOfSymbols = 1;
389  uint32_t VASize = is32bit(Machine) ? 4 : 8;
390 
391  // COFF Header
392  coff_file_header Header{
393  u16(Machine),
394  u16(NumberOfSections),
395  u32(0),
396  u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section)) +
397  // .idata$5
398  VASize +
399  // .idata$4
400  VASize),
401  u32(NumberOfSymbols),
402  u16(0),
404  };
405  append(Buffer, Header);
406 
407  // Section Header Table
408  const coff_section SectionTable[NumberOfSections] = {
409  {{'.', 'i', 'd', 'a', 't', 'a', '$', '5'},
410  u32(0),
411  u32(0),
412  u32(VASize),
413  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section)),
414  u32(0),
415  u32(0),
416  u16(0),
417  u16(0),
422  {{'.', 'i', 'd', 'a', 't', 'a', '$', '4'},
423  u32(0),
424  u32(0),
425  u32(VASize),
426  u32(sizeof(coff_file_header) + NumberOfSections * sizeof(coff_section) +
427  VASize),
428  u32(0),
429  u32(0),
430  u16(0),
431  u16(0),
436  };
437  append(Buffer, SectionTable);
438 
439  // .idata$5, ILT
440  append(Buffer, u32(0));
441  if (!is32bit(Machine))
442  append(Buffer, u32(0));
443 
444  // .idata$4, IAT
445  append(Buffer, u32(0));
446  if (!is32bit(Machine))
447  append(Buffer, u32(0));
448 
449  // Symbol Table
450  coff_symbol16 SymbolTable[NumberOfSymbols] = {
451  {{{0, 0, 0, 0, 0, 0, 0, 0}},
452  u32(0),
453  u16(1),
454  u16(0),
456  0},
457  };
458  SymbolTable[0].Name.Offset.Offset = sizeof(uint32_t);
459  append(Buffer, SymbolTable);
460 
461  // String Table
462  writeStringTable(Buffer, {NullThunkSymbolName});
463 
464  StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
465  return {MemoryBufferRef{F, ImportName}};
466 }
467 
468 NewArchiveMember ObjectFactory::createShortImport(StringRef Sym,
469  uint16_t Ordinal,
472  size_t ImpSize = ImportName.size() + Sym.size() + 2; // +2 for NULs
473  size_t Size = sizeof(coff_import_header) + ImpSize;
474  char *Buf = Alloc.Allocate<char>(Size);
475  memset(Buf, 0, Size);
476  char *P = Buf;
477 
478  // Write short import library.
479  auto *Imp = reinterpret_cast<coff_import_header *>(P);
480  P += sizeof(*Imp);
481  Imp->Sig2 = 0xFFFF;
482  Imp->Machine = Machine;
483  Imp->SizeOfData = ImpSize;
484  if (Ordinal > 0)
485  Imp->OrdinalHint = Ordinal;
486  Imp->TypeInfo = (NameType << 2) | ImportType;
487 
488  // Write symbol name and DLL name.
489  memcpy(P, Sym.data(), Sym.size());
490  P += Sym.size() + 1;
491  memcpy(P, ImportName.data(), ImportName.size());
492 
493  return {MemoryBufferRef(StringRef(Buf, Size), ImportName)};
494 }
495 
496 NewArchiveMember ObjectFactory::createWeakExternal(StringRef Sym,
497  StringRef Weak, bool Imp) {
498  std::vector<uint8_t> Buffer;
499  const uint32_t NumberOfSections = 1;
500  const uint32_t NumberOfSymbols = 5;
501 
502  // COFF Header
503  coff_file_header Header{
504  u16(Machine),
505  u16(NumberOfSections),
506  u32(0),
507  u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section))),
508  u32(NumberOfSymbols),
509  u16(0),
510  u16(0),
511  };
512  append(Buffer, Header);
513 
514  // Section Header Table
515  const coff_section SectionTable[NumberOfSections] = {
516  {{'.', 'd', 'r', 'e', 'c', 't', 'v', 'e'},
517  u32(0),
518  u32(0),
519  u32(0),
520  u32(0),
521  u32(0),
522  u32(0),
523  u16(0),
524  u16(0),
526  append(Buffer, SectionTable);
527 
528  // Symbol Table
529  coff_symbol16 SymbolTable[NumberOfSymbols] = {
530  {{{'@', 'c', 'o', 'm', 'p', '.', 'i', 'd'}},
531  u32(0),
532  u16(0xFFFF),
533  u16(0),
535  0},
536  {{{'@', 'f', 'e', 'a', 't', '.', '0', '0'}},
537  u32(0),
538  u16(0xFFFF),
539  u16(0),
541  0},
542  {{{0, 0, 0, 0, 0, 0, 0, 0}},
543  u32(0),
544  u16(0),
545  u16(0),
547  0},
548  {{{0, 0, 0, 0, 0, 0, 0, 0}},
549  u32(0),
550  u16(0),
551  u16(0),
553  1},
554  {{{2, 0, 0, 0, IMAGE_WEAK_EXTERN_SEARCH_ALIAS, 0, 0, 0}},
555  u32(0),
556  u16(0),
557  u16(0),
559  0},
560  };
561  SymbolTable[2].Name.Offset.Offset = sizeof(uint32_t);
562 
563  //__imp_ String Table
564  StringRef Prefix = Imp ? "__imp_" : "";
565  SymbolTable[3].Name.Offset.Offset =
566  sizeof(uint32_t) + Sym.size() + Prefix.size() + 1;
567  append(Buffer, SymbolTable);
568  writeStringTable(Buffer, {(Prefix + Sym).str(),
569  (Prefix + Weak).str()});
570 
571  // Copied here so we can still use writeStringTable
572  char *Buf = Alloc.Allocate<char>(Buffer.size());
573  memcpy(Buf, Buffer.data(), Buffer.size());
574  return {MemoryBufferRef(StringRef(Buf, Buffer.size()), ImportName)};
575 }
576 
579  MachineTypes Machine, bool MinGW) {
580 
581  std::vector<NewArchiveMember> Members;
582  ObjectFactory OF(llvm::sys::path::filename(ImportName), Machine);
583 
584  std::vector<uint8_t> ImportDescriptor;
585  Members.push_back(OF.createImportDescriptor(ImportDescriptor));
586 
587  std::vector<uint8_t> NullImportDescriptor;
588  Members.push_back(OF.createNullImportDescriptor(NullImportDescriptor));
589 
590  std::vector<uint8_t> NullThunk;
591  Members.push_back(OF.createNullThunk(NullThunk));
592 
593  for (COFFShortExport E : Exports) {
594  if (E.Private)
595  continue;
596 
598  if (E.Data)
600  if (E.Constant)
602 
603  StringRef SymbolName = E.SymbolName.empty() ? E.Name : E.SymbolName;
604  ImportNameType NameType = E.Noname
606  : getNameType(SymbolName, E.Name,
607  Machine, MinGW);
608  Expected<std::string> Name = E.ExtName.empty()
609  ? std::string(SymbolName)
610  : replace(SymbolName, E.Name, E.ExtName);
611 
612  if (!Name)
613  return Name.takeError();
614 
615  if (!E.AliasTarget.empty() && *Name != E.AliasTarget) {
616  Members.push_back(OF.createWeakExternal(E.AliasTarget, *Name, false));
617  Members.push_back(OF.createWeakExternal(E.AliasTarget, *Name, true));
618  continue;
619  }
620 
621  Members.push_back(
622  OF.createShortImport(*Name, E.Ordinal, ImportType, NameType));
623  }
624 
625  return writeArchive(Path, Members, /*WriteSymtab*/ true,
627  /*Deterministic*/ true, /*Thin*/ false);
628 }
629 
630 } // namespace object
631 } // namespace llvm
llvm::Check::Size
@ Size
Definition: FileCheck.h:77
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::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:70
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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:36
llvm::COFF::IMAGE_SYM_CLASS_STATIC
@ IMAGE_SYM_CLASS_STATIC
Static.
Definition: COFF.h:210
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:160
llvm::support::detail::packed_endian_specific_integral
Definition: Endian.h:206
T
llvm::object::coff_symbol::Name
union llvm::object::coff_symbol::@329 Name
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:52
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:135
llvm::COFF::IMAGE_SYM_CLASS_EXTERNAL
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
Definition: COFF.h:209
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:336
llvm::COFF::IMAGE_FILE_MACHINE_ARMNT
@ IMAGE_FILE_MACHINE_ARMNT
Definition: COFF.h:99
llvm::StringRef::substr
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:564
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:442
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::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: DWARFDebugLoc.h:24
ArchiveWriter.h
llvm::StringRef::startswith
bool startswith(StringRef Prefix) const
Definition: StringRef.h:260
llvm::COFF::IMAGE_SCN_LNK_REMOVE
@ IMAGE_SCN_LNK_REMOVE
Definition: COFF.h:293
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: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: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:2020
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::object::writeStringTable
static void writeStringTable(std::vector< uint8_t > &B, ArrayRef< const std::string > Strings)
Definition: COFFImportFile.cpp:72
llvm::StringRef::data
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:131
NameType
Definition: ItaniumDemangle.h:479
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:63
ArrayRef.h
llvm::object::writeImportLibrary
Error writeImportLibrary(StringRef ImportName, StringRef Path, ArrayRef< COFFShortExport > Exports, COFF::MachineTypes Machine, bool MinGW)
Definition: COFFImportFile.cpp:577
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::IMAGE_FILE_MACHINE_ARM64EC
@ IMAGE_FILE_MACHINE_ARM64EC
Definition: COFF.h:101
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:33
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:50
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: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
Archive.h
llvm::object::getImgRelRelocation
static uint16_t getImgRelRelocation(MachineTypes Machine)
Definition: COFFImportFile.cpp:50
llvm::COFF::IMAGE_FILE_MACHINE_ARM64
@ IMAGE_FILE_MACHINE_ARM64
Definition: COFF.h:100
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
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:386
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
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:148
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:92
llvm::COFF::IMAGE_SYM_CLASS_SECTION
@ IMAGE_SYM_CLASS_SECTION
Line number, reformatted as symbol.
Definition: COFF.h:233
llvm::StringRef::contains
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:428
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:577
Machine
COFF::MachineTypes Machine
Definition: COFFYAML.cpp:370
COFF.h
llvm::object::append
static void append(std::vector< uint8_t > &B, const T &Data)
Definition: COFFImportFile.cpp:66
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:98
llvm::COFF::IMAGE_SCN_MEM_WRITE
@ IMAGE_SCN_MEM_WRITE
Definition: COFF.h:322