llvm.org GIT mirror llvm / 3d371bd
llvm-dwarfdump: Add support for some COFF relocations DWARF in COFF utilizes several relocations. Implement support for them in RelocVisitor to support llvm-dwarfdump. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219280 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 5 years ago
4 changed file(s) with 88 addition(s) and 37 deletion(s). Raw diff Collapse all Expand all
4646
4747 virtual std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
4848 bool &IsDefault) const = 0;
49
50 static inline bool classof(const Binary *v) { return v->isELF(); }
4951 };
5052
5153 template class ELFObjectFile : public ELFObjectFileBase {
1616 #define LLVM_OBJECT_RELOCVISITOR_H
1717
1818 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Object/COFF.h"
1920 #include "llvm/Object/ELFObjectFile.h"
2021 #include "llvm/Object/ObjectFile.h"
2122 #include "llvm/Support/Debug.h"
4546 // TODO: Should handle multiple applied relocations via either passing in the
4647 // previously computed value or just count paired relocations as a single
4748 // visit.
48 RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t SecAddr = 0,
49 uint64_t Value = 0) {
49 RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t Value = 0) {
50 if (isa(ObjToVisit))
51 return visitELF(RelocType, R, Value);
52 if (isa(ObjToVisit))
53 return visitCOFF(RelocType, R, Value);
54
55 HasError = true;
56 return RelocToApply();
57 }
58
59 bool error() { return HasError; }
60
61 private:
62 ObjectFile &ObjToVisit;
63 bool HasError;
64
65 RelocToApply visitELF(uint32_t RelocType, RelocationRef R, uint64_t Value) {
5066 if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file
5167 switch (ObjToVisit.getArch()) {
5268 case Triple::x86_64:
5672 case llvm::ELF::R_X86_64_64:
5773 return visitELF_X86_64_64(R, Value);
5874 case llvm::ELF::R_X86_64_PC32:
59 return visitELF_X86_64_PC32(R, Value, SecAddr);
75 return visitELF_X86_64_PC32(R, Value);
6076 case llvm::ELF::R_X86_64_32:
6177 return visitELF_X86_64_32(R, Value);
6278 case llvm::ELF::R_X86_64_32S:
132148 case llvm::ELF::R_386_32:
133149 return visitELF_386_32(R, Value);
134150 case llvm::ELF::R_386_PC32:
135 return visitELF_386_PC32(R, Value, SecAddr);
151 return visitELF_386_PC32(R, Value);
136152 default:
137153 HasError = true;
138154 return RelocToApply();
181197 }
182198 }
183199
184 bool error() { return HasError; }
185
186 private:
187 ObjectFile &ObjToVisit;
188 bool HasError;
189
190 int64_t getAddend32LE(RelocationRef R) {
200 RelocToApply visitCOFF(uint32_t RelocType, RelocationRef R, uint64_t Value) {
201 switch (ObjToVisit.getArch()) {
202 case Triple::x86:
203 switch (RelocType) {
204 case COFF::IMAGE_REL_I386_SECREL:
205 return visitCOFF_I386_SECREL(R, Value);
206 case COFF::IMAGE_REL_I386_DIR32:
207 return visitCOFF_I386_DIR32(R, Value);
208 }
209 break;
210 case Triple::x86_64:
211 switch (RelocType) {
212 case COFF::IMAGE_REL_AMD64_SECREL:
213 return visitCOFF_AMD64_SECREL(R, Value);
214 case COFF::IMAGE_REL_AMD64_ADDR64:
215 return visitCOFF_AMD64_ADDR64(R, Value);
216 }
217 break;
218 }
219 HasError = true;
220 return RelocToApply();
221 }
222
223 int64_t getELFAddend32LE(RelocationRef R) {
191224 const ELF32LEObjectFile *Obj = cast(R.getObjectFile());
192225 DataRefImpl DRI = R.getRawDataRefImpl();
193226 int64_t Addend;
195228 return Addend;
196229 }
197230
198 int64_t getAddend64LE(RelocationRef R) {
231 int64_t getELFAddend64LE(RelocationRef R) {
199232 const ELF64LEObjectFile *Obj = cast(R.getObjectFile());
200233 DataRefImpl DRI = R.getRawDataRefImpl();
201234 int64_t Addend;
203236 return Addend;
204237 }
205238
206 int64_t getAddend32BE(RelocationRef R) {
239 int64_t getELFAddend32BE(RelocationRef R) {
207240 const ELF32BEObjectFile *Obj = cast(R.getObjectFile());
208241 DataRefImpl DRI = R.getRawDataRefImpl();
209242 int64_t Addend;
211244 return Addend;
212245 }
213246
214 int64_t getAddend64BE(RelocationRef R) {
247 int64_t getELFAddend64BE(RelocationRef R) {
215248 const ELF64BEObjectFile *Obj = cast(R.getObjectFile());
216249 DataRefImpl DRI = R.getRawDataRefImpl();
217250 int64_t Addend;
228261 // Ideally the Addend here will be the addend in the data for
229262 // the relocation. It's not actually the case for Rel relocations.
230263 RelocToApply visitELF_386_32(RelocationRef R, uint64_t Value) {
231 int64_t Addend = getAddend32LE(R);
264 int64_t Addend = getELFAddend32LE(R);
232265 return RelocToApply(Value + Addend, 4);
233266 }
234267
235 RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value,
236 uint64_t SecAddr) {
237 int64_t Addend = getAddend32LE(R);
268 RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value) {
269 int64_t Addend = getELFAddend32LE(R);
238270 uint64_t Address;
239271 R.getOffset(Address);
240272 return RelocToApply(Value + Addend - Address, 4);
245277 return RelocToApply(0, 0);
246278 }
247279 RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) {
248 int64_t Addend = getAddend64LE(R);
280 int64_t Addend = getELFAddend64LE(R);
249281 return RelocToApply(Value + Addend, 8);
250282 }
251 RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value,
252 uint64_t SecAddr) {
253 int64_t Addend = getAddend64LE(R);
283 RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value) {
284 int64_t Addend = getELFAddend64LE(R);
254285 uint64_t Address;
255286 R.getOffset(Address);
256287 return RelocToApply(Value + Addend - Address, 4);
257288 }
258289 RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) {
259 int64_t Addend = getAddend64LE(R);
290 int64_t Addend = getELFAddend64LE(R);
260291 uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
261292 return RelocToApply(Res, 4);
262293 }
263294 RelocToApply visitELF_X86_64_32S(RelocationRef R, uint64_t Value) {
264 int64_t Addend = getAddend64LE(R);
295 int64_t Addend = getELFAddend64LE(R);
265296 int32_t Res = (Value + Addend) & 0xFFFFFFFF;
266297 return RelocToApply(Res, 4);
267298 }
281312
282313 /// PPC32 ELF
283314 RelocToApply visitELF_PPC_ADDR32(RelocationRef R, uint64_t Value) {
284 int64_t Addend = getAddend32BE(R);
315 int64_t Addend = getELFAddend32BE(R);
285316 uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
286317 return RelocToApply(Res, 4);
287318 }
322353
323354 // SystemZ ELF
324355 RelocToApply visitELF_390_32(RelocationRef R, uint64_t Value) {
325 int64_t Addend = getAddend64BE(R);
356 int64_t Addend = getELFAddend64BE(R);
326357 int64_t Res = Value + Addend;
327358
328359 // Overflow check allows for both signed and unsigned interpretation.
333364 }
334365
335366 RelocToApply visitELF_390_64(RelocationRef R, uint64_t Value) {
336 int64_t Addend = getAddend64BE(R);
367 int64_t Addend = getELFAddend64BE(R);
337368 return RelocToApply(Value + Addend, 8);
338369 }
339370
340371 RelocToApply visitELF_SPARC_32(RelocationRef R, uint32_t Value) {
341 int32_t Addend = getAddend32BE(R);
372 int32_t Addend = getELFAddend32BE(R);
342373 return RelocToApply(Value + Addend, 4);
343374 }
344375
345376 RelocToApply visitELF_SPARCV9_32(RelocationRef R, uint64_t Value) {
346 int32_t Addend = getAddend64BE(R);
377 int32_t Addend = getELFAddend64BE(R);
347378 return RelocToApply(Value + Addend, 4);
348379 }
349380
350381 RelocToApply visitELF_SPARCV9_64(RelocationRef R, uint64_t Value) {
351 int64_t Addend = getAddend64BE(R);
382 int64_t Addend = getELFAddend64BE(R);
352383 return RelocToApply(Value + Addend, 8);
353384 }
354385
364395 return RelocToApply(static_cast(Res), 4);
365396 }
366397
398 /// I386 COFF
399 RelocToApply visitCOFF_I386_SECREL(RelocationRef R, uint64_t Value) {
400 return RelocToApply(static_cast(Value), /*Width=*/4);
401 }
402
403 RelocToApply visitCOFF_I386_DIR32(RelocationRef R, uint64_t Value) {
404 return RelocToApply(static_cast(Value), /*Width=*/4);
405 }
406
407 /// AMD64 COFF
408 RelocToApply visitCOFF_AMD64_SECREL(RelocationRef R, uint64_t Value) {
409 return RelocToApply(static_cast(Value), /*Width=*/4);
410 }
411
412 RelocToApply visitCOFF_AMD64_ADDR64(RelocationRef R, uint64_t Value) {
413 return RelocToApply(Value, /*Width=*/8);
414 }
367415 };
368416
369417 }
619619 uint64_t Type;
620620 Reloc.getType(Type);
621621 uint64_t SymAddr = 0;
622 // ELF relocations may need the symbol address
623 if (Obj.isELF()) {
624 object::symbol_iterator Sym = Reloc.getSymbol();
622 object::symbol_iterator Sym = Reloc.getSymbol();
623 if (Sym != Obj.symbol_end())
625624 Sym->getAddress(SymAddr);
626 }
627625
628626 object::RelocVisitor V(Obj);
629 // The section address is always 0 for debug sections.
630 object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr));
627 object::RelocToApply R(V.visit(Type, Reloc, SymAddr));
631628 if (V.error()) {
632629 SmallString<32> Name;
633630 std::error_code ec(Reloc.getTypeName(Name));
0 ; RUN: llc -filetype=obj -O0 < %s -mtriple x86_64-none-linux | \
11 ; RUN: llvm-dwarfdump - 2>&1 | FileCheck %s
22 ; RUN: llc -filetype=obj -O0 < %s -mtriple i386-none-linux | \
3 ; RUN: llvm-dwarfdump - 2>&1 | FileCheck %s
4 ; RUN: llc -filetype=obj -O0 < %s -mtriple x86_64-none-mingw32 | \
5 ; RUN: llvm-dwarfdump - 2>&1 | FileCheck %s
6 ; RUN: llc -filetype=obj -O0 < %s -mtriple i386-none-mingw32 | \
37 ; RUN: llvm-dwarfdump - 2>&1 | FileCheck %s
48
59 ; CHECK-NOT: failed to compute relocation
1216 !1 = metadata !{metadata !"empty.c", metadata !"/a"}
1317 !2 = metadata !{}
1418 !3 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
15 !4 = metadata !{i32 2, metadata !"Debug Info Version", i32 1}
19 !4 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
1620 !5 = metadata !{metadata !"clang version 3.6.0 "}