Skip to content

[LLD][COFF] Clarify EC vs. native symbols in diagnostics on ARM64X #130857

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lld/COFF/InputFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -705,9 +705,9 @@ void ObjFile::handleComdatSelection(
// seems better though.
// (This behavior matches ModuleLinker::getComdatResult().)
if (selection != leaderSelection) {
Log(ctx) << "conflicting comdat type for " << leader << ": "
<< (int)leaderSelection << " in " << leader->getFile() << " and "
<< (int)selection << " in " << this;
Log(ctx) << "conflicting comdat type for " << symtab.printSymbol(leader)
<< ": " << (int)leaderSelection << " in " << leader->getFile()
<< " and " << (int)selection << " in " << this;
symtab.reportDuplicate(leader, this);
return;
}
Expand Down
27 changes: 17 additions & 10 deletions lld/COFF/SymbolTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,9 @@ struct UndefinedDiag {
std::vector<File> files;
};

static void reportUndefinedSymbol(COFFLinkerContext &ctx,
const UndefinedDiag &undefDiag) {
void SymbolTable::reportUndefinedSymbol(const UndefinedDiag &undefDiag) {
auto diag = errorOrWarn(ctx);
diag << "undefined symbol: " << undefDiag.sym;
diag << "undefined symbol: " << printSymbol(undefDiag.sym);

const size_t maxUndefReferences = 3;
size_t numDisplayedRefs = 0, numRefs = 0;
Expand Down Expand Up @@ -363,12 +362,12 @@ void SymbolTable::reportProblemSymbols(

for (Symbol *b : ctx.config.gcroot) {
if (undefs.count(b))
errorOrWarn(ctx) << "<root>: undefined symbol: " << b;
errorOrWarn(ctx) << "<root>: undefined symbol: " << printSymbol(b);
if (localImports)
if (Symbol *imp = localImports->lookup(b))
Warn(ctx) << "<root>: locally defined symbol imported: " << imp
<< " (defined in " << toString(imp->getFile())
<< ") [LNK4217]";
Warn(ctx) << "<root>: locally defined symbol imported: "
<< printSymbol(imp) << " (defined in "
<< toString(imp->getFile()) << ") [LNK4217]";
}

std::vector<UndefinedDiag> undefDiags;
Expand All @@ -389,7 +388,8 @@ void SymbolTable::reportProblemSymbols(
}
if (localImports)
if (Symbol *imp = localImports->lookup(sym))
Warn(ctx) << file << ": locally defined symbol imported: " << imp
Warn(ctx) << file
<< ": locally defined symbol imported: " << printSymbol(imp)
<< " (defined in " << imp->getFile() << ") [LNK4217]";
}
};
Expand All @@ -402,7 +402,7 @@ void SymbolTable::reportProblemSymbols(
processFile(file, file->getSymbols());

for (const UndefinedDiag &undefDiag : undefDiags)
reportUndefinedSymbol(ctx, undefDiag);
reportUndefinedSymbol(undefDiag);
}

void SymbolTable::reportUnresolvable() {
Expand Down Expand Up @@ -822,7 +822,7 @@ void SymbolTable::reportDuplicate(Symbol *existing, InputFile *newFile,
uint32_t newSectionOffset) {
COFFSyncStream diag(ctx, ctx.config.forceMultiple ? DiagLevel::Warn
: DiagLevel::Err);
diag << "duplicate symbol: " << existing;
diag << "duplicate symbol: " << printSymbol(existing);

DefinedRegular *d = dyn_cast<DefinedRegular>(existing);
if (d && isa<ObjFile>(d->getFile())) {
Expand Down Expand Up @@ -1350,6 +1350,13 @@ Symbol *SymbolTable::addUndefined(StringRef name) {
return addUndefined(name, nullptr, false);
}

std::string SymbolTable::printSymbol(Symbol *sym) const {
std::string name = maybeDemangleSymbol(ctx, sym->getName());
if (ctx.hybridSymtab)
return name + (isEC() ? " (EC symbol)" : " (native symbol)");
return name;
}

void SymbolTable::compileBitcodeFiles() {
if (bitcodeFileInstances.empty())
return;
Expand Down
5 changes: 5 additions & 0 deletions lld/COFF/SymbolTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ struct WrappedSymbol {
Symbol *wrap;
};

struct UndefinedDiag;

// SymbolTable is a bucket of all known symbols, including defined,
// undefined, or lazy symbols (the last one is symbols in archive
// files whose archive members are not yet loaded).
Expand Down Expand Up @@ -195,6 +197,8 @@ class SymbolTable {
uint32_t loadConfigSize = 0;
void initializeLoadConfig();

std::string printSymbol(Symbol *sym) const;

private:
/// Given a name without "__imp_" prefix, returns a defined symbol
/// with the "__imp_" prefix, if it exists.
Expand All @@ -216,6 +220,7 @@ class SymbolTable {
reportProblemSymbols(const llvm::SmallPtrSetImpl<Symbol *> &undefs,
const llvm::DenseMap<Symbol *, Symbol *> *localImports,
bool needBitcodeFiles);
void reportUndefinedSymbol(const UndefinedDiag &undefDiag);
};

std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex);
Expand Down
4 changes: 0 additions & 4 deletions lld/COFF/Symbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,6 @@ coff::operator<<(const COFFSyncStream &s,
return s;
}

const COFFSyncStream &coff::operator<<(const COFFSyncStream &s, Symbol *sym) {
return s << maybeDemangleSymbol(s.ctx, sym->getName());
}

namespace coff {

void Symbol::computeName() {
Expand Down
1 change: 0 additions & 1 deletion lld/COFF/Symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ class SymbolTable;

const COFFSyncStream &operator<<(const COFFSyncStream &,
const llvm::object::Archive::Symbol *);
const COFFSyncStream &operator<<(const COFFSyncStream &, Symbol *);

// The base class for real symbol classes.
class Symbol {
Expand Down
11 changes: 7 additions & 4 deletions lld/COFF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1282,12 +1282,13 @@ void Writer::createImportTables() {
ctx.config.dllOrder[dll] = ctx.config.dllOrder.size();

if (file->impSym && !isa<DefinedImportData>(file->impSym))
Fatal(ctx) << file->impSym << " was replaced";
Fatal(ctx) << file->symtab.printSymbol(file->impSym) << " was replaced";
DefinedImportData *impSym = cast_or_null<DefinedImportData>(file->impSym);
if (ctx.config.delayLoads.count(StringRef(file->dllName).lower())) {
if (!file->thunkSym)
Fatal(ctx) << "cannot delay-load " << toString(file)
<< " due to import of data: " << impSym;
<< " due to import of data: "
<< file->symtab.printSymbol(impSym);
delayIdata.add(impSym);
} else {
idata.add(impSym);
Expand All @@ -1306,15 +1307,17 @@ void Writer::appendImportThunks() {

if (file->thunkSym) {
if (!isa<DefinedImportThunk>(file->thunkSym))
Fatal(ctx) << file->thunkSym << " was replaced";
Fatal(ctx) << file->symtab.printSymbol(file->thunkSym)
<< " was replaced";
auto *chunk = cast<DefinedImportThunk>(file->thunkSym)->getChunk();
if (chunk->live)
textSec->addChunk(chunk);
}

if (file->auxThunkSym) {
if (!isa<DefinedImportThunk>(file->auxThunkSym))
Fatal(ctx) << file->auxThunkSym << " was replaced";
Fatal(ctx) << file->symtab.printSymbol(file->auxThunkSym)
<< " was replaced";
auto *chunk = cast<DefinedImportThunk>(file->auxThunkSym)->getChunk();
if (chunk->live)
textSec->addChunk(chunk);
Expand Down
4 changes: 2 additions & 2 deletions lld/test/COFF/arm64x-altnames.s
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// RUN: 2>&1 | FileCheck --check-prefix=ERR-NATIVE %s

// ERR-NATIVE-NOT: test-arm64ec.obj
// ERR-NATIVE: lld-link: error: undefined symbol: sym
// ERR-NATIVE: lld-link: error: undefined symbol: sym (native symbol)
// ERR-NATIVE-NEXT: >>> referenced by test-arm64.obj:(.test)
// ERR-NATIVE-NOT: test-arm64ec.obj

Expand All @@ -25,7 +25,7 @@
// RUN: 2>&1 | FileCheck --check-prefix=ERR-EC %s

// ERR-EC-NOT: test-arm64.obj
// ERR-EC: lld-link: error: undefined symbol: sym
// ERR-EC: lld-link: error: undefined symbol: sym (EC symbol)
// ERR-EC-NEXT: >>> referenced by test-arm64ec.obj:(.test)
// ERR-EC-NOT: test-arm64.obj

Expand Down
9 changes: 5 additions & 4 deletions lld/test/COFF/arm64x-incl.s
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@
// Check that including a missing symbol results in an error.

// RUN: not lld-link -machine:arm64x -out:err.dll -dll -noentry loadconfig-arm64.obj loadconfig-arm64ec.obj -include:sym sym-aarch64.obj \
// RUN: 2>&1 | FileCheck --check-prefix=ERR %s
// ERR: lld-link: error: <root>: undefined symbol: sym
// RUN: 2>&1 | FileCheck --check-prefix=ERR-EC %s
// ERR-EC: lld-link: error: <root>: undefined symbol: sym (EC symbol)

// RUN: not lld-link -machine:arm64x -out:err.dll -dll -noentry loadconfig-arm64.obj loadconfig-arm64ec.obj drectve-arm64ec.obj sym-aarch64.obj \
// RUN: 2>&1 | FileCheck --check-prefix=ERR %s
// RUN: 2>&1 | FileCheck --check-prefix=ERR-EC %s

// RUN: not lld-link -machine:arm64x -out:err.dll -dll -noentry loadconfig-arm64.obj loadconfig-arm64ec.obj drectve-aarch64.obj sym-arm64ec.obj \
// RUN: 2>&1 | FileCheck --check-prefix=ERR %s
// RUN: 2>&1 | FileCheck --check-prefix=ERR-NATIVE %s
// ERR-NATIVE: lld-link: error: <root>: undefined symbol: sym (native symbol)

#--- sym-aarch64.s
.section ".test","dr"
Expand Down
6 changes: 3 additions & 3 deletions lld/test/COFF/arm64x-symtab.s
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@

// RUN: not lld-link -machine:arm64x -dll -noentry -out:err1.dll symref-aarch64.obj sym-arm64ec.obj \
// RUN: 2>&1 | FileCheck --check-prefix=UNDEF %s
// UNDEF: lld-link: error: undefined symbol: sym
// UNDEF: lld-link: error: undefined symbol: sym (native symbol)
// UNDEF-NEXT: >>> referenced by symref-aarch64.obj:(.data)

// Check that EC object files can't reference native symbols.

// RUN: not lld-link -machine:arm64x -dll -noentry -out:out.dll symref-arm64ec.obj sym-aarch64.obj \
// RUN: 2>&1 | FileCheck --check-prefix=UNDEFEC %s
// UNDEFEC: lld-link: error: undefined symbol: sym
// UNDEFEC: lld-link: error: undefined symbol: sym (EC symbol)
// UNDEFEC-NEXT: >>> referenced by symref-arm64ec.obj:(.data)

// RUN: not lld-link -machine:arm64x -dll -noentry -out:out.dll symref-x86_64.obj sym-aarch64.obj \
// RUN: 2>&1 | FileCheck --check-prefix=UNDEFX86 %s
// UNDEFX86: lld-link: error: undefined symbol: sym
// UNDEFX86: lld-link: error: undefined symbol: sym (EC symbol)
// UNDEFX86-NEXT: >>> referenced by symref-x86_64.obj:(.data)

// RUN: not lld-link -machine:arm64x -dll -noentry -out:err2.dll symref-aarch64.obj sym-x86_64.obj \
Expand Down
4 changes: 2 additions & 2 deletions lld/test/COFF/locally-imported-arm64x.s
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %s -o %t.arm64ec.obj

// RUN: lld-link -machine:arm64x -dll -noentry %t.arm64.obj %t.arm64ec.obj -out:%t.dll 2>&1 | FileCheck --check-prefix=WARN %s
// WARN: lld-link: warning: {{.*}}.arm64.obj: locally defined symbol imported: func
// WARN-NEXT: lld-link: warning: {{.*}}.arm64ec.obj: locally defined symbol imported: func
// WARN: lld-link: warning: {{.*}}.arm64.obj: locally defined symbol imported: func (native symbol)
// WARN-NEXT: lld-link: warning: {{.*}}.arm64ec.obj: locally defined symbol imported: func (EC symbol)

// RUN: llvm-readobj --hex-dump=.test %t.dll | FileCheck --check-prefix=TEST %s
// TEST: 0x180005000 00300000 08300000
Expand Down
Loading