mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-14 20:56:26 +00:00
[LLD][ELF] Allow merging XO and RX sections, and add --[no-]xosegment
flag (#132412)
Following from the discussion in #132224, this seems like the best approach to deal with a mix of XO and RX output sections in the same binary. This change will also simplify the implementation of the PURECODE section flag for AArch64. To control this behaviour, the `--[no-]xosegment` flag is added to LLD (similarly to `--[no-]rosegment`), which determines whether to allow merging XO and RX sections in the same segment. The default value is `--no-xosegment`, which is a breaking change compared to the previous behaviour. Release notes are also added, since this will be a breaking change.
This commit is contained in:
parent
0d19efa9d5
commit
2c1bdd4a08
@ -341,6 +341,7 @@ struct Config {
|
||||
llvm::DenseSet<llvm::StringRef> saveTempsArgs;
|
||||
llvm::SmallVector<std::pair<llvm::GlobPattern, uint32_t>, 0> shuffleSections;
|
||||
bool singleRoRx;
|
||||
bool singleXoRx;
|
||||
bool shared;
|
||||
bool symbolic;
|
||||
bool isStatic = false;
|
||||
|
@ -1485,6 +1485,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
|
||||
ctx.arg.randomizeSectionPadding =
|
||||
args::getInteger(args, OPT_randomize_section_padding, 0);
|
||||
ctx.arg.singleRoRx = !args.hasFlag(OPT_rosegment, OPT_no_rosegment, true);
|
||||
ctx.arg.singleXoRx = !args.hasFlag(OPT_xosegment, OPT_no_xosegment, false);
|
||||
ctx.arg.soName = args.getLastArgValue(OPT_soname);
|
||||
ctx.arg.sortSection = getSortSection(ctx, args);
|
||||
ctx.arg.splitStackAdjustSize =
|
||||
|
@ -432,6 +432,10 @@ defm rosegment: BB<"rosegment",
|
||||
"Put read-only non-executable sections in their own segment (default)",
|
||||
"Do not put read-only non-executable sections in their own segment">;
|
||||
|
||||
defm xosegment: BB<"xosegment",
|
||||
"Put execute-only sections in their own segment",
|
||||
"Do not put execute-only sections in their own segment (default)">;
|
||||
|
||||
defm rpath: Eq<"rpath", "Add a DT_RUNPATH to the output">;
|
||||
|
||||
def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">;
|
||||
|
@ -2379,10 +2379,16 @@ Writer<ELFT>::createPhdrs(Partition &part) {
|
||||
// so when hasSectionsCommand, since we cannot introduce the extra alignment
|
||||
// needed to create a new LOAD)
|
||||
uint64_t newFlags = computeFlags(ctx, sec->getPhdrFlags());
|
||||
// When --no-rosegment is specified, RO and RX sections are compatible.
|
||||
uint32_t incompatible = flags ^ newFlags;
|
||||
if (ctx.arg.singleRoRx && !(newFlags & PF_W))
|
||||
incompatible &= ~PF_X;
|
||||
uint64_t incompatible = flags ^ newFlags;
|
||||
if (!(newFlags & PF_W)) {
|
||||
// When --no-rosegment is specified, RO and RX sections are compatible.
|
||||
if (ctx.arg.singleRoRx)
|
||||
incompatible &= ~PF_X;
|
||||
// When --no-xosegment is specified (the default), XO and RX sections are
|
||||
// compatible.
|
||||
if (ctx.arg.singleXoRx)
|
||||
incompatible &= ~PF_R;
|
||||
}
|
||||
if (incompatible)
|
||||
load = nullptr;
|
||||
|
||||
|
@ -42,8 +42,16 @@ ELF Improvements
|
||||
* Linker script ``OVERLAY`` descriptions now support virtual memory regions
|
||||
(e.g. ``>region``) and ``NOCROSSREFS``.
|
||||
|
||||
* Added ``--xosegment`` and ``--no-xosegment`` flags to control whether to place
|
||||
executable-only and readable-executable sections in the same segment. The
|
||||
default value is ``--no-xosegment``.
|
||||
(`#132412 <https://github.com/llvm/llvm-project/pull/132412>`_)
|
||||
|
||||
Breaking changes
|
||||
----------------
|
||||
* Executable-only and readable-executable sections are now allowed to be placed
|
||||
in the same segment by default. Pass ``--xosegment`` to lld in order to get
|
||||
the old behavior back.
|
||||
|
||||
COFF Improvements
|
||||
-----------------
|
||||
|
55
lld/test/ELF/aarch64-execute-only-mixed.s
Normal file
55
lld/test/ELF/aarch64-execute-only-mixed.s
Normal file
@ -0,0 +1,55 @@
|
||||
// REQUIRES: aarch64
|
||||
// RUN: rm -rf %t && split-file %s %t && cd %t
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=aarch64 start.s -o start.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=aarch64 xo.s -o xo.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=aarch64 rx.s -o rx.o
|
||||
// RUN: ld.lld start.o xo.o -o xo
|
||||
// RUN: ld.lld start.o rx.o -o rx-default
|
||||
// RUN: ld.lld --xosegment start.o rx.o -o rx-xosegment
|
||||
// RUN: ld.lld --no-xosegment start.o rx.o -o rx-no-xosegment
|
||||
// RUN: llvm-readelf -l xo | FileCheck --check-prefix=CHECK-XO %s
|
||||
// RUN: llvm-readelf -l rx-default | FileCheck --check-prefix=CHECK-MERGED %s
|
||||
// RUN: llvm-readelf -l rx-xosegment | FileCheck --check-prefix=CHECK-SEPARATE %s
|
||||
// RUN: llvm-readelf -l rx-no-xosegment | FileCheck --check-prefix=CHECK-MERGED %s
|
||||
|
||||
// CHECK-XO: PHDR
|
||||
// CHECK-XO-NEXT: LOAD
|
||||
// CHECK-XO-NEXT: LOAD 0x000120 0x0000000000210120 0x0000000000210120 0x00000c 0x00000c E 0x10000
|
||||
/// Index should match the index of the LOAD segment above.
|
||||
// CHECK-XO: 02 .text .foo
|
||||
|
||||
// CHECK-MERGED: PHDR
|
||||
// CHECK-MERGED-NEXT: LOAD
|
||||
// CHECK-MERGED-NEXT: LOAD 0x000120 0x0000000000210120 0x0000000000210120 0x00000c 0x00000c R E 0x10000
|
||||
/// Index should match the index of the LOAD segment above.
|
||||
// CHECK-MERGED: 02 .text .foo
|
||||
|
||||
// CHECK-SEPARATE: PHDR
|
||||
// CHECK-SEPARATE-NEXT: LOAD
|
||||
// CHECK-SEPARATE-NEXT: LOAD 0x000158 0x0000000000210158 0x0000000000210158 0x000008 0x000008 E 0x10000
|
||||
// CHECK-SEPARATE-NEXT: LOAD 0x000160 0x0000000000220160 0x0000000000220160 0x000004 0x000004 R E 0x10000
|
||||
/// Index should match the index of the LOAD segment above.
|
||||
// CHECK-SEPARATE: 02 .text
|
||||
// CHECK-SEPARATE: 03 .foo
|
||||
|
||||
//--- start.s
|
||||
.section .text,"axy",@progbits,unique,0
|
||||
.global _start
|
||||
_start:
|
||||
bl foo
|
||||
ret
|
||||
|
||||
//--- xo.s
|
||||
.section .foo,"axy",@progbits,unique,0
|
||||
.global foo
|
||||
foo:
|
||||
ret
|
||||
|
||||
//--- rx.s
|
||||
/// Ensure that the implicitly-created .text section has the SHF_AARCH64_PURECODE flag.
|
||||
.section .text,"axy",@progbits,unique,0
|
||||
.section .foo,"ax",@progbits,unique,0
|
||||
.global foo
|
||||
foo:
|
||||
ret
|
@ -1,12 +1,12 @@
|
||||
// REQUIRES: aarch64
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
|
||||
// RUN: ld.lld %t.o -o %t.so -shared
|
||||
// RUN: ld.lld --xosegment %t.o -o %t.so -shared
|
||||
// RUN: llvm-readelf -l %t.so | FileCheck --implicit-check-not=LOAD %s
|
||||
|
||||
// RUN: echo ".section .foo,\"ax\"; ret" > %t.s
|
||||
// RUN: llvm-mc -filetype=obj -triple=aarch64 %t.s -o %t2.o
|
||||
// RUN: ld.lld %t.o %t2.o -o %t.so -shared
|
||||
// RUN: ld.lld --xosegment %t.o %t2.o -o %t.so -shared
|
||||
// RUN: llvm-readelf -l %t.so | FileCheck --check-prefix=DIFF --implicit-check-not=LOAD %s
|
||||
|
||||
// CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x000245 0x000245 R 0x10000
|
||||
|
55
lld/test/ELF/arm-execute-only-mixed.s
Normal file
55
lld/test/ELF/arm-execute-only-mixed.s
Normal file
@ -0,0 +1,55 @@
|
||||
// REQUIRES: arm
|
||||
// RUN: rm -rf %t && split-file %s %t && cd %t
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7 start.s -o start.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7 xo.s -o xo.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7 rx.s -o rx.o
|
||||
// RUN: ld.lld start.o xo.o -o xo
|
||||
// RUN: ld.lld start.o rx.o -o rx-default
|
||||
// RUN: ld.lld --xosegment start.o rx.o -o rx-xosegment
|
||||
// RUN: ld.lld --no-xosegment start.o rx.o -o rx-no-xosegment
|
||||
// RUN: llvm-readelf -l xo | FileCheck --check-prefix=CHECK-XO %s
|
||||
// RUN: llvm-readelf -l rx-default | FileCheck --check-prefix=CHECK-MERGED %s
|
||||
// RUN: llvm-readelf -l rx-xosegment | FileCheck --check-prefix=CHECK-SEPARATE %s
|
||||
// RUN: llvm-readelf -l rx-no-xosegment | FileCheck --check-prefix=CHECK-MERGED %s
|
||||
|
||||
// CHECK-XO: PHDR
|
||||
// CHECK-XO-NEXT: LOAD
|
||||
// CHECK-XO-NEXT: LOAD 0x0000b4 0x000200b4 0x000200b4 0x0000c 0x0000c E 0x10000
|
||||
/// Index should match the index of the LOAD segment above.
|
||||
// CHECK-XO: 02 .text .foo
|
||||
|
||||
// CHECK-MERGED: PHDR
|
||||
// CHECK-MERGED-NEXT: LOAD
|
||||
// CHECK-MERGED-NEXT: LOAD 0x0000b4 0x000200b4 0x000200b4 0x0000c 0x0000c R E 0x10000
|
||||
/// Index should match the index of the LOAD segment above.
|
||||
// CHECK-MERGED: 02 .text .foo
|
||||
|
||||
// CHECK-SEPARATE: PHDR
|
||||
// CHECK-SEPARATE-NEXT: LOAD
|
||||
// CHECK-SEPARATE-NEXT: LOAD 0x0000d4 0x000200d4 0x000200d4 0x00008 0x00008 E 0x10000
|
||||
// CHECK-SEPARATE-NEXT: LOAD 0x0000dc 0x000300dc 0x000300dc 0x00004 0x00004 R E 0x10000
|
||||
/// Index should match the index of the LOAD segment above.
|
||||
// CHECK-SEPARATE: 02 .text
|
||||
// CHECK-SEPARATE: 03 .foo
|
||||
|
||||
//--- start.s
|
||||
.section .text,"axy",%progbits,unique,0
|
||||
.global _start
|
||||
_start:
|
||||
bl foo
|
||||
bx lr
|
||||
|
||||
//--- xo.s
|
||||
.section .foo,"axy",%progbits,unique,0
|
||||
.global foo
|
||||
foo:
|
||||
bx lr
|
||||
|
||||
//--- rx.s
|
||||
/// Ensure that the implicitly-created .text section has the SHF_ARM_PURECODE flag.
|
||||
.section .text,"axy",%progbits,unique,0
|
||||
.section .foo,"ax",%progbits,unique,0
|
||||
.global foo
|
||||
foo:
|
||||
bx lr
|
@ -1,13 +1,13 @@
|
||||
// REQUIRES: arm
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7-pc-linux %s -o %t.o
|
||||
// RUN: ld.lld %t.o -o %t.so -shared
|
||||
// RUN: ld.lld --xosegment %t.o -o %t.so -shared
|
||||
// RUN: llvm-readelf -l %t.so | FileCheck --implicit-check-not=LOAD %s
|
||||
|
||||
// RUN: echo ".section .foo,\"ax\"; \
|
||||
// RUN: bx lr" > %t.s
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7-pc-linux %t.s -o %t2.o
|
||||
// RUN: ld.lld %t.o %t2.o -o %t.so -shared
|
||||
// RUN: ld.lld --xosegment %t.o %t2.o -o %t.so -shared
|
||||
// RUN: llvm-readelf -l %t.so | FileCheck --check-prefix=DIFF --implicit-check-not=LOAD %s
|
||||
|
||||
// CHECK: LOAD 0x000000 0x00000000 0x00000000 0x0016d 0x0016d R 0x10000
|
||||
|
Loading…
x
Reference in New Issue
Block a user