LLVM: lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h Source File (original) (raw)

124

125

126

127 virtual bool excludeSection(const typename ELFT::Shdr &Sect) const {

128 return false;

129 }

130

131

132

133

134

135

136 template

138 RelocHandlerMethod &&Func);

139

140

141

142

143

144

145 template

147 RelocHandlerMethod &&Func);

148

149

150

151

152 template <typename ClassT, typename RelocHandlerMethod>

154 ClassT *Instance, RelocHandlerMethod &&Method) {

156 RelSect,

157 [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {

158 return (Instance->*Method)(Rel, Target, GS);

159 });

160 }

161

162

163

164

165 template <typename ClassT, typename RelocHandlerMethod>

167 ClassT *Instance, RelocHandlerMethod &&Method) {

169 RelSect,

170 [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {

171 return (Instance->*Method)(Rel, Target, GS);

172 });

173 }

174

176

177 typename ELFFile::Elf_Shdr_Range Sections;

178 const typename ELFFile::Elf_Shdr *SymTabSec = nullptr;

181

182

183

186 DenseMap<const typename ELFFile::Elf_Shdr *,

189};

190

191template

193 const ELFFile &Obj, std::shared_ptrorc::SymbolStringPool SSP, Triple TT,

198 std::move(GetEdgeKindName))),

201 { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });

202}

203

204template

208

209 if (auto Err = prepare())

210 return std::move(Err);

211

213 return std::move(Err);

214

216 return std::move(Err);

217

219 return std::move(Err);

220

221 return std::move(G);

222}

223

224template

227 const typename ELFT::Sym &Sym, StringRef Name) {

230

231 switch (Sym.getBinding()) {

234 break;

236

237 break;

241 break;

242 default:

244 "Unrecognized symbol binding " +

245 Twine(static_cast<int>(Sym.getBinding())) + " for " + Name,

247 }

248

249 switch (Sym.getVisibility()) {

252

253

254

255 break;

257

260 break;

263 "Unrecognized symbol visibility " +

264 Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name,

266 }

267

268 return std::make_pair(L, S);

269}

270

273

274

275 if (auto SectionsOrErr = Obj.sections())

277 else

278 return SectionsOrErr.takeError();

279

280

281 if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections))

283 else

284 return SectionStringTabOrErr.takeError();

285

286

291 else

293 G->getName());

294 }

295

296

298 uint32_t SymtabNdx = Sec.sh_link;

299 if (SymtabNdx >= Sections.size())

301

302 auto ShndxTable = Obj.getSHNDXTable(Sec);

303 if (!ShndxTable)

304 return ShndxTable.takeError();

305

307 }

308 }

309

311}

312

314 LLVM_DEBUG(dbgs() << " Creating graph sections...\n");

315

316

318

319 auto &Sec = Sections[SecIndex];

320

321

323 if (!Name)

324 return Name.takeError();

327 dbgs() << " " << SecIndex << ": Skipping section \"" << *Name

328 << "\" explicitly\n";

329 });

330 continue;

331 }

332

333

336 dbgs() << " " << SecIndex << ": has type SHT_NULL. Skipping.\n";

337 });

338 continue;

339 }

340

341

342

345 dbgs() << " " << SecIndex << ": \"" << *Name

346 << "\" is a debug section: "

347 "No graph section will be created.\n";

348 });

349 continue;

350 }

351

353 dbgs() << " " << SecIndex << ": Creating section for \"" << *Name

354 << "\"\n";

355 });

356

357

363

364

365 auto *GraphSec = G->findSectionByName(*Name);

366 if (!GraphSec) {

367 GraphSec = &G->createSection(*Name, Prot);

368

372 dbgs() << " " << SecIndex << ": \"" << *Name

373 << "\" is not a SHF_ALLOC section. Using NoAlloc lifetime.\n";

374 });

375 }

376 }

377

378 if (GraphSec->getMemProt() != Prot) {

379 std::string ErrMsg;

381 << "In " << G->getName() << ", section " << *Name

382 << " is present more than once with different permissions: "

383 << GraphSec->getMemProt() << " vs " << Prot;

385 }

386

389 auto Data = Obj.template getSectionContentsAsArray(Sec);

391 return Data.takeError();

392

393 B = &G->createContentBlock(*GraphSec, *Data,

395 Sec.sh_addralign, 0);

396 } else

397 B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size,

399 Sec.sh_addralign, 0);

400

402

405 }

406

408 }

409

411}

412

414 LLVM_DEBUG(dbgs() << " Creating graph symbols...\n");

415

416

419

420

422 if (!Symbols)

423 return Symbols.takeError();

424

425

427 if (!StringTab)

428 return StringTab.takeError();

429

432

434 SymTabName = *SymTabNameOrErr;

435 else {

436 dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: "

437 << toString(SymTabNameOrErr.takeError()) << "\n";

438 SymTabName = "<SHT_SYMTAB section with invalid name>";

439 }

440

441 dbgs() << " Adding symbols from symtab section \"" << SymTabName

442 << "\"\n";

443 });

444

