diff --git a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h index 8dd176cd07f92..8946fc31db4d8 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h +++ b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h @@ -375,14 +375,7 @@ template Error ELFLinkGraphBuilder::graphifySections() { } } - if (GraphSec->getMemProt() != Prot) { - std::string ErrMsg; - raw_string_ostream(ErrMsg) - << "In " << G->getName() << ", section " << *Name - << " is present more than once with different permissions: " - << GraphSec->getMemProt() << " vs " << Prot; - return make_error(std::move(ErrMsg)); - } + GraphSec->setMemProt(GraphSec->getMemProt() | Prot); Block *B = nullptr; if (Sec.sh_type != ELF::SHT_NOBITS) { @@ -513,7 +506,14 @@ template Error ELFLinkGraphBuilder::graphifySymbols() { TargetFlagsType Flags = makeTargetFlags(Sym); orc::ExecutorAddrDiff Offset = getRawOffset(Sym, Flags); - if (Offset + Sym.st_size > B->getSize()) { + // Truncate symbol if it would overflow -- ELF size fields can't be + // trusted. + // FIXME: this makes the following error check unreachable, but it's + // left here to reduce merge conflicts. + uint64_t Size = + std::min(static_cast(Sym.st_size), B->getSize() - Offset); + + if (Offset + Size > B->getSize()) { std::string ErrMsg; raw_string_ostream ErrStream(ErrMsg); ErrStream << "In " << G->getName() << ", symbol "; @@ -536,11 +536,9 @@ template Error ELFLinkGraphBuilder::graphifySymbols() { // anonymous symbol. auto &GSym = Name->empty() - ? G->addAnonymousSymbol(*B, Offset, Sym.st_size, - false, false) - : G->addDefinedSymbol(*B, Offset, *Name, Sym.st_size, L, - S, Sym.getType() == ELF::STT_FUNC, - false); + ? G->addAnonymousSymbol(*B, Offset, Size, false, false) + : G->addDefinedSymbol(*B, Offset, *Name, Size, L, S, + Sym.getType() == ELF::STT_FUNC, false); GSym.setTargetFlags(Flags); setGraphSymbol(SymIndex, GSym);