~ubuntu-branches/ubuntu/trusty/llvm-toolchain-snapshot/trusty-201310232150

« back to all changes in this revision

Viewing changes to lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-27 15:01:57 UTC
  • mfrom: (0.10.1) (0.9.1) (0.8.1) (0.7.1) (0.6.1) (0.5.2)
  • Revision ID: package-import@ubuntu.com-20130527150157-tdkrsjpuvht7v0qx
Tags: 1:3.4~svn182733-1~exp1
* New snapshot release (3.4 release)
* Add a symlink of libLLVM-3.4.so.1 to usr/lib/llvm-3.4/lib/libLLVM-3.4.so
    to fix make the llvm-config-3.4 --libdir work (Closes: #708677)
  * Various packages rename to allow co installations:
    * libclang1 => libclang1-3.4
    * libclang1-dbg => libclang1-3.4-dbg
    * libclang-dev => libclang-3.4-dev
    * libclang-common-dev => libclang-common-3.4-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
namespace llvm {
23
23
 
 
24
static unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText, intptr_t DeltaForEH) {
 
25
  uint32_t Length = *((uint32_t*)P);
 
26
  P += 4;
 
27
  unsigned char *Ret = P + Length;
 
28
  uint32_t Offset = *((uint32_t*)P);
 
29
  if (Offset == 0) // is a CIE
 
30
    return Ret;
 
31
 
 
32
  P += 4;
 
33
  intptr_t FDELocation = *((intptr_t*)P);
 
34
  intptr_t NewLocation = FDELocation - DeltaForText;
 
35
  *((intptr_t*)P) = NewLocation;
 
36
  P += sizeof(intptr_t);
 
37
 
 
38
  // Skip the FDE address range
 
39
  P += sizeof(intptr_t);
 
40
 
 
41
  uint8_t Augmentationsize = *P;
 
42
  P += 1;
 
43
  if (Augmentationsize != 0) {
 
44
    intptr_t LSDA = *((intptr_t*)P);
 
45
    intptr_t NewLSDA = LSDA - DeltaForEH;
 
46
    *((intptr_t*)P) = NewLSDA;
 
47
  }
 
48
 
 
49
  return Ret;
 
50
}
 
51
 
 
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;
 
56
}
 
57
 
 
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")
 
66
      Text = &Sections[i];
 
67
    else if (Sections[i].Name == "__gcc_except_tab")
 
68
      ExceptTab = &Sections[i];
 
69
  }
 
70
  if (Text == NULL || EHFrame == NULL)
 
71
    return StringRef();
 
72
 
 
73
  intptr_t DeltaForText = computeDelta(Text, EHFrame);
 
74
  intptr_t DeltaForEH = 0;
 
75
  if (ExceptTab)
 
76
    DeltaForEH = computeDelta(ExceptTab, EHFrame);
 
77
 
 
78
  unsigned char *P = EHFrame->Address;
 
79
  unsigned char *End = P + EHFrame->Size;
 
80
  do  {
 
81
    P = processFDE(P, DeltaForText, DeltaForEH);
 
82
  } while(P != End);
 
83
 
 
84
  return StringRef((char*)EHFrame->Address, EHFrame->Size);
 
85
}
 
86
 
 
87
void RuntimeDyldMachO::resolveRelocation(const RelocationEntry &RE,
 
88
                                         uint64_t Value) {
 
89
  const SectionEntry &Section = Sections[RE.SectionID];
 
90
  return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,
 
91
                           RE.IsPCRel, RE.Size);
 
92
}
 
93
 
24
94
void RuntimeDyldMachO::resolveRelocation(const SectionEntry &Section,
25
95
                                         uint64_t Offset,
26
96
                                         uint64_t Value,
27
97
                                         uint32_t Type,
28
 
                                         int64_t Addend) {
 
98
                                         int64_t Addend,
 
99
                                         bool isPCRel,
 
100
                                         unsigned LogSize) {
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;
34
105
 
35
106
  DEBUG(dbgs() << "resolveRelocation LocalAddress: " 
36
107
        << format("%p", LocalAddress)
205
276
  return false;
206
277
}
207
278
 
208
 
void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel,
 
279
void RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
 
280
                                            RelocationRef RelI,
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());
213
288
 
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];
217
 
 
218
 
  bool isExtern = (RelType >> 27) & 1;
 
