blob: ca1ff7f4c60f2c1063b395248cd6d4d185f061fd [file] [log] [blame]
Martin Storsjoe84a0b52018-12-19 07:24:38 +00001//===- 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"
Martin Storsjo10b72962019-01-10 21:28:24 +000014#include "llvm/ADT/DenseMap.h"
Martin Storsjoe84a0b52018-12-19 07:24:38 +000015#include "llvm/ADT/StringRef.h"
Martin Storsjo10b72962019-01-10 21:28:24 +000016#include "llvm/ADT/iterator_range.h"
Martin Storsjoe84a0b52018-12-19 07:24:38 +000017#include "llvm/BinaryFormat/COFF.h"
18#include "llvm/Object/COFF.h"
19#include <cstddef>
20#include <cstdint>
21#include <vector>
22
23namespace llvm {
24namespace objcopy {
25namespace coff {
26
Martin Storsjo10b72962019-01-10 21:28:24 +000027struct Relocation {
28 object::coff_relocation Reloc;
29 size_t Target;
30 StringRef TargetName; // Used for diagnostics only
31};
32
Martin Storsjoe84a0b52018-12-19 07:24:38 +000033struct Section {
34 object::coff_section Header;
35 ArrayRef<uint8_t> Contents;
Martin Storsjo10b72962019-01-10 21:28:24 +000036 std::vector<Relocation> Relocs;
Martin Storsjoe84a0b52018-12-19 07:24:38 +000037 StringRef Name;
38};
39
40struct Symbol {
41 object::coff_symbol32 Sym;
42 StringRef Name;
43 ArrayRef<uint8_t> AuxData;
Martin Storsjo10b72962019-01-10 21:28:24 +000044 size_t UniqueId;
45 size_t RawIndex;
46 bool Referenced;
Martin Storsjoe84a0b52018-12-19 07:24:38 +000047};
48
49struct Object {
50 bool IsPE = false;
51
52 object::dos_header DosHeader;
53 ArrayRef<uint8_t> DosStub;
54
55 object::coff_file_header CoffFileHeader;
56
57 bool Is64 = false;
58 object::pe32plus_header PeHeader;
59 uint32_t BaseOfData = 0; // pe32plus_header lacks this field.
60
61 std::vector<object::data_directory> DataDirectories;
62 std::vector<Section> Sections;
Martin Storsjo10b72962019-01-10 21:28:24 +000063
64 ArrayRef<Symbol> getSymbols() const { return Symbols; }
65 // This allows mutating individual Symbols, but not mutating the list
66 // of symbols itself.
67 iterator_range<std::vector<Symbol>::iterator> getMutableSymbols() {
68 return make_range(Symbols.begin(), Symbols.end());
69 }
70
71 const Symbol *findSymbol(size_t UniqueId) const;
72
73 void addSymbols(ArrayRef<Symbol> NewSymbols);
74 void removeSymbols(function_ref<bool(const Symbol &)> ToRemove);
75
76 // Set the Referenced field on all Symbols, based on relocations in
77 // all sections.
78 Error markSymbols();
79
80private:
Martin Storsjoe84a0b52018-12-19 07:24:38 +000081 std::vector<Symbol> Symbols;
Martin Storsjo10b72962019-01-10 21:28:24 +000082 DenseMap<size_t, Symbol *> SymbolMap;
83
84 size_t NextSymbolUniqueId = 0;
85
86 // Update SymbolMap and RawIndex in each Symbol.
87 void updateSymbols();
Martin Storsjoe84a0b52018-12-19 07:24:38 +000088};
89
90// Copy between coff_symbol16 and coff_symbol32.
91// The source and destination files can use either coff_symbol16 or
92// coff_symbol32, while we always store them as coff_symbol32 in the
93// intermediate data structure.
94template <class Symbol1Ty, class Symbol2Ty>
95void copySymbol(Symbol1Ty &Dest, const Symbol2Ty &Src) {
96 static_assert(sizeof(Dest.Name.ShortName) == sizeof(Src.Name.ShortName),
97 "Mismatched name sizes");
98 memcpy(Dest.Name.ShortName, Src.Name.ShortName, sizeof(Dest.Name.ShortName));
99 Dest.Value = Src.Value;
100 Dest.SectionNumber = Src.SectionNumber;
101 Dest.Type = Src.Type;
102 Dest.StorageClass = Src.StorageClass;
103 Dest.NumberOfAuxSymbols = Src.NumberOfAuxSymbols;
104}
105
106// Copy between pe32_header and pe32plus_header.
107// We store the intermediate state in a pe32plus_header.
108template <class PeHeader1Ty, class PeHeader2Ty>
109void copyPeHeader(PeHeader1Ty &Dest, const PeHeader2Ty &Src) {
110 Dest.Magic = Src.Magic;
111 Dest.MajorLinkerVersion = Src.MajorLinkerVersion;
112 Dest.MinorLinkerVersion = Src.MinorLinkerVersion;
113 Dest.SizeOfCode = Src.SizeOfCode;
114 Dest.SizeOfInitializedData = Src.SizeOfInitializedData;
115 Dest.SizeOfUninitializedData = Src.SizeOfUninitializedData;
116 Dest.AddressOfEntryPoint = Src.AddressOfEntryPoint;
117 Dest.BaseOfCode = Src.BaseOfCode;
118 Dest.ImageBase = Src.ImageBase;
119 Dest.SectionAlignment = Src.SectionAlignment;
120 Dest.FileAlignment = Src.FileAlignment;
121 Dest.MajorOperatingSystemVersion = Src.MajorOperatingSystemVersion;
122 Dest.MinorOperatingSystemVersion = Src.MinorOperatingSystemVersion;
123 Dest.MajorImageVersion = Src.MajorImageVersion;
124 Dest.MinorImageVersion = Src.MinorImageVersion;
125 Dest.MajorSubsystemVersion = Src.MajorSubsystemVersion;
126 Dest.MinorSubsystemVersion = Src.MinorSubsystemVersion;
127 Dest.Win32VersionValue = Src.Win32VersionValue;
128 Dest.SizeOfImage = Src.SizeOfImage;
129 Dest.SizeOfHeaders = Src.SizeOfHeaders;
130 Dest.CheckSum = Src.CheckSum;
131 Dest.Subsystem = Src.Subsystem;
132 Dest.DLLCharacteristics = Src.DLLCharacteristics;
133 Dest.SizeOfStackReserve = Src.SizeOfStackReserve;
134 Dest.SizeOfStackCommit = Src.SizeOfStackCommit;
135 Dest.SizeOfHeapReserve = Src.SizeOfHeapReserve;
136 Dest.SizeOfHeapCommit = Src.SizeOfHeapCommit;
137 Dest.LoaderFlags = Src.LoaderFlags;
138 Dest.NumberOfRvaAndSize = Src.NumberOfRvaAndSize;
139}
140
141} // end namespace coff
142} // end namespace objcopy
143} // end namespace llvm
144
145#endif // LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H