LLVM: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

19

20using namespace llvm;

22

23#define DEBUG_TYPE "dyld"

24

25namespace {

26

27class LoadedMachOObjectInfo final

29 RuntimeDyld::LoadedObjectInfo> {

30public:

32 ObjSectionToIDMap ObjSecToIDMap)

34

36 getObjectForDebug(const ObjectFile &Obj) const override {

38 }

39};

40

41}

42

43namespace llvm {

44

46 unsigned NumBytes = 1 << RE.Size;

48

50}

51

57 bool TargetIsLocalThumbFunc) {

62

64 uint32_t RelocType = Obj.getAnyRelocationType(RE);

65 bool IsPCRel = Obj.getAnyRelocationPCRel(RE);

66 unsigned Size = Obj.getAnyRelocationLength(RE);

68 uint8_t *LocalAddress = Section.getAddressWithOffset(Offset);

69 unsigned NumBytes = 1 << Size;

71

72 unsigned SymbolBaseAddr = Obj.getScatteredRelocationValue(RE);

74 assert(TargetSI != Obj.section_end() && "Can't find section for symbol");

77 bool IsCode = TargetSection.isText();

78 uint32_t TargetSectionID = ~0U;

79 if (auto TargetSectionIDOrErr =

81 TargetSectionID = *TargetSectionIDOrErr;

82 else

83 return TargetSectionIDOrErr.takeError();

84

85 Addend -= SectionBaseAddr;

87 R.IsTargetThumbFunc = TargetIsLocalThumbFunc;

88

90

91 return ++RelI;

92}

93

94

99

105

106 bool IsExternal = Obj.getPlainRelocationExternal(RelInfo);

107 if (IsExternal) {

110 if (auto TargetNameOrErr = Symbol->getName())

111 TargetName = *TargetNameOrErr;

112 else

113 return TargetNameOrErr.takeError();

117 const auto &SymInfo = SI->second;

120 } else {

121 Value.SymbolName = TargetName.data();

123 }

124 } else {

125 SectionRef Sec = Obj.getAnyRelocationSection(RelInfo);

126 bool IsCode = Sec.isText();

128 ObjSectionToID))

129 Value.SectionID = *SectionIDOrErr;

130 else

131 return SectionIDOrErr.takeError();

134 }

135

137}

138

141 unsigned OffsetToNextPC) {

145}

146

150 uint8_t *LocalAddress = Section.getAddress() + RE.Offset;

151 uint64_t FinalAddress = Section.getLoadAddress() + RE.Offset;

152

154 << " LocalAddress: " << format("%p", LocalAddress)

155 << " FinalAddress: " << format("0x%016" PRIx64, FinalAddress)

156 << " Value: " << format("0x%016" PRIx64, Value) << " Addend: " << RE.Addend

157 << " isPCRel: " << RE.IsPCRel << " MachoType: " << RE.RelType

158 << " Size: " << (1 << RE.Size) << "\n";

159}

160

166

167 for (; SI != SE; ++SI) {

170 if ((Addr >= SAddr) && (Addr < SAddr + SSize))

171 return SI;

172 }

173

174 return SE;

175}

176

177

178

182 unsigned PTSectionID) {

183 assert(!Obj.is64Bit() &&

184 "Pointer table section not supported in 64-bit MachO.");

185

189 unsigned FirstIndirectSymbol = Sec32.reserved1;

190 const unsigned PTEntrySize = 4;

191 unsigned NumPTEntries = PTSectionSize / PTEntrySize;

192 unsigned PTEntryOffset = 0;

193

194 assert((PTSectionSize % PTEntrySize) == 0 &&

195 "Pointers section does not contain a whole number of stubs?");

196

197 LLVM_DEBUG(dbgs() << "Populating pointer table section "

199 << PTSectionID << ", " << NumPTEntries << " entries, "

200 << PTEntrySize << " bytes each:\n");

201

202 for (unsigned i = 0; i < NumPTEntries; ++i) {

203 unsigned SymbolIndex =

204 Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i);

207 if (auto IndirectSymbolNameOrErr = SI->getName())

208 IndirectSymbolName = *IndirectSymbolNameOrErr;

209 else

210 return IndirectSymbolNameOrErr.takeError();

211 LLVM_DEBUG(dbgs() << " " << IndirectSymbolName << ": index " << SymbolIndex

212 << ", PT offset: " << PTEntryOffset << "\n");

216 PTEntryOffset += PTEntrySize;

217 }

