LLVM  16.0.0git
COFFObject.h
Go to the documentation of this file.
1 //===- COFFObject.h ---------------------------------------------*- 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 
9 #ifndef LLVM_LIB_OBJCOPY_COFF_COFFOBJECT_H
10 #define LLVM_LIB_OBJCOPY_COFF_COFFOBJECT_H
11 
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/Optional.h"
15 #include "llvm/ADT/StringRef.h"
17 #include "llvm/BinaryFormat/COFF.h"
18 #include "llvm/Object/COFF.h"
19 #include <cstddef>
20 #include <cstdint>
21 #include <vector>
22 
23 namespace llvm {
24 namespace objcopy {
25 namespace coff {
26 
27 struct Relocation {
28  Relocation() = default;
30 
32  size_t Target = 0;
33  StringRef TargetName; // Used for diagnostics only
34 };
35 
36 struct Section {
38  std::vector<Relocation> Relocs;
40  ssize_t UniqueId;
41  size_t Index;
42 
44  if (!OwnedContents.empty())
45  return OwnedContents;
46  return ContentsRef;
47  }
48 
50  OwnedContents.clear();
51  ContentsRef = Data;
52  }
53 
54  void setOwnedContents(std::vector<uint8_t> &&Data) {
55  ContentsRef = ArrayRef<uint8_t>();
56  OwnedContents = std::move(Data);
57  Header.SizeOfRawData = OwnedContents.size();
58  }
59 
60  void clearContents() {
61  ContentsRef = ArrayRef<uint8_t>();
62  OwnedContents.clear();
63  }
64 
65 private:
66  ArrayRef<uint8_t> ContentsRef;
67  std::vector<uint8_t> OwnedContents;
68 };
69 
70 struct AuxSymbol {
72  assert(In.size() == sizeof(Opaque));
73  std::copy(In.begin(), In.end(), Opaque);
74  }
75 
77  return ArrayRef<uint8_t>(Opaque, sizeof(Opaque));
78  }
79 
80  uint8_t Opaque[sizeof(object::coff_symbol16)];
81 };
82 
83 struct Symbol {
86  std::vector<AuxSymbol> AuxData;
88  ssize_t TargetSectionId;
91  size_t UniqueId;
92  size_t RawIndex;
93  bool Referenced;
94 };
95 
96 struct Object {
97  bool IsPE = false;
98 
101 
103 
104  bool Is64 = false;
106  uint32_t BaseOfData = 0; // pe32plus_header lacks this field.
107 
108  std::vector<object::data_directory> DataDirectories;
109 
110  ArrayRef<Symbol> getSymbols() const { return Symbols; }
111  // This allows mutating individual Symbols, but not mutating the list
112  // of symbols itself.
114  return make_range(Symbols.begin(), Symbols.end());
115  }
116 
117  const Symbol *findSymbol(size_t UniqueId) const;
118 
119  void addSymbols(ArrayRef<Symbol> NewSymbols);
121 
122  // Set the Referenced field on all Symbols, based on relocations in
123  // all sections.
124  Error markSymbols();
125 
126  ArrayRef<Section> getSections() const { return Sections; }
127  // This allows mutating individual Sections, but not mutating the list
128  // of sections itself.
130  return make_range(Sections.begin(), Sections.end());
131  }
132 
133  const Section *findSection(ssize_t UniqueId) const;
134 
135  void addSections(ArrayRef<Section> NewSections);
136  void removeSections(function_ref<bool(const Section &)> ToRemove);
137  void truncateSections(function_ref<bool(const Section &)> ToTruncate);
138 
139 private:
140  std::vector<Symbol> Symbols;
141  DenseMap<size_t, Symbol *> SymbolMap;
142 
143  size_t NextSymbolUniqueId = 0;
144 
145  std::vector<Section> Sections;
146  DenseMap<ssize_t, Section *> SectionMap;
147 
148  ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined.
149 
150  // Update SymbolMap.
151  void updateSymbols();
152 
153  // Update SectionMap and Index in each Section.
154  void updateSections();
155 };
156 
157 // Copy between coff_symbol16 and coff_symbol32.
158 // The source and destination files can use either coff_symbol16 or
159 // coff_symbol32, while we always store them as coff_symbol32 in the
160 // intermediate data structure.
161 template <class Symbol1Ty, class Symbol2Ty>
162 void copySymbol(Symbol1Ty &Dest, const Symbol2Ty &Src) {
163  static_assert(sizeof(Dest.Name.ShortName) == sizeof(Src.Name.ShortName),
164  "Mismatched name sizes");
165  memcpy(Dest.Name.ShortName, Src.Name.ShortName, sizeof(Dest.Name.ShortName));
166  Dest.Value = Src.Value;
167  Dest.SectionNumber = Src.SectionNumber;
168  Dest.Type = Src.Type;
169  Dest.StorageClass = Src.StorageClass;
170  Dest.NumberOfAuxSymbols = Src.NumberOfAuxSymbols;
171 }
172 
173 // Copy between pe32_header and pe32plus_header.
174 // We store the intermediate state in a pe32plus_header.
175 template <class PeHeader1Ty, class PeHeader2Ty>
176 void copyPeHeader(PeHeader1Ty &Dest, const PeHeader2Ty &Src) {
177  Dest.Magic = Src.Magic;
178  Dest.MajorLinkerVersion = Src.MajorLinkerVersion;
179  Dest.MinorLinkerVersion = Src.MinorLinkerVersion;
180  Dest.SizeOfCode = Src.SizeOfCode;
181  Dest.SizeOfInitializedData = Src.SizeOfInitializedData;
182  Dest.SizeOfUninitializedData = Src.SizeOfUninitializedData;
183  Dest.AddressOfEntryPoint = Src.AddressOfEntryPoint;
184  Dest.BaseOfCode = Src.BaseOfCode;
185  Dest.ImageBase = Src.ImageBase;
186  Dest.SectionAlignment = Src.SectionAlignment;
187  Dest.FileAlignment = Src.FileAlignment;
188  Dest.MajorOperatingSystemVersion = Src.MajorOperatingSystemVersion;
189  Dest.MinorOperatingSystemVersion = Src.MinorOperatingSystemVersion;
190  Dest.MajorImageVersion = Src.MajorImageVersion;
191  Dest.MinorImageVersion = Src.MinorImageVersion;
192  Dest.MajorSubsystemVersion = Src.MajorSubsystemVersion;
193  Dest.MinorSubsystemVersion = Src.MinorSubsystemVersion;
194  Dest.Win32VersionValue = Src.Win32VersionValue;
195  Dest.SizeOfImage = Src.SizeOfImage;
196  Dest.SizeOfHeaders = Src.SizeOfHeaders;
197  Dest.CheckSum = Src.CheckSum;
198  Dest.Subsystem = Src.Subsystem;
199  Dest.DLLCharacteristics = Src.DLLCharacteristics;
200  Dest.SizeOfStackReserve = Src.SizeOfStackReserve;
201  Dest.SizeOfStackCommit = Src.SizeOfStackCommit;
202  Dest.SizeOfHeapReserve = Src.SizeOfHeapReserve;
203  Dest.SizeOfHeapCommit = Src.SizeOfHeapCommit;
204  Dest.LoaderFlags = Src.LoaderFlags;
205  Dest.NumberOfRvaAndSize = Src.NumberOfRvaAndSize;
206 }
207 
208 } // end namespace coff
209 } // end namespace objcopy
210 } // end namespace llvm
211 
212 #endif // LLVM_LIB_OBJCOPY_COFF_COFFOBJECT_H
llvm::objcopy::coff::Object::PeHeader
object::pe32plus_header PeHeader
Definition: COFFObject.h:105
llvm::objcopy::coff::Object::getSections
ArrayRef< Section > getSections() const
Definition: COFFObject.h:126
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:53
llvm::objcopy::coff::AuxSymbol::Opaque
uint8_t Opaque[sizeof(object::coff_symbol16)]
Definition: COFFObject.h:80
Optional.h
llvm::objcopy::coff::Object::DataDirectories
std::vector< object::data_directory > DataDirectories
Definition: COFFObject.h:108
llvm::objcopy::coff::Section::Name
StringRef Name
Definition: COFFObject.h:39
StringRef.h
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:149
llvm::objcopy::coff::Section::Header
object::coff_section Header
Definition: COFFObject.h:37
ToRemove
ReachingDefAnalysis InstSet & ToRemove
Definition: ARMLowOverheadLoops.cpp:547
llvm::objcopy::coff::Object::removeSymbols
Error removeSymbols(function_ref< Expected< bool >(const Symbol &)> ToRemove)
Definition: COFFObject.cpp:37
llvm::objcopy::coff::Symbol::WeakTargetSymbolId
Optional< size_t > WeakTargetSymbolId
Definition: COFFObject.h:90
llvm::objcopy::coff::Object::truncateSections
void truncateSections(function_ref< bool(const Section &)> ToTruncate)
Definition: COFFObject.cpp:120
COFF.h
DenseMap.h
llvm::objcopy::coff::Section
Definition: COFFObject.h:36
llvm::Optional< size_t >
llvm::objcopy::coff::Section::setContentsRef
void setContentsRef(ArrayRef< uint8_t > Data)
Definition: COFFObject.h:49
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::object::pe32plus_header
The 64-bit PE header that follows the COFF header.
Definition: COFF.h:140
llvm::objcopy::coff::Symbol::AuxData
std::vector< AuxSymbol > AuxData
Definition: COFFObject.h:86
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::objcopy::coff::Relocation
Definition: COFFObject.h:27
llvm::object::dos_header
The DOS compatible header at the front of all PE/COFF executables.
Definition: COFF.h:53
llvm::object::coff_file_header
Definition: COFF.h:75
llvm::objcopy::coff::Symbol::UniqueId
size_t UniqueId
Definition: COFFObject.h:91
llvm::objcopy::coff::Object::DosStub
ArrayRef< uint8_t > DosStub
Definition: COFFObject.h:100
llvm::objcopy::coff::Object::removeSections
void removeSections(function_ref< bool(const Section &)> ToRemove)
Definition: COFFObject.cpp:89
llvm::objcopy::coff::Object::BaseOfData
uint32_t BaseOfData
Definition: COFFObject.h:106
llvm::objcopy::coff::Object::markSymbols
Error markSymbols()
Definition: COFFObject.cpp:53
llvm::objcopy::coff::Object::addSections
void addSections(ArrayRef< Section > NewSections)
Definition: COFFObject.cpp:68
llvm::objcopy::coff::Symbol::Sym
object::coff_symbol32 Sym
Definition: COFFObject.h:84
llvm::objcopy::coff::Object
Definition: COFFObject.h:96
llvm::objcopy::coff::Object::DosHeader
object::dos_header DosHeader
Definition: COFFObject.h:99
llvm::objcopy::coff::Section::clearContents
void clearContents()
Definition: COFFObject.h:60
llvm::object::coff_symbol< support::ulittle32_t >
llvm::object::coff_symbol16
coff_symbol< support::ulittle16_t > coff_symbol16
Definition: COFF.h:265
llvm::object::coff_relocation
Definition: COFF.h:474
llvm::objcopy::coff::Object::IsPE
bool IsPE
Definition: COFFObject.h:97
llvm::objcopy::coff::Symbol::RawIndex
size_t RawIndex
Definition: COFFObject.h:92
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLFunctionalExtras.h:36
llvm::tgtok::In
@ In
Definition: TGLexer.h:51
llvm::objcopy::coff::Object::findSection
const Section * findSection(ssize_t UniqueId) const
Definition: COFFObject.cpp:85
llvm::objcopy::coff::Section::Relocs
std::vector< Relocation > Relocs
Definition: COFFObject.h:38
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::DenseMap
Definition: DenseMap.h:714
llvm::objcopy::coff::AuxSymbol
Definition: COFFObject.h:70
ArrayRef.h
llvm::objcopy::coff::Relocation::Reloc
object::coff_relocation Reloc
Definition: COFFObject.h:31
llvm::objcopy::coff::Object::getMutableSymbols
iterator_range< std::vector< Symbol >::iterator > getMutableSymbols()
Definition: COFFObject.h:113
llvm::objcopy::coff::Relocation::Relocation
Relocation()=default
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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(<
iterator_range.h
llvm::objcopy::coff::Symbol::AuxFile
StringRef AuxFile
Definition: COFFObject.h:87
llvm::objcopy::coff::Section::getContents
ArrayRef< uint8_t > getContents() const
Definition: COFFObject.h:43
llvm::objcopy::coff::Symbol::Referenced
bool Referenced
Definition: COFFObject.h:93
llvm::objcopy::coff::AuxSymbol::getRef
ArrayRef< uint8_t > getRef() const
Definition: COFFObject.h:76
llvm::ArrayRef< uint8_t >
llvm::objcopy::coff::Object::getMutableSections
iterator_range< std::vector< Section >::iterator > getMutableSections()
Definition: COFFObject.h:129
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
uint32_t
llvm::object::coff_section::SizeOfRawData
support::ulittle32_t SizeOfRawData
Definition: COFF.h:444
llvm::objcopy::coff::Object::findSymbol
const Symbol * findSymbol(size_t UniqueId) const
Definition: COFFObject.cpp:33
llvm::objcopy::coff::Symbol::TargetSectionId
ssize_t TargetSectionId
Definition: COFFObject.h:88
llvm::objcopy::coff::Object::Is64
bool Is64
Definition: COFFObject.h:104
llvm::objcopy::coff::copyPeHeader
void copyPeHeader(PeHeader1Ty &Dest, const PeHeader2Ty &Src)
Definition: COFFObject.h:176
llvm::objcopy::coff::Symbol::AssociativeComdatTargetSectionId
ssize_t AssociativeComdatTargetSectionId
Definition: COFFObject.h:89
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::objcopy::coff::Section::Index
size_t Index
Definition: COFFObject.h:41
llvm::object::coff_section
Definition: COFF.h:440
llvm::objcopy::coff::copySymbol
void copySymbol(Symbol1Ty &Dest, const Symbol2Ty &Src)
Definition: COFFObject.h:162
llvm::objcopy::coff::AuxSymbol::AuxSymbol
AuxSymbol(ArrayRef< uint8_t > In)
Definition: COFFObject.h:71
llvm::objcopy::coff::Object::addSymbols
void addSymbols(ArrayRef< Symbol > NewSymbols)
Definition: COFFObject.cpp:19
llvm::objcopy::coff::Relocation::Relocation
Relocation(const object::coff_relocation &R)
Definition: COFFObject.h:29
llvm::objcopy::coff::Symbol::Name
StringRef Name
Definition: COFFObject.h:85
COFF.h
llvm::objcopy::coff::Section::setOwnedContents
void setOwnedContents(std::vector< uint8_t > &&Data)
Definition: COFFObject.h:54
llvm::iterator_range
A range adaptor for a pair of iterators.
Definition: iterator_range.h:30
llvm::objcopy::coff::Section::UniqueId
ssize_t UniqueId
Definition: COFFObject.h:40
llvm::objcopy::coff::Symbol
Definition: COFFObject.h:83
llvm::objcopy::coff::Object::CoffFileHeader
object::coff_file_header CoffFileHeader
Definition: COFFObject.h:102
copy
we should consider alternate ways to model stack dependencies Lots of things could be done in WebAssemblyTargetTransformInfo cpp there are numerous optimization related hooks that can be overridden in WebAssemblyTargetLowering Instead of the OptimizeReturned which should consider preserving the returned attribute through to MachineInstrs and extending the MemIntrinsicResults pass to do this optimization on calls too That would also let the WebAssemblyPeephole pass clean up dead defs for such as it does for stores Consider implementing and or getMachineCombinerPatterns Find a clean way to fix the problem which leads to the Shrink Wrapping pass being run after the WebAssembly PEI pass When setting multiple variables to the same we currently get code like const It could be done with a smaller encoding like local tee $pop5 local copy
Definition: README.txt:101
llvm::objcopy::coff::Relocation::TargetName
StringRef TargetName
Definition: COFFObject.h:33
llvm::objcopy::coff::Object::getSymbols
ArrayRef< Symbol > getSymbols() const
Definition: COFFObject.h:110