291
  SectionEntry &Section = Sections[SectionID];
 
292
 
 
293
  bool isExtern = MachO->getPlainRelocationExternal(RE);
 
294
  bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
 
295
  unsigned Size = MachO->getAnyRelocationLength(RE);
 
296
  uint64_t Offset;
 
297
  RelI.getOffset(Offset);
 
298
  uint8_t *LocalAddress = Section.Address + Offset;
 
299
  unsigned NumBytes = 1 << Size;
 
300
  uint64_t Addend = 0;
 
301
  memcpy(&Addend, LocalAddress, NumBytes);
 
302
 
219
303
  if (isExtern) {
220
304
    // Obtain the symbol name which is referenced in the relocation
 
305
    SymbolRef Symbol;
 
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;
229
314
    } else {
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;
235
 
      } else
 
319
        Value.Addend = gsi->second.second + Addend;
 
320
      } else {
236
321
        Value.SymbolName = TargetName.data();
 
322
        Value.Addend = Addend;
 
323
      }
237
324
    }
238
325
  } else {
239
 
    error_code err;
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++) {
244
 
      error_code err;
245
 
      si.increment(err);
246
 
      if (si == se)
247
 
        break;
248
 
    }
249
 
    assert(si != se && "No section containing relocation!");
250
 
    Value.SectionID = findOrEmitSection(Obj, *si, true, ObjSectionToID);
251
 
    Value.Addend = 0;
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;
257
 
    if (Value.Addend) {
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;
261
 
    }
 
326
    SectionRef Sec = MachO->getRelocationSection(RE);
 
327
    Value.SectionID = findOrEmitSection(Obj, Sec, true, ObjSectionToID);
 
328
    uint64_t Addr;
 
329
    Sec.getAddress(Addr);
 
330
    Value.Addend = Addend - Addr;
262
331
  }
263
332
 
264
 
  if (Arch == Triple::arm && (RelType & 0xf) == macho::RIT_ARM_Branch24Bit) {
 
333
  if (Arch == Triple::x86_64 && RelType == macho::RIT_X86_64_GOT) {
 
334
    assert(IsPCRel);
 
335
    assert(Size == 2);
 
336
    StubMap::const_iterator i = Stubs.find(Value);
 
337
    uint8_t *Addr;
 
338
    if (i != Stubs.end()) {
 
339
      Addr = Section.Address + i->second;
 
340
    } else {
 
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,
 
345
                         3);
 
346
      if (Value.SymbolName)
 
347
        addRelocationForSymbol(RE, Value.SymbolName);
 
348
      else
 
349
        addRelocationForSection(RE, Value.SectionID);
 
350
      Section.StubOffset += 8;
 
351
      Addr = GOTEntry;
 
352
    }
 
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.
266
358
 
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,
272
 
                        RelType, 0);
 
364
                        RelType, 0, IsPCRel, Size);
273
365
    else {
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);
282
374
      else
283
375
        addRelocationForSection(RE, Value.SectionID);
284
 
      resolveRelocation(Section, Rel.Offset,
 
376
      resolveRelocation(Section, Offset,
285
377
                        (uint64_t)Section.Address + Section.StubOffset,
286
 
                        RelType, 0);
 
378
                        RelType, 0, IsPCRel, Size);
287
379
      Section.StubOffset += getMaxStubSize();
288
380
    }
289
381
  } else {
290
 
    RelocationEntry RE(Rel.SectionID, Rel.Offset, RelType, Value.Addend);
 
382
    RelocationEntry RE(SectionID, Offset, RelType, Value.Addend,
 
383
                       IsPCRel, Size);
291
384
    if (Value.SymbolName)
292
385
      addRelocationForSymbol(RE, Value.SymbolName);
293
386
    else