Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added tests/i386/hash_without_dynstr
Binary file not shown.
Binary file added tests/i386/linked_with_emit_relocs
Binary file not shown.
15 changes: 15 additions & 0 deletions tests_src/elf/hash_without_dynstr/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
# Rebuild the dangling-sh_link ELF fixture.
#
# Freestanding: no libc, no start files, so this needs only clang and GNU ld.
# The linker script discards .dynstr while keeping .hash and .dynsym, so the
# linker leaves sh_link = 0 in both -- the same section table u-boot images
# carry. --emit-relocs keeps the link-time .rel sections around as u-boot does.
# The build is deterministic; rebuilding produces the same bytes.
set -euo pipefail
cd "$(dirname "$0")"
out=../../../tests/i386/hash_without_dynstr
clang --target=i386-unknown-linux-gnu -c -fPIC -O1 -ffreestanding \
-fno-asynchronous-unwind-tables -o table.o table.c
ld -m elf_i386 -pie --emit-relocs -T table.lds -o "$out" table.o
rm -f table.o
14 changes: 14 additions & 0 deletions tests_src/elf/hash_without_dynstr/table.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* A freestanding image whose only path to two of its functions is a table of
function pointers, the way u-boot's linker lists work. Built with a linker
script that discards .dynstr, which leaves .hash and .dynsym with an sh_link
that points at nothing -- the shape that used to make CLE throw the whole
section header table away, .symtab included. */
static int counter;

int table_helper(int x) { return x * 3 + counter; }
int table_entry_one(void) { return table_helper(1); }
int table_entry_two(void) { return table_helper(2); }

int (*const entries[])(void) = {table_entry_one, table_entry_two};

void _start(void) { counter = entries[0]() + entries[1](); }
21 changes: 21 additions & 0 deletions tests_src/elf/hash_without_dynstr/table.lds
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* Keeps .hash and .dynsym while discarding .dynstr, as u-boot's own linker
scripts do. The linker then writes sh_link = 0 into both of them. */
ENTRY(_start)
SECTIONS
{
. = 0x1000;
.text : { *(.text*) }
.rodata : { *(.rodata*) }
.data : { *(.data*) }
.bss : { *(.bss*) *(COMMON) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.rela.dyn : { *(.rela*) }
/DISCARD/ : { *(.dynstr*) }
/DISCARD/ : { *(.dynamic*) }
/DISCARD/ : { *(.interp*) }
/DISCARD/ : { *(.gnu*) }
/DISCARD/ : { *(.note*) }
/DISCARD/ : { *(.comment) }
/DISCARD/ : { *(.eh_frame*) }
}
15 changes: 15 additions & 0 deletions tests_src/elf/linked_with_emit_relocs/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
# Rebuild the already-linked-image relocation fixture.
#
# Freestanding: no libc, no start files, so this needs only clang and GNU ld.
# The section table is ordinary; what the fixture carries is a fixed link
# address of 0x1000 and, through --emit-relocs, the link-time .rel.text and
# .rel.data the linker has already applied. The build is deterministic;
# rebuilding produces the same bytes.
set -euo pipefail
cd "$(dirname "$0")"
out=../../../tests/i386/linked_with_emit_relocs
clang --target=i386-unknown-linux-gnu -c -fPIC -O1 -ffreestanding \
-fno-asynchronous-unwind-tables -o table.o table.c
ld -m elf_i386 -pie --emit-relocs -T table.lds -o "$out" table.o
rm -f table.o
14 changes: 14 additions & 0 deletions tests_src/elf/linked_with_emit_relocs/table.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* A freestanding image whose only path to two of its functions is a table of
function pointers, the way u-boot's linker lists work. Built with a linker
script that discards .dynstr, which leaves .hash and .dynsym with an sh_link
that points at nothing -- the shape that used to make CLE throw the whole
section header table away, .symtab included. */
static int counter;

int table_helper(int x) { return x * 3 + counter; }
int table_entry_one(void) { return table_helper(1); }
int table_entry_two(void) { return table_helper(2); }

int (*const entries[])(void) = {table_entry_one, table_entry_two};

void _start(void) { counter = entries[0]() + entries[1](); }
23 changes: 23 additions & 0 deletions tests_src/elf/linked_with_emit_relocs/table.lds
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* An ordinary linker script for a fixed-address image: nothing unusual in the
section table, so every ELF reader parses it. What matters is that the image
is linked at 0x1000 rather than at 0, and that --emit-relocs leaves the
link-time .rel sections behind the way u-boot's build does. */
ENTRY(_start)
SECTIONS
{
. = 0x1000;
.text : { *(.text*) }
.rodata : { *(.rodata*) }
.data : { *(.data*) }
.bss : { *(.bss*) *(COMMON) }
.rel.dyn : { *(.rel.dyn) }
/DISCARD/ : { *(.hash) }
/DISCARD/ : { *(.dynsym) }
/DISCARD/ : { *(.dynstr*) }
/DISCARD/ : { *(.dynamic*) }
/DISCARD/ : { *(.interp*) }
/DISCARD/ : { *(.gnu*) }
/DISCARD/ : { *(.note*) }
/DISCARD/ : { *(.comment) }
/DISCARD/ : { *(.eh_frame*) }
}