Skip to content

Commit

Permalink
Support -z nosectionheader
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Jul 31, 2023
1 parent e06d886 commit 084ca55
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 9 deletions.
5 changes: 4 additions & 1 deletion docs/mold.1
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.\" generated with Ronn-NG/v0.9.1
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
.TH "MOLD" "1" "March 2023" ""
.TH "MOLD" "1" "July 2023" ""
.SH "NAME"
\fBmold\fR \- a modern linker
.SH "SYNOPSIS"
Expand Down Expand Up @@ -425,6 +425,9 @@ Some sections such as \fB\.dynamic\fR have to be writable only during an executa
.IP
By default, \fBmold\fR generates a relro segment\. \fB\-z norelro\fR disables the feature\.
.TP
\fB\-z sectionheader\fR, \fB\-z nosectionheader\fR
\fB\-z nosectionheader\fR tell the linker to omit the section header\. By default, the linker does not omit the section header\.
.TP
\fB\-z separate\-loadable\-segments\fR, \fB\-z separate\-code\fR, \fB\-z noseparate\-code\fR
If one memory page contains multiple segments, the page protection bits are set in such a way that the needed attributes (writable or executable) are satisfied for all segments\. This usually happens at a boundary of two segments with two different attributes\.
.IP
Expand Down
4 changes: 4 additions & 0 deletions docs/mold.md
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,10 @@ arguments.
By default, `mold` generates a relro segment. `-z norelro` disables the
feature.

* `-z sectionheader`, `-z nosectionheader`:
`-z nosectionheader` tell the linker to omit the section header.
By default, the linker does not omit the section header.

* `-z separate-loadable-segments`, `-z separate-code`, `-z noseparate-code`:
If one memory page contains multiple segments, the page protection bits are
set in such a way that the needed attributes (writable or executable) are
Expand Down
6 changes: 6 additions & 0 deletions elf/cmdline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ inline const char helpmsg[] = R"(
-z origin Mark object requiring immediate $ORIGIN processing at runtime
-z pack-relative-relocs Alias for --pack-dyn-relocs=relr
-z nopack-relative-relocs
-z sectionheader Do not omit section header (default)
-z nosectionheader Omit section header
-z separate-loadable-segments
Separate all loadable segments to different pages
-z separate-code Separate code and data into different pages
Expand Down Expand Up @@ -886,6 +888,10 @@ std::vector<std::string> parse_nonpositional_args(Context<E> &ctx) {
ctx.arg.z_dynamic_undefined_weak = true;
} else if (read_z_flag("nodynamic-undefined-weak")) {
ctx.arg.z_dynamic_undefined_weak = false;
} else if (read_z_flag("sectionheader")) {
ctx.arg.z_sectionheader = true;
} else if (read_z_flag("nosectionheader")) {
ctx.arg.z_sectionheader = false;
} else if (read_flag("no-undefined")) {
ctx.arg.z_defs = true;
} else if (read_flag("fatal-warnings")) {
Expand Down
1 change: 1 addition & 0 deletions elf/mold.h
Original file line number Diff line number Diff line change
Expand Up @@ -1794,6 +1794,7 @@ struct Context {
bool z_now = false;
bool z_origin = false;
bool z_relro = true;
bool z_sectionheader = true;
bool z_shstk = false;
bool z_text = false;
i64 filler = -1;
Expand Down
12 changes: 7 additions & 5 deletions elf/output-chunks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,12 @@ void OutputEhdr<E>::copy_buf(Context<E> &ctx) {

// If e_shstrndx is too large, a dummy value is set to e_shstrndx.
// The real value is stored to the zero'th section's sh_link field.
if (ctx.shstrtab->shndx < SHN_LORESERVE)
hdr.e_shstrndx = ctx.shstrtab->shndx;
else
hdr.e_shstrndx = SHN_XINDEX;
if (ctx.shstrtab) {
if (ctx.shstrtab->shndx < SHN_LORESERVE)
hdr.e_shstrndx = ctx.shstrtab->shndx;
else
hdr.e_shstrndx = SHN_XINDEX;
}

if (ctx.arg.relocatable)
hdr.e_type = ET_REL;
Expand Down Expand Up @@ -140,7 +142,7 @@ void OutputShdr<E>::copy_buf(Context<E> &ctx) {
if (UINT16_MAX < shnum)
hdr->sh_size = shnum;

if (SHN_LORESERVE <= ctx.shstrtab->shndx)
if (ctx.shstrtab && SHN_LORESERVE <= ctx.shstrtab->shndx)
hdr->sh_link = ctx.shstrtab->shndx;

for (Chunk<E> *chunk : ctx.chunks)
Expand Down
8 changes: 5 additions & 3 deletions elf/passes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ void create_synthetic_sections(Context<E> &ctx) {
else
ctx.phdr = push(new OutputPhdr<E>(0));

ctx.shdr = push(new OutputShdr<E>);
if (ctx.arg.z_sectionheader)
ctx.shdr = push(new OutputShdr<E>);
}

ctx.got = push(new GotSection<E>);
Expand All @@ -81,7 +82,7 @@ void create_synthetic_sections(Context<E> &ctx) {
ctx.copyrel = push(new CopyrelSection<E>(false));
ctx.copyrel_relro = push(new CopyrelSection<E>(true));

if (!ctx.arg.oformat_binary)
if (ctx.shdr)
ctx.shstrtab = push(new ShstrtabSection<E>);

if (!ctx.arg.dynamic_linker.empty())
Expand Down Expand Up @@ -2522,7 +2523,8 @@ i64 compress_debug_sections(Context<E> &ctx) {
ctx.chunks[i] = comp;
});

ctx.shstrtab->update_shdr(ctx);
if (ctx.shstrtab)
ctx.shstrtab->update_shdr(ctx);

if (ctx.ehdr)
ctx.ehdr->update_shdr(ctx);
Expand Down
15 changes: 15 additions & 0 deletions test/elf/z-sectionheader.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash
. $(dirname $0)/common.inc

cat <<EOF | $CC -o $t/a.o -c -xc -
#include <stdio.h>
int main() {
printf("Hello ");
puts("world");
}
EOF

$CC -B. -o $t/exe $t/a.o -Wl,-z,nosectionheader
$QEMU $t/exe | grep -q 'Hello world'

readelf -h $t/exe 2>&1 | grep -Eq 'Size of section headers:\s+0 '

0 comments on commit 084ca55

Please sign in to comment.