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

1

2

3

4

5

6

7

8

9

10

11

12

23#include

24

25#include

26

27using namespace llvm;

29

30#define DEBUG_TYPE "dyld"

31

32namespace {

33

34enum RuntimeDyldErrorCode {

35 GenericRTDyldError = 1

36};

37

38

39

40

41class RuntimeDyldErrorCategory : public std::error_category {

42public:

43 const char *name() const noexcept override { return "runtimedyld"; }

44

45 std::string message(int Condition) const override {

46 switch (static_cast<RuntimeDyldErrorCode>(Condition)) {

47 case GenericRTDyldError: return "Generic RuntimeDyld error";

48 }

50 }

51};

52

53}

54

56

58 OS << ErrMsg << "\n";

59}

60

62 static RuntimeDyldErrorCategory RTDyldErrorCategory;

63 return std::error_code(GenericRTDyldError, RTDyldErrorCategory);

64}

65

66

68

69

71

72namespace llvm {

73

75

77 MemMgr.deregisterEHFrames();

78}

79

80#ifndef NDEBUG

82 dbgs() << "----- Contents of section " << S.getName() << " " << State

83 << " -----";

84

86 dbgs() << "\n

\n";

87 return;

88 }

89

90 const unsigned ColsPerRow = 16;

91

94

95 unsigned StartPadding = LoadAddr & (ColsPerRow - 1);

96 unsigned BytesRemaining = S.getSize();

97

98 if (StartPadding) {

99 dbgs() << "\n" << format("0x%016" PRIx64,

100 LoadAddr & ~(uint64_t)(ColsPerRow - 1)) << ":";

101 while (StartPadding--)

102 dbgs() << " ";

103 }

104

105 while (BytesRemaining > 0) {

106 if ((LoadAddr & (ColsPerRow - 1)) == 0)

107 dbgs() << "\n" << format("0x%016" PRIx64, LoadAddr) << ":";

108

109 dbgs() << " " << format("%02x", *DataAddr);

110

111 ++DataAddr;

112 ++LoadAddr;

113 --BytesRemaining;

114 }

115

116 dbgs() << "\n";

117}

118#endif

119

120

122 std::lock_guardsys::Mutex locked(lock);

123

124

128 });

129

130

134 }

135

137

138

142 });

143}

144

146

148

149

150

151 unsigned Idx = Rel.first;

153 LLVM_DEBUG(dbgs() << "Resolving relocations Section #" << Idx << "\t"

154 << format("%p", (uintptr_t)Addr) << "\n");

156 }

158}

159

162 std::lock_guardsys::Mutex locked(lock);

163 for (unsigned i = 0, e = Sections.size(); i != e; ++i) {

164 if (Sections[i].getAddress() == LocalAddress) {

166 return;

167 }

168 }

169 llvm_unreachable("Attempting to remap address of unknown section!");

170}

171

175 if (!AddressOrErr)

177 Result = *AddressOrErr - Sec.getAddress();

179}

180

183 std::lock_guardsys::Mutex locked(lock);

184

185

186 Arch = Obj.getArch();

189

190

191

192 if (MemMgr.needsToReserveAllocationSpace()) {

194 Align CodeAlign, RODataAlign, RWDataAlign;

196 RODataAlign, RWDataSize, RWDataAlign))

197 return std::move(Err);

198 MemMgr.reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign,

199 RWDataSize, RWDataAlign);

200 }

201

202

204

205

207

210

211

212

214 {

216 for (auto &Sym : Obj.symbols()) {

218 if (!FlagsOrErr)

219

223

224 if (auto NameOrErr = Sym.getName())

225 Symbols.insert(*NameOrErr);

226 else

227 return NameOrErr.takeError();

228 }

229 }

230

231 if (auto ResultOrErr = Resolver.getResponsibilitySet(Symbols))

232 ResponsibilitySet = std::move(*ResultOrErr);

233 else

234 return ResultOrErr.takeError();

235 }

236

237

239 for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;

240 ++I) {

242 if (!FlagsOrErr)

243

245

246

248 continue;

249

250

252 if (auto SymTypeOrErr = I->getType())

253 SymType = *SymTypeOrErr;

254 else

255 return SymTypeOrErr.takeError();

256

257

259 if (auto NameOrErr = I->getName())

260 Name = *NameOrErr;

261 else

262 return NameOrErr.takeError();

263

264

266 if (!JITSymFlags)

267 return JITSymFlags.takeError();

268

269

270

271

272

273 if (JITSymFlags->isWeak() || JITSymFlags->isCommon()) {

274

276 continue;

277

278

279 if (!ResponsibilitySet.count(Name))

280 continue;

281

282

283

284 if (JITSymFlags->isWeak())

286 if (JITSymFlags->isCommon()) {

290 if (!CommonAlign)

291 CommonAlign = Align;

293 CommonSymbolsToAllocate.push_back(*I);

294 }

295 }

296

300 if (auto AddrOrErr = I->getAddress())

301 Addr = *AddrOrErr;

302 else

303 return AddrOrErr.takeError();

304

306

307 LLVM_DEBUG(dbgs() << "\tType: " << SymType << " (absolute) Name: " << Name

308 << " SID: " << SectionID

309 << " Offset: " << format("%p", (uintptr_t)Addr)

310 << " flags: " << *FlagsOrErr << "\n");

311

312 if (!Name.empty()) {

316 }

321

323 if (auto SIOrErr = I->getSection())

324 SI = *SIOrErr;

325 else

326 return SIOrErr.takeError();

327

328 if (SI == Obj.section_end())

329 continue;

330

331

333 if (auto Err = getOffset(*I, *SI, SectOffset))

334 return std::move(Err);

335

336 bool IsCode = SI->isText();

337 unsigned SectionID;

338 if (auto SectionIDOrErr =

340 SectionID = *SectionIDOrErr;

341 else

342 return SectionIDOrErr.takeError();

343

344 LLVM_DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name

345 << " SID: " << SectionID

346 << " Offset: " << format("%p", (uintptr_t)SectOffset)

347 << " flags: " << *FlagsOrErr << "\n");

348

349 if (!Name.empty()) {

351 Name, SymbolTableEntry(SectionID, SectOffset, *JITSymFlags));

353 }

