1
1
mirror of https://github.com/rui314/mold.git synced 2024-10-26 13:10:46 +03:00

Compare commits

...

6 Commits

Author SHA1 Message Date
Rui Ueyama
2015347b0c Report an error for incompatible relocation types 2023-07-31 15:44:29 +09:00
Rui Ueyama
4daa9aad36 Do not write special symbol values to .symtab_shndx 2023-07-31 15:10:30 +09:00
Rui Ueyama
084ca55a36 Support -z nosectionheader 2023-07-31 13:50:50 +09:00
Rui Ueyama
e06d886252 Report an error if a non-PIC object file is given for an PIC output 2023-07-31 12:44:27 +09:00
Rui Ueyama
9fe3d750cc Fix test
Fixes https://github.com/rui314/mold/issues/1073
2023-07-31 09:26:00 +09:00
Rui Ueyama
13bb00bfa2 Refactor 2023-07-31 09:05:19 +09:00
10 changed files with 62 additions and 14 deletions

View File

@ -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"
@ -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

View File

@ -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

View File

@ -297,7 +297,6 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
};
auto find_paired_reloc = [&] {
Symbol<E> &sym = *file.symbols[rels[i].r_sym];
assert(sym.get_input_section() == this);
if (sym.value < r_offset) {

View File

@ -188,6 +188,8 @@ Options:
-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
@ -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")) {

View File

@ -273,11 +273,19 @@ void ObjectFile<E>::initialize_sections(Context<E> &ctx) {
comdat_groups.push_back({group, (u32)i, entries.subspan(1)});
break;
}
case SHT_REL:
if constexpr (E::is_rela)
Fatal(ctx) << *this << ": REL-type relocation table is not supported"
<< " for this target";
break;
case SHT_RELA:
if constexpr (!E::is_rela)
Fatal(ctx) << *this <<": RELA-type relocation table is not supported"
<< " for this target";
break;
case SHT_SYMTAB:
case SHT_SYMTAB_SHNDX:
case SHT_STRTAB:
case SHT_REL:
case SHT_RELA:
case SHT_NULL:
break;
default: {
@ -1094,6 +1102,11 @@ void ObjectFile<E>::scan_relocations(Context<E> &ctx) {
for (ElfRel<E> &rel : cie.get_rels()) {
Symbol<E> &sym = *this->symbols[rel.r_sym];
if (ctx.arg.pic && rel.r_type == E::R_ABS)
Error(ctx) << *this << ": relocation " << rel << " in .eh_frame can not"
<< " be used when making a position-independent output;"
<< " recompile with -fPIE or -fPIC";
if (sym.is_imported) {
if (sym.get_type() != STT_FUNC)
Fatal(ctx) << *this << ": " << sym

View File

@ -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;

View File

@ -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;
@ -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)
@ -1640,7 +1642,10 @@ ElfSym<E> to_output_esym(Context<E> &ctx, Symbol<E> &sym, u32 st_name,
// the symbol table.
if (shn_xindex) {
*shn_xindex = shndx;
esym.st_shndx = SHN_XINDEX;
if (shndx == SHN_UNDEF || shndx == SHN_ABS || shndx == SHN_COMMON)
esym.st_shndx = shndx;
else
esym.st_shndx = SHN_XINDEX;
} else {
if (shndx >= SHN_LORESERVE && shndx != SHN_ABS && shndx != SHN_COMMON)
Fatal(ctx) << sym << ": internal error: output symbol index too large: "

View File

@ -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>);
@ -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())
@ -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);

View File

@ -54,7 +54,7 @@ fi
if [ $MACHINE = x86_64 -o $MACHINE = aarch64 ]; then
$CXX -c -o $t/e.o $t/a.cc -mcmodel=large -fno-PIC
$CXX -B. -o $t/exe9 $t/e.o $static
$CXX -B. -o $t/exe9 $t/e.o -no-pie $static
$QEMU $t/exe9
$CXX -B. -o $t/exe10 $t/e.o -no-pie

15
test/elf/z-sectionheader.sh Executable file
View File

@ -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 '