OSDN Git Service

[RuntimeDyld] Thread Error through some APIs, remove calls to report_fatal_error.
[android-x86/external-llvm.git] / lib / ExecutionEngine / RuntimeDyld / Targets / RuntimeDyldCOFFI386.h
1 //===--- RuntimeDyldCOFFI386.h --- COFF/X86_64 specific code ---*- 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 // COFF x86 support for MC-JIT runtime dynamic linker.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFI386_H
15 #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFI386_H
16
17 #include "llvm/Object/COFF.h"
18 #include "llvm/Support/COFF.h"
19 #include "../RuntimeDyldCOFF.h"
20
21 #define DEBUG_TYPE "dyld"
22
23 namespace llvm {
24
25 class RuntimeDyldCOFFI386 : public RuntimeDyldCOFF {
26 public:
27   RuntimeDyldCOFFI386(RuntimeDyld::MemoryManager &MM,
28                       RuntimeDyld::SymbolResolver &Resolver)
29       : RuntimeDyldCOFF(MM, Resolver) {}
30
31   unsigned getMaxStubSize() override {
32     return 8; // 2-byte jmp instruction + 32-bit relative address + 2 byte pad
33   }
34
35   unsigned getStubAlignment() override { return 1; }
36
37   Expected<relocation_iterator>
38   processRelocationRef(unsigned SectionID,
39                        relocation_iterator RelI,
40                        const ObjectFile &Obj,
41                        ObjSectionToIDMap &ObjSectionToID,
42                        StubMap &Stubs) override {
43
44     auto Symbol = RelI->getSymbol();
45     if (Symbol == Obj.symbol_end())
46       report_fatal_error("Unknown symbol in relocation");
47
48     Expected<StringRef> TargetNameOrErr = Symbol->getName();
49     if (!TargetNameOrErr)
50       return TargetNameOrErr.takeError();
51     StringRef TargetName = *TargetNameOrErr;
52
53     auto SectionOrErr = Symbol->getSection();
54     if (!SectionOrErr)
55       return SectionOrErr.takeError();
56     auto Section = *SectionOrErr;
57
58     uint64_t RelType = RelI->getType();
59     uint64_t Offset = RelI->getOffset();
60
61 #if !defined(NDEBUG)
62     SmallString<32> RelTypeName;
63     RelI->getTypeName(RelTypeName);
64 #endif
65     DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset
66                  << " RelType: " << RelTypeName << " TargetName: " << TargetName
67                  << "\n");
68
69     unsigned TargetSectionID = -1;
70     if (Section == Obj.section_end()) {
71       RelocationEntry RE(SectionID, Offset, RelType, 0, -1, 0, 0, 0, false, 0);
72       addRelocationForSymbol(RE, TargetName);
73     } else {
74       if (auto TargetSectionIDOrErr =
75           findOrEmitSection(Obj, *Section, Section->isText(), ObjSectionToID))
76         TargetSectionID = *TargetSectionIDOrErr;
77       else
78         return TargetSectionIDOrErr.takeError();
79
80       switch (RelType) {
81       case COFF::IMAGE_REL_I386_ABSOLUTE:
82         // This relocation is ignored.
83         break;
84       case COFF::IMAGE_REL_I386_DIR32:
85       case COFF::IMAGE_REL_I386_DIR32NB:
86       case COFF::IMAGE_REL_I386_REL32: {
87         RelocationEntry RE =
88             RelocationEntry(SectionID, Offset, RelType, 0, TargetSectionID,
89                             getSymbolOffset(*Symbol), 0, 0, false, 0);
90         addRelocationForSection(RE, TargetSectionID);
91         break;
92       }
93       case COFF::IMAGE_REL_I386_SECTION: {
94         RelocationEntry RE =
95             RelocationEntry(TargetSectionID, Offset, RelType, 0);
96         addRelocationForSection(RE, TargetSectionID);
97         break;
98       }
99       case COFF::IMAGE_REL_I386_SECREL: {
100         RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType,
101                                              getSymbolOffset(*Symbol));
102         addRelocationForSection(RE, TargetSectionID);
103         break;
104       }
105       default:
106         llvm_unreachable("unsupported relocation type");
107       }
108
109     }
110
111     return ++RelI;
112   }
113
114   void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {
115     const auto Section = Sections[RE.SectionID];
116     uint8_t *Target = Section.getAddressWithOffset(RE.Offset);
117
118     switch (RE.RelType) {
119     case COFF::IMAGE_REL_I386_ABSOLUTE:
120       // This relocation is ignored.
121       break;
122     case COFF::IMAGE_REL_I386_DIR32: {
123       // The target's 32-bit VA.
124       uint64_t Result =
125           RE.Sections.SectionA == static_cast<uint32_t>(-1)
126               ? Value
127               : Sections[RE.Sections.SectionA].getLoadAddressWithOffset(
128                     RE.Addend);
129       assert(static_cast<int32_t>(Result) <= INT32_MAX &&
130              "relocation overflow");
131       assert(static_cast<int32_t>(Result) >= INT32_MIN &&
132              "relocation underflow");
133       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
134                    << " RelType: IMAGE_REL_I386_DIR32"
135                    << " TargetSection: " << RE.Sections.SectionA
136                    << " Value: " << format("0x%08" PRIx32, Result) << '\n');
137       writeBytesUnaligned(Result, Target, 4);
138       break;
139     }
140     case COFF::IMAGE_REL_I386_DIR32NB: {
141       // The target's 32-bit RVA.
142       // NOTE: use Section[0].getLoadAddress() as an approximation of ImageBase
143       uint64_t Result =
144           Sections[RE.Sections.SectionA].getLoadAddressWithOffset(RE.Addend) -
145           Sections[0].getLoadAddress();
146       assert(static_cast<int32_t>(Result) <= INT32_MAX &&
147              "relocation overflow");
148       assert(static_cast<int32_t>(Result) >= INT32_MIN &&
149              "relocation underflow");
150       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
151                    << " RelType: IMAGE_REL_I386_DIR32NB"
152                    << " TargetSection: " << RE.Sections.SectionA
153                    << " Value: " << format("0x%08" PRIx32, Result) << '\n');
154       writeBytesUnaligned(Result, Target, 4);
155       break;
156     }
157     case COFF::IMAGE_REL_I386_REL32: {
158       // 32-bit relative displacement to the target.
159       uint64_t Result = Sections[RE.Sections.SectionA].getLoadAddress() -
160                         Section.getLoadAddress() + RE.Addend - 4 - RE.Offset;
161       assert(static_cast<int32_t>(Result) <= INT32_MAX &&
162              "relocation overflow");
163       assert(static_cast<int32_t>(Result) >= INT32_MIN &&
164              "relocation underflow");
165       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
166                    << " RelType: IMAGE_REL_I386_REL32"
167                    << " TargetSection: " << RE.Sections.SectionA
168                    << " Value: " << format("0x%08" PRIx32, Result) << '\n');
169       writeBytesUnaligned(Result, Target, 4);
170       break;
171     }
172     case COFF::IMAGE_REL_I386_SECTION:
173       // 16-bit section index of the section that contains the target.
174       assert(static_cast<int32_t>(RE.SectionID) <= INT16_MAX &&
175              "relocation overflow");
176       assert(static_cast<int32_t>(RE.SectionID) >= INT16_MIN &&
177              "relocation underflow");
178       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
179                    << " RelType: IMAGE_REL_I386_SECTION Value: " << RE.SectionID
180                    << '\n');
181       writeBytesUnaligned(RE.SectionID, Target, 2);
182       break;
183     case COFF::IMAGE_REL_I386_SECREL:
184       // 32-bit offset of the target from the beginning of its section.
185       assert(static_cast<int32_t>(RE.Addend) <= INT32_MAX &&
186              "relocation overflow");
187       assert(static_cast<int32_t>(RE.Addend) >= INT32_MIN &&
188              "relocation underflow");
189       DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
190                    << " RelType: IMAGE_REL_I386_SECREL Value: " << RE.Addend
191                    << '\n');
192       writeBytesUnaligned(RE.Addend, Target, 2);
193       break;
194     default:
195       llvm_unreachable("unsupported relocation type");
196     }
197   }
198
199   void registerEHFrames() override {}
200   void deregisterEHFrames() override {}
201 };
202
203 }
204
205 #endif
206