354 }

355 }

356

357

358 if (auto Err = emitCommonSymbols(Obj, CommonSymbolsToAllocate, CommonSize,

359 CommonAlign))

360 return std::move(Err);

361

362

364 for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();

365 SI != SE; ++SI) {

367

369 if (!RelSecOrErr)

371

373 if (RelocatedSection == SE)

374 continue;

375

378

380 continue;

381

382 bool IsCode = RelocatedSection->isText();

383 unsigned SectionID = 0;

384 if (auto SectionIDOrErr = findOrEmitSection(Obj, *RelocatedSection, IsCode,

385 LocalSections))

386 SectionID = *SectionIDOrErr;

387 else

388 return SectionIDOrErr.takeError();

389

390 LLVM_DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");

391

392 for (; I != E;)

394 I = *IOrErr;

395 else

396 return IOrErr.takeError();

397

398

399

401 StringRef FileName = Obj.getFileName();

403 for (auto &KV : Stubs) {

404

405 auto &VR = KV.first;

406 uint64_t StubAddr = KV.second;

407

408

409 if (VR.SymbolName) {

411 StubAddr);

412 continue;

413 }

414

415

417 StringRef SymbolName = GSTMapEntry.first();

418 auto &GSTEntry = GSTMapEntry.second;

419 if (GSTEntry.getSectionID() == VR.SectionID &&

420 GSTEntry.getOffset() == VR.Offset) {

422 StubAddr);

423 break;

424 }

425 }

426 }

427 }

428 }

429

430

432 LLVM_DEBUG(dbgs() << "Process remaining sections:\n");

433 for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();

434 SI != SE; ++SI) {

435

436

437 if (LocalSections.find(*SI) != LocalSections.end())

438 continue;

439

440 bool IsCode = SI->isText();

441 if (auto SectionIDOrErr =

443 LLVM_DEBUG(dbgs() << "\tSectionID: " << (*SectionIDOrErr) << "\n");

444 else

445 return SectionIDOrErr.takeError();

446 }

447 }

448

449

450 if (auto Err = finalizeLoad(Obj, LocalSections))

451 return std::move(Err);

452

453

454

455

456 return LocalSections;

457}

458

459

460

461

464 Align Alignment) {

466 for (uint64_t SectionSize : SectionSizes)

467 TotalSize += alignTo(SectionSize, Alignment);

468 return TotalSize;

469}

470

472 const ObjectFile *Obj = Section.getObject();

476 const coff_section *CoffSection = COFFObj->getCOFFSection(Section);

477

478

479

480

481

482 bool HasContent =

484 bool IsDiscardable =

487 return HasContent && !IsDiscardable;

488 }

489

491 return true;

492}

493

495 const ObjectFile *Obj = Section.getObject();

500 return ((COFFObj->getCOFFSection(Section)->Characteristics &

504 ==

507

509 return false;

510}

511

513 const ObjectFile *Obj = Section.getObject();

517 return COFFObj->getCOFFSection(Section)->Characteristics &

519

521 unsigned SectionType = MachO->getSectionType(Section);

524}

525

527 const ObjectFile *Obj = Section.getObject();

530 return false;

531}

532

533

534

538 Align &RWDataAlign) {

539

540 std::vector<uint64_t> CodeSectionSizes;

541 std::vector<uint64_t> ROSectionSizes;

542 std::vector<uint64_t> RWSectionSizes;

543

544

545

546 for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();

547 SI != SE; ++SI) {

549

551

552

553 if (IsRequired) {

555 Align Alignment = Section.getAlignment();

556 bool IsCode = Section.isText();

558 bool IsTLS = isTLS(Section);

559

561 if (!NameOrErr)

564

566

568 if (Name == ".eh_frame")

569 PaddingSize += 4;

570 if (StubBufSize != 0)

572

574

575

576

577

578

579

580 if (Name == ".eh_frame")

581 SectionSize += 4;

582

583 if (!SectionSize)

584 SectionSize = 1;

585

586 if (IsCode) {

587 CodeAlign = std::max(CodeAlign, Alignment);

588 CodeSectionSizes.push_back(SectionSize);

589 } else if (IsReadOnly) {

590 RODataAlign = std::max(RODataAlign, Alignment);

591 ROSectionSizes.push_back(SectionSize);

592 } else if (!IsTLS) {

593 RWDataAlign = std::max(RWDataAlign, Alignment);

594 RWSectionSizes.push_back(SectionSize);

595 }

596 }

597 }

