Skip to content

Commit a43bf8a

Browse files
committed
[JITLink][ELF] Add error checks to the ELFLinkGraphBuilder.
We now check for: 1. Duplicate definitions of the same section name with different permissions. 2. Symbols whose size extends past the end of the containing block. It's not clear to me whether either of these is strictly prohibited by the ELF spec, but they seem pathalogical and JITLink doesn't currently handle them. For now we'll make them recoverable errors so that if we do encounter these in the wild we can report the issue(s).
1 parent bf2f9d2 commit a43bf8a

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,14 @@ template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() {
374374
}
375375
}
376376

377-
assert(GraphSec->getMemProt() == Prot && "MemProt should match");
377+
if (GraphSec->getMemProt() != Prot) {
378+
std::string ErrMsg;
379+
raw_string_ostream(ErrMsg)
380+
<< "In " << G->getName() << ", section " << *Name
381+
<< " is present more than once with different permissions: "
382+
<< GraphSec->getMemProt() << " vs " << Prot;
383+
return make_error<JITLinkError>(std::move(ErrMsg));
384+
}
378385

379386
Block *B = nullptr;
380387
if (Sec.sh_type != ELF::SHT_NOBITS) {
@@ -499,6 +506,22 @@ template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() {
499506
TargetFlagsType Flags = makeTargetFlags(Sym);
500507
orc::ExecutorAddrDiff Offset = getRawOffset(Sym, Flags);
501508

509+
if (Offset + Sym.st_size > B->getSize()) {
510+
std::string ErrMsg;
511+
raw_string_ostream ErrStream(ErrMsg);
512+
ErrStream << "In " << G->getName() << ", symbol ";
513+
if (!Name->empty())
514+
ErrStream << *Name;
515+
else
516+
ErrStream << "<anon>";
517+
ErrStream << " (" << (B->getAddress() + Offset) << " -- "
518+
<< (B->getAddress() + Offset + Sym.st_size) << ") extends "
519+
<< formatv("{0:x}", Offset + Sym.st_size - B->getSize())
520+
<< " bytes past the end of its containing block ("
521+
<< B->getRange() << ")";
522+
return make_error<JITLinkError>(std::move(ErrMsg));
523+
}
524+
502525
// In RISCV, temporary symbols (Used to generate dwarf, eh_frame
503526
// sections...) will appear in object code's symbol table, and LLVM does
504527
// not use names on these temporary symbols (RISCV gnu toolchain uses

0 commit comments

Comments
 (0)