mirror of
https://github.com/intel/llvm.git
synced 2026-01-19 01:15:50 +08:00
[ELF] Check COMMON symbols for PROVIDE and don't redefine COMMON symbols edata/end/etext
In GNU ld, the definition precedence is: regular symbol assignment > relocatable object definition > `PROVIDE` symbol assignment. GNU ld's internal linker scripts define the non-reserved (by C and C++) edata/end/etext with `PROVIDE` so the relocatable object definition takes precedence. This makes sense because `int end;` is valid. We currently redefine such symbols if they are COMMON, but not if they are regular definitions, so `int end;` with -fcommon is essentially a UB in ld.lld. Fix this (also improve consistency and match GNU ld) by using the `isDefined` code path for `isCommon`. In GNU ld, reserved identifiers like `__ehdr_start` do not use `PROVIDE`, while we treat them all as `PROVIDE`, this seems fine. Reviewed By: peter.smith Differential Revision: https://reviews.llvm.org/D120389
This commit is contained in:
@@ -203,7 +203,7 @@ static bool shouldDefineSym(SymbolAssignment *cmd) {
|
||||
// If a symbol was in PROVIDE(), we need to define it only
|
||||
// when it is a referenced undefined symbol.
|
||||
Symbol *b = symtab->find(cmd->name);
|
||||
if (b && !b->isDefined())
|
||||
if (b && !b->isDefined() && !b->isCommon())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user