598

599

600

601

603 RWSectionSizes.push_back(GotSize);

605 }

606

607

609 Align CommonAlign;

610 for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;

611 ++I) {

613 if (!FlagsOrErr)

614

617

619 Align Alignment = Align(I->getAlignment());

620

621

622 if (CommonSize == 0)

623 CommonAlign = Alignment;

624 CommonSize = alignTo(CommonSize, Alignment) + Size;

625 }

626 }

627 if (CommonSize != 0) {

628 RWSectionSizes.push_back(CommonSize);

629 RWDataAlign = std::max(RWDataAlign, CommonAlign);

630 }

631

632 if (!CodeSectionSizes.empty()) {

633

634 CodeSectionSizes.push_back(64);

635 }

636

637

638

639

640

641

645

647}

648

649

652 if (!GotEntrySize)

653 return 0;

654

655 size_t GotSize = 0;

656 for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();

657 SI != SE; ++SI) {

658

661 GotSize += GotEntrySize;

662 }

663

664 return GotSize;

665}

666

667

670 if (MemMgr.allowStubAllocation()) {

671 return 0;

672 }

673

675 if (StubSize == 0) {

676 return 0;

677 }

678

679

680

681 unsigned StubBufSize = 0;

682 for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();

683 SI != SE; ++SI) {

684

686 if (!RelSecOrErr)

688

690 if (!(RelSecI == Section))

691 continue;

692

695 StubBufSize += StubSize;

698 }

699 }

700

701

703 Align Alignment = Section.getAlignment();

704

705

708 if (StubAlignment > EndAlignment)

709 StubBufSize += StubAlignment.value() - EndAlignment.value();

710 return StubBufSize;

711}

712

714 unsigned Size) const {

717 Src += Size - 1;

718 while (Size--)

719 Result = (Result << 8) | *Src--;

720 } else

721 while (Size--)

722 Result = (Result << 8) | *Src++;

723

724 return Result;

725}

726

728 unsigned Size) const {

730 while (Size--) {

731 *Dst++ = Value & 0xFF;

733 }

734 } else {

735 Dst += Size - 1;

736 while (Size--) {

737 *Dst-- = Value & 0xFF;

739 }

740 }

741}

742

747

752 if (SymbolsToAllocate.empty())

754

755

756 unsigned SectionID = Sections.size();

757 uint8_t *Addr = MemMgr.allocateDataSection(CommonSize, CommonAlign, SectionID,

758 "", false);

759 if (!Addr)

763 SectionEntry("", Addr, CommonSize, CommonSize, 0));

764 memset(Addr, 0, CommonSize);

765

766 LLVM_DEBUG(dbgs() << "emitCommonSection SectionID: " << SectionID

767 << " new addr: " << format("%p", Addr)

768 << " DataSize: " << CommonSize << "\n");

769

770

771 for (auto &Sym : SymbolsToAllocate) {

772 uint32_t Alignment = Sym.getAlignment();

775 if (auto NameOrErr = Sym.getName())

776 Name = *NameOrErr;

777 else

778 return NameOrErr.takeError();

779 if (Alignment) {

780

783 Addr += AlignOffset;

784 Offset += AlignOffset;

785 }

787

788 if (!JITSymFlags)

789 return JITSymFlags.takeError();

790

791 LLVM_DEBUG(dbgs() << "Allocating common symbol " << Name << " address "

792 << format("%p", Addr) << "\n");

793 if (!Name.empty())

797 Addr += Size;

798 }

799

801}

802

806 bool IsCode) {

808 Align Alignment = Section.getAlignment();

809

810 unsigned PaddingSize = 0;

811 unsigned StubBufSize = 0;

813 bool IsVirtual = Section.isVirtual();

814 bool IsZeroInit = isZeroInit(Section);

816 bool IsTLS = isTLS(Section);

818

820 if (!NameOrErr)

823

825

826

827

828

829 if (Name == ".eh_frame")

830 PaddingSize = 4;

831

832 uintptr_t Allocate;

833 unsigned SectionID = Sections.size();

836 const char *pData = nullptr;

837

838

839

840 if (!IsVirtual && !IsZeroInit) {

841

842

845 else

846 return E.takeError();

847 pData = data.data();

848 }

849

850

851

852

853 if (StubBufSize != 0) {

856 }

857

858

859

861 Allocate = DataSize + PaddingSize + StubBufSize;

862 if (!Allocate)

863 Allocate = 1;

864 if (IsTLS) {

865 auto TLSSection = MemMgr.allocateTLSSection(Allocate, Alignment.value(),

866 SectionID, Name);

867 Addr = TLSSection.InitializationImage;

868 LoadAddress = TLSSection.Offset;

869 } else if (IsCode) {

870 Addr = MemMgr.allocateCodeSection(Allocate, Alignment.value(), SectionID,

871 Name);

872 } else {

873 Addr = MemMgr.allocateDataSection(Allocate, Alignment.value(), SectionID,

874 Name, IsReadOnly);

875 }

876 if (!Addr)

878

879

880 if (IsZeroInit || IsVirtual)

882 else

883 memcpy(Addr, pData, DataSize);

884

885

886 if (PaddingSize != 0) {

887 memset(Addr + DataSize, 0, PaddingSize);

888

890

891

892

893 if (StubBufSize > 0)

895 }

896

897 LLVM_DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: "

898 << Name << " obj addr: " << format("%p", pData)

899 << " new addr: " << format("%p", Addr) << " DataSize: "

900 << DataSize << " StubBufSize: " << StubBufSize

901 << " Allocate: " << Allocate << "\n");

