mirror of
https://github.com/rui314/mold.git
synced 2026-11-07 09:16:04 -10:00
Create .dynamic for static executables that export symbols
A static executable had no .dynamic, so -E, --dynamic-list and the other options that export symbols were silently ignored. Such an executable now has .dynamic and .dynsym with the exported symbols, as the options ask. It still has no .interp and runs as before. -static -shared output, which also lacked .dynamic, now has one.
This commit is contained in:
1 parent
c522789231
commit
c12b4144fd
3 files changed
+29
-16
No files matched your search
@@ -265,9 +265,6 @@ fn for_each_entry<E: Target>(ctx: &Context<E>, mut define: impl FnMut(u32, u64))
|
||||
}
|
||||
|
||||
pub fn update_shdr<E: Target>(ctx: &mut Context<E>) {
|
||||
if ctx.args.is_static && !ctx.args.pie {
|
||||
return;
|
||||
}
|
||||
let mut n = 0;
|
||||
for_each_entry(ctx, |_, _| n += 1);
|
||||
let size = (n * size_of::<ElfDyn<E>>()) as u64;
|
||||
|
||||
+11
-4
@@ -160,7 +160,15 @@ pub fn create_synthetic_sections<E: Target>(ctx: &mut Context<E>) {
|
||||
chunks.push(ChunkId::GnuDebuglink);
|
||||
}
|
||||
|
||||
if ctx.args.shared || !ctx.dsos.is_empty() || ctx.args.pie {
|
||||
// An executable that exports symbols has .dynamic even if it is
|
||||
// statically linked.
|
||||
if ctx.args.shared
|
||||
|| !ctx.dsos.is_empty()
|
||||
|| ctx.args.pie
|
||||
|| ctx.args.export_dynamic
|
||||
|| ctx.args.dynamic_list_data
|
||||
|| !ctx.dynamic_list_patterns.is_empty()
|
||||
{
|
||||
ctx.dynamic = Some(chunks::dynamic::new_header::<E>(&ctx.args));
|
||||
chunks.push(ChunkId::Dynamic);
|
||||
// If .dynamic exists, .dynsym and .dynstr must exist as well
|
||||
@@ -2605,7 +2613,7 @@ pub fn scan_relocations<E: Target>(ctx: &mut Context<E>) {
|
||||
};
|
||||
|
||||
// An executable without .dynamic has no dynamic symbol table even
|
||||
// if --export-dynamic or --dynamic-list exports symbols.
|
||||
// if a version script exports symbols.
|
||||
if (is_imported || is_exported) && ctx.dynamic.is_some() {
|
||||
ctx.dynsym.add_symbol(&mut ctx.symbols, id);
|
||||
}
|
||||
@@ -3907,8 +3915,7 @@ pub fn fix_synthetic_symbols<E: Target>(ctx: &mut Context<E>) {
|
||||
|
||||
// __rel_iplt_start and __rel_iplt_end. These symbols need to be
|
||||
// defined in a statically-linked non-relocatable executable because
|
||||
// such an executable lacks the .dynamic section and thus there's no way
|
||||
// to find ifunc relocations other than these symbols.
|
||||
// libc's startup code finds ifunc relocations by these symbols.
|
||||
if ctx.chunks.contains(&ChunkId::RelDyn) && ctx.args.is_static && !ctx.args.pie {
|
||||
let n = num_irelative_relocs(ctx) as i64 * size_of::<ElfRel<E>>() as i64;
|
||||
stop(ctx, ctx.syms.rel_iplt_start, Some(ChunkId::RelDyn), -n);
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
. $(dirname $0)/common.inc
|
||||
|
||||
# An executable that doesn't link against any DSO has no .dynamic, so it
|
||||
# must not have .dynsym or .dynstr either, even if symbols are exported.
|
||||
cat <<EOF | $CC -c -o $t/a.o -xc -
|
||||
# A statically-linked executable that exports symbols has .dynamic and
|
||||
# .dynsym.
|
||||
test_cflags -static || skip
|
||||
|
||||
cat <<EOF | $CC -o $t/a.o -c -xc -
|
||||
#include <stdio.h>
|
||||
void foo() {}
|
||||
void _start() {}
|
||||
int main() {
|
||||
printf("Hello world\n");
|
||||
}
|
||||
EOF
|
||||
|
||||
$CC -B. -o $t/exe1 $t/a.o -static -Wl,--export-dynamic
|
||||
readelf -W --dyn-syms $t/exe1 | grep -w foo
|
||||
$QEMU $t/exe1 | grep 'Hello world'
|
||||
|
||||
echo '{ foo; };' > $t/dyn
|
||||
$CC -B. -o $t/exe2 $t/a.o -static -Wl,--dynamic-list=$t/dyn
|
||||
readelf -W --dyn-syms $t/exe2 | grep -w foo
|
||||
$QEMU $t/exe2 | grep 'Hello world'
|
||||
|
||||
./mold -o $t/exe1 $t/a.o --dynamic-list=$t/dyn
|
||||
readelf -SW $t/exe1 | not grep -E '\.dyn(sym|str)'
|
||||
|
||||
./mold -o $t/exe2 $t/a.o --export-dynamic
|
||||
readelf -SW $t/exe2 | not grep -E '\.dyn(sym|str)'
|
||||
$CC -B. -o $t/exe3 $t/a.o -static
|
||||
readelf -WS $t/exe3 | not grep -F .dynamic
|
||||
Reference in new issue
Block a user