[lld] [ELF] Implement --force-group-allocation (PR #94704)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 7 14:16:58 PDT 2024
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/94704
>From 880b593466ddba2adbdda5da0b6d4b1c741b54cc Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Thu, 6 Jun 2024 17:17:19 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.5-bogner
---
lld/ELF/Config.h | 1 +
lld/ELF/Driver.cpp | 3 +++
lld/ELF/InputFiles.cpp | 2 +-
lld/ELF/InputSection.cpp | 9 +++++----
lld/ELF/Options.td | 5 +++++
lld/docs/ld.lld.1 | 4 ++++
lld/test/ELF/relocatable-comdat.s | 12 ++++++++++++
7 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 883c4a2f84294..0173be396163e 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -286,6 +286,7 @@ struct Config {
bool relax;
bool relaxGP;
bool relocatable;
+ bool resolveGroups;
bool relrGlibc = false;
bool relrPackDynRelocs = false;
llvm::DenseSet<llvm::StringRef> saveTempsArgs;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index ddc574a11314b..e8442cc993821 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1384,6 +1384,9 @@ static void readConfigs(opt::InputArgList &args) {
config->relaxGP = args.hasFlag(OPT_relax_gp, OPT_no_relax_gp, false);
config->rpath = getRpath(args);
config->relocatable = args.hasArg(OPT_relocatable);
+ config->resolveGroups = !args.hasArg(OPT_relocatable) ||
+ args.hasFlag(OPT_force_group_allocation,
+ OPT_inhibit_group_allocation, false);
if (args.hasArg(OPT_save_temps)) {
// --save-temps implies saving all temps.
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index d760dddcf5ec5..9021bbd91b5f7 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -676,7 +676,7 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
symtab.comdatGroups.try_emplace(CachedHashStringRef(signature), this)
.second;
if (keepGroup) {
- if (config->relocatable)
+ if (!config->resolveGroups)
this->sections[i] = createInputSection(
i, sec, check(obj.getSectionName(sec, shstrtab)));
continue;
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index e6c5996c0b392..0f176f144d46b 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -76,12 +76,13 @@ InputSectionBase::InputSectionBase(InputFile *file, uint64_t flags,
invokeELFT(parseCompressedHeader,);
}
-// Drop SHF_GROUP bit unless we are producing a re-linkable object file.
-// SHF_GROUP is a marker that a section belongs to some comdat group.
-// That flag doesn't make sense in an executable.
+// SHF_INFO_LINK and SHF_GROUP are normally resolved and not copied to the
+// output section. However, for relocatable linking with the default
+// --inhibit-group-allocation, the SHF_GROUP marker and section groups are
+// retained.
static uint64_t getFlags(uint64_t flags) {
flags &= ~(uint64_t)SHF_INFO_LINK;
- if (!config->relocatable)
+ if (config->resolveGroups)
flags &= ~(uint64_t)SHF_GROUP;
return flags;
}
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index ff61a566f52f7..23385c76182eb 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -254,6 +254,11 @@ def fix_cortex_a53_843419: F<"fix-cortex-a53-843419">,
def fix_cortex_a8: F<"fix-cortex-a8">,
HelpText<"Apply fixes for ARM Cortex-A8 erratum 657417">;
+def force_group_allocation: FF<"force-group-allocation">,
+ HelpText<"Only meaningful for -r. Section groups are discarded. If two section group members are combined into the same output section, combine their relocations as well">;
+def inhibit_group_allocation: FF<"inhibit-group-allocation">,
+ HelpText<"This is the default for -r. Section groups are retained. Section group members' relocations are not combined">;
+
defm format: Eq<"format", "Change the input format of the inputs following this option">,
MetaVarName<"[default,elf,binary]">;
diff --git a/lld/docs/ld.lld.1 b/lld/docs/ld.lld.1
index da3b926d02a28..82d590a1d084f 100644
--- a/lld/docs/ld.lld.1
+++ b/lld/docs/ld.lld.1
@@ -278,6 +278,10 @@ Set the
field to the specified value.
.It Fl -fini Ns = Ns Ar symbol
Specify a finalizer function.
+.It Fl -force-group-allocation
+Only meaningful for -r. Section groups are discarded. If two section group members are combined into the same output section, combine their relocations as well.
+.It Fl -inhibit-group-allocation
+This is the default for -r. Section groups are retained. Section group members' relocations are not combined.
.It Fl -format Ns = Ns Ar input-format , Fl b Ar input-format
Specify the format of the inputs following this option.
.Ar input-format
diff --git a/lld/test/ELF/relocatable-comdat.s b/lld/test/ELF/relocatable-comdat.s
index 45ca9fb7a2484..8ca8f107f885e 100644
--- a/lld/test/ELF/relocatable-comdat.s
+++ b/lld/test/ELF/relocatable-comdat.s
@@ -47,6 +47,18 @@
# COMBINE-NEXT: .rela.text
# COMBINE-NEXT: .rela.text
+## If --force-group-allocation is specified, discard .group and combine .rela.* if their relocated sections are combined.
+# RUN: ld.lld -r -T combine.lds a.o a.o --force-group-allocation -o combine-a.ro
+# RUN: llvm-readelf -g -S combine-a.ro | FileCheck %s --check-prefix=COMBINE-A
+## --inhibit-group-allocation restores the default behavior.
+# RUN: ld.lld -r -T combine.lds a.o a.o --force-group-allocation --inhibit-group-allocation -o - | cmp - combine.ro
+
+# COMBINE-A: Name Type Address Off Size ES Flg Lk Inf Al
+# COMBINE-A: .rodata PROGBITS 0000000000000000 {{.*}} 000002 00 A 0 0 1
+# COMBINE-A-NEXT: .text PROGBITS 0000000000000000 {{.*}} 000010 00 AX 0 0 4
+# COMBINE-A-NEXT: .rela.text RELA 0000000000000000 {{.*}} 000030 18 I [[#]] [[#]] 8
+# COMBINE-A-NEXT: .note.GNU-stack
+
# RUN: echo 'SECTIONS { /DISCARD/ : {*(.rodata.*)} }' > discard-rodata.lds
# RUN: ld.lld -r -T discard-rodata.lds a.o a.o -o discard-rodata.ro
# RUN: llvm-readelf -g -S discard-rodata.ro | FileCheck %s --check-prefix=NO-RODATA
More information about the llvm-commits
mailing list