902 } else {

903

904

905

906 Allocate = 0;

907 Addr = nullptr;

909 dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name

910 << " obj addr: " << format("%p", data.data()) << " new addr: 0"

911 << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize

912 << " Allocate: " << Allocate << "\n");

913 }

914

917

918

919

920 if (IsTLS)

921 Sections.back().setLoadAddress(LoadAddress);

922

923 if (!IsRequired)

924 Sections.back().setLoadAddress(0);

925

926 return SectionID;

927}

928

932 bool IsCode,

934

935 unsigned SectionID = 0;

936 ObjSectionToIDMap::iterator i = LocalSections.find(Section);

937 if (i != LocalSections.end())

938 SectionID = i->second;

939 else {

940 if (auto SectionIDOrErr = emitSection(Obj, Section, IsCode))

941 SectionID = *SectionIDOrErr;

942 else

943 return SectionIDOrErr.takeError();

944 LocalSections[Section] = SectionID;

945 }

946 return SectionID;

947}

948

950 unsigned SectionID) {

952}

953

956

957

958

962 } else {

963 assert(!SymbolName.empty() &&

964 "Empty symbol should not be in GlobalSymbolTable");

965

970 }

971}

972

974 unsigned AbiVariant) {

977

978

979

980

982 writeBytesUnaligned(0xf2c00010, Addr+4, 4);

983 writeBytesUnaligned(0xf2a00010, Addr+8, 4);

984 writeBytesUnaligned(0xf2800010, Addr+12, 4);

986

987 return Addr;

989

990

992 return Addr + 4;

994

995

996

997

998

1004 return Addr;

1006

1007

1008

1009

1010 const unsigned LuiT9Instr = 0x3c190000, AdduiT9Instr = 0x27390000;

1011 const unsigned NopInstr = 0x0;

1012 unsigned JrT9Instr = 0x03200008;

1015 JrT9Instr = 0x03200009;

1016

1021 return Addr;

1023

1024

1025

1026

1027

1028

1029

1030

1031 const unsigned LuiT9Instr = 0x3c190000, DaddiuT9Instr = 0x67390000,

1032 DsllT9Instr = 0x19CC38;

1033 const unsigned NopInstr = 0x0;

1034 unsigned JrT9Instr = 0x03200008;

1036 JrT9Instr = 0x03200009;

1037

1046 return Addr;

1048

1049

1050

1051 writeInt32BE(Addr, 0x3D800000);

1052 writeInt32BE(Addr+4, 0x618C0000);

1053 writeInt32BE(Addr+8, 0x798C07C6);

1054 writeInt32BE(Addr+12, 0x658C0000);

1055 writeInt32BE(Addr+16, 0x618C0000);

1056 if (AbiVariant == 2) {

1057

1058

1059 writeInt32BE(Addr+20, 0xF8410018);

1060 writeInt32BE(Addr+24, 0x7D8903A6);

1062 } else {

1063

1064

1065

1066 writeInt32BE(Addr+20, 0xF8410028);

1067 writeInt32BE(Addr+24, 0xE96C0000);

1068 writeInt32BE(Addr+28, 0xE84C0008);

1069 writeInt32BE(Addr+32, 0x7D6903A6);

1070 writeInt32BE(Addr+36, 0xE96C0010);

1072 }

1073 return Addr;

1079

1080 return Addr;

1082 *Addr = 0xFF;

1083 *(Addr+1) = 0x25;

1084

1086 *Addr = 0xE9;

1087 }

1088 return Addr;

1089}

1090

1091

1092

1095

1096

1097

1098

1099

1100

1101

1102

1103

1104

1106 dbgs() << "Reassigning address for section " << SectionID << " ("

1108 << format("0x%016" PRIx64, Sections[SectionID].getLoadAddress())

1109 << " -> " << format("0x%016" PRIx64, Addr) << "\n");

1110 Sections[SectionID].setLoadAddress(Addr);

1111}

1112

1116

1118 Sections[RE.SectionID].getAddress() == nullptr)

1119 continue;

1121 }

1122}

1123

1127 StringRef Name = RelocKV.first();

1129 if (Name.size() == 0) {

1130

1131 LLVM_DEBUG(dbgs() << "Resolving absolute relocations."

1132 << "\n");

1134 } else {

1139 auto RRI = ExternalSymbolMap.find(Name);

1140 assert(RRI != ExternalSymbolMap.end() && "No result for symbol");

1141 Addr = RRI->second.getAddress();

1142 Flags = RRI->second.getFlags();

1143 } else {

1144

1145

1149 Flags = SymInfo.getFlags();

1150 }

1151

1152

1153 if (!Addr && Resolver.allowsZeroSymbols())

1155 "' which could not be resolved!");

1156

1157

1158

1160

1161

1162

1163

1165

1166 LLVM_DEBUG(dbgs() << "Resolving relocations Name: " << Name << "\t"

1167 << format("0x%lx", Addr) << "\n");

1169 }

1170 }

1171 }

1173}

1174

1177

1178

1179

