Skip to content

Commit

Permalink
Add --spare-program-headers
Browse files Browse the repository at this point in the history
This is a new experimental flag to make room at the end of PHDR
so that post-processing tools can add more entries as needed.

Fixes #1148
  • Loading branch information
rui314 committed Nov 16, 2023
1 parent efdac9a commit eb6c213
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 0 deletions.
5 changes: 5 additions & 0 deletions elf/cmdline.cc
Expand Up @@ -141,6 +141,8 @@ inline const char helpmsg[] = R"(
--sort-common Ignored
--sort-section Ignored
--spare-dynamic-tags NUMBER Reserve give number of tags in .dynamic section
--spare-program-headers NUMBER
Reserve give number of slots in the program header
--start-lib Give following object files in-archive-file semantics
--end-lib End the effect of --start-lib
--stats Print input statistics
Expand Down Expand Up @@ -606,6 +608,9 @@ std::vector<std::string> parse_nonpositional_args(Context<E> &ctx) {
ctx.arg.shared = true;
} else if (read_arg("spare-dynamic-tags")) {
ctx.arg.spare_dynamic_tags = parse_number(ctx, "spare-dynamic-tags", arg);
} else if (read_arg("spare-program-headers")) {
ctx.arg.spare_program_headers
= parse_number(ctx, "spare-program-headers", arg);
} else if (read_flag("start-lib")) {
remaining.push_back("--start-lib");
} else if (read_flag("start-stop")) {
Expand Down
1 change: 1 addition & 0 deletions elf/mold.h
Expand Up @@ -1700,6 +1700,7 @@ struct Context {
bool z_text = false;
i64 filler = -1;
i64 spare_dynamic_tags = 5;
i64 spare_program_headers = 0;
i64 thread_count = 0;
i64 z_stack_size = 0;
u64 shuffle_sections_seed;
Expand Down
1 change: 1 addition & 0 deletions elf/output-chunks.cc
Expand Up @@ -352,6 +352,7 @@ static std::vector<ElfPhdr<E>> create_phdr(Context<E> &ctx) {
}
}

vec.resize(vec.size() + ctx.arg.spare_program_headers);
return vec;
}

Expand Down
25 changes: 25 additions & 0 deletions test/elf/spare-program-headers.sh
@@ -0,0 +1,25 @@
#!/bin/bash
. $(dirname $0)/common.inc

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
$QEMU $t/exe1 | grep -q 'Hello world'
[ "$(readelf -Wl $t/exe1 | grep NULL | wc -l)" -eq 0 ]

$CC -B. -o $t/exe2 $t/a.o -Wl,--spare-program-headers=0
$QEMU $t/exe2 | grep -q 'Hello world'
[ "$(readelf -Wl $t/exe2 | grep NULL | wc -l)" -eq 0 ]

$CC -B. -o $t/exe3 $t/a.o -Wl,--spare-program-headers=1
$QEMU $t/exe3 | grep -q 'Hello world'
[ "$(readelf -Wl $t/exe3 | grep NULL | wc -l)" -eq 1 ]

$CC -B. -o $t/exe4 $t/a.o -Wl,--spare-program-headers=5
$QEMU $t/exe4 | grep -q 'Hello world'
[ "$(readelf -Wl $t/exe4 | grep NULL | wc -l)" -eq 5 ]

0 comments on commit eb6c213

Please sign in to comment.