llvm.org GIT mirror llvm / 806e03d
Add a relocation visitor to lib object. This works via caching relocated values in a map that can be passed to consumers. Add a testcase that ensures this works for llvm-dwarfdump. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167558 91177308-0d34-0410-b5e6-96231b3b80d8 Eric Christopher 6 years ago
8 changed file(s) with 342 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
1414 #ifndef LLVM_DEBUGINFO_DICONTEXT_H
1515 #define LLVM_DEBUGINFO_DICONTEXT_H
1616
17 #include "llvm/ADT/DenseMap.h"
1718 #include "llvm/ADT/SmallVector.h"
1819 #include "llvm/ADT/SmallString.h"
1920 #include "llvm/ADT/StringRef.h"
8889 }
8990 };
9091
92 // In place of applying the relocations to the data we've read from disk we use
93 // a separate mapping table to the side and checking that at locations in the dwarf
94 // we expec relocated values. This adds a bit of complexity to the dwarf
95 // parsing/extraction at the benefit of not allocating memory for the entire
96 // size of the debug info sections.
97 typedef DenseMap > RelocAddrMap;
98
9199 class DIContext {
92100 public:
93101 virtual ~DIContext();
99107 StringRef aRangeSection = StringRef(),
100108 StringRef lineSection = StringRef(),
101109 StringRef stringSection = StringRef(),
102 StringRef rangeSection = StringRef());
110 StringRef rangeSection = StringRef(),
111 const RelocAddrMap &Map = RelocAddrMap());
103112
104113 virtual void dump(raw_ostream &OS) = 0;
105114
0 //===-- RelocVisitor.h - Visitor for object file relocations -*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file provides a wrapper around all the different types of relocations
10 // in different file formats, such that a client can handle them in a unified
11 // manner by only implementing a minimal number of functions.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef _LLVM_OBJECT_RELOCVISITOR
16 #define _LLVM_OBJECT_RELOCVISITOR
17
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include "llvm/Object/ObjectFile.h"
21 #include "llvm/Object/ELF.h"
22 #include "llvm/ADT/StringRef.h"
23
24 namespace llvm {
25 namespace object {
26
27 struct RelocToApply {
28 // The computed value after applying the relevant relocations.
29 int64_t Value;
30
31 // The width of the value; how many bytes to touch when applying the
32 // relocation.
33 char Width;
34 RelocToApply(const RelocToApply &In) : Value(In.Value), Width(In.Width) {}
35 RelocToApply(int64_t Value, char Width) : Value(Value), Width(Width) {}
36 RelocToApply() : Value(0), Width(0) {}
37 };
38
39 /// @brief Base class for object file relocation visitors.
40 class RelocVisitor {
41 public:
42 explicit RelocVisitor(llvm::StringRef FileFormat)
43 : FileFormat(FileFormat), HasError(false) {}
44
45 // TODO: Should handle multiple applied relocations via either passing in the
46 // previously computed value or just count paired relocations as a single
47 // visit.
48 RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t SecAddr = 0,
49 uint64_t Value = 0) {
50 if (FileFormat == "ELF64-x86-64") {
51 switch (RelocType) {
52 case llvm::ELF::R_X86_64_NONE:
53 return visitELF_X86_64_NONE(R);
54 case llvm::ELF::R_X86_64_64:
55 return visitELF_X86_64_64(R, Value);
56 case llvm::ELF::R_X86_64_PC32:
57 return visitELF_X86_64_PC32(R, Value, SecAddr);
58 case llvm::ELF::R_X86_64_32:
59 return visitELF_X86_64_32(R, Value);
60 case llvm::ELF::R_X86_64_32S:
61 return visitELF_X86_64_32S(R, Value);
62 default:
63 HasError = true;
64 return RelocToApply();
65 }
66 }
67 return RelocToApply();
68 }
69
70 bool error() { return HasError; }
71
72 private:
73 llvm::StringRef FileFormat;
74 bool HasError;
75
76 /// Operations
77
78 // Width is the width in bytes of the extend.
79 RelocToApply zeroExtend(RelocToApply r, char Width) {
80 if (Width == r.Width)
81 return r;
82 r.Value &= (1 << ((Width * 8))) - 1;
83 return r;
84 }
85 RelocToApply signExtend(RelocToApply r, char Width) {
86 if (Width == r.Width)
87 return r;
88 bool SignBit = r.Value & (1 << ((Width * 8) - 1));
89 if (SignBit) {
90 r.Value |= ~((1 << (Width * 8)) - 1);
91 } else {
92 r.Value &= (1 << (Width * 8)) - 1;
93 }
94 return r;
95 }
96
97 /// X86-64 ELF
98 RelocToApply visitELF_X86_64_NONE(RelocationRef R) {
99 return RelocToApply(0, 0);
100 }
101 RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) {
102 int64_t Addend;
103 R.getAdditionalInfo(Addend);
104 return RelocToApply(Value + Addend, 8);
105 }
106 RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value,
107 uint64_t SecAddr) {
108 int64_t Addend;
109 R.getAdditionalInfo(Addend);
110 uint64_t Address;
111 R.getAddress(Address);
112 return RelocToApply(Value + Addend - Address, 4);
113 }
114 RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) {
115 int64_t Addend;
116 R.getAdditionalInfo(Addend);
117 uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
118 return RelocToApply(Res, 4);
119 }
120 RelocToApply visitELF_X86_64_32S(RelocationRef R, uint64_t Value) {
121 int64_t Addend;
122 R.getAdditionalInfo(Addend);
123 int32_t Res = (Value + Addend) & 0xFFFFFFFF;
124 return RelocToApply(Res, 4);
125 }
126 };
127
128 }
129 }
130 #endif
99 #ifndef LLVM_SUPPORT_DATAEXTRACTOR_H
1010 #define LLVM_SUPPORT_DATAEXTRACTOR_H
1111
12 #include "llvm/ADT/DenseMap.h"
1213 #include "llvm/ADT/StringRef.h"
1314 #include "llvm/Support/DataTypes.h"
1415
1818 StringRef aRangeSection,
1919 StringRef lineSection,
2020 StringRef stringSection,
21 StringRef rangeSection) {
21 StringRef rangeSection,
22 const RelocAddrMap &Map) {
2223 return new DWARFContextInMemory(isLittleEndian, infoSection, abbrevSection,
2324 aRangeSection, lineSection, stringSection,
24 rangeSection);
25 rangeSection, Map);
2526 }
2525 /// methods that a concrete implementation provides.
2626 class DWARFContext : public DIContext {
2727 bool IsLittleEndian;
28 const RelocAddrMap &RelocMap;
2829
2930 SmallVector CUs;
3031 OwningPtr Abbrev;
3738 /// Read compile units from the debug_info section and store them in CUs.
3839 void parseCompileUnits();
3940 protected:
40 DWARFContext(bool isLittleEndian) : IsLittleEndian(isLittleEndian) {}
41 DWARFContext(bool isLittleEndian, const RelocAddrMap &Map) :
42 IsLittleEndian(isLittleEndian), RelocMap(Map) {}
4143 public:
4244 virtual void dump(raw_ostream &OS);
45
4346 /// Get the number of compile units in this context.
4447 unsigned getNumCompileUnits() {
4548 if (CUs.empty())
6972 DILineInfoSpecifier Specifier = DILineInfoSpecifier());
7073
7174 bool isLittleEndian() const { return IsLittleEndian; }
75 const RelocAddrMap &relocMap() const { return RelocMap; }
7276
7377 virtual StringRef getInfoSection() = 0;
7478 virtual StringRef getAbbrevSection() = 0;
107111 StringRef aRangeSection,
108112 StringRef lineSection,
109113 StringRef stringSection,
110 StringRef rangeSection)
111 : DWARFContext(isLittleEndian),
114 StringRef rangeSection,
115 const RelocAddrMap &Map = RelocAddrMap())
116 : DWARFContext(isLittleEndian, Map),
112117 InfoSection(infoSection),
113118 AbbrevSection(abbrevSection),
114119 ARangeSection(aRangeSection),
99 #include "DWARFFormValue.h"
1010 #include "DWARFCompileUnit.h"
1111 #include "DWARFContext.h"
12 #include "llvm/Support/Debug.h"
1213 #include "llvm/Support/Dwarf.h"
1314 #include "llvm/Support/Format.h"
1415 #include "llvm/Support/raw_ostream.h"
9798 indirect = false;
9899 switch (Form) {
99100 case DW_FORM_addr:
100 case DW_FORM_ref_addr:
101 Value.uval = data.getUnsigned(offset_ptr, cu->getAddressByteSize());
101 case DW_FORM_ref_addr: {
102 RelocAddrMap::const_iterator AI
103 = cu->getContext().relocMap().find(*offset_ptr);
104 if (AI != cu->getContext().relocMap().end()) {
105 const std::pair &R = AI->second;
106 Value.uval = R.second;
107 *offset_ptr += R.first;
108 } else
109 Value.uval = data.getUnsigned(offset_ptr, cu->getAddressByteSize());
110 }
102111 break;
103112 case DW_FORM_exprloc:
104113 case DW_FORM_block:
137146 case DW_FORM_sdata:
138147 Value.sval = data.getSLEB128(offset_ptr);
139148 break;
140 case DW_FORM_strp:
141 Value.uval = data.getU32(offset_ptr);
142 break;
149 case DW_FORM_strp: {
150 RelocAddrMap::const_iterator AI
151 = cu->getContext().relocMap().find(*offset_ptr);
152 if (AI != cu->getContext().relocMap().end()) {
153 const std::pair &R = AI->second;
154 Value.uval = R.second;
155 *offset_ptr += R.first;
156 } else
157 Value.uval = data.getU32(offset_ptr);
158 break;
159 }
143160 case DW_FORM_udata:
144161 case DW_FORM_ref_udata:
145162 Value.uval = data.getULEB128(offset_ptr);
0 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu %s -o %t -filetype=obj
1 ; RUN: llvm-dwarfdump %t | FileCheck %s
2
3 ; CHECK: 0x0000000b: DW_TAG_compile_unit
4 ; CHECK: 0x00000012: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000035] = "foo.cpp")
5 ; CHECK: 0x0000003c: DW_TAG_class_type
6 ; CHECK: 0x0000003d: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000006d] = "D")
7 ; CHECK: 0x00000044: DW_TAG_member
8 ; CHECK: 0x00000045: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000005d] = "c1")
9
10 %class.D = type { i32, i32, i32, i32 }
11
12 @_ZN1DC1Ev = alias void (%class.D*)* @_ZN1DC2Ev
13 @_ZN1DC1ERKS_ = alias void (%class.D*, %class.D*)* @_ZN1DC2ERKS_
14
15 define void @_ZN1DC2Ev(%class.D* nocapture %this) unnamed_addr nounwind uwtable align 2 {
16 entry:
17 tail call void @llvm.dbg.value(metadata !{%class.D* %this}, i64 0, metadata !29), !dbg !36
18 %c1 = getelementptr inbounds %class.D* %this, i64 0, i32 0, !dbg !37
19 store i32 1, i32* %c1, align 4, !dbg !37, !tbaa !39
20 %c2 = getelementptr inbounds %class.D* %this, i64 0, i32 1, !dbg !42
21 store i32 2, i32* %c2, align 4, !dbg !42, !tbaa !39
22 %c3 = getelementptr inbounds %class.D* %this, i64 0, i32 2, !dbg !43
23 store i32 3, i32* %c3, align 4, !dbg !43, !tbaa !39
24 %c4 = getelementptr inbounds %class.D* %this, i64 0, i32 3, !dbg !44
25 store i32 4, i32* %c4, align 4, !dbg !44, !tbaa !39
26 ret void, !dbg !45
27 }
28
29 define void @_ZN1DC2ERKS_(%class.D* nocapture %this, %class.D* nocapture %d) unnamed_addr nounwind uwtable align 2 {
30 entry:
31 tail call void @llvm.dbg.value(metadata !{%class.D* %this}, i64 0, metadata !34), !dbg !46
32 tail call void @llvm.dbg.value(metadata !{%class.D* %d}, i64 0, metadata !35), !dbg !46
33 %c1 = getelementptr inbounds %class.D* %d, i64 0, i32 0, !dbg !47
34 %0 = load i32* %c1, align 4, !dbg !47, !tbaa !39
35 %c12 = getelementptr inbounds %class.D* %this, i64 0, i32 0, !dbg !47
36 store i32 %0, i32* %c12, align 4, !dbg !47, !tbaa !39
37 %c2 = getelementptr inbounds %class.D* %d, i64 0, i32 1, !dbg !49
38 %1 = load i32* %c2, align 4, !dbg !49, !tbaa !39
39 %c23 = getelementptr inbounds %class.D* %this, i64 0, i32 1, !dbg !49
40 store i32 %1, i32* %c23, align 4, !dbg !49, !tbaa !39
41 %c3 = getelementptr inbounds %class.D* %d, i64 0, i32 2, !dbg !50
42 %2 = load i32* %c3, align 4, !dbg !50, !tbaa !39
43 %c34 = getelementptr inbounds %class.D* %this, i64 0, i32 2, !dbg !50
44 store i32 %2, i32* %c34, align 4, !dbg !50, !tbaa !39
45 %c4 = getelementptr inbounds %class.D* %d, i64 0, i32 3, !dbg !51
46 %3 = load i32* %c4, align 4, !dbg !51, !tbaa !39
47 %c45 = getelementptr inbounds %class.D* %this, i64 0, i32 3, !dbg !51
48 store i32 %3, i32* %c45, align 4, !dbg !51, !tbaa !39
49 ret void, !dbg !52
50 }
51
52 declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
53
54 !llvm.dbg.cu = !{!0}
55
56 !0 = metadata !{i32 786449, i32 0, i32 4, metadata !"foo.cpp", metadata !"/usr/local/google/home/echristo", metadata !"clang version 3.2 (trunk 167506) (llvm/trunk 167505)", i1 true, i1 true, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !1} ; [ DW_TAG_compile_unit ] [/usr/local/google/home/echristo/foo.cpp] [DW_LANG_C_plus_plus]
57 !1 = metadata !{metadata !2}
58 !2 = metadata !{i32 0}
59 !3 = metadata !{metadata !4}
60 !4 = metadata !{metadata !5, metadata !31}
61 !5 = metadata !{i32 786478, i32 0, null, metadata !"D", metadata !"D", metadata !"_ZN1DC2Ev", metadata !6, i32 12, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, void (%class.D*)* @_ZN1DC2Ev, null, metadata !17, metadata !27, i32 12} ; [ DW_TAG_subprogram ] [line 12] [def] [D]
62 !6 = metadata !{i32 786473, metadata !"foo.cpp", metadata !"/usr/local/google/home/echristo", null} ; [ DW_TAG_file_type ]
63 !7 = metadata !{i32 786453, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
64 !8 = metadata !{null, metadata !9}
65 !9 = metadata !{i32 786447, i32 0, metadata !"", i32 0, i32 0, i64 64, i64 64, i64 0, i32 1088, metadata !10} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from D]
66 !10 = metadata !{i32 786434, null, metadata !"D", metadata !6, i32 1, i64 128, i64 32, i32 0, i32 0, null, metadata !11, i32 0, null, null} ; [ DW_TAG_class_type ] [D] [line 1, size 128, align 32, offset 0] [from ]
67 !11 = metadata !{metadata !12, metadata !14, metadata !15, metadata !16, metadata !17, metadata !20}
68 !12 = metadata !{i32 786445, metadata !10, metadata !"c1", metadata !6, i32 6, i64 32, i64 32, i64 0, i32 1, metadata !13} ; [ DW_TAG_member ] [c1] [line 6, size 32, align 32, offset 0] [private] [from int]
69 !13 = metadata !{i32 786468, null, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
70 !14 = metadata !{i32 786445, metadata !10, metadata !"c2", metadata !6, i32 7, i64 32, i64 32, i64 32, i32 1, metadata !13} ; [ DW_TAG_member ] [c2] [line 7, size 32, align 32, offset 32] [private] [from int]
71 !15 = metadata !{i32 786445, metadata !10, metadata !"c3", metadata !6, i32 8, i64 32, i64 32, i64 64, i32 1, metadata !13} ; [ DW_TAG_member ] [c3] [line 8, size 32, align 32, offset 64] [private] [from int]
72 !16 = metadata !{i32 786445, metadata !10, metadata !"c4", metadata !6, i32 9, i64 32, i64 32, i64 96, i32 1, metadata !13} ; [ DW_TAG_member ] [c4] [line 9, size 32, align 32, offset 96] [private] [from int]
73 !17 = metadata !{i32 786478, i32 0, metadata !10, metadata !"D", metadata !"D", metadata !"", metadata !6, i32 3, metadata !7, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 true, null, null, i32 0, metadata !18, i32 3} ; [ DW_TAG_subprogram ] [line 3] [D]
74 !18 = metadata !{metadata !19}
75 !19 = metadata !{i32 786468} ; [ DW_TAG_base_type ] [line 0, size 0, align 0, offset 0]
76 !20 = metadata !{i32 786478, i32 0, metadata !10, metadata !"D", metadata !"D", metadata !"", metadata !6, i32 4, metadata !21, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 true, null, null, i32 0, metadata !25, i32 4} ; [ DW_TAG_subprogram ] [line 4] [D]
77 !21 = metadata !{i32 786453, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !22, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
78 !22 = metadata !{null, metadata !9, metadata !23}
79 !23 = metadata !{i32 786448, null, null, null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !24} ; [ DW_TAG_reference_type ] [line 0, size 0, align 0, offset 0] [from ]
80 !24 = metadata !{i32 786470, null, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !10} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from D]
81 !25 = metadata !{metadata !26}
82 !26 = metadata !{i32 786468} ; [ DW_TAG_base_type ] [line 0, size 0, align 0, offset 0]
83 !27 = metadata !{metadata !28}
84 !28 = metadata !{metadata !29}
85 !29 = metadata !{i32 786689, metadata !5, metadata !"this", metadata !6, i32 16777228, metadata !30, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 12]
86 !30 = metadata !{i32 786447, null, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !10} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from D]
87 !31 = metadata !{i32 786478, i32 0, null, metadata !"D", metadata !"D", metadata !"_ZN1DC2ERKS_", metadata !6, i32 19, metadata !21, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, void (%class.D*, %class.D*)* @_ZN1DC2ERKS_, null, metadata !20, metadata !32, i32 19} ; [ DW_TAG_subprogram ] [line 19] [def] [D]
88 !32 = metadata !{metadata !33}
89 !33 = metadata !{metadata !34, metadata !35}
90 !34 = metadata !{i32 786689, metadata !31, metadata !"this", metadata !6, i32 16777235, metadata !30, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 19]
91 !35 = metadata !{i32 786689, metadata !31, metadata !"d", metadata !6, i32 33554451, metadata !23, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [d] [line 19]
92 !36 = metadata !{i32 12, i32 0, metadata !5, null}
93 !37 = metadata !{i32 13, i32 0, metadata !38, null}
94 !38 = metadata !{i32 786443, metadata !5, i32 12, i32 0, metadata !6, i32 0} ; [ DW_TAG_lexical_block ] [/usr/local/google/home/echristo/foo.cpp]
95 !39 = metadata !{metadata !"int", metadata !40}
96 !40 = metadata !{metadata !"omnipotent char", metadata !41}
97 !41 = metadata !{metadata !"Simple C/C++ TBAA"}
98 !42 = metadata !{i32 14, i32 0, metadata !38, null}
99 !43 = metadata !{i32 15, i32 0, metadata !38, null}
100 !44 = metadata !{i32 16, i32 0, metadata !38, null}
101 !45 = metadata !{i32 17, i32 0, metadata !38, null}
102 !46 = metadata !{i32 19, i32 0, metadata !31, null}
103 !47 = metadata !{i32 20, i32 0, metadata !48, null}
104 !48 = metadata !{i32 786443, metadata !31, i32 19, i32 0, metadata !6, i32 1} ; [ DW_TAG_lexical_block ] [/usr/local/google/home/echristo/foo.cpp]
105 !49 = metadata !{i32 21, i32 0, metadata !48, null}
106 !50 = metadata !{i32 22, i32 0, metadata !48, null}
107 !51 = metadata !{i32 23, i32 0, metadata !48, null}
108 !52 = metadata !{i32 24, i32 0, metadata !48, null}
1414 #include "llvm/ADT/Triple.h"
1515 #include "llvm/ADT/STLExtras.h"
1616 #include "llvm/Object/ObjectFile.h"
17 #include "llvm/Object/RelocVisitor.h"
1718 #include "llvm/DebugInfo/DIContext.h"
1819 #include "llvm/Support/CommandLine.h"
1920 #include "llvm/Support/Debug.h"
2728 #include "llvm/Support/system_error.h"
2829 #include
2930 #include
31 #include
32 #include
33
3034 using namespace llvm;
3135 using namespace object;
3236
6670 OwningPtr Obj(ObjectFile::createObjectFile(Buff.take()));
6771
6872 StringRef DebugInfoSection;
73 RelocAddrMap RelocMap;
6974 StringRef DebugAbbrevSection;
7075 StringRef DebugLineSection;
7176 StringRef DebugArangesSection;
96101 DebugStringSection = data;
97102 else if (name == "debug_ranges")
98103 DebugRangesSection = data;
104 // Any more debug info sections go here.
105 else
106 continue;
107
108 // TODO: For now only handle relocations for the debug_info section.
109 if (name != "debug_info")
110 continue;
111
112 if (i->begin_relocations() != i->end_relocations()) {
113 uint64_t SectionSize;
114 i->getSize(SectionSize);
115 for (relocation_iterator reloc_i = i->begin_relocations(),
116 reloc_e = i->end_relocations();
117 reloc_i != reloc_e; reloc_i.increment(ec)) {
118 uint64_t Address;
119 reloc_i->getAddress(Address);
120 uint64_t Type;
121 reloc_i->getType(Type);
122
123 RelocVisitor V(Obj->getFileFormatName());
124 // The section address is always 0 for debug sections.
125 RelocToApply R(V.visit(Type, *reloc_i));
126 if (V.error()) {
127 SmallString<32> Name;
128 error_code ec(reloc_i->getTypeName(Name));
129 if (ec) {
130 errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n";
131 }
132 errs() << "error: failed to compute relocation: "
133 << Name << "\n";
134 continue;
135 }
136
137 if (Address + R.Width > SectionSize) {
138 errs() << "error: " << R.Width << "-byte relocation starting "
139 << Address << " bytes into section " << name << " which is "
140 << SectionSize << " bytes long.\n";
141 continue;
142 }
143 if (R.Width > 8) {
144 errs() << "error: can't handle a relocation of more than 8 bytes at "
145 "a time.\n";
146 continue;
147 }
148 DEBUG(dbgs() << "Writing " << format("%p", R.Value)
149 << " at " << format("%p", Address)
150 << " with width " << format("%d", R.Width)
151 << "\n");
152 RelocMap[Address] = std::make_pair(R.Width, R.Value);
153 }
154 }
99155 }
100156
101157 OwningPtr dictx(DIContext::getDWARFContext(/*FIXME*/true,
104160 DebugArangesSection,
105161 DebugLineSection,
106162 DebugStringSection,
107 DebugRangesSection));
163 DebugRangesSection,
164 RelocMap));
108165 if (Address == -1ULL) {
109166 outs() << Filename
110167 << ":\tfile format " << Obj->getFileFormatName() << "\n\n";