1180 {

1182

1183 while (true) {

1185

1187 StringRef Name = RelocKV.first();

1189 !ResolvedSymbols.count(Name))

1190 NewSymbols.insert(Name);

1191 }

1192

1193 if (NewSymbols.empty())

1194 break;

1195

1196#ifdef _MSC_VER

1197 using ExpectedLookupResult =

1199#else

1201#endif

1202

1203 auto NewSymbolsP = std::make_shared<std::promise>();

1204 auto NewSymbolsF = NewSymbolsP->get_future();

1207 NewSymbolsP->set_value(std::move(Result));

1208 });

1209

1210 auto NewResolverResults = NewSymbolsF.get();

1211

1212 if (!NewResolverResults)

1213 return NewResolverResults.takeError();

1214

1215 assert(NewResolverResults->size() == NewSymbols.size() &&

1216 "Should have errored on unresolved symbols");

1217

1218 for (auto &RRKV : *NewResolverResults) {

1219 assert(!ResolvedSymbols.count(RRKV.first) && "Redundant resolution?");

1220 ExternalSymbolMap.insert(RRKV);

1221 ResolvedSymbols.insert(RRKV.first);

1222 }

1223 }

1224 }

1225

1227

1229}

1230

1232 std::unique_ptr This,

1234 std::unique_ptrRuntimeDyld::LoadedObjectInfo, Error)>

1235 OnEmitted,

1237 std::unique_ptrRuntimeDyld::LoadedObjectInfo Info) {

1238

1239 auto SharedThis = std::shared_ptr(std::move(This));

1240 auto PostResolveContinuation =

1241 [SharedThis, OnEmitted = std::move(OnEmitted), O = std::move(O),

1242 Info = std::move(Info)](

1244 if (!Result) {

1245 OnEmitted(std::move(O), std::move(Info), Result.takeError());

1246 return;

1247 }

1248

1249

1251 for (auto &KV : *Result)

1252 Resolved[KV.first] = KV.second;

1253

1254 SharedThis->applyExternalSymbolRelocations(Resolved);

1255 SharedThis->resolveLocalRelocations();

1256 SharedThis->registerEHFrames();

1257 std::string ErrMsg;

1258 if (SharedThis->MemMgr.finalizeMemory(&ErrMsg))

1259 OnEmitted(std::move(O), std::move(Info),

1262 else

1263 OnEmitted(std::move(O), std::move(Info), Error::success());

1264 };

1265

1267

1268 for (auto &RelocKV : SharedThis->ExternalSymbolRelocations) {

1269 StringRef Name = RelocKV.first();

1270 if (Name.empty())

1271 continue;

1272 assert(!SharedThis->GlobalSymbolTable.count(Name) &&

1273 "Name already processed. RuntimeDyld instances can not be re-used "

1274 "when finalizing with finalizeAsync.");

1275 Symbols.insert(Name);

1276 }

1277

1278 if (!Symbols.empty()) {

1279 SharedThis->Resolver.lookup(Symbols, std::move(PostResolveContinuation));

1280 } else

1281 PostResolveContinuation(std::map<StringRef, JITEvaluatedSymbol>());

1282}

1283

1284

1285

1286

1289

1292 return RTDyld.Sections[I->second].getLoadAddress();

1293

1294 return 0;

1295}

1296

1299 unsigned Alignment,

1300 unsigned SectionID,

1303}

1304

1305void RuntimeDyld::MemoryManager::anchor() {}

1306void JITSymbolResolver::anchor() {}

1307void LegacyJITSymbolResolver::anchor() {}

1308

1311 : MemMgr(MemMgr), Resolver(Resolver) {

1312

1313

1314

1315

1316

1317

1318 Dyld = nullptr;

1319 ProcessAllSections = false;

1320}

1321

1323

1324static std::unique_ptr

1329 std::unique_ptr Dyld =

1331 Dyld->setProcessAllSections(ProcessAllSections);

1332 Dyld->setNotifyStubEmitted(std::move(NotifyStubEmitted));

1333 return Dyld;

1334}

1335

1336static std::unique_ptr

1340 std::unique_ptr Dyld =

1342 Dyld->setProcessAllSections(ProcessAllSections);

1343 Dyld->setNotifyStubEmitted(std::move(NotifyStubEmitted));

1344 return Dyld;

1345}

1346

1347static std::unique_ptr

1351 bool ProcessAllSections,

1353 std::unique_ptr Dyld =

1355 Dyld->setProcessAllSections(ProcessAllSections);

1356 Dyld->setNotifyStubEmitted(std::move(NotifyStubEmitted));

1357 return Dyld;

1358}

1359

1360std::unique_ptrRuntimeDyld::LoadedObjectInfo

1362 if (!Dyld) {

1363 if (Obj.isELF())

1365 ProcessAllSections,

1366 std::move(NotifyStubEmitted));

1367 else if (Obj.isMachO())

1369 ProcessAllSections,

1370 std::move(NotifyStubEmitted));

1371 else if (Obj.isCOFF())

1373 ProcessAllSections,

1374 std::move(NotifyStubEmitted));

1375 else

1377 }

1378

1379 if (!Dyld->isCompatibleFile(Obj))

1381

1382 auto LoadedObjInfo = Dyld->loadObject(Obj);

1383 MemMgr.notifyObjectLoaded(*this, Obj);

1384 return LoadedObjInfo;

1385}

1386

1388 if (!Dyld)

