1 //===- Object.h -------------------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H
11 #define LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H
12
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/DenseMap.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ADT/iterator_range.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 {
RelocationRelocation28 Relocation() {}
RelocationRelocation29 Relocation(const object::coff_relocation& R) : Reloc(R) {}
30
31 object::coff_relocation Reloc;
32 size_t Target;
33 StringRef TargetName; // Used for diagnostics only
34 };
35
36 struct Section {
37 object::coff_section Header;
38 ArrayRef<uint8_t> Contents;
39 std::vector<Relocation> Relocs;
40 StringRef Name;
41 };
42
43 struct Symbol {
44 object::coff_symbol32 Sym;
45 StringRef Name;
46 ArrayRef<uint8_t> AuxData;
47 size_t UniqueId;
48 size_t RawIndex;
49 bool Referenced;
50 };
51
52 struct Object {
53 bool IsPE = false;
54
55 object::dos_header DosHeader;
56 ArrayRef<uint8_t> DosStub;
57
58 object::coff_file_header CoffFileHeader;
59
60 bool Is64 = false;
61 object::pe32plus_header PeHeader;
62 uint32_t BaseOfData = 0; // pe32plus_header lacks this field.
63
64 std::vector<object::data_directory> DataDirectories;
65 std::vector<Section> Sections;
66
getSymbolsObject67 ArrayRef<Symbol> getSymbols() const { return Symbols; }
68 // This allows mutating individual Symbols, but not mutating the list
69 // of symbols itself.
getMutableSymbolsObject70 iterator_range<std::vector<Symbol>::iterator> getMutableSymbols() {
71 return make_range(Symbols.begin(), Symbols.end());
72 }
73
74 const Symbol *findSymbol(size_t UniqueId) const;
75
76 void addSymbols(ArrayRef<Symbol> NewSymbols);
77 void removeSymbols(function_ref<bool(const Symbol &)> ToRemove);
78
79 // Set the Referenced field on all Symbols, based on relocations in
80 // all sections.
81 Error markSymbols();
82
83 private:
84 std::vector<Symbol> Symbols;
85 DenseMap<size_t, Symbol *> SymbolMap;
86
87 size_t NextSymbolUniqueId = 0;
88
89 // Update SymbolMap and RawIndex in each Symbol.
90 void updateSymbols();
91 };
92
93 // Copy between coff_symbol16 and coff_symbol32.
94 // The source and destination files can use either coff_symbol16 or
95 // coff_symbol32, while we always store them as coff_symbol32 in the
96 // intermediate data structure.
97 template <class Symbol1Ty, class Symbol2Ty>
copySymbol(Symbol1Ty & Dest,const Symbol2Ty & Src)98 void copySymbol(Symbol1Ty &Dest, const Symbol2Ty &Src) {
99 static_assert(sizeof(Dest.Name.ShortName) == sizeof(Src.Name.ShortName),
100 "Mismatched name sizes");
101 memcpy(Dest.Name.ShortName, Src.Name.ShortName, sizeof(Dest.Name.ShortName));
102 Dest.Value = Src.Value;
103 Dest.SectionNumber = Src.SectionNumber;
104 Dest.Type = Src.Type;
105 Dest.StorageClass = Src.StorageClass;
106 Dest.NumberOfAuxSymbols = Src.NumberOfAuxSymbols;
107 }
108
109 // Copy between pe32_header and pe32plus_header.
110 // We store the intermediate state in a pe32plus_header.
111 template <class PeHeader1Ty, class PeHeader2Ty>
copyPeHeader(PeHeader1Ty & Dest,const PeHeader2Ty & Src)112 void copyPeHeader(PeHeader1Ty &Dest, const PeHeader2Ty &Src) {
113 Dest.Magic = Src.Magic;
114 Dest.MajorLinkerVersion = Src.MajorLinkerVersion;
115 Dest.MinorLinkerVersion = Src.MinorLinkerVersion;
116 Dest.SizeOfCode = Src.SizeOfCode;
117 Dest.SizeOfInitializedData = Src.SizeOfInitializedData;
118 Dest.SizeOfUninitializedData = Src.SizeOfUninitializedData;
119 Dest.AddressOfEntryPoint = Src.AddressOfEntryPoint;
120 Dest.BaseOfCode = Src.BaseOfCode;
121 Dest.ImageBase = Src.ImageBase;
122 Dest.SectionAlignment = Src.SectionAlignment;
123 Dest.FileAlignment = Src.FileAlignment;
124 Dest.MajorOperatingSystemVersion = Src.MajorOperatingSystemVersion;
125 Dest.MinorOperatingSystemVersion = Src.MinorOperatingSystemVersion;
126 Dest.MajorImageVersion = Src.MajorImageVersion;
127 Dest.MinorImageVersion = Src.MinorImageVersion;
128 Dest.MajorSubsystemVersion = Src.MajorSubsystemVersion;
129 Dest.MinorSubsystemVersion = Src.MinorSubsystemVersion;
130 Dest.Win32VersionValue = Src.Win32VersionValue;
131 Dest.SizeOfImage = Src.SizeOfImage;
132 Dest.SizeOfHeaders = Src.SizeOfHeaders;
133 Dest.CheckSum = Src.CheckSum;
134 Dest.Subsystem = Src.Subsystem;
135 Dest.DLLCharacteristics = Src.DLLCharacteristics;
136 Dest.SizeOfStackReserve = Src.SizeOfStackReserve;
137 Dest.SizeOfStackCommit = Src.SizeOfStackCommit;
138 Dest.SizeOfHeapReserve = Src.SizeOfHeapReserve;
139 Dest.SizeOfHeapCommit = Src.SizeOfHeapCommit;
140 Dest.LoaderFlags = Src.LoaderFlags;
141 Dest.NumberOfRvaAndSize = Src.NumberOfRvaAndSize;
142 }
143
144 } // end namespace coff
145 } // end namespace objcopy
146 } // end namespace llvm
147
148 #endif // LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H
149