[ELF] Remove obscure -dp and GNU ld incompatible --[no-]define-common, ignore -d/-dc

https://maskray.me/blog/2022-02-06-all-about-common-symbols#no-define-common

In GNU ld, -dc only affects -r links and causes COMMON symbols to be allocated.
--no-define-common is defined to make COMMON symbols undefined for -shared.
AIUI --no-define-common is a workaround around glibc 2.1 time and not really useful.

gold confuses --define-common with -d/FORCE_COMMON_ALLOCATION and implements
--define-common with -d semantics. Its --no-define-common is incompatible with
GNU ld.

In ld.lld, b2a23cf3c0 fixed the default -r
behavior for COMMON symbols but ported the incompatible gold
--[no-]define-common. To the best of my knowledge, no project uses -dp
--[no-]define-common. So just remove these options.

-d/-dc are used by the following projects:

* grub grub-core/genmod.sh.in uses -Wl,-r,-d (https://lists.gnu.org/archive/html/grub-devel/2022-02/msg00088.html)
* FreeBSD crunchgen uses -Wl,-dc (https://reviews.freebsd.org/D34215)

A no-op implementation works for them. Only when a program inspects relocatable
output by itself and does not recognize COMMON symbols, there may be a problem.
This is an extremely unlikely case.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D119108
This commit is contained in:
Fangrui Song 2022-02-09 10:35:53 -08:00
parent 83f895d952
commit ce45c95694
8 changed files with 13 additions and 44 deletions

View File

@ -160,7 +160,6 @@ struct Configuration {
bool compressDebugSections; bool compressDebugSections;
bool cref; bool cref;
std::vector<std::pair<llvm::GlobPattern, uint64_t>> deadRelocInNonAlloc; std::vector<std::pair<llvm::GlobPattern, uint64_t>> deadRelocInNonAlloc;
bool defineCommon;
bool demangle = true; bool demangle = true;
bool dependentLibraries; bool dependentLibraries;
bool disableVerify; bool disableVerify;

View File

@ -334,9 +334,6 @@ static void checkOptions() {
if (!config->shared && !config->auxiliaryList.empty()) if (!config->shared && !config->auxiliaryList.empty())
error("-f may not be used without -shared"); error("-f may not be used without -shared");
if (!config->relocatable && !config->defineCommon)
error("-no-define-common not supported in non relocatable output");
if (config->strip == StripPolicy::All && config->emitRelocs) if (config->strip == StripPolicy::All && config->emitRelocs)
error("--strip-all and --emit-relocs may not be used together"); error("--strip-all and --emit-relocs may not be used together");
@ -996,8 +993,6 @@ static void readConfigs(opt::InputArgList &args) {
config->chroot = args.getLastArgValue(OPT_chroot); config->chroot = args.getLastArgValue(OPT_chroot);
config->compressDebugSections = getCompressDebugSections(args); config->compressDebugSections = getCompressDebugSections(args);
config->cref = args.hasArg(OPT_cref); config->cref = args.hasArg(OPT_cref);
config->defineCommon = args.hasFlag(OPT_define_common, OPT_no_define_common,
!args.hasArg(OPT_relocatable));
config->optimizeBBJumps = config->optimizeBBJumps =
args.hasFlag(OPT_optimize_bb_jumps, OPT_no_optimize_bb_jumps, false); args.hasFlag(OPT_optimize_bb_jumps, OPT_no_optimize_bb_jumps, false);
config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true); config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true);

View File

@ -129,10 +129,6 @@ def color_diagnostics_eq: JJ<"color-diagnostics=">,
def cref: FF<"cref">, def cref: FF<"cref">,
HelpText<"Output cross reference table. If -Map is specified, print to the map file">; HelpText<"Output cross reference table. If -Map is specified, print to the map file">;
defm define_common: B<"define-common",
"Assign space to common symbols",
"Do not assign space to common symbols">;
defm demangle: B<"demangle", defm demangle: B<"demangle",
"Demangle symbol names (default)", "Demangle symbol names (default)",
"Do not demangle symbol names">; "Do not demangle symbol names">;
@ -512,9 +508,6 @@ def: F<"dy">, Alias<Bdynamic>, HelpText<"Alias for --Bdynamic">;
def: F<"dn">, Alias<Bstatic>, HelpText<"Alias for --Bstatic">; def: F<"dn">, Alias<Bstatic>, HelpText<"Alias for --Bstatic">;
def: F<"non_shared">, Alias<Bstatic>, HelpText<"Alias for --Bstatic">; def: F<"non_shared">, Alias<Bstatic>, HelpText<"Alias for --Bstatic">;
def: F<"static">, Alias<Bstatic>, HelpText<"Alias for --Bstatic">; def: F<"static">, Alias<Bstatic>, HelpText<"Alias for --Bstatic">;
def: Flag<["-"], "d">, Alias<define_common>, HelpText<"Alias for --define-common">;
def: F<"dc">, Alias<define_common>, HelpText<"Alias for --define-common">;
def: F<"dp">, Alias<define_common>, HelpText<"Alias for --define-common">;
def: Flag<["-"], "x">, Alias<discard_all>, HelpText<"Alias for --discard-all">; def: Flag<["-"], "x">, Alias<discard_all>, HelpText<"Alias for --discard-all">;
def: Flag<["-"], "X">, Alias<discard_locals>, HelpText<"Alias for --discard-locals">; def: Flag<["-"], "X">, Alias<discard_locals>, HelpText<"Alias for --discard-locals">;
def: Flag<["-"], "q">, Alias<emit_relocs>, HelpText<"Alias for --emit-relocs">; def: Flag<["-"], "q">, Alias<emit_relocs>, HelpText<"Alias for --emit-relocs">;
@ -693,6 +686,8 @@ def plugin_opt_eq : J<"plugin-opt=">;
// Options listed below are silently ignored for now for compatibility. // Options listed below are silently ignored for now for compatibility.
def: F<"detect-odr-violations">; def: F<"detect-odr-violations">;
def: Flag<["-"], "d">;
def: Flag<["-"], "dc">;
def: Flag<["-"], "g">; def: Flag<["-"], "g">;
def: F<"long-plt">; def: F<"long-plt">;
def: F<"no-copy-dt-needed-entries">; def: F<"no-copy-dt-needed-entries">;

View File

@ -2192,7 +2192,7 @@ SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &strTabSec)
} }
static BssSection *getCommonSec(Symbol *sym) { static BssSection *getCommonSec(Symbol *sym) {
if (!config->defineCommon) if (config->relocatable)
if (auto *d = dyn_cast<Defined>(sym)) if (auto *d = dyn_cast<Defined>(sym))
return dyn_cast_or_null<BssSection>(d->section); return dyn_cast_or_null<BssSection>(d->section);
return nullptr; return nullptr;
@ -2234,8 +2234,8 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
eSym->st_other |= sym->stOther & STO_AARCH64_VARIANT_PCS; eSym->st_other |= sym->stOther & STO_AARCH64_VARIANT_PCS;
if (BssSection *commonSec = getCommonSec(sym)) { if (BssSection *commonSec = getCommonSec(sym)) {
// st_value is usually an address of a symbol, but that has a special // When -r is specified, a COMMON symbol is not allocated. Its st_shndx
// meaning for uninstantiated common symbols (--no-define-common). // holds SHN_COMMON and st_value holds the alignment.
eSym->st_shndx = SHN_COMMON; eSym->st_shndx = SHN_COMMON;
eSym->st_value = commonSec->alignment; eSym->st_value = commonSec->alignment;
eSym->st_size = cast<Defined>(sym)->size; eSym->st_size = cast<Defined>(sym)->size;

View File

@ -29,7 +29,9 @@ ELF Improvements
Breaking changes Breaking changes
---------------- ----------------
* ... * The GNU ld incompatible ``--no-define-common`` has been removed.
* The obscure ``-dc``/``-dp`` options have been removed.
* ``-d`` is now ignored.
COFF Improvements COFF Improvements
----------------- -----------------

View File

@ -144,8 +144,9 @@ to set the compression level to 6.
Output cross reference table. If Output cross reference table. If
.Fl Map .Fl Map
is specified, print to the map file. is specified, print to the map file.
.It Fl -define-common , Fl d .It Fl dc
Assign space to common symbols. .Fl r
specific: assign space to COMMON symbols like building an executable or shared object.
.It Fl -defsym Ns = Ns Ar symbol Ns = Ns Ar expression .It Fl -defsym Ns = Ns Ar symbol Ns = Ns Ar expression
Define a symbol alias. Define a symbol alias.
.Ar expression .Ar expression
@ -326,8 +327,6 @@ Always set
for shared libraries. for shared libraries.
.It Fl -no-color-diagnostics .It Fl -no-color-diagnostics
Do not use colors in diagnostics. Do not use colors in diagnostics.
.It Fl -no-define-common
Do not assign space to common symbols.
.It Fl -no-demangle .It Fl -no-demangle
Do not demangle symbol names. Do not demangle symbol names.
.It Fl -no-dynamic-linker .It Fl -no-dynamic-linker

View File

@ -2,16 +2,6 @@
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
# RUN: ld.lld -r %t1.o -o %t # RUN: ld.lld -r %t1.o -o %t
# RUN: llvm-readobj --symbols -r %t | FileCheck %s # RUN: llvm-readobj --symbols -r %t | FileCheck %s
# RUN: ld.lld -r --no-define-common %t1.o -o %t
# RUN: llvm-readobj --symbols -r %t | FileCheck %s
# RUN: ld.lld -r --define-common %t1.o -o %t
# RUN: llvm-readobj --symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
# RUN: ld.lld -r -d %t1.o -o %t
# RUN: llvm-readobj --symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
# RUN: ld.lld -r -dc %t1.o -o %t
# RUN: llvm-readobj --symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
# RUN: ld.lld -r -dp %t1.o -o %t
# RUN: llvm-readobj --symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
# CHECK: Symbol { # CHECK: Symbol {
# CHECK: Name: common # CHECK: Name: common
@ -23,17 +13,4 @@
# CHECK-NEXT: Section: Common (0xFFF2) # CHECK-NEXT: Section: Common (0xFFF2)
# CHECK-NEXT: } # CHECK-NEXT: }
# DEFCOMM: Symbol {
# DEFCOMM: Name: common
# DEFCOMM-NEXT: Value: 0x0
# DEFCOMM-NEXT: Size: 4
# DEFCOMM-NEXT: Binding: Global
# DEFCOMM-NEXT: Type: Object
# DEFCOMM-NEXT: Other: 0
# DEFCOMM-NEXT: Section: COMMON
# DEFCOMM-NEXT: }
# RUN: not ld.lld -shared --no-define-common %t1.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR %s
# ERROR: error: -no-define-common not supported in non relocatable output
.comm common,4,4 .comm common,4,4

View File

@ -1,4 +1,6 @@
RUN: ld.lld --version \ RUN: ld.lld --version \
RUN: -d \
RUN: -dc \
RUN: -detect-odr-violations \ RUN: -detect-odr-violations \
RUN: -g \ RUN: -g \
RUN: -long-plt \ RUN: -long-plt \