219}

220

222 return Obj.isMachO();

223}

224

225template

232

233 for (const auto &Section : Obj.sections()) {

236 Name = *NameOrErr;

237 else

239

240

241

242

243 if (Name == "__text") {

244 if (auto TextSIDOrErr = findOrEmitSection(Obj, Section, true, SectionMap))

245 TextSID = *TextSIDOrErr;

246 else

247 return TextSIDOrErr.takeError();

248 } else if (Name == "__eh_frame") {

249 if (auto EHFrameSIDOrErr = findOrEmitSection(Obj, Section, false,

250 SectionMap))

251 EHFrameSID = *EHFrameSIDOrErr;

252 else

253 return EHFrameSIDOrErr.takeError();

254 } else if (Name == "__gcc_except_tab") {

255 if (auto ExceptTabSIDOrErr = findOrEmitSection(Obj, Section, true,

256 SectionMap))

257 ExceptTabSID = *ExceptTabSIDOrErr;

258 else

259 return ExceptTabSIDOrErr.takeError();

260 } else {

261 auto I = SectionMap.find(Section);

262 if (I != SectionMap.end())

263 if (auto Err = impl().finalizeSection(Obj, I->second, Section))

264 return Err;

265 }

266 }

269

271}

272

273template

274unsigned char *RuntimeDyldMachOCRTPBase::processFDE(uint8_t *P,

275 int64_t DeltaForText,

276 int64_t DeltaForEH) {

277 typedef typename Impl::TargetPtrT TargetPtrT;

278

279 LLVM_DEBUG(dbgs() << "Processing FDE: Delta for text: " << DeltaForText

280 << ", Delta for EH: " << DeltaForEH << "\n");

282 P += 4;

285 if (Offset == 0)

286 return Ret;

287

288 P += 4;

289 TargetPtrT FDELocation = readBytesUnaligned(P, sizeof(TargetPtrT));

290 TargetPtrT NewLocation = FDELocation - DeltaForText;

291 writeBytesUnaligned(NewLocation, P, sizeof(TargetPtrT));

292

293 P += sizeof(TargetPtrT);

294

295

296 P += sizeof(TargetPtrT);

297

298 uint8_t Augmentationsize = *P;

299 P += 1;

300 if (Augmentationsize != 0) {

301 TargetPtrT LSDA = readBytesUnaligned(P, sizeof(TargetPtrT));

302 TargetPtrT NewLSDA = LSDA - DeltaForEH;

303 writeBytesUnaligned(NewLSDA, P, sizeof(TargetPtrT));

304 }

305

306 return Ret;

307}

308

310 int64_t ObjDistance = static_cast<int64_t>(A->getObjAddress()) -

311 static_cast<int64_t>(B->getObjAddress());

312 int64_t MemDistance = A->getLoadAddress() - B->getLoadAddress();

313 return ObjDistance - MemDistance;

314}

315

316template

318

323 continue;

329

330 int64_t DeltaForText = computeDelta(Text, EHFrame);

331 int64_t DeltaForEH = 0;

332 if (ExceptTab)

333 DeltaForEH = computeDelta(ExceptTab, EHFrame);

334

337 while (P != End) {

338 P = processFDE(P, DeltaForText, DeltaForEH);

339 }

340

343 }

345}

346

347std::unique_ptr

351 switch (Arch) {

352 default:

353 llvm_unreachable("Unsupported target for RuntimeDyldMachO.");

354 break;

356 return std::make_unique(MemMgr, Resolver);

358 return std::make_unique(MemMgr, Resolver);

360 return std::make_unique(MemMgr, Resolver);

362 return std::make_unique(MemMgr, Resolver);

364 return std::make_unique<RuntimeDyldMachOX86_64>(MemMgr, Resolver);

365 }

366}

367

368std::unique_ptrRuntimeDyld::LoadedObjectInfo

371 return std::make_unique(*this,

372 *ObjSectionToIDOrErr);

373 else {

377 return nullptr;

378 }

379}

380

381}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static StringRef getName(Value *V)

#define RTDYLD_INVALID_SECTION_ID

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Symbol resolution interface.

RelocationEntry - used to represent relocations internally in the dynamic linker.

unsigned Size

The size of this relocation (MachO specific).

uint32_t RelType

RelType - relocation type.

uint64_t Offset

Offset - offset into the section.

bool IsPCRel

True if this is a PCRel relocation (MachO specific).

int64_t Addend

Addend - the relocation addend encoded in the instruction itself.

unsigned SectionID

SectionID - the section this relocation points to.

std::map< SectionRef, unsigned > ObjSectionToIDMap

void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName)

JITSymbolResolver & Resolver

RuntimeDyld::MemoryManager & MemMgr

void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID)

Expected< unsigned > findOrEmitSection(const ObjectFile &Obj, const SectionRef &Section, bool IsCode, ObjSectionToIDMap &LocalSections)

Find Section in LocalSections.

uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const

Endian-aware read Read the least significant Size bytes from Src.

RTDyldSymbolTable GlobalSymbolTable

Expected< ObjSectionToIDMap > loadObjectImpl(const object::ObjectFile &Obj)

void registerEHFrames() override

Definition RuntimeDyldMachO.cpp:317

Error finalizeLoad(const ObjectFile &Obj, ObjSectionToIDMap &SectionMap) override

Definition RuntimeDyldMachO.cpp:227

static std::unique_ptr< RuntimeDyldMachO > create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver)

Create a RuntimeDyldMachO instance for the given target architecture.

Definition RuntimeDyldMachO.cpp:348

static section_iterator getSectionByAddress(const MachOObjectFile &Obj, uint64_t Addr)

Definition RuntimeDyldMachO.cpp:162

int64_t memcpyAddend(const RelocationEntry &RE) const

This convenience method uses memcpy to extract a contiguous addend (the addend size and offset are ta...

Definition RuntimeDyldMachO.cpp:45

SmallVector< EHFrameRelatedSections, 2 > UnregisteredEHFrameSections

std::unique_ptr< RuntimeDyld::LoadedObjectInfo > loadObject(const object::ObjectFile &O) override

Definition RuntimeDyldMachO.cpp:369

Error populateIndirectSymbolPointersSection(const MachOObjectFile &Obj, const SectionRef &PTSection, unsigned PTSectionID)

Definition RuntimeDyldMachO.cpp:179

void makeValueAddendPCRel(RelocationValueRef &Value, const relocation_iterator &RI, unsigned OffsetToNextPC)

Make the RelocationValueRef addend PC-relative.

Definition RuntimeDyldMachO.cpp:139

Expected< RelocationValueRef > getRelocationValueRef(const ObjectFile &BaseTObj, const relocation_iterator &RI, const RelocationEntry &RE, ObjSectionToIDMap &ObjSectionToID)

Construct a RelocationValueRef representing the relocation target.

Definition RuntimeDyldMachO.cpp:96

Expected< relocation_iterator > processScatteredVANILLA(unsigned SectionID, relocation_iterator RelI, const ObjectFile &BaseObjT, RuntimeDyldMachO::ObjSectionToIDMap &ObjSectionToID, bool TargetIsLocalThumbFunc=false)

Process a scattered vanilla relocation.

Definition RuntimeDyldMachO.cpp:53

bool isCompatibleFile(const object::ObjectFile &Obj) const override

Definition RuntimeDyldMachO.cpp:221

void dumpRelocationToResolve(const RelocationEntry &RE, uint64_t Value) const

Dump information about the relocation entry (RE) and resolved value.

Definition RuntimeDyldMachO.cpp:147

SectionEntry - represents a section emitted into memory by the dynamic linker.

uint8_t * getAddress() const

uint64_t getLoadAddress() const

StringMapIterBase< SymbolTableEntry, true > const_iterator

StringRef - Represent a constant reference to a string, i.e.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

LLVM Value Representation.

This class is the base class for all object file types.

uint64_t getOffset() const

symbol_iterator getSymbol() const

const ObjectFile * getObject() const

DataRefImpl getRawDataRefImpl() const

This is a value type class that represents a single section in the list of sections in the object fil...

DataRefImpl getRawDataRefImpl() const

uint64_t getAddress() const

bool isText() const

Whether this section contains instructions.

A raw_ostream that writes to an std::string.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

content_iterator< SectionRef > section_iterator

content_iterator< RelocationRef > relocation_iterator

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})

Log all errors (if any) in E to OS.

static int64_t computeDelta(SectionEntry *A, SectionEntry *B)

Definition RuntimeDyldMachO.cpp:309

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

void consumeError(Error Err)

Consume a Error without doing anything.

SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...