1389 return nullptr;

1390 return Dyld->getSymbolLocalAddress(Name);

1391}

1392

1394 assert(Dyld && "No RuntimeDyld instance attached");

1395 return Dyld->getSymbolSectionID(Name);

1396}

1397

1399 if (!Dyld)

1400 return nullptr;

1401 return Dyld->getSymbol(Name);

1402}

1403

1405 if (!Dyld)

1406 return std::map<StringRef, JITEvaluatedSymbol>();

1407 return Dyld->getSymbolTable();

1408}

1409

1411

1413 Dyld->reassignSectionAddress(SectionID, Addr);

1414}

1415

1418 Dyld->mapSectionAddress(LocalAddress, TargetAddress);

1419}

1420

1422

1424

1426 bool MemoryFinalizationLocked = MemMgr.FinalizationLocked;

1427 MemMgr.FinalizationLocked = true;

1430 if (!MemoryFinalizationLocked) {

1431 MemMgr.finalizeMemory();

1432 MemMgr.FinalizationLocked = false;

1433 }

1434}

1435

1437 assert(Dyld && "No Dyld instance attached");

1438 return Dyld->getSectionContent(SectionID);

1439}

1440

1442 assert(Dyld && "No Dyld instance attached");

1443 return Dyld->getSectionLoadAddress(SectionID);

1444}

1445

1447 if (Dyld)

1448 Dyld->registerEHFrames();

1449}

1450

1452 if (Dyld)

1453 Dyld->deregisterEHFrames();

1454}

1455

1456

1457

1461 bool ProcessAllSections,

1464 std::map<StringRef, JITEvaluatedSymbol>)>

1465 OnLoaded,

1467 std::unique_ptrRuntimeDyld::LoadedObjectInfo, Error)>

1468 OnEmitted) {

1469

1472

1473 auto Info = RTDyld.loadObject(*O.getBinary());

1474

1476 OnEmitted(std::move(O), std::move(Info),

1479 return;

1480 }

1481

1482 if (auto Err = OnLoaded(*O.getBinary(), *Info, RTDyld.getSymbolTable())) {

1483 OnEmitted(std::move(O), std::move(Info), std::move(Err));

1484 return;

1485 }

1486

1488 std::move(O), std::move(Info));

1489}

1490

1491}

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

static StringRef getName(Value *V)

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.

Error takeError()

Take ownership of the stored error.

Represents a symbol that has been evaluated to an address already.

Flags for symbols in the JIT.

static LLVM_ABI Expected< JITSymbolFlags > fromObjectSymbol(const object::SymbolRef &Symbol)

Construct a JITSymbolFlags value based on the flags of the given libobject symbol.

Symbol resolution interface.

std::set< StringRef > LookupSet

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

int64_t Addend

Addend - the relocation addend encoded in the instruction itself.

Interface for looking up the initializer for a variable name, used by Init::resolveReferences.

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

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

void log(raw_ostream &OS) const override

Print an error message to an output stream.

Definition RuntimeDyld.cpp:57

std::error_code convertToErrorCode() const override

Convert this error to a std::error_code.

Definition RuntimeDyld.cpp:61

virtual bool relocationNeedsGot(const RelocationRef &R) const

void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress)

Definition RuntimeDyld.cpp:160

virtual void processNewSymbol(const SymbolRef &ObjSymbol, SymbolTableEntry &Entry)

StringMap< RelocationList > ExternalSymbolRelocations

void reassignSectionAddress(unsigned SectionID, uint64_t Addr)

Definition RuntimeDyld.cpp:1093

NotifyStubEmittedFunction NotifyStubEmitted

virtual uint64_t modifyAddressBasedOnFlags(uint64_t Addr, JITSymbolFlags Flags) const

Modify the given target address based on the given symbol flags.

virtual Expected< relocation_iterator > processRelocationRef(unsigned SectionID, relocation_iterator RelI, const ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID, StubMap &Stubs)=0

Parses one or more object file relocations (some object files use relocation pairs) and stores it to ...

std::map< SectionRef, unsigned > ObjSectionToIDMap

virtual void resolveRelocation(const RelocationEntry &RE, uint64_t Value)=0

A object file specific relocation resolver.

virtual Align getStubAlignment()=0

void writeInt32BE(uint8_t *Addr, uint32_t Value)

virtual Error finalizeLoad(const ObjectFile &ObjImg, ObjSectionToIDMap &SectionMap)

void applyExternalSymbolRelocations(const StringMap< JITEvaluatedSymbol > ExternalSymbolMap)

Definition RuntimeDyld.cpp:1124

void resolveRelocationList(const RelocationList &Relocs, uint64_t Value)

Resolves relocations from Relocs list with address from Value.

Definition RuntimeDyld.cpp:1113

SmallVector< RelocationEntry, 64 > RelocationList

std::map< RelocationValueRef, uintptr_t > StubMap

void deregisterEHFrames()

Definition RuntimeDyld.cpp:76

void writeInt16BE(uint8_t *Addr, uint16_t Value)

static const unsigned AbsoluteSymbolSection

void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName)

Definition RuntimeDyld.cpp:954

virtual void registerEHFrames()

Definition RuntimeDyld.cpp:74

bool IsTargetLittleEndian

JITSymbolResolver & Resolver

virtual ~RuntimeDyldImpl()

