24
static unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText, intptr_t DeltaForEH) {
25
uint32_t Length = *((uint32_t*)P);
27
unsigned char *Ret = P + Length;
28
uint32_t Offset = *((uint32_t*)P);
29
if (Offset == 0) // is a CIE
33
intptr_t FDELocation = *((intptr_t*)P);
34
intptr_t NewLocation = FDELocation - DeltaForText;
35
*((intptr_t*)P) = NewLocation;
36
P += sizeof(intptr_t);
38
// Skip the FDE address range
39
P += sizeof(intptr_t);
41
uint8_t Augmentationsize = *P;
43
if (Augmentationsize != 0) {
44
intptr_t LSDA = *((intptr_t*)P);
45
intptr_t NewLSDA = LSDA - DeltaForEH;
46
*((intptr_t*)P) = NewLSDA;
52
static intptr_t computeDelta(SectionEntry *A, SectionEntry *B) {
53
intptr_t ObjDistance = A->ObjAddress - B->ObjAddress;
54
intptr_t MemDistance = A->LoadAddress - B->LoadAddress;
55
return ObjDistance - MemDistance;
58
StringRef RuntimeDyldMachO::getEHFrameSection() {
59
SectionEntry *Text = NULL;
60
SectionEntry *EHFrame = NULL;
61
SectionEntry *ExceptTab = NULL;
62
for (int i = 0, e = Sections.size(); i != e; ++i) {
63
if (Sections[i].Name == "__eh_frame")
64
EHFrame = &Sections[i];
65
else if (Sections[i].Name == "__text")
67
else if (Sections[i].Name == "__gcc_except_tab")
68
ExceptTab = &Sections[i];
70
if (Text == NULL || EHFrame == NULL)
73
intptr_t DeltaForText = computeDelta(Text, EHFrame);
74
intptr_t DeltaForEH = 0;
76
DeltaForEH = computeDelta(ExceptTab, EHFrame);
78
unsigned char *P = EHFrame->Address;
79
unsigned char *End = P + EHFrame->Size;
81
P = processFDE(P, DeltaForText, DeltaForEH);
84
return StringRef((char*)EHFrame->Address, EHFrame->Size);
87
void RuntimeDyldMachO::resolveRelocation(const RelocationEntry &RE,
89
const SectionEntry &Section = Sections[RE.SectionID];
90
return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,
24
94
void RuntimeDyldMachO::resolveRelocation(const SectionEntry &Section,
29
101
uint8_t *LocalAddress = Section.Address + Offset;
30
102
uint64_t FinalAddress = Section.LoadAddress + Offset;
31
bool isPCRel = (Type >> 24) & 1;
32
unsigned MachoType = (Type >> 28) & 0xf;
33
unsigned Size = 1 << ((Type >> 25) & 3);
103
unsigned MachoType = Type;
104
unsigned Size = 1 << LogSize;
35
106
DEBUG(dbgs() << "resolveRelocation LocalAddress: "
36
107
<< format("%p", LocalAddress)
208
void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel,
279
void RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
209
281
ObjectImage &Obj,
210
282
ObjSectionToIDMap &ObjSectionToID,
211
283
const SymbolTableMap &Symbols,
212
284
StubMap &Stubs) {
285
const ObjectFile *OF = Obj.getObjectFile();
286
const MachOObjectFile *MachO = static_cast<const MachOObjectFile*>(OF);
287
macho::RelocationEntry RE = MachO->getRelocation(RelI.getRawDataRefImpl());
214
uint32_t RelType = (uint32_t) (Rel.Type & 0xffffffffL);
289
uint32_t RelType = MachO->getAnyRelocationType(RE);
215
290
RelocationValueRef Value;
216
SectionEntry &Section = Sections[Rel.SectionID];
218
bool isExtern = (RelType >> 27) & 1;
291
SectionEntry &Section = Sections[SectionID];
293
bool isExtern = MachO->getPlainRelocationExternal(RE);
294
bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
295
unsigned Size = MachO->getAnyRelocationLength(RE);
297
RelI.getOffset(Offset);
298
uint8_t *LocalAddress = Section.Address + Offset;
299
unsigned NumBytes = 1 << Size;
301
memcpy(&Addend, LocalAddress, NumBytes);
220
304
// Obtain the symbol name which is referenced in the relocation
306
RelI.getSymbol(Symbol);
221
307
StringRef TargetName;
222
const SymbolRef &Symbol = Rel.Symbol;
223
308
Symbol.getName(TargetName);
224
309
// First search for the symbol in the local symbol table
225
310
SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data());
226
311
if (lsi != Symbols.end()) {
227
312
Value.SectionID = lsi->second.first;
228
Value.Addend = lsi->second.second;
313
Value.Addend = lsi->second.second + Addend;
230
315
// Search for the symbol in the global symbol table
231
316
SymbolTableMap::const_iterator gsi = GlobalSymbolTable.find(TargetName.data());
232
317
if (gsi != GlobalSymbolTable.end()) {
233
318
Value.SectionID = gsi->second.first;
234
Value.Addend = gsi->second.second;
319
Value.Addend = gsi->second.second + Addend;
236
321
Value.SymbolName = TargetName.data();
322
Value.Addend = Addend;
240
uint8_t sectionIndex = static_cast<uint8_t>(RelType & 0xFF);
241
section_iterator si = Obj.begin_sections(),
242
se = Obj.end_sections();
243
for (uint8_t i = 1; i < sectionIndex; i++) {
249
assert(si != se && "No section containing relocation!");
250
Value.SectionID = findOrEmitSection(Obj, *si, true, ObjSectionToID);
252
// FIXME: The size and type of the relocation determines if we can
253
// encode an Addend in the target location itself, and if so, how many
254
// bytes we should read in order to get it. We don't yet support doing
255
// that, and just assuming it's sizeof(intptr_t) is blatantly wrong.
256
//Value.Addend = *(const intptr_t *)Target;
258
// The MachO addend is an offset from the current section. We need it
259
// to be an offset from the destination section
260
Value.Addend += Section.ObjAddress - Sections[Value.SectionID].ObjAddress;
326
SectionRef Sec = MachO->getRelocationSection(RE);
327
Value.SectionID = findOrEmitSection(Obj, Sec, true, ObjSectionToID);
329
Sec.getAddress(Addr);
330
Value.Addend = Addend - Addr;
264
if (Arch == Triple::arm && (RelType & 0xf) == macho::RIT_ARM_Branch24Bit) {
333
if (Arch == Triple::x86_64 && RelType == macho::RIT_X86_64_GOT) {
336
StubMap::const_iterator i = Stubs.find(Value);
338
if (i != Stubs.end()) {
339
Addr = Section.Address + i->second;
341
Stubs[Value] = Section.StubOffset;
342
uint8_t *GOTEntry = Section.Address + Section.StubOffset;
343
RelocationEntry RE(SectionID, Section.StubOffset,
344
macho::RIT_X86_64_Unsigned, Value.Addend - 4, false,
346
if (Value.SymbolName)
347
addRelocationForSymbol(RE, Value.SymbolName);
349
addRelocationForSection(RE, Value.SectionID);
350
Section.StubOffset += 8;
353
resolveRelocation(Section, Offset, (uint64_t)Addr,
354
macho::RIT_X86_64_Unsigned, 4, true, 2);
355
} else if (Arch == Triple::arm &&
356
(RelType & 0xf) == macho::RIT_ARM_Branch24Bit) {
265
357
// This is an ARM branch relocation, need to use a stub function.
267
359
// Look up for existing stub.
268
360
StubMap::const_iterator i = Stubs.find(Value);
269
361
if (i != Stubs.end())
270
resolveRelocation(Section, Rel.Offset,
362
resolveRelocation(Section, Offset,
271
363
(uint64_t)Section.Address + i->second,
364
RelType, 0, IsPCRel, Size);
274
366
// Create a new stub function.
275
367
Stubs[Value] = Section.StubOffset;
276
368
uint8_t *StubTargetAddr = createStubFunction(Section.Address +
277
369
Section.StubOffset);
278
RelocationEntry RE(Rel.SectionID, StubTargetAddr - Section.Address,
370
RelocationEntry RE(SectionID, StubTargetAddr - Section.Address,
279
371
macho::RIT_Vanilla, Value.Addend);
280
372
if (Value.SymbolName)
281
373
addRelocationForSymbol(RE, Value.SymbolName);
283
375
addRelocationForSection(RE, Value.SectionID);
284
resolveRelocation(Section, Rel.Offset,
376
resolveRelocation(Section, Offset,
285
377
(uint64_t)Section.Address + Section.StubOffset,
378
RelType, 0, IsPCRel, Size);
287
379
Section.StubOffset += getMaxStubSize();
290
RelocationEntry RE(Rel.SectionID, Rel.Offset, RelType, Value.Addend);
382
RelocationEntry RE(SectionID, Offset, RelType, Value.Addend,
291
384
if (Value.SymbolName)
292
385
addRelocationForSymbol(RE, Value.SymbolName);