445 for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) {

446 auto &Sym = (*Symbols)[SymIndex];

447

448

449 switch (Sym.getType()) {

452 if (auto Name = Sym.getName(*StringTab))

453 dbgs() << " " << SymIndex << ": Skipping STT_FILE symbol \""

454 << *Name << "\"\n";

455 else {

456 dbgs() << "Could not get STT_FILE symbol name: "

457 << toString(Name.takeError()) << "\n";

458 dbgs() << " " << SymIndex

459 << ": Skipping STT_FILE symbol with invalid name\n";

460 }

461 });

462 continue;

463 break;

464 }

465

466

467 auto Name = Sym.getName(*StringTab);

468 if (!Name)

469 return Name.takeError();

470

471

472 if (Sym.isCommon()) {

473 Symbol &GSym = G->addDefinedSymbol(

478 continue;

479 }

480

481 if (Sym.isDefined() &&

485

486

490 std::tie(L, S) = *LSOrErr;

491 else

492 return LSOrErr.takeError();

493

494

495 unsigned Shndx = Sym.st_shndx;

499 continue;

501 Sym, SymIndex, ShndxTable->second);

502 if (!NdxOrErr)

503 return NdxOrErr.takeError();

504 Shndx = *NdxOrErr;

505 }

508 dbgs() << " " << SymIndex

509 << ": Creating defined graph symbol for ELF symbol \"" << *Name

510 << "\"\n";

511 });

512

515

516 if (Offset + Sym.st_size > B->getSize()) {

517 std::string ErrMsg;

519 ErrStream << "In " << G->getName() << ", symbol ";

520 if (!Name->empty())

521 ErrStream << *Name;

522 else

523 ErrStream << "";

524 ErrStream << " (" << (B->getAddress() + Offset) << " -- "

525 << (B->getAddress() + Offset + Sym.st_size) << ") extends "

526 << formatv("{0:x}", Offset + Sym.st_size - B->getSize())

527 << " bytes past the end of its containing block ("

528 << B->getRange() << ")";

530 }

531

532

533

534

535

536

537 auto &GSym =

538 Name->empty()

539 ? G->addAnonymousSymbol(*B, Offset, Sym.st_size,

540 false, false)

541 : G->addDefinedSymbol(*B, Offset, *Name, Sym.st_size, L,

543 false);

544

545 GSym.setTargetFlags(Flags);

547 }

548 } else if (Sym.isUndefined() && Sym.isExternal()) {

550 dbgs() << " " << SymIndex

551 << ": Creating external graph symbol for ELF symbol \"" << *Name

552 << "\"\n";

553 });

554

558 "Invalid symbol binding " +

559 Twine(static_cast<int>(Sym.getBinding())) +

560 " for external symbol " + *Name,

562

563

564 auto &GSym = G->addExternalSymbol(*Name, Sym.st_size,

567 } else if (Sym.isUndefined() && Sym.st_value == 0 && Sym.st_size == 0 &&

569 Sym.getBinding() == ELF::STB_LOCAL && Name->empty()) {

570

571

573 dbgs() << " " << SymIndex << ": Creating null graph symbol\n";

574 });

575

576 auto SymName =

577 G->allocateContent("__jitlink_ELF_SYM_UND_" + Twine(SymIndex));

578 auto SymNameRef = StringRef(SymName.data(), SymName.size());

579 auto &GSym = G->addAbsoluteSymbol(SymNameRef, orc::ExecutorAddr(0), 0,

582 } else {

584 dbgs() << " " << SymIndex

585 << ": Not creating graph symbol for ELF symbol \"" << *Name

586 << "\" with unrecognized type\n";

587 });

588 }

589 }

590

592}

597 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {

598

601

602

603

604 auto FixupSection = Obj.getSection(RelSect.sh_info);

605 if (!FixupSection)

606 return FixupSection.takeError();

607

608

610 if (!Name)

611 return Name.takeError();

613

614

616 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");

618 }

620 LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");

622 }

623

624

625 auto *BlockToFix = getGraphBlock(RelSect.sh_info);

626 if (!BlockToFix)

628 "Refencing a section that wasn't added to the graph: " + *Name,

630

631 auto RelEntries = Obj.relas(RelSect);

632 if (!RelEntries)

633 return RelEntries.takeError();

634

635

636 for (const typename ELFT::Rela &R : *RelEntries)

637 if (Error Err = Func(R, **FixupSection, *BlockToFix))

638 return Err;

639

642}

647 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {

648

651

652

653

654 auto FixupSection = Obj.getSection(RelSect.sh_info);

655 if (!FixupSection)

656 return FixupSection.takeError();

657

658

660 if (!Name)

661 return Name.takeError();

663

664

666 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");

668 }

670 LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");

672 }

673

674

675 auto *BlockToFix = getGraphBlock(RelSect.sh_info);

676 if (!BlockToFix)

678 "Refencing a section that wasn't added to the graph: " + *Name,

680

681 auto RelEntries = Obj.rels(RelSect);

682 if (!RelEntries)

683 return RelEntries.takeError();

684

685

686 for (const typename ELFT::Rel &R : *RelEntries)

687 if (Error Err = Func(R, **FixupSection, *BlockToFix))

688 return Err;

689

692}