static void finalizeAsync(std::unique_ptr< RuntimeDyldImpl > This, unique_function< void(object::OwningBinary< object::ObjectFile >, std::unique_ptr< RuntimeDyld::LoadedObjectInfo >, Error)> OnEmitted, object::OwningBinary< object::ObjectFile > O, std::unique_ptr< RuntimeDyld::LoadedObjectInfo > Info)

Definition RuntimeDyld.cpp:1231

Error emitCommonSymbols(const ObjectFile &Obj, CommonSymbolList &CommonSymbols, uint64_t CommonSize, uint32_t CommonAlign)

Given the common symbols discovered in the object file, emit a new section for them and update the sy...

Definition RuntimeDyld.cpp:748

Expected< unsigned > emitSection(const ObjectFile &Obj, const SectionRef &Section, bool IsCode)

Emits section data from the object file to the MemoryManager.

Definition RuntimeDyld.cpp:804

virtual unsigned sizeAfterAddingDLLImportStub(unsigned Size) const

std::unordered_map< unsigned, RelocationList > Relocations

std::vector< SymbolRef > CommonSymbolList

RuntimeDyld::MemoryManager & MemMgr

void resolveLocalRelocations()

Definition RuntimeDyld.cpp:145

void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID)

Definition RuntimeDyld.cpp:949

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

Find Section in LocalSections.

Definition RuntimeDyld.cpp:930

virtual bool relocationNeedsStub(const RelocationRef &R) const

unsigned computeGOTSize(const ObjectFile &Obj)

Definition RuntimeDyld.cpp:650

virtual void setMipsABI(const ObjectFile &Obj)

void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const

Endian-aware write.

Definition RuntimeDyld.cpp:727

virtual size_t getGOTEntrySize()

uint8_t * createStubFunction(uint8_t *Addr, unsigned AbiVariant=0)

Emits long jump instruction to Addr.

Definition RuntimeDyld.cpp:973

uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const

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

Definition RuntimeDyld.cpp:713

virtual bool relocationNeedsDLLImportStub(const RelocationRef &R) const

uint64_t getSectionLoadAddress(unsigned SectionID) const

virtual unsigned getMaxStubSize() const =0

Error computeTotalAllocSize(const ObjectFile &Obj, uint64_t &CodeSize, Align &CodeAlign, uint64_t &RODataSize, Align &RODataAlign, uint64_t &RWDataSize, Align &RWDataAlign)

Definition RuntimeDyld.cpp:535

unsigned computeSectionStubBufSize(const ObjectFile &Obj, const SectionRef &Section)

Definition RuntimeDyld.cpp:668

void resolveRelocations()

Definition RuntimeDyld.cpp:121

RTDyldSymbolTable GlobalSymbolTable

virtual Expected< JITSymbolFlags > getJITSymbolFlags(const SymbolRef &Sym)

Generate JITSymbolFlags from a libObject symbol.

Definition RuntimeDyld.cpp:744

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

Definition RuntimeDyld.cpp:182

Error resolveExternalSymbols()

Resolve relocations to external symbols.

Definition RuntimeDyld.cpp:1175

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

Create a RuntimeDyldMachO instance for the given target architecture.

Information about the loaded object.

uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const override

Obtain the Load Address of a section by SectionRef.

Definition RuntimeDyld.cpp:1287

ObjSectionToIDMap ObjSecToIDMap

virtual void anchor()

Definition RuntimeDyld.cpp:70

virtual TLSSection allocateTLSSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName)

Allocate a memory block of (at least) the given size to be used for thread-local storage (TLS).

Definition RuntimeDyld.cpp:1298

LLVM_ABI void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress)

Map a section to its target address space value.

Definition RuntimeDyld.cpp:1416

void setProcessAllSections(bool ProcessAllSections)

By default, only sections that are "required for execution" are passed to the RTDyldMemoryManager,...

LLVM_ABI void reassignSectionAddress(unsigned SectionID, uint64_t Addr)

Definition RuntimeDyld.cpp:1412

LLVM_ABI uint64_t getSectionLoadAddress(unsigned SectionID) const

If the section was loaded, return the section's load address, otherwise return std::nullopt.

Definition RuntimeDyld.cpp:1441

LLVM_ABI void * getSymbolLocalAddress(StringRef Name) const

Get the address of our local copy of the symbol.

Definition RuntimeDyld.cpp:1387

LLVM_ABI std::map< StringRef, JITEvaluatedSymbol > getSymbolTable() const

Returns a copy of the symbol table.

Definition RuntimeDyld.cpp:1404

LLVM_ABI void resolveRelocations()

Resolve the relocations for all symbols we currently know about.

Definition RuntimeDyld.cpp:1410

LLVM_ABI void finalizeWithMemoryManagerLocking()

Perform all actions needed to make the code owned by this RuntimeDyld instance executable:

Definition RuntimeDyld.cpp:1425

std::function< void( StringRef FileName, StringRef SectionName, StringRef SymbolName, unsigned SectionID, uint32_t StubOffset)> NotifyStubEmittedFunction

LLVM_ABI void deregisterEHFrames()

Definition RuntimeDyld.cpp:1451

LLVM_ABI void registerEHFrames()

Register any EH frame sections that have been loaded but not previously registered with the memory ma...

Definition RuntimeDyld.cpp:1446

LLVM_ABI StringRef getSectionContent(unsigned SectionID) const

