mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Vendor import of lld release_60 branch r325330:
https://llvm.org/svn/llvm-project/lld/branches/release_60@325330
This commit is contained in:
parent
168413e17e
commit
c5bd7e5db0
9 changed files with 83 additions and 24 deletions
55
COFF/PDB.cpp
55
COFF/PDB.cpp
|
|
@ -96,10 +96,11 @@ public:
|
|||
/// If the object does not use a type server PDB (compiled with /Z7), we merge
|
||||
/// all the type and item records from the .debug$S stream and fill in the
|
||||
/// caller-provided ObjectIndexMap.
|
||||
const CVIndexMap &mergeDebugT(ObjFile *File, CVIndexMap &ObjectIndexMap);
|
||||
Expected<const CVIndexMap&> mergeDebugT(ObjFile *File,
|
||||
CVIndexMap &ObjectIndexMap);
|
||||
|
||||
const CVIndexMap &maybeMergeTypeServerPDB(ObjFile *File,
|
||||
TypeServer2Record &TS);
|
||||
Expected<const CVIndexMap&> maybeMergeTypeServerPDB(ObjFile *File,
|
||||
TypeServer2Record &TS);
|
||||
|
||||
/// Add the section map and section contributions to the PDB.
|
||||
void addSections(ArrayRef<OutputSection *> OutputSections,
|
||||
|
|
@ -140,6 +141,10 @@ private:
|
|||
|
||||
/// Type index mappings of type server PDBs that we've loaded so far.
|
||||
std::map<GUID, CVIndexMap> TypeServerIndexMappings;
|
||||
|
||||
/// List of TypeServer PDBs which cannot be loaded.
|
||||
/// Cached to prevent repeated load attempts.
|
||||
std::set<GUID> MissingTypeServerPDBs;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -230,8 +235,8 @@ maybeReadTypeServerRecord(CVTypeArray &Types) {
|
|||
return std::move(TS);
|
||||
}
|
||||
|
||||
const CVIndexMap &PDBLinker::mergeDebugT(ObjFile *File,
|
||||
CVIndexMap &ObjectIndexMap) {
|
||||
Expected<const CVIndexMap&> PDBLinker::mergeDebugT(ObjFile *File,
|
||||
CVIndexMap &ObjectIndexMap) {
|
||||
ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
|
||||
if (Data.empty())
|
||||
return ObjectIndexMap;
|
||||
|
|
@ -304,11 +309,19 @@ tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) {
|
|||
return std::move(NS);
|
||||
}
|
||||
|
||||
const CVIndexMap &PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
|
||||
TypeServer2Record &TS) {
|
||||
// First, check if we already loaded a PDB with this GUID. Return the type
|
||||
Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
|
||||
TypeServer2Record &TS) {
|
||||
const GUID& TSId = TS.getGuid();
|
||||
StringRef TSPath = TS.getName();
|
||||
|
||||
// First, check if the PDB has previously failed to load.
|
||||
if (MissingTypeServerPDBs.count(TSId))
|
||||
return make_error<pdb::GenericError>(
|
||||
pdb::generic_error_code::type_server_not_found, TSPath);
|
||||
|
||||
// Second, check if we already loaded a PDB with this GUID. Return the type
|
||||
// index mapping if we have it.
|
||||
auto Insertion = TypeServerIndexMappings.insert({TS.getGuid(), CVIndexMap()});
|
||||
auto Insertion = TypeServerIndexMappings.insert({TSId, CVIndexMap()});
|
||||
CVIndexMap &IndexMap = Insertion.first->second;
|
||||
if (!Insertion.second)
|
||||
return IndexMap;
|
||||
|
|
@ -319,18 +332,21 @@ const CVIndexMap &PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
|
|||
// Check for a PDB at:
|
||||
// 1. The given file path
|
||||
// 2. Next to the object file or archive file
|
||||
auto ExpectedSession = tryToLoadPDB(TS.getGuid(), TS.getName());
|
||||
auto ExpectedSession = tryToLoadPDB(TSId, TSPath);
|
||||
if (!ExpectedSession) {
|
||||
consumeError(ExpectedSession.takeError());
|
||||
StringRef LocalPath =
|
||||
!File->ParentName.empty() ? File->ParentName : File->getName();
|
||||
SmallString<128> Path = sys::path::parent_path(LocalPath);
|
||||
sys::path::append(
|
||||
Path, sys::path::filename(TS.getName(), sys::path::Style::windows));
|
||||
ExpectedSession = tryToLoadPDB(TS.getGuid(), Path);
|
||||
Path, sys::path::filename(TSPath, sys::path::Style::windows));
|
||||
ExpectedSession = tryToLoadPDB(TSId, Path);
|
||||
}
|
||||
if (auto E = ExpectedSession.takeError()) {
|
||||
TypeServerIndexMappings.erase(TSId);
|
||||
MissingTypeServerPDBs.emplace(TSId);
|
||||
return std::move(E);
|
||||
}
|
||||
if (auto E = ExpectedSession.takeError())
|
||||
fatal("Type server PDB was not found: " + toString(std::move(E)));
|
||||
|
||||
auto ExpectedTpi = (*ExpectedSession)->getPDBFile().getPDBTpiStream();
|
||||
if (auto E = ExpectedTpi.takeError())
|
||||
|
|
@ -707,7 +723,16 @@ void PDBLinker::addObjFile(ObjFile *File) {
|
|||
// the PDB first, so that we can get the map from object file type and item
|
||||
// indices to PDB type and item indices.
|
||||
CVIndexMap ObjectIndexMap;
|
||||
const CVIndexMap &IndexMap = mergeDebugT(File, ObjectIndexMap);
|
||||
auto IndexMapResult = mergeDebugT(File, ObjectIndexMap);
|
||||
|
||||
// If the .debug$T sections fail to merge, assume there is no debug info.
|
||||
if (!IndexMapResult) {
|
||||
warn("Type server PDB for " + Name + " is invalid, ignoring debug info. " +
|
||||
toString(IndexMapResult.takeError()));
|
||||
return;
|
||||
}
|
||||
|
||||
const CVIndexMap &IndexMap = *IndexMapResult;
|
||||
|
||||
// Now do all live .debug$S sections.
|
||||
for (SectionChunk *DebugChunk : File->getDebugChunks()) {
|
||||
|
|
|
|||
|
|
@ -638,7 +638,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
|
|||
Config->Optimize = args::getInteger(Args, OPT_O, 1);
|
||||
Config->OrphanHandling = getOrphanHandling(Args);
|
||||
Config->OutputFile = Args.getLastArgValue(OPT_o);
|
||||
Config->Pie = Args.hasFlag(OPT_pie, OPT_nopie, false);
|
||||
Config->Pie = Args.hasFlag(OPT_pie, OPT_no_pie, false);
|
||||
Config->PrintGcSections =
|
||||
Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
|
||||
Config->Rpath = getRpath(Args);
|
||||
|
|
|
|||
|
|
@ -856,6 +856,14 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (Config->EMachine == EM_MIPS) {
|
||||
// FIXME: MIPS BFD linker puts _gp_disp symbol into DSO files
|
||||
// and incorrectly assigns VER_NDX_LOCAL to this section global
|
||||
// symbol. Here is a workaround for this bug.
|
||||
if (Versym && VersymIndex == VER_NDX_LOCAL && Name == "_gp_disp")
|
||||
continue;
|
||||
}
|
||||
|
||||
const Elf_Verdef *Ver = nullptr;
|
||||
if (VersymIndex != VER_NDX_GLOBAL) {
|
||||
if (VersymIndex >= Verdefs.size() || VersymIndex == VER_NDX_LOCAL) {
|
||||
|
|
|
|||
|
|
@ -202,6 +202,8 @@ def no_gnu_unique: F<"no-gnu-unique">,
|
|||
def no_merge_exidx_entries: F<"no-merge-exidx-entries">,
|
||||
HelpText<"Disable merging .ARM.exidx entries">;
|
||||
|
||||
def no_pie: F<"no-pie">, HelpText<"Do not create a position independent executable">;
|
||||
|
||||
def no_threads: F<"no-threads">,
|
||||
HelpText<"Do not run the linker multi-threaded">;
|
||||
|
||||
|
|
@ -211,8 +213,6 @@ def no_whole_archive: F<"no-whole-archive">,
|
|||
def noinhibit_exec: F<"noinhibit-exec">,
|
||||
HelpText<"Retain the executable output file whenever it is still usable">;
|
||||
|
||||
def nopie: F<"nopie">, HelpText<"Do not create a position independent executable">;
|
||||
|
||||
def no_omagic: Flag<["--"], "no-omagic">, MetaVarName<"<magic>">,
|
||||
HelpText<"Do not set the text data sections to be writable">;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
# This is an object compiled with /Zi (see the LF_TYPESERVER2 record) without an
|
||||
# adjacent type server PDB. Test that LLD fails gracefully on it.
|
||||
|
||||
# FIXME: Ideally we'd do what MSVC does, which is to warn and drop all debug
|
||||
# info in the object with the missing PDB.
|
||||
|
||||
# RUN: yaml2obj %s -o %t.obj
|
||||
# RUN: not lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
|
||||
# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
|
||||
|
||||
# CHECK: error: Type server PDB was not found
|
||||
# CHECK: warning: Type server PDB for {{.*}}.obj is invalid, ignoring debug info.
|
||||
|
||||
--- !COFF
|
||||
header:
|
||||
|
|
|
|||
14
test/ELF/Inputs/mips-gp-dips-corrupt-ver.s
Normal file
14
test/ELF/Inputs/mips-gp-dips-corrupt-ver.s
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# Source file for mips-gp-dips-corrupt-ver.so
|
||||
#
|
||||
# % cat gpdisp.ver
|
||||
# LLD_1.0.0 { global: foo; };
|
||||
#
|
||||
# % as mips-gp-dips-corrupt-ver.s -o mips-gp-dips-corrupt-ver.o
|
||||
# % ld -shared -o mips-gp-dips-corrupt-ver.so \
|
||||
# --version-script gpdisp.ver mips-gp-dips-corrupt-ver.o
|
||||
|
||||
.global foo
|
||||
.text
|
||||
foo:
|
||||
lui $t0, %hi(_gp_disp)
|
||||
addi $t0, $t0, %lo(_gp_disp)
|
||||
BIN
test/ELF/Inputs/mips-gp-dips-corrupt-ver.so
Executable file
BIN
test/ELF/Inputs/mips-gp-dips-corrupt-ver.so
Executable file
Binary file not shown.
15
test/ELF/mips-gp-disp-ver.s
Normal file
15
test/ELF/mips-gp-disp-ver.s
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# MIPS BFD linker puts _gp_disp symbol into DSO files and assigns zero
|
||||
# version definition index to it. This value means 'unversioned local symbol'
|
||||
# while _gp_disp is a section global symbol. We have to handle this bug
|
||||
# in the LLD because BFD linker is used for building MIPS toolchain
|
||||
# libraries. This test checks such handling.
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
|
||||
# RUN: ld.lld %t.o %S/Inputs/mips-gp-dips-corrupt-ver.so
|
||||
|
||||
# REQUIRES: mips
|
||||
|
||||
.global __start
|
||||
.text
|
||||
__start:
|
||||
lw $t0, %got(foo)($gp)
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
# CHECK: Type: PT_DYNAMIC
|
||||
|
||||
## Check -nopie
|
||||
# RUN: ld.lld -nopie %t1.o -o %t2
|
||||
# RUN: ld.lld -no-pie %t1.o -o %t2
|
||||
# RUN: llvm-readobj -file-headers -r %t2 | FileCheck %s --check-prefix=NOPIE
|
||||
# NOPIE-NOT: Type: SharedObject
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue