LLVM: lib/ObjCopy/COFF/COFFReader.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

16#include

17#include

18

19namespace llvm {

21namespace coff {

22

23using namespace object;

24using namespace COFF;

25

26Error COFFReader::readExecutableHeaders(Object &Obj) const {

27 const dos_header *DH = COFFObj.getDOSHeader();

28 Obj.Is64 = COFFObj.is64();

29 if (!DH)

31

32 Obj.IsPE = true;

33 Obj.DosHeader = *DH;

34 if (DH->AddressOfNewExeHeader > sizeof(*DH))

35 Obj.DosStub = ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&DH[1]),

36 DH->AddressOfNewExeHeader - sizeof(*DH));

37

38 if (COFFObj.is64()) {

39 Obj.PeHeader = *COFFObj.getPE32PlusHeader();

40 } else {

41 const pe32_header *PE32 = COFFObj.getPE32Header();

43

44 Obj.BaseOfData = PE32->BaseOfData;

45 }

46

47 for (size_t I = 0; I < Obj.PeHeader.NumberOfRvaAndSize; I++) {

48 const data_directory *Dir = COFFObj.getDataDirectory(I);

49 if (!Dir)

51 Obj.DataDirectories.emplace_back(*Dir);

52 }

54}

55

56Error COFFReader::readSections(Object &Obj) const {

57 std::vector

Sections;

58

59 for (size_t I = 1, E = COFFObj.getNumberOfSections(); I <= E; I++) {

60 Expected<const coff_section *> SecOrErr = COFFObj.getSection(I);

61 if (!SecOrErr)

62 return SecOrErr.takeError();

63 const coff_section *Sec = *SecOrErr;

64 Sections.push_back(Section());

65 Section &S = Sections.back();

66 S.Header = *Sec;

68 ArrayRef<uint8_t> Contents;

69 if (Error E = COFFObj.getSectionContents(Sec, Contents))

70 return E;

71 S.setContentsRef(Contents);

74 if (Expected NameOrErr = COFFObj.getSectionName(Sec))

75 S.Name = *NameOrErr;

76 else

77 return NameOrErr.takeError();

78 }

79 Obj.addSections(Sections);

81}

82

83Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {

84 std::vector Symbols;

85 Symbols.reserve(COFFObj.getNumberOfSymbols());

87 for (uint32_t I = 0, E = COFFObj.getNumberOfSymbols(); I < E;) {

88 Expected SymOrErr = COFFObj.getSymbol(I);

89 if (!SymOrErr)

90 return SymOrErr.takeError();

91 COFFSymbolRef SymRef = *SymOrErr;

92

95

96 if (IsBigObj)

98 *reinterpret_cast<const coff_symbol32 *>(SymRef.getRawPtr()));

99 else

101 *reinterpret_cast<const coff_symbol16 *>(SymRef.getRawPtr()));

102 auto NameOrErr = COFFObj.getSymbolName(SymRef);

103 if (!NameOrErr)

104 return NameOrErr.takeError();

105 Sym.Name = *NameOrErr;

106

107 ArrayRef<uint8_t> AuxData = COFFObj.getSymbolAuxData(SymRef);

109 assert(AuxData.size() == SymSize * SymRef.getNumberOfAuxSymbols());

110

111

112

113

114

115

116 if (SymRef.isFileRecord())

117 Sym.AuxFile = StringRef(reinterpret_cast<const char *>(AuxData.data()),

118 AuxData.size())

119 .rtrim('\0');

120 else

121 for (size_t I = 0; I < SymRef.getNumberOfAuxSymbols(); I++)

122 Sym.AuxData.push_back(AuxData.slice(I * SymSize, sizeof(AuxSymbol)));

123

124

125 if (SymRef.getSectionNumber() <=

126 0)

127 Sym.TargetSectionId = SymRef.getSectionNumber();

128 else if (static_cast<uint32_t>(SymRef.getSectionNumber() - 1) <

129 Sections.size())

130 Sym.TargetSectionId = Sections[SymRef.getSectionNumber() - 1].UniqueId;

131 else

133 "section number out of range");

134

135

136 const coff_aux_section_definition *SD = SymRef.getSectionDefinition();

137 const coff_aux_weak_external *WE = SymRef.getWeakExternal();

139 int32_t Index = SD->getNumber(IsBigObj);

140 if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size())

142 "unexpected associative section index");

143 Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId;

144 } else if (WE) {

145

146

147

148 Sym.WeakTargetSymbolId = WE->TagIndex;

149 }

150 I += 1 + SymRef.getNumberOfAuxSymbols();

151 }

152 Obj.addSymbols(Symbols);

154}

155

156Error COFFReader::setSymbolTargets(Object &Obj) const {

157 std::vector<const Symbol *> RawSymbolTable;

158 for (const Symbol &Sym : Obj.getSymbols()) {

159 RawSymbolTable.push_back(&Sym);

160 for (size_t I = 0; I < Sym.Sym.NumberOfAuxSymbols; I++)

161 RawSymbolTable.push_back(nullptr);

162 }

163 for (Symbol &Sym : Obj.getMutableSymbols()) {

164

165

166 if (Sym.WeakTargetSymbolId) {

167 if (*Sym.WeakTargetSymbolId >= RawSymbolTable.size())

169 "weak external reference out of range");

170 const Symbol *Target = RawSymbolTable[*Sym.WeakTargetSymbolId];

171 if (Target == nullptr)

173 "invalid SymbolTableIndex");

174 Sym.WeakTargetSymbolId = Target->UniqueId;

175 }

176 }

177 for (Section &Sec : Obj.getMutableSections()) {

178 for (Relocation &R : Sec.Relocs) {

179 if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size())

181 "SymbolTableIndex out of range");

182 const Symbol *Sym = RawSymbolTable[R.Reloc.SymbolTableIndex];

183 if (Sym == nullptr)

185 "invalid SymbolTableIndex");

186 R.Target = Sym->UniqueId;

187 R.TargetName = Sym->Name;

188 }

189 }

191}

192

194 auto Obj = std::make_unique();

195

196 bool IsBigObj = false;

198 Obj->CoffFileHeader = *CFH;

199 } else {

201 if (!CBFH)

203 "no COFF file header returned");

204

205

206 Obj->CoffFileHeader.Machine = CBFH->Machine;

207 Obj->CoffFileHeader.TimeDateStamp = CBFH->TimeDateStamp;

208 IsBigObj = true;

209 }

210

211 if (Error E = readExecutableHeaders(*Obj))

212 return std::move(E);

213 if (Error E = readSections(*Obj))

214 return std::move(E);

215 if (Error E = readSymbols(*Obj, IsBigObj))

216 return std::move(E);

217 if (Error E = setSymbolTargets(*Obj))

218 return std::move(E);

219

220 return std::move(Obj);

221}

222

223}

224}

225}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Expected< std::unique_ptr< Object > > create() const

Definition COFFReader.cpp:193

@ IMAGE_SCN_LNK_NRELOC_OVFL

@ IMAGE_COMDAT_SELECT_ASSOCIATIVE

void copySymbol(Symbol1Ty &Dest, const Symbol2Ty &Src)

void copyPeHeader(PeHeader1Ty &Dest, const PeHeader2Ty &Src)

coff_symbol< support::ulittle16_t > coff_symbol16

coff_symbol< support::ulittle32_t > coff_symbol32

This is an optimization pass for GlobalISel generic memory operations.

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.

ArrayRef(const T &OneElt) -> ArrayRef< T >

LLVM_ABI Error errorCodeToError(std::error_code EC)

Helper for converting an std::error_code to a Error.