Returns the section's working memory.

Definition RuntimeDyld.cpp:1436

LLVM_ABI JITEvaluatedSymbol getSymbol(StringRef Name) const

Get the target address and flags for the named symbol.

Definition RuntimeDyld.cpp:1398

LLVM_ABI RuntimeDyld(MemoryManager &MemMgr, JITSymbolResolver &Resolver)

Construct a RuntimeDyld instance.

Definition RuntimeDyld.cpp:1309

LLVM_ABI bool hasError()

Definition RuntimeDyld.cpp:1421

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

Add the referenced object file to the list of objects to be loaded and relocated.

Definition RuntimeDyld.cpp:1361

LLVM_ABI StringRef getErrorString()

Definition RuntimeDyld.cpp:1423

LLVM_ABI unsigned getSymbolSectionID(StringRef Name) const

Get the section ID for the section containing the given symbol.

Definition RuntimeDyld.cpp:1393

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

StringRef getName() const

uint8_t * getAddress() const

uint64_t getLoadAddress() const

StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...

iterator find(StringRef Key)

StringMapIterBase< SymbolTableEntry, true > const_iterator

bool insert(MapEntryTy *KeyValue)

insert - Insert the specified key/value pair into the map.

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

Symbol info for RuntimeDyld.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM Value Representation.

uint64_t getFlags() const

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

This is a value type class that represents a single relocation in the list of relocations in the obje...

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

uint64_t getAddress() const

bool isText() const

Whether this section contains instructions.

This is a value type class that represents a single symbol in the list of symbols in the object file.

Expected< uint64_t > getAddress() const

Returns the symbol virtual address (i.e.

This class implements an extremely fast bulk output stream that can only output to a stream.

unique_function is a type-erasing functor similar to std::function.

#define llvm_unreachable(msg)

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

@ IMAGE_SCN_CNT_UNINITIALIZED_DATA

@ IMAGE_SCN_MEM_DISCARDABLE

@ IMAGE_SCN_CNT_INITIALIZED_DATA

@ S_GB_ZEROFILL

S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4 gigabytes).

@ S_ZEROFILL

S_ZEROFILL - Zero fill on demand section.

content_iterator< SectionRef > section_iterator

content_iterator< RelocationRef > relocation_iterator

This is an optimization pass for GlobalISel generic memory operations.

decltype(auto) dyn_cast(const From &Val)

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

LLVM_ABI std::error_code inconvertibleErrorCode()

The value returned by this function can be returned from convertToErrorCode for Error values where no...

static std::unique_ptr< RuntimeDyldMachO > createRuntimeDyldMachO(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM, JITSymbolResolver &Resolver, bool ProcessAllSections, RuntimeDyld::NotifyStubEmittedFunction NotifyStubEmitted)

Definition RuntimeDyld.cpp:1348

FunctionAddr VTableAddr uintptr_t uintptr_t DataSize

static bool isTLS(const SectionRef Section)

Definition RuntimeDyld.cpp:526

static void dumpSectionMemory(const SectionEntry &S, StringRef State)

Definition RuntimeDyld.cpp:81

static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)

Definition RuntimeDyld.cpp:172

static std::unique_ptr< RuntimeDyldCOFF > createRuntimeDyldCOFF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM, JITSymbolResolver &Resolver, bool ProcessAllSections, RuntimeDyld::NotifyStubEmittedFunction NotifyStubEmitted)

Definition RuntimeDyld.cpp:1325

LLVM_ABI raw_ostream & dbgs()

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

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

static bool isReadOnlyData(const SectionRef Section)

Definition RuntimeDyld.cpp:494

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

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

These are helper functions used to produce formatted output.

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

uint64_t offsetToAlignment(uint64_t Value, Align Alignment)

Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...

LLVM_ABI void jitLinkForORC(object::OwningBinary< object::ObjectFile > O, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver, bool ProcessAllSections, unique_function< Error(const object::ObjectFile &Obj, RuntimeDyld::LoadedObjectInfo &, std::map< StringRef, JITEvaluatedSymbol >)> OnLoaded, unique_function< void(object::OwningBinary< object::ObjectFile >, std::unique_ptr< RuntimeDyld::LoadedObjectInfo >, Error)> OnEmitted)

static std::unique_ptr< RuntimeDyldELF > createRuntimeDyldELF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM, JITSymbolResolver &Resolver, bool ProcessAllSections, RuntimeDyld::NotifyStubEmittedFunction NotifyStubEmitted)

Definition RuntimeDyld.cpp:1337

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)

static bool isZeroInit(const SectionRef Section)

Definition RuntimeDyld.cpp:512

decltype(auto) cast(const From &Val)

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

Align commonAlignment(Align A, uint64_t Offset)

Returns the alignment that satisfies both alignments.

static uint64_t computeAllocationSizeForSections(std::vector< uint64_t > &SectionSizes, Align Alignment)

Definition RuntimeDyld.cpp:463

static bool isRequiredForExecution(const SectionRef Section)

Definition RuntimeDyld.cpp:471

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

This struct is a compact representation of a valid (non-zero power of two) alignment.

constexpr uint64_t value() const

This is a hole in the type system and should not be abused.

An allocated TLS section.

support::ulittle32_t VirtualSize

support::ulittle32_t Characteristics

support::ulittle32_t SizeOfRawData