1
1
mirror of https://github.com/rui314/mold.git synced 2024-11-14 07:18:42 +03:00

[ELF] Add --rosegment and --no-rosegment

Fixes https://github.com/rui314/mold/issues/514
This commit is contained in:
Rui Ueyama 2022-05-13 19:36:27 +08:00
parent fcb3bedf0d
commit b1c0a13386
4 changed files with 45 additions and 3 deletions

View File

@ -113,6 +113,8 @@ Options:
--require-defined SYMBOL Require SYMBOL be defined in the final output
--retain-symbols-file FILE Keep only symbols listed in FILE
--reverse-sections Reverses input sections in the output file
--rosegment Put read-only non-executable sections in their own segment (default)
--no-rosegment Put read-only non-executable sections in an executable segment
--rpath DIR Add DIR to runtime search path
--rpath-link DIR Ignored
--run COMMAND ARG... Run COMMAND with mold as /usr/bin/ld
@ -537,6 +539,10 @@ std::vector<std::string> parse_nonpositional_args(Context<E> &ctx) {
ctx.arg.shuffle_sections_seed = parse_number(ctx, "shuffle-sections", arg);
} else if (read_flag("reverse-sections")) {
ctx.arg.shuffle_sections = SHUFFLE_SECTIONS_REVERSE;
} else if (read_flag("rosegment")) {
ctx.arg.rosegment = true;
} else if (read_flag("no-rosegment")) {
ctx.arg.rosegment = false;
} else if (read_arg("y") || read_arg("trace-symbol")) {
ctx.arg.trace_symbol.push_back(arg);
} else if (read_arg("filler")) {

View File

@ -1593,6 +1593,7 @@ struct Context {
bool relax = true;
bool relocatable = false;
bool repro = false;
bool rosegment = true;
bool shared = false;
bool stats = false;
bool strip_all = false;

View File

@ -116,10 +116,12 @@ static i64 to_phdr_flags(Context<E> &ctx, Chunk<E> *chunk) {
return PF_R | PF_W | PF_X;
i64 ret = PF_R;
if (chunk->shdr.sh_flags & SHF_WRITE)
bool write = (chunk->shdr.sh_flags & SHF_WRITE);
if (write)
ret |= PF_W;
if ((chunk->shdr.sh_flags & SHF_EXECINSTR) ||
(ctx.arg.z_separate_code == NOSEPARATE_CODE))
if ((ctx.arg.z_separate_code == NOSEPARATE_CODE) ||
(!ctx.arg.rosegment && !write) ||
(chunk->shdr.sh_flags & SHF_EXECINSTR))
ret |= PF_X;
return ret;
}

33
test/elf/rosegment.sh Executable file
View File

@ -0,0 +1,33 @@
#!/bin/bash
export LC_ALL=C
set -e
CC="${TEST_CC:-cc}"
CXX="${TEST_CXX:-c++}"
GCC="${TEST_GCC:-gcc}"
GXX="${TEST_GXX:-g++}"
OBJDUMP="${OBJDUMP:-objdump}"
MACHINE="${MACHINE:-$(uname -m)}"
testname=$(basename "$0" .sh)
echo -n "Testing $testname ... "
cd "$(dirname "$0")"/../..
t=out/test/elf/$testname
mkdir -p $t
cat <<EOF | $CC -o $t/a.o -c -xc -
#include <stdio.h>
int main() { printf("Hello world\n"); }
EOF
$CC -B. -o $t/exe1 $t/a.o
readelf -W --segments $t/exe1 > $t/log1
! grep -q '\.interp .* \.text' $t/log1 || false
$CC -B. -o $t/exe2 $t/a.o -Wl,--rosegment
readelf -W --segments $t/exe2 > $t/log2
! grep -q '\.interp .* \.text' $t/log2 || false
$CC -B. -o $t/exe3 $t/a.o -Wl,--no-rosegment
readelf -W --segments $t/exe3 > $t/log3
grep -q '\.interp .* \.text' $t/log3
echo OK