From ab04f8876eef5e9da79573368d440da067293c2e Mon Sep 17 00:00:00 2001 From: Johannes Stoelp Date: Sun, 30 Mar 2025 01:46:26 +0100 Subject: ld: linker script example --- src/development/ld/Makefile | 15 ++++++++++++++ src/development/ld/data.S | 23 ++++++++++++++++++++ src/development/ld/link-mem.ld | 45 ++++++++++++++++++++++++++++++++++++++++ src/development/ld/link-nomem.ld | 43 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 126 insertions(+) create mode 100644 src/development/ld/Makefile create mode 100644 src/development/ld/data.S create mode 100644 src/development/ld/link-mem.ld create mode 100644 src/development/ld/link-nomem.ld (limited to 'src/development/ld') diff --git a/src/development/ld/Makefile b/src/development/ld/Makefile new file mode 100644 index 0000000..16869a8 --- /dev/null +++ b/src/development/ld/Makefile @@ -0,0 +1,15 @@ +show-mem: +show-nomem: +show-%: link-% + readelf -W -S -l $^ + nm $^ + objdump -d $^ + +link-%: link-%.ld data.o + ld -o $@ -T $^ + +%.o: %.S + gcc -c $^ + +clean: + $(RM) mem *.o diff --git a/src/development/ld/data.S b/src/development/ld/data.S new file mode 100644 index 0000000..d76adcf --- /dev/null +++ b/src/development/ld/data.S @@ -0,0 +1,23 @@ +.section .text, "ax", @progbits +.global _entry +_entry: + mov $_stack_top, %rsp + mov $asm_array, %rax + mov (asm_len), %eax + + hlt + jmp _entry + +.section .data.asm, "aw", @progbits +asm_array: + .4byte 0xa + .4byte 0xb + .4byte 0xc + .4byte 0xd +.rept 4 + .4byte 0xff +.endr + +.section .rodata.asm, "a", @progbits +asm_len: + .4byte 8 diff --git a/src/development/ld/link-mem.ld b/src/development/ld/link-mem.ld new file mode 100644 index 0000000..b5167a5 --- /dev/null +++ b/src/development/ld/link-mem.ld @@ -0,0 +1,45 @@ +OUTPUT_FORMAT(elf64-x86-64) +ENTRY(_entry) + +MEMORY { + ROM : ORIGIN = 0x00100000, LENGTH = 0x4000 + RAM : ORIGIN = 0x00800000, LENGTH = 0x4000 +} + +SECTIONS { + /* Create .text output section at ROM (vaddr) */ + .text : { + *(.text*) + } > ROM + + ASSERT(. == ORIGIN(ROM) + SIZEOF(.text), "inc loc counter automatically") + + /* Create .data output section at RAM (vaddr) */ + /* Set load addr to ROM, right after .text (paddr) */ + .data : { + HIDDEN(_data_vaddr = .); + HIDDEN(_data_paddr = LOADADDR(.data)); + *(.data*) + } > RAM AT > ROM + + /* Append .rodata output section at ROM (vaddr) */ + .rodata : { + *(.rodata*) + } > ROM + + /* Append .stack output section at RAM (vaddr) aligned up to next 0x1000 */ + .stack : ALIGN (0x1000) { + . += 0x1000; + HIDDEN(_stack_top = .); + } > RAM + + /DISCARD/ : { + *(.*) + } +} + +/* Some example assertions */ +ASSERT(ADDR(.data) != LOADADDR(.data), "DATA vaddr and paddr must be different") +ASSERT(ADDR(.rodata) == LOADADDR(.rodata), "RODATA vaddr and paddr must be euqal") +ASSERT(ADDR(.stack) == ORIGIN(RAM) + 0x1000, "STACK section must aligned to 0x1000") +ASSERT(SIZEOF(.stack) == 0x1000, "STACK section must be 0x1000") diff --git a/src/development/ld/link-nomem.ld b/src/development/ld/link-nomem.ld new file mode 100644 index 0000000..32b7f3c --- /dev/null +++ b/src/development/ld/link-nomem.ld @@ -0,0 +1,43 @@ +OUTPUT_FORMAT(elf64-x86-64) +ENTRY(_entry) + +SECTIONS { + /* Set the initial location counter (vaddr) */ + . = 0x00800000; + + /* Create .text output section at current vaddr */ + .text : { + *(.text*) + } + + ASSERT(. == 0x00800000 + SIZEOF(.text), "inc loc counter automatically") + + /* Create .data section at location counter aligned to the next 0x100 (vaddr) */ + /* Set the load address to 0x00100000 (paddr) */ + .data ALIGN(0x100) : AT(0x00100000) { + HIDDEN(_data_vaddr = .); + HIDDEN(_data_paddr = LOADADDR(.data)); + *(.data*) + } + + /* Create .rodata with explicit vaddr */ + /* Re-adjust the paddr location counter */ + .rodata 0x00804000 : AT(ADDR(.rodata)) { + *(.rodata*) + } + + ASSERT(. == 0x00804000 + SIZEOF(.rodata), "inc loc counter automatically") + + .stack ALIGN (0x1000) : { + . += 0x1000; + HIDDEN(_stack_top = .); + } + + /DISCARD/ : { + *(.*) + } +} + +/* Some example assertions */ +ASSERT(ADDR(.data) != LOADADDR(.data), "DATA vaddr and paddr must be different") +ASSERT(SIZEOF(.stack) == 0x1000, "STACK section must be 0x1000") -- cgit v1.2.3