Skip to content

[ELF] Implement --force-group-allocation #94704

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
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
1 change: 1 addition & 0 deletions lld/ELF/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions lld/ELF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1384,6 +1384,8 @@ 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.hasArg(OPT_force_group_allocation);

if (args.hasArg(OPT_save_temps)) {
// --save-temps implies saving all temps.
Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/InputFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions lld/ELF/InputSection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ 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 without
// --force-group-allocation, the SHF_GROUP flag 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;
}
Expand Down
3 changes: 3 additions & 0 deletions lld/ELF/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@ 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 placed to the same output section, combine their relocations as well">;

defm format: Eq<"format", "Change the input format of the inputs following this option">,
MetaVarName<"[default,elf,binary]">;

Expand Down
4 changes: 4 additions & 0 deletions lld/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ ELF Improvements
(typical for embedded). It also makes full LTO feasible in such cases, since
IR merging currently prevents the linker script from referring to input
files. (`#90007 <https://github.com/llvm/llvm-project/pull/90007>`_)
* ``--force-group-allocation`` is implemented to discard ``SHT_GROUP`` sections
and combine relocation sections if their relocated section group members are
placed to the same output section.
(`#94704 <https://github.com/llvm/llvm-project/pull/94704>`_)

Breaking changes
----------------
Expand Down
2 changes: 2 additions & 0 deletions lld/docs/ld.lld.1
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ 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 placed to the same output section, combine their relocations as well.
.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
Expand Down
1 change: 1 addition & 0 deletions lld/test/ELF/comdat.s
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// RUN: ld.lld -shared %t.o %t2.o -o %t
// RUN: llvm-objdump -d %t | FileCheck %s
// RUN: llvm-readelf -S -s %t | FileCheck --check-prefix=READ %s
// RUN: ld.lld -shared --force-group-allocation %t.o %t2.o -o - | cmp - %t

// Check that we don't crash with --gc-section and that we print a list of
// reclaimed sections on stderr.
Expand Down
10 changes: 10 additions & 0 deletions lld/test/ELF/relocatable-comdat.s
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@
# 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

# 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
Expand Down
Loading