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 1 commit
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
3 changes: 3 additions & 0 deletions lld/ELF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) ||
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I've understood the benefit of --inhibit-group-allocation.

  • For a non relocatable link it is ignored.
  • For a relocatable link its behaviour is the default state, so there is no need to explicitly use it.

The only reason I can think to use it if there is an existing linker command-line that with --force-group-allocation that I want to disable. I don't think that is likely though.

Unless I've missed something, would it be better to keep the command-line interface simple with

config->resolveGroups = !args.hasArg(OPT_relocatable) ||
args.hasFlag(OPT_force_group_allocation, false);

I couldn't find it in the GNU ld documentation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking that --inhibit-group-allocation could be kept to document the default behavior. I agree that it's not useful and I will remove it.

args.hasFlag(OPT_force_group_allocation,
OPT_inhibit_group_allocation, false);

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
9 changes: 5 additions & 4 deletions lld/ELF/InputSection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
5 changes: 5 additions & 0 deletions lld/ELF/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -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]">;

Expand Down
4 changes: 4 additions & 0 deletions lld/docs/ld.lld.1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions lld/test/ELF/relocatable-comdat.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading