From 10b97045dffa915863c73201ccf3200f7fdded25 Mon Sep 17 00:00:00 2001 From: Calascibetta Romain Date: Mon, 23 Dec 2024 23:44:47 +0100 Subject: [PATCH] . --- GNUmakefile | 69 ++- armstub8.S | 213 ------- doc.txt | 7 +- gen_toolchain_tool.sh | 133 ++++ include/memory.h | 1 + kernel.c | 78 --- clock.c => kernel/clock.c | 0 coherent_page.c => kernel/coherent_page.c | 0 crt.c => kernel/crt.c | 0 {nolibc => kernel}/dlmalloc.i | 0 dtb.c => kernel/dtb.c | 5 - .../exception_handler.c | 0 exception_stub.S => kernel/exception_stub.S | 0 .../interrupt_handler.c | 0 kernel/kernel.c | 126 ++++ led.c => kernel/led.c | 0 log.c => kernel/log.c | 2 +- mbox.c => kernel/mbox.c | 0 memory.c => kernel/memory.c | 83 ++- pager.c => kernel/pager.c | 0 power.c => kernel/power.c | 0 printf.c => kernel/printf.c | 0 serial.c => kernel/serial.c | 0 spinlock.c => kernel/spinlock.c | 0 startup.S => kernel/startup.S | 0 synchronize.c => kernel/synchronize.c | 0 tag.c => kernel/tag.c | 0 timer.c => kernel/timer.c | 0 .../translation_table.c | 4 +- libgilbraltar.a | Bin 0 -> 118100 bytes test/test.c | 6 + test/test01.c | 15 - test/test02.c | 9 - test/test03.c | 28 - test03.map | 574 ------------------ 35 files changed, 395 insertions(+), 958 deletions(-) delete mode 100644 armstub8.S create mode 100755 gen_toolchain_tool.sh delete mode 100644 kernel.c rename clock.c => kernel/clock.c (100%) rename coherent_page.c => kernel/coherent_page.c (100%) rename crt.c => kernel/crt.c (100%) rename {nolibc => kernel}/dlmalloc.i (100%) rename dtb.c => kernel/dtb.c (80%) rename exception_handler.c => kernel/exception_handler.c (100%) rename exception_stub.S => kernel/exception_stub.S (100%) rename interrupt_handler.c => kernel/interrupt_handler.c (100%) create mode 100644 kernel/kernel.c rename led.c => kernel/led.c (100%) rename log.c => kernel/log.c (93%) rename mbox.c => kernel/mbox.c (100%) rename memory.c => kernel/memory.c (58%) rename pager.c => kernel/pager.c (100%) rename power.c => kernel/power.c (100%) rename printf.c => kernel/printf.c (100%) rename serial.c => kernel/serial.c (100%) rename spinlock.c => kernel/spinlock.c (100%) rename startup.S => kernel/startup.S (100%) rename synchronize.c => kernel/synchronize.c (100%) rename tag.c => kernel/tag.c (100%) rename timer.c => kernel/timer.c (100%) rename translation_table.c => kernel/translation_table.c (96%) create mode 100644 libgilbraltar.a create mode 100644 test/test.c delete mode 100644 test/test01.c delete mode 100644 test/test02.c delete mode 100644 test/test03.c delete mode 100644 test03.map diff --git a/GNUmakefile b/GNUmakefile index 70c1bc2..7845cfc 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -15,16 +15,6 @@ $(TOPDIR)/Makeconf: include $(TOPDIR)/Makeconf -# armstub8.bin: armstub8.S -# @echo "CC -DGIC=1 $<" -# @$(CC) -DGIC=1 -o ${<:S=o} -c $< -# @echo "LD --section-start=.text=0 ${<:S=o}" -# @$(LD) --section-start=.text=0 -o ${<:S=elf} ${<:S=o} -# @echo "DUMP ${<:S=elf}" -# @$(OBJDUMP) -D ${<:S=elf} > ${<:S=lst} -# @echo "COPY ${<:S=elf}" -# @$(OBJCOPY) ${<:S=elf} -O binary $@ - include/$(CONFIG_TARGET_TRIPLE): @echo "GEN $@" @./gen-headers.sh $@ @@ -55,6 +45,9 @@ SRCS= kernel.c timer.c led.c interrupt_handler.c exception_handler.c \ ASMS= startup.S exception_stub.S +SRCS:=$(addprefix kernel/,$(SRCS)) +ASMS:=$(addprefix kernel/,$(ASMS)) + OBJS= $(SRCS:c=o) $(ASMS:S=o) %.o: %.S @@ -65,7 +58,7 @@ OBJS= $(SRCS:c=o) $(ASMS:S=o) @echo "CC $@" @$(CC) $(CFLAGS) -c -o $@ $< -libgilbraltar.a: $(OBJS) +kernel/libgilbraltar.a: $(OBJS) @echo "AR $@" @rm -f $@ @$(AR) cr $@ $^ @@ -77,6 +70,37 @@ phony-openlibm: include/$(CONFIG_TARGET_TRIPLE) openlibm/libopenlibm.a: phony-openlibm +ocaml: + test ! -d $@ + cp -r "$$(ocamlfind query ocaml-src)" $@ + VERSION="$$(head -n1 ocaml/VERSION)" ; \ + if test -d "patches/$$VERSION" ; then \ + git apply --directory=$@ "patches/$$VERSION"/*; \ + fi + +ocaml/Makefile.config: | ocaml + PATH="$$PWD/$(TOOLDIR_FOR_BUILD):$$PATH" ; + cd ocaml && \ + ./configure \ + --target="$(MAKECONF_TARGET_ARCH)-gilbraltar-ocaml" \ + --prefix="$(MAKECONF_SYSROOT)" \ + --disable-shared \ + --disable-systhreads \ + --disable-unix-lib \ + --disable-instrumented-runtime \ + --disable-debug-runtime \ + --disable-ocamltest \ + --disable-ocamldoc \ + --disable-zstd \ + $(MAKECONF_OCAML_CONFIGURE_OPTIONS) + +OCAML_IS_BUILT := _build/ocaml_is_built +$(OCAML_IS_BUILT): ocaml/Makefile.config | _build + PATH="$$PWD/$(TOOLDIR_FOR_BUILD):$$PATH" $(MAKE) -C ocaml cross.opt + cd ocaml && ocamlrun tools/stripdebug ocamlc ocamlc.tmp + cd ocaml && ocamlrun tools/stripdebug ocalmopt ocamlopt.tmp + touch $@ + NOLIBC_CFLAGS= $(CFLAGS) -I $(TOPDIR)/nolibc/include -I $(TOPDIR)/openlibm/src -I $(TOPDIR)/openlibm/include .PHONY: phony-nolibc @@ -87,35 +111,28 @@ phony-nolibc: include/$(CONFIG_TARGET_TRIPLE) nolibc/libnolibc.a: phony-nolibc .PHONY: all -all: libgilbraltar.a +all: kernel/libgilbraltar.a .PHONY: clean clean: - $(RM) -f *.o *.a *.elf *.bin *.lst *.img + $(RM) -f kernel/*.o kernel/*.a *.elf *.bin *.img *.map $(RM) -rf include/$(CONFIG_TARGET_TRIPLE) + $(RM) -rf _build + if [ -d ocaml ] ; then $(MAKE) -C ocaml clean ; fi $(RM) -f test/*.o $(MAKE) -C openlibm clean $(MAKE) -C nolibc clean FREESTANDING_CFLAGS=_ .PHONY: distclean distclean: clean - $(RM) -f Makeconf + $(RM) -f Makeconf Makeconf.sh + if [ -d ocaml ] ; then $(MAKE) -C ocaml distclean ; fi test/%.o: test/%.c @echo "CC $@" @$(CC) $(CFLAGS) -c -o $@ $< -test01.img: libgilbraltar.a nolibc/libnolibc.a openlibm/libopenlibm.a test/test01.o +kernel_2712.img: kernel/libgilbraltar.a nolibc/libnolibc.a openlibm/libopenlibm.a test/test.o @echo "LD ${@:img=elf}" - @$(LD) test/${@:img=o} -o ${@:img=elf} $(LDFLAGS) -Wl,-T gilbraltar.ld - @$(OBJCOPY) ${@:img=elf} -O binary $@ - -test02.img: libgilbraltar.a nolibc/libnolibc.a openlibm/libopenlibm.a test/test02.o - @echo "LD ${@:img=elf}" - @$(LD) test/${@:img=o} -o ${@:img=elf} $(LDFLAGS) -Wl,-T gilbraltar.ld - @$(OBJCOPY) ${@:img=elf} -O binary $@ - -test03.img: libgilbraltar.a nolibc/libnolibc.a openlibm/libopenlibm.a test/test03.o - @echo "LD ${@:img=elf}" - @$(LD) test/${@:img=o} -o ${@:img=elf} $(LDFLAGS) -Wl,-Map ${@:img=map} -Wl,-T gilbraltar.ld + @$(LD) test/test.o -o ${@:img=elf} $(LDFLAGS) -Wl,-Map ${@:img=map} -Wl,-T gilbraltar.ld @$(OBJCOPY) ${@:img=elf} -O binary $@ diff --git a/armstub8.S b/armstub8.S deleted file mode 100644 index 84ea1e1..0000000 --- a/armstub8.S +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) 2024 Romain Calascibetta - * Copyright (c) 2016-2019 Raspberry Pi (Trading) Ltd. - * Copyright (c) 2016 Stephen Warren - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#define BIT(x) (1 << (x)) - -#define LOCAL_CONTROL 0xff800000 -#define LOCAL_PRESCALER 0xff800008 -#define GIC_DISTB 0xff841000 -#define GIC_CPUB 0xff842000 -#define OSC_FREQ 54000000 - -#define SCR_RW BIT(10) -#define SCR_HCE BIT(8) -#define SCR_SMD BIT(7) -#define SCR_RES1_5 BIT(5) -#define SCR_RES1_4 BIT(4) -#define SCR_NS BIT(0) -#define SCR_VAL \ - (SCR_RW | SCR_HCE | SCR_SMD | SCR_RES1_5 | SCR_RES1_4 | SCR_NS) - -#define ACTLR_VAL \ - (BIT(0) | BIT(1) | BIT(4) | BIT(5) | BIT(6)) - -#define CPUECTLR_EL1 S3_1_C15_C2_1 -#define CPUECTLR_EL1_SMPEN BIT(6) - -#define SPSR_EL3_D BIT(9) -#define SPSR_EL3_A BIT(8) -#define SPSR_EL3_I BIT(7) -#define SPSR_EL3_F BIT(6) -#define SPSR_EL3_MODE_EL2H 9 -#define SPSR_EL3_VAL \ - (SPSR_EL3_D | SPSR_EL3_A | SPSR_EL3_I | SPSR_EL3_F | SPSR_EL3_MODE_EL2H) - -#define L2CTLR_EL1 S3_1_C11_C0_2 -#define GICC_CTRLR 0x0 -#define GICC_PMR 0x4 -#define IT_NR 0x8 // Number of interrupt enable registers (256 total irqs) -#define GICD_CTRLR 0x0 -#define GICD_IGROUPR 0x80 - -.globl _start -_start: - // LOCAL_CONTROL: - // Bit 9 clear: Increment by 1 (vs. 2). - // Bit 8 clear: Timer source is 19.2MHz crystal (vs. APB). - ldr x0, =LOCAL_CONTROL - str wzr, [x0] - // LOCAL_PRESCALER; divide-by (0x80000000 / register_val) == 1 - mov w1, 0x80000000 - str w1, [x0, #(LOCAL_PRESCALER - LOCAL_CONTROL)] - - // Set L2 read/write cache latency to 3 - mrs x0, L2CTLR_EL1 - mov x1, #0x22 - orr x0, x0, x1 - msr L2CTLR_EL1, x0 - - // Set up CNTFRQ_EL0 - ldr x0, =OSC_FREQ - msr CNTFRQ_EL0, x0 - - // Set up CNTVOFF_EL2 - msr CNTVOFF_EL2, xzr - - // Enable FP/SIMD - // Bit 10 (TFP) is set to 0 - msr CPTR_EL3, xzr - - // Set up SCR - mov x0, #SCR_VAL - msr SCR_EL3, x0 - - // Set up ACTLR - mov x0, #ACTLR_VAL - msr ACTLR_EL3, x0 - - // Set SMPEN - mov x0, #CPUECTLR_EL1_SMPEN - msr CPUECTLR_EL1, x0 - -#ifdef GIC - bl setup_gic -#endif - // Set up SCTLR_EL2 - // All set bits below are res1. LE, no WXN/I/SA/C/A/M - ldr x0, =0x30c50830 - msr SCTLR_EL2, x0 - - // Switch to EL2 - mov x0, #SPSR_EL3_VAL - msr spsr_el3, x0 - adr x0, in_el2 - msr elr_el3, x0 - eret -in_el2: - mrs x6, MPIDR_EL1 - and x6, x6, #0x3 - cbz x6, primary_cpu - - adr x5, spin_cpu0 -secondary_spin: - wfe - ldr x4, [x5, x6, lsl #3] - cbz x4, secondary_spin - mov x0, #0 - b boot_kernel - -primary_cpu: - ldr w4, kernel_entry32 - ldr w0, dtb_ptr32 - -boot_kernel: - mov x1, #0 - mov x2, #0 - mov x3, #0 - br x4 - -.ltorg - -.org 0xd8 -.globl spin_cpu0 -spin_cpu0: - .quad 0 -.org 0xe0 -.globl spin_cpu1 -spin_cpu1: - .quad 0 -.org 0xe8 -.globl spin_cpu2 -spin_cpu2: - .quad 0 -.org 0xf0 -.globl spin_cpu3 -spin_cpu3: -# Shared with next two symbols/.word -# FW clears the next 8 bytes after reading the initial value, leaving -# the location suitable for use as spin_cpu3 -.org 0xf0 -.globl stub_magic -stub_magic: - .word 0x5afe570b -.org 0xf4 -.globl stub_version -stub_version: - .word 0 -.org 0xf8 -.globl dtb_ptr32 -dtb_ptr32: - .word 0x0 -.org 0xfc -.globl kernel_entry32 -kernel_entry32: - .word 0x0 - -.org 0x100 - -#ifdef GIC - -setup_gic: // Called from secure mode - set all interrupts to group 1 and enable. - mrs x0, MPIDR_EL1 - ldr x2, =GIC_DISTB - tst x0, #0x3 - b.eq 2f // primary core - - mov w0, #3 // Enable group 0 and 1 IRQs from distributor - str w0, [x2, #GICD_CTRLR] -2: - add x1, x2, #(GIC_CPUB - GIC_DISTB) - mov w0, #0x1e7 - str w0, [x1, #GICC_CTRLR] // Enable group 1 IRQs from CPU interface - mov w0, #0xff - str w0, [x1, #GICC_PMR] // priority mask - add x2, x2, #GICD_IGROUPR - mov x0, #(IT_NR * 4) - mov w1, #~0 // group 1 all the things -3: - subs x0, x0, #4 - str w1, [x2, x0] - b.ne 3b - ret - -#endif - -.globl dtb_space -dtb_space: diff --git a/doc.txt b/doc.txt index 73f95f2..411150f 100644 --- a/doc.txt +++ b/doc.txt @@ -47,12 +47,11 @@ BCM2712 is the Broadcom chip used by Raspberry Pi 5 | 00350000 | 32 KByte | for Core 2 | | 00358000 | 32 KByte | for Core 3 | | 00360000 | | End of FIQ stacks | -| | Page Table | | -| 00360000 | 16 KByte | | -| 00364000 | | End of page table | | 00500000 | 4 MByte | Coherent region | | 00900000 | | | +| 1b000000 | 16 MByte | Pager | +| 1c000000 | | | | 40000000 | | Heap | | ... -| 1FFFFFFFF | 8192 MB | Heap | +| 100000000 | 8192 MB | Heap | | 1000000000 | 16 MByte | AXI peripherals | diff --git a/gen_toolchain_tool.sh b/gen_toolchain_tool.sh new file mode 100755 index 0000000..11c3855 --- /dev/null +++ b/gen_toolchain_tool.sh @@ -0,0 +1,133 @@ +#!/bin/sh + +# Generate a wrapper for Gilbraltar (G)CC, ld, objcopy and any other binutil +# Expected argument: the tool to generate +# Expected environment variables: +# ARCH: the target architecture (x86_64 or aarch64) +# TOOL_CFLAGS and TOOL_LDFLAGS: extra flags +# GILBRALTAR_TOOLCHAIN: the target for the wrapped Gilbraltar toolchain +# OTHERTOOLPREFIX: the prefix for tools not in the Gilbraltar toolchain +# TARGET_X: overrides the command for binutil X + +gen_cc() { + # Note that -nostdlib is not required, as it is injected by Solo5' cc, ld + + CFLAGS="$TOOL_CFLAGS" + LDFLAGS="$TOOL_LDFLAGS" + EXTRALIBS="" + + case "$ARCH" in + aarch64) + EXTRALIBS="-lgcc" + ;; + esac + + # Add the -Wno-unused-command-line-argument option for clang, as we always + # give it compiling options, even if it will be only linking + # Reuse the test from Solo5 to detect clang + if "$SOLO5_TOOLCHAIN-cc" -dM -E - /dev/null; then + TOOL="$SOLO5_TOOLCHAIN-$TOOL" + else + case "$TOOL" in + as) + TOOL="$SOLO5_TOOLCHAIN-cc -c" + ;; + *) + if command -v -- "$OTHERTOOLPREFIX$TOOL" > /dev/null; then + TOOL="$OTHERTOOLPREFIX$TOOL" + fi + ;; + esac + fi + + cat << EOF +#!/bin/sh +exec $TOOL "\$@" +EOF +} + +case "$1" in + cc|gcc) + gen_cc + ;; + *) + gen_tool "$1" + ;; +esac diff --git a/include/memory.h b/include/memory.h index 1aa4de4..ed3ce24 100644 --- a/include/memory.h +++ b/include/memory.h @@ -2,5 +2,6 @@ #define __GILBRALTAR_MEMORY__ void gilbraltar_memory_init(void); +void gilbraltar_get_heap(uintptr_t *, uintptr_t *); #endif diff --git a/kernel.c b/kernel.c deleted file mode 100644 index dde4a26..0000000 --- a/kernel.c +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern int main(int, char *const *); - -extern char __bss_start; -extern char _etext[]; -extern char _end[]; - -#define PROPTAG_GET_COMMAND_LINE 0x00050001 - -struct __attribute__((packed)) command_line { - uint32_t id; - uint32_t value_len; - uint32_t param_len; - uint8_t str[2048]; -}; - -static size_t split(char *src, char *dst[], size_t len) { - int i = 0; - char *rem = src; - - while (rem != NULL && *rem != '\0' && i < len) { - char *e = strstr(rem, " "); - dst[i++] = rem; - if (e != NULL) { - *e = '\0'; - while (*(++e) == ' ') - ; - } - rem = e; - } - - return (i); -} - -void gilbraltar_sysinit(void) { - enable_fiqs(); - enable_irqs(); - memset(&__bss_start, 0, (uintptr_t)_end - (uintptr_t)__bss_start); - crt_init_ssp(); - - gilbraltar_serial_init(); - gilbraltar_memory_init(); - - struct command_line p; - char *cmdline[64] = {NULL}; - size_t ac = 1; - cmdline[0] = "gilbraltar"; - - if (!gilbraltar_get_tag(PROPTAG_GET_COMMAND_LINE, &p, sizeof(p), 2048)) { - gilbraltar_log(ERROR, "Impossible to retrieve cmdline.txt.\r\n"); - ac = 1; - } else if (p.param_len >= sizeof(p.str)) { - gilbraltar_log(ERROR, "cmdline.txt too long.\r\n"); - ac = 1; - } else { - p.str[p.param_len] = '\0'; - ac = split((char *)p.str, cmdline + 1, 62); - } - - gilbraltar_dtb_init(); - - int ret = main(ac + 1, cmdline); - gilbraltar_log(DEBUG, "End of program: %3d.", ret); - - if (ret == 0) - poweroff(); -} diff --git a/clock.c b/kernel/clock.c similarity index 100% rename from clock.c rename to kernel/clock.c diff --git a/coherent_page.c b/kernel/coherent_page.c similarity index 100% rename from coherent_page.c rename to kernel/coherent_page.c diff --git a/crt.c b/kernel/crt.c similarity index 100% rename from crt.c rename to kernel/crt.c diff --git a/nolibc/dlmalloc.i b/kernel/dlmalloc.i similarity index 100% rename from nolibc/dlmalloc.i rename to kernel/dlmalloc.i diff --git a/dtb.c b/kernel/dtb.c similarity index 80% rename from dtb.c rename to kernel/dtb.c index 8d199fa..f47cd9a 100644 --- a/dtb.c +++ b/kernel/dtb.c @@ -39,10 +39,5 @@ bool gilbraltar_dtb_init(void) { if (total_size < sizeof(struct header) || total_size > DTB_MAX_SIZE) return false; - gilbraltar_log(INFO, " dtb magic : %04x\r\n", be32toh(hdr->magic)); - gilbraltar_log(INFO, "dtb version : %d\r\n", be32toh(hdr->last_comp_version)); - gilbraltar_log(INFO, " dtb size : %d byte(s)\r\n", - be32toh(hdr->total_size)); - return true; } diff --git a/exception_handler.c b/kernel/exception_handler.c similarity index 100% rename from exception_handler.c rename to kernel/exception_handler.c diff --git a/exception_stub.S b/kernel/exception_stub.S similarity index 100% rename from exception_stub.S rename to kernel/exception_stub.S diff --git a/interrupt_handler.c b/kernel/interrupt_handler.c similarity index 100% rename from interrupt_handler.c rename to kernel/interrupt_handler.c diff --git a/kernel/kernel.c b/kernel/kernel.c new file mode 100644 index 0000000..e3e74dd --- /dev/null +++ b/kernel/kernel.c @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int main(int, char *const *); + +extern char __bss_start; +extern char _etext[]; +extern char _end[]; + +#define PROPTAG_GET_COMMAND_LINE 0x00050001 + +struct __attribute__((packed)) command_line { + uint32_t id; + uint32_t value_len; + uint32_t param_len; + uint8_t str[2048]; +}; + +static size_t split(char *src, char *dst[], size_t len) { + int i = 0; + char *rem = src; + + while (rem != NULL && *rem != '\0' && i < len) { + char *e = strstr(rem, " "); + dst[i++] = rem; + if (e != NULL) { + *e = '\0'; + while (*(++e) == ' ') + ; + } + rem = e; + } + + return (i); +} + +void gilbraltar_dump(void) { + uintptr_t heap_start; + uintptr_t heap_end; + + gilbraltar_get_heap(&heap_start, &heap_end); + uintptr_t kernel_start = MEM_KERNEL_START; + uintptr_t kernel_end = (uintptr_t)_etext; + uintptr_t kernel_top = (uintptr_t)_end; + uintptr_t kernel_stack_start = MEM_KERNEL_STACK - KERNEL_STACK_SIZE; + uintptr_t kernel_stack_end = MEM_KERNEL_STACK; + uintptr_t exn_stack_start = MEM_EXCEPTION_STACK - EXCEPTION_STACK_SIZE; + uintptr_t exn_stack_end = MEM_EXCEPTION_STACK; + uintptr_t irq_stack_start = MEM_IRQ_STACK - EXCEPTION_STACK_SIZE; + uintptr_t irq_stack_end = MEM_IRQ_STACK; + uintptr_t fiq_stack_start = MEM_FIQ_STACK - EXCEPTION_STACK_SIZE; + uintptr_t fiq_stack_end = MEM_FIQ_STACK; + uintptr_t page_table_start = MEM_PAGE_TABLE1; + uintptr_t page_table_end = MEM_PAGE_TABLE1_END; + uintptr_t coherent_region_start = MEM_COHERENT_REGION; + uintptr_t coherent_region_end = MEM_COHERENT_REGION + 4 * MEGABYTE; + + gilbraltar_log(INFO, " _____ _ _ _ _ _ \r\n"); + gilbraltar_log(INFO, "| __|_| | |_ ___ ___| | |_ ___ ___ \r\n"); + gilbraltar_log(INFO, "| | | | | . | _| .'| | _| .'| _|\r\n"); + gilbraltar_log(INFO, "|_____|_|_|___|_| |__,|_|_| |__,|_| \r\n"); + gilbraltar_log(INFO, " BL31 @ 0x%08x - 0x%08x\r\n", 0x0, 0x8000); + gilbraltar_log(INFO, " EL3 stack @ 0x%08x\r\n", 0x6f000); + gilbraltar_log(INFO, " kernel @ 0x%08lx - 0x%08lx | 0x%08lx\r\n", + kernel_start, kernel_end, kernel_top); + gilbraltar_log(INFO, " stack @ 0x%08lx - 0x%08lx\r\n", + kernel_stack_start, kernel_stack_end); + gilbraltar_log(INFO, "exception stack @ 0x%08lx - 0x%08lx\r\n", + exn_stack_start, exn_stack_end); + gilbraltar_log(INFO, " irq stack @ 0x%08lx - 0x%08lx\r\n", + irq_stack_start, irq_stack_end); + gilbraltar_log(INFO, " fiq stack @ 0x%08lx - 0x%08lx\r\n", + fiq_stack_start, fiq_stack_end); + gilbraltar_log(INFO, " pages table @ 0x%08lx - 0x%08lx\r\n", + page_table_start, page_table_end); + gilbraltar_log(INFO, "coherent region @ 0x%08lx - 0x%08lx\r\n", + coherent_region_start, coherent_region_end); + gilbraltar_log(INFO, " heap @ 0x%08lx - 0x%08lx\r\n", heap_start, + heap_end); + gilbraltar_log(INFO, "\r\n"); +} + +void gilbraltar_sysinit(void) { + enable_fiqs(); + enable_irqs(); + memset(&__bss_start, 0, (uintptr_t)_end - (uintptr_t)__bss_start); + crt_init_ssp(); + + gilbraltar_serial_init(); + gilbraltar_memory_init(); + + struct command_line p; + char *cmdline[64] = {NULL}; + size_t ac = 1; + cmdline[0] = "gilbraltar"; + + if (!gilbraltar_get_tag(PROPTAG_GET_COMMAND_LINE, &p, sizeof(p), 2048)) { + gilbraltar_log(ERROR, "Impossible to retrieve cmdline.txt.\r\n"); + ac = 1; + } else if (p.param_len >= sizeof(p.str)) { + gilbraltar_log(ERROR, "cmdline.txt too long.\r\n"); + ac = 1; + } else { + p.str[p.param_len] = '\0'; + ac = split((char *)p.str, cmdline + 1, 62); + } + + gilbraltar_dtb_init(); + gilbraltar_dump(); + + int ret = main(ac + 1, cmdline); + gilbraltar_log(DEBUG, "End of program: %3d.", ret); + + if (ret == 0) + poweroff(); +} diff --git a/led.c b/kernel/led.c similarity index 100% rename from led.c rename to kernel/led.c diff --git a/log.c b/kernel/log.c similarity index 93% rename from log.c rename to kernel/log.c index 9e6cfb4..8e3a606 100644 --- a/log.c +++ b/kernel/log.c @@ -2,7 +2,7 @@ #include #include -static enum log_level actual_level = DEBUG; +static enum log_level actual_level = INFO; size_t gilbraltar_log(enum log_level level, const char *fmt, ...) { if (actual_level < level) diff --git a/mbox.c b/kernel/mbox.c similarity index 100% rename from mbox.c rename to kernel/mbox.c diff --git a/memory.c b/kernel/memory.c similarity index 58% rename from memory.c rename to kernel/memory.c index 64df9d6..31009e8 100644 --- a/memory.c +++ b/kernel/memory.c @@ -1,7 +1,9 @@ +#include #include #include #include #include +#include #include #include #include @@ -84,14 +86,89 @@ static void enable_mmu(void) { __asm__ __volatile("msr sctlr_el1, %0" : : "r"(sctlr_el1) : "memory"); } +static uintptr_t sbrk_start; +static uintptr_t sbrk_end; +static uintptr_t sbrk_cur; +static uintptr_t sbrk_guard_size; + +void *sbrk(intptr_t increment) { + uintptr_t prev, brk; + uintptr_t max = (uintptr_t)&prev - sbrk_guard_size; + prev = brk = sbrk_cur; + + brk += increment; + + if (brk >= max || brk >= sbrk_end || brk < sbrk_start) + return ((void *)(-1)); + + sbrk_cur = brk; + return ((void *)prev); +} + +#define PROPTAG_GET_BOARD_REVISION 0x00010002 + +struct __attribute__((packed)) board_revision { + uint32_t id; + uint32_t value_len; + uint32_t param_len; + uint32_t revision; +}; + void gilbraltar_memory_init(void) { size_t rsv = ARM_MEM_SIZE - MEM_HEAP_START - PAGE_RESERVE; gilbraltar_pager_init(MEM_HEAP_START + rsv, PAGE_RESERVE); - gilbraltar_log(INFO, " pager @ 0x%08lx - 0x%08lx\r\n", - MEM_HEAP_START + rsv, MEM_HEAP_START + rsv + PAGE_RESERVE); - gilbraltar_translation_table_init(ARM_MEM_SIZE); enable_mmu(); instruction_sync_barrier(); + + struct board_revision b; + + if (!gilbraltar_get_tag(PROPTAG_GET_BOARD_REVISION, &b, sizeof(b), 4)) { + gilbraltar_log(ERROR, "Impossible to retrieve the board revision.\r\n"); + abort(); + } + + assert(b.revision & (1 << 23)); // new revision scheme + size_t ram_size = 256 << ((b.revision >> 20) & 7); + size_t heap_size = (ram_size - 1024) * MEGABYTE; + heap_size = (heap_size > (8 * GIGABYTE) - GIGABYTE) + ? (8 * GIGABYTE) - GIGABYTE + : heap_size; + sbrk_guard_size = (heap_size >= MEGABYTE) ? MEGABYTE : (heap_size / 2); + sbrk_start = sbrk_cur = GIGABYTE; + sbrk_end = GIGABYTE + heap_size; } + +void gilbraltar_get_heap(uintptr_t *start, uintptr_t *end) { + *start = sbrk_start; + *end = sbrk_end; +} + +#include +#define ABORT_ON_ASSERT_FAILURE 0 + +#undef WIN32 +#define HAVE_MMAP 0 +#define HAVE_MREMAP 0 +#define MMAP_CLEARS 0 +#define NO_MALLOC_STATS 1 +#define LACKS_FCNTL_H +#define LACKS_SYS_PARAM_H +#define LACKS_SYS_MMAN_H +#define LACKS_STRINGS_H +#define LACKS_SYS_TYPES_H +#define LACKS_SCHED_H +#define LACKS_TIME_H +#define MALLOC_FAILURE_ACTION +#define USE_LOCKS 0 // TODO(dinosaure): for multicore. +#define STRUCT_MALLINFO_DECLARED 1 +#define FOOTERS 1 + +/* disable null-pointer-arithmetic warning on clang */ +#if defined(__clang__) && __clang_major__ >= 6 +#pragma clang diagnostic ignored "-Wnull-pointer-arithmetic" +#endif + +/* inline the dlmalloc implementation into this module */ +#include "dlmalloc.i" diff --git a/pager.c b/kernel/pager.c similarity index 100% rename from pager.c rename to kernel/pager.c diff --git a/power.c b/kernel/power.c similarity index 100% rename from power.c rename to kernel/power.c diff --git a/printf.c b/kernel/printf.c similarity index 100% rename from printf.c rename to kernel/printf.c diff --git a/serial.c b/kernel/serial.c similarity index 100% rename from serial.c rename to kernel/serial.c diff --git a/spinlock.c b/kernel/spinlock.c similarity index 100% rename from spinlock.c rename to kernel/spinlock.c diff --git a/startup.S b/kernel/startup.S similarity index 100% rename from startup.S rename to kernel/startup.S diff --git a/synchronize.c b/kernel/synchronize.c similarity index 100% rename from synchronize.c rename to kernel/synchronize.c diff --git a/tag.c b/kernel/tag.c similarity index 100% rename from tag.c rename to kernel/tag.c diff --git a/timer.c b/kernel/timer.c similarity index 100% rename from timer.c rename to kernel/timer.c diff --git a/translation_table.c b/kernel/translation_table.c similarity index 96% rename from translation_table.c rename to kernel/translation_table.c index d09c0dd..26f0087 100644 --- a/translation_table.c +++ b/kernel/translation_table.c @@ -60,7 +60,7 @@ uintptr_t gilbraltar_translation_table_base(void) { void gilbraltar_translation_table_init(size_t size) { l2_table = (union TARMV8MMU_LEVEL2_DESCRIPTOR *)gilbraltar_palloc(); - gilbraltar_log(INFO, "L2 table allocated.\r\n"); + gilbraltar_log(DEBUG, "L2 table allocated.\r\n"); memset(l2_table, 0, PAGE_SIZE); @@ -74,7 +74,7 @@ void gilbraltar_translation_table_init(size_t size) { !(MEM_IOMEM_PCIE_START <= base_addr && base_addr <= MEM_IOMEM_PCIE_END)) continue; // as far as we can - gilbraltar_log(INFO, "New L3 table.\r\n"); + gilbraltar_log(DEBUG, "New L3 table.\r\n"); union TARMV8MMU_LEVEL3_DESCRIPTOR *l3_table = new_level_l3_table(base_addr); struct TARMV8MMU_LEVEL2_TABLE_DESCRIPTOR *desc = &l2_table[entry].table; diff --git a/libgilbraltar.a b/libgilbraltar.a new file mode 100644 index 0000000000000000000000000000000000000000..2ef3e95cd4d3852d3abaa449c970b74181506e88 GIT binary patch literal 118100 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 + +int main(int ac, const char *av[]) { + gilbraltar_log(INFO, "Hello World!\r\n"); + return (0); +} diff --git a/test/test01.c b/test/test01.c deleted file mode 100644 index 48705a4..0000000 --- a/test/test01.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include - -/* The kernel should start and the LED should blink. - * The time between blinks should be "fairly" long (around 1s). - */ - -void main(void) { - while (1) { - gilbraltar_led(false); - gilbraltar_delay_hot_loop(0x3f0000); - gilbraltar_led(true); - gilbraltar_delay_hot_loop(0x3f0000); - } -} diff --git a/test/test02.c b/test/test02.c deleted file mode 100644 index 1e21641..0000000 --- a/test/test02.c +++ /dev/null @@ -1,9 +0,0 @@ -#include - -/* The kernel should start and you should see - * "Hello World!" in your terminal! - */ -void main(void) { - gilbraltar_serial_init(); - gilbraltar_serial_puts("Hello World!\r\n"); -} diff --git a/test/test03.c b/test/test03.c deleted file mode 100644 index 589da7f..0000000 --- a/test/test03.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - -extern char _etext[]; - -void main(void) { - gilbraltar_log(INFO, " _____ _ _ _ _ _ \r\n"); - gilbraltar_log(INFO, "| __|_| | |_ ___ ___| | |_ ___ ___ \r\n"); - gilbraltar_log(INFO, "| | | | | . | _| .'| | _| .'| _|\r\n"); - gilbraltar_log(INFO, "|_____|_|_|___|_| |__,|_|_| |__,|_| \r\n"); - gilbraltar_log(INFO, " BL31 @ 0x%08x - 0x%08x\r\n", 0x0, 0x8000); - gilbraltar_log(INFO, " EL3 stack @ 0x%08x\r\n", 0x6f000); - gilbraltar_log(INFO, " kernel @ 0x%08x - 0x%08lx\r\n", - MEM_KERNEL_START, (uintptr_t) _etext); - gilbraltar_log(INFO, " stack @ 0x%08x - 0x%08x\r\n", - MEM_KERNEL_STACK - KERNEL_STACK_SIZE, MEM_KERNEL_STACK); - gilbraltar_log(INFO, "exception stack @ 0x%08x - 0x%08x\r\n", - MEM_EXCEPTION_STACK - EXCEPTION_STACK_SIZE, - MEM_EXCEPTION_STACK); - gilbraltar_log(INFO, " irq stack @ 0x%08x - 0x%08x\r\n", - MEM_IRQ_STACK - EXCEPTION_STACK_SIZE, MEM_IRQ_STACK); - gilbraltar_log(INFO, " fiq stack @ 0x%08x - 0x%08x\r\n", - MEM_FIQ_STACK - EXCEPTION_STACK_SIZE, MEM_FIQ_STACK); - gilbraltar_log(INFO, " pages table @ 0x%08x - 0x%08x\r\n", MEM_PAGE_TABLE1, - MEM_PAGE_TABLE1_END); - gilbraltar_log(INFO, "coherent region @ 0x%08x - 0x%08x\r\n", - MEM_COHERENT_REGION, MEM_COHERENT_REGION + 4 * MEGABYTE); -} diff --git a/test03.map b/test03.map deleted file mode 100644 index 6ba0504..0000000 --- a/test03.map +++ /dev/null @@ -1,574 +0,0 @@ -Archive member included to satisfy reference by file (symbol) - -./libgilbraltar.a(log.o) test/test03.o (gilbraltar_log) -./libgilbraltar.a(startup.o) (_start) -./libgilbraltar.a(exception_stub.o) - ./libgilbraltar.a(startup.o) (VectorTable) -./libgilbraltar.a(kernel.o) ./libgilbraltar.a(startup.o) (gilbraltar_sysinit) -./libgilbraltar.a(interrupt_handler.o) - ./libgilbraltar.a(exception_stub.o) (gilbraltar_interrupt_handler) -./libgilbraltar.a(exception_handler.o) - ./libgilbraltar.a(exception_stub.o) (gilbraltar_exception_handler) -./libgilbraltar.a(crt.o) ./libgilbraltar.a(log.o) (__stack_chk_guard) -./libgilbraltar.a(serial.o) ./libgilbraltar.a(kernel.o) (gilbraltar_serial_init) -./libgilbraltar.a(power.o) ./libgilbraltar.a(kernel.o) (poweroff) -./libgilbraltar.a(tag.o) ./libgilbraltar.a(kernel.o) (gilbraltar_get_tag) -./libgilbraltar.a(coherent_page.o) - ./libgilbraltar.a(tag.o) (get_coherent_page) -./libgilbraltar.a(dtb.o) ./libgilbraltar.a(kernel.o) (gilbraltar_dtb_init) -./libgilbraltar.a(memory.o) ./libgilbraltar.a(kernel.o) (gilbraltar_memory_init) -./libgilbraltar.a(pager.o) ./libgilbraltar.a(memory.o) (gilbraltar_pager_init) -./libgilbraltar.a(translation_table.o) - ./libgilbraltar.a(memory.o) (gilbraltar_translation_table_base) -./libgilbraltar.a(mbox.o) ./libgilbraltar.a(tag.o) (gilbraltar_mbox_write_read) -./libgilbraltar.a(clock.o) ./libgilbraltar.a(serial.o) (gilbraltar_get_rate_of_clock) -./libgilbraltar.a(spinlock.o) - ./libgilbraltar.a(pager.o) (gilbraltar_spinlock_acquire) -./libgilbraltar.a(synchronize.o) - ./libgilbraltar.a(spinlock.o) (gilbraltar_enter_critical) -nolibc/libnolibc.a(assert.o) ./libgilbraltar.a(serial.o) (_assert_fail) -nolibc/libnolibc.a(memcpy.o) ./libgilbraltar.a(tag.o) (memcpy) -nolibc/libnolibc.a(memset.o) ./libgilbraltar.a(kernel.o) (memset) -nolibc/libnolibc.a(strstr.o) ./libgilbraltar.a(kernel.o) (strstr) -nolibc/libnolibc.a(puts.o) nolibc/libnolibc.a(assert.o) (puts) -nolibc/libnolibc.a(vsnprintf.o) - ./libgilbraltar.a(log.o) (vsnprintf) -nolibc/libnolibc.a(sysdeps.o) - ./libgilbraltar.a(coherent_page.o) (abort) -nolibc/libnolibc.a(memchr.o) nolibc/libnolibc.a(strstr.o) (memchr) -nolibc/libnolibc.a(memcmp.o) nolibc/libnolibc.a(strstr.o) (memcmp) -nolibc/libnolibc.a(strlen.o) nolibc/libnolibc.a(puts.o) (strlen) -nolibc/libnolibc.a(strchr.o) nolibc/libnolibc.a(strstr.o) (strchr) -nolibc/libnolibc.a(strchrnul.o) - nolibc/libnolibc.a(strchr.o) (__strchrnul) -nolibc/libnolibc.a(vfprintf.o) - nolibc/libnolibc.a(vsnprintf.o) (vfprintf) -nolibc/libnolibc.a(ctype.o) nolibc/libnolibc.a(vfprintf.o) (isdigit) -nolibc/libnolibc.a(stubs.o) nolibc/libnolibc.a(vfprintf.o) (strerror) -nolibc/libnolibc.a(printf.o) nolibc/libnolibc.a(stubs.o) (printf) -openlibm/libopenlibm.a(s_frexp.c.o) - nolibc/libnolibc.a(vfprintf.o) (frexp) -openlibm/libopenlibm.a(s_isfinite.c.o) - nolibc/libnolibc.a(vfprintf.o) (__isfinite) -openlibm/libopenlibm.a(s_signbit.c.o) - nolibc/libnolibc.a(vfprintf.o) (__signbit) -/usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - nolibc/libnolibc.a(vfprintf.o) (__extenddftf2) -/usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - nolibc/libnolibc.a(vfprintf.o) (__trunctfdf2) -/usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o) - /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) (__sfp_handle_exceptions) - -There are no discarded input sections - -Memory Configuration - -Name Origin Length Attributes -*default* 0x0000000000000000 0xffffffffffffffff - -Linker script and memory map - -LOAD test/test03.o -Address of section .init set to 0x80000 -START GROUP -LOAD ./libgilbraltar.a -LOAD nolibc/libnolibc.a -LOAD openlibm/libopenlibm.a -LOAD /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a -END GROUP - -.init 0x0000000000080000 0xa8 - *(.init) - .init 0x0000000000080000 0xa8 ./libgilbraltar.a(startup.o) - 0x0000000000080000 _start - -.text 0x0000000000080800 0x7960 - *(.text*) - .text 0x0000000000080800 0x7c test/test03.o - 0x0000000000080800 main - .text 0x000000000008087c 0x1b0 ./libgilbraltar.a(log.o) - 0x000000000008087c gilbraltar_log - 0x0000000000080a08 gilbraltar_log_set - .text 0x0000000000080a2c 0x0 ./libgilbraltar.a(startup.o) - *fill* 0x0000000000080a2c 0x5d4 - .text 0x0000000000081000 0x9d8 ./libgilbraltar.a(exception_stub.o) - 0x0000000000081000 VectorTable - 0x0000000000081784 unexpected_stub - 0x00000000000817bc synchronous_stub - 0x00000000000817f4 system_error_stub - 0x000000000008182c IRQ_stub - 0x00000000000818dc FIQ_stub - 0x0000000000081988 SMC_stub - .text 0x00000000000819d8 0x2dc ./libgilbraltar.a(kernel.o) - 0x0000000000081ac0 gilbraltar_sysinit - .text 0x0000000000081cb4 0x28 ./libgilbraltar.a(interrupt_handler.o) - 0x0000000000081cb4 gilbraltar_interrupt_handler - 0x0000000000081cd4 gilbraltar_secure_monitor_handler - .text 0x0000000000081cdc 0x400 ./libgilbraltar.a(exception_handler.o) - 0x0000000000081cdc gilbraltar_exception_handler - .text 0x00000000000820dc 0x1c ./libgilbraltar.a(crt.o) - 0x00000000000820dc __stack_chk_fail - .text 0x00000000000820f8 0x440 ./libgilbraltar.a(serial.o) - 0x0000000000082224 gilbraltar_serial_init - 0x0000000000082354 gilbraltar_serial_send - 0x000000000008243c gilbraltar_serial_recv - 0x0000000000082484 gilbraltar_serial_puts - 0x00000000000824c8 gilbraltar_serial_putchar - 0x00000000000824ec gilbraltar_serial_write - .text 0x0000000000082538 0x7c ./libgilbraltar.a(power.o) - 0x000000000008255c reboot - 0x000000000008259c poweroff - .text 0x00000000000825b4 0x5ac ./libgilbraltar.a(tag.o) - 0x00000000000825b4 gilbraltar_get_tags - 0x0000000000082810 gilbraltar_get_tag - .text 0x0000000000082b60 0x44 ./libgilbraltar.a(coherent_page.o) - 0x0000000000082b60 get_coherent_page - .text 0x0000000000082ba4 0x20c ./libgilbraltar.a(dtb.o) - 0x0000000000082ba4 gilbraltar_dtb_init - .text 0x0000000000082db0 0x104 ./libgilbraltar.a(memory.o) - 0x0000000000082e50 gilbraltar_memory_init - .text 0x0000000000082eb4 0x268 ./libgilbraltar.a(pager.o) - 0x0000000000082eb4 gilbraltar_pager_init - 0x0000000000082f0c gilbraltar_pager_free_space - 0x0000000000082f2c gilbraltar_palloc - 0x00000000000830a8 gilbraltar_pager_free - .text 0x000000000008311c 0x554 ./libgilbraltar.a(translation_table.o) - 0x00000000000833d8 gilbraltar_translation_table_base - 0x00000000000833e8 gilbraltar_translation_table_init - .text 0x0000000000083670 0x10c ./libgilbraltar.a(mbox.o) - 0x00000000000836ac gilbraltar_mbox_write_read - .text 0x000000000008377c 0x184 ./libgilbraltar.a(clock.o) - 0x000000000008377c gilbraltar_get_rate_of_clock - .text 0x0000000000083900 0x108 ./libgilbraltar.a(spinlock.o) - 0x0000000000083900 gilbraltar_spinlock_init - 0x0000000000083918 gilbraltar_spinlock_acquire - 0x00000000000839b8 gilbraltar_spinlock_release - .text 0x0000000000083a08 0x21c ./libgilbraltar.a(synchronize.o) - 0x0000000000083a08 gilbraltar_enter_critical - 0x0000000000083b44 gilbraltar_leave_critical - *fill* 0x0000000000083c24 0x1c - .text 0x0000000000083c40 0x50 nolibc/libnolibc.a(assert.o) - 0x0000000000083c40 _assert_fail - *fill* 0x0000000000083c90 0x10 - .text 0x0000000000083ca0 0x3e0 nolibc/libnolibc.a(memcpy.o) - 0x0000000000083ca0 memcpy - .text 0x0000000000084080 0xe0 nolibc/libnolibc.a(memset.o) - 0x0000000000084080 memset - .text 0x0000000000084160 0x584 nolibc/libnolibc.a(strstr.o) - 0x0000000000084520 strstr - *fill* 0x00000000000846e4 0x1c - .text 0x0000000000084700 0x64 nolibc/libnolibc.a(puts.o) - 0x0000000000084700 puts - 0x0000000000084740 putchar - *fill* 0x0000000000084764 0x1c - .text 0x0000000000084780 0x14c nolibc/libnolibc.a(vsnprintf.o) - 0x00000000000847d0 vsnprintf - *fill* 0x00000000000848cc 0x14 - .text 0x00000000000848e0 0xbc nolibc/libnolibc.a(sysdeps.o) - 0x000000000008490c write - 0x0000000000084960 exit - 0x0000000000084968 abort - 0x0000000000084988 __getauxval - *fill* 0x000000000008499c 0x4 - .text 0x00000000000849a0 0xbc nolibc/libnolibc.a(memchr.o) - 0x00000000000849a0 memchr - *fill* 0x0000000000084a5c 0x4 - .text 0x0000000000084a60 0x38 nolibc/libnolibc.a(memcmp.o) - 0x0000000000084a60 memcmp - *fill* 0x0000000000084a98 0x8 - .text 0x0000000000084aa0 0x78 nolibc/libnolibc.a(strlen.o) - 0x0000000000084aa0 strlen - *fill* 0x0000000000084b18 0x8 - .text 0x0000000000084b20 0x2c nolibc/libnolibc.a(strchr.o) - 0x0000000000084b20 strchr - *fill* 0x0000000000084b4c 0x14 - .text 0x0000000000084b60 0xd8 nolibc/libnolibc.a(strchrnul.o) - 0x0000000000084b60 __strchrnul - *fill* 0x0000000000084c38 0x8 - .text 0x0000000000084c40 0x1e38 nolibc/libnolibc.a(vfprintf.o) - 0x0000000000084f88 printf_core - 0x00000000000869c8 vfprintf - *fill* 0x0000000000086a78 0x8 - .text 0x0000000000086a80 0x70 nolibc/libnolibc.a(ctype.o) - 0x0000000000086a80 isalpha - 0x0000000000086aa0 isdigit - 0x0000000000086ab0 isprint - 0x0000000000086ac0 isspace - 0x0000000000086ae0 isupper - *fill* 0x0000000000086af0 0x10 - .text 0x0000000000086b00 0xec0 nolibc/libnolibc.a(stubs.o) - 0x0000000000086b00 fflush - 0x0000000000086b6c rename - 0x0000000000086b8c sscanf - 0x0000000000086bac fread - 0x0000000000086c20 getc - 0x0000000000086c90 ungetc - 0x0000000000086d00 fwrite - 0x0000000000086d70 fputc - 0x0000000000086de0 fputs - 0x0000000000086e50 putc - 0x0000000000086ec0 ferror - 0x0000000000086f30 fopen - 0x0000000000086fa0 fclose - 0x0000000000087010 getenv - 0x0000000000087080 secure_getenv - 0x00000000000870f0 system - 0x0000000000087110 chdir - 0x0000000000087180 close - 0x00000000000871a0 getcwd - 0x00000000000871c0 getpid - 0x0000000000087230 getppid - 0x00000000000872a0 isatty - 0x00000000000872c0 lseek - 0x00000000000872e0 read - 0x0000000000087300 readlink - 0x0000000000087320 unlink - 0x0000000000087340 rmdir - 0x0000000000087360 ftruncate - 0x0000000000087380 execv - 0x00000000000873a0 closedir - 0x0000000000087410 opendir - 0x0000000000087480 readdir - 0x00000000000874f0 fcntl - 0x0000000000087510 open - 0x0000000000087580 setjmp - 0x00000000000875a0 signal - 0x00000000000875c0 raise - 0x00000000000875e0 strerror - 0x0000000000087600 stat - 0x0000000000087670 mkdir - 0x0000000000087690 pthread_join - 0x00000000000876a4 pthread_create - 0x00000000000876c0 pthread_attr_init - 0x00000000000876e0 pthread_cleanup_push - 0x0000000000087700 pthread_cleanup_pop - 0x0000000000087720 pthread_mutex_lock - 0x0000000000087740 pthread_mutex_trylock - 0x0000000000087760 pthread_mutex_unlock - 0x0000000000087780 pthread_mutex_destroy - 0x00000000000877a0 pthread_mutex_init - 0x00000000000877c0 pthread_mutexattr_init - 0x00000000000877e0 pthread_mutexattr_destroy - 0x0000000000087800 pthread_mutexattr_settype - 0x0000000000087820 pthread_sigmask - 0x0000000000087840 pthread_equal - 0x0000000000087860 pthread_condattr_init - 0x0000000000087880 pthread_cond_init - 0x00000000000878a0 pthread_cond_destroy - 0x00000000000878c0 pthread_cond_wait - 0x00000000000878e0 pthread_cond_signal - 0x0000000000087900 pthread_cond_broadcast - 0x0000000000087920 pthread_self - 0x0000000000087940 pthread_detach - 0x0000000000087960 sigfillset - 0x0000000000087980 sigwait - 0x00000000000879a0 usleep - .text 0x00000000000879c0 0xbc nolibc/libnolibc.a(printf.o) - 0x00000000000879c0 printf - *fill* 0x0000000000087a7c 0x4 - .text 0x0000000000087a80 0x78 openlibm/libopenlibm.a(s_frexp.c.o) - 0x0000000000087a80 frexp - *fill* 0x0000000000087af8 0x8 - .text 0x0000000000087b00 0x64 openlibm/libopenlibm.a(s_isfinite.c.o) - 0x0000000000087b00 __isfinite - 0x0000000000087b20 __isfinitef - 0x0000000000087b40 __isfinitel - *fill* 0x0000000000087b64 0x1c - .text 0x0000000000087b80 0x38 openlibm/libopenlibm.a(s_signbit.c.o) - 0x0000000000087b80 __signbit - 0x0000000000087b8c __signbitf - 0x0000000000087ba0 __signbitl - .text 0x0000000000087bb8 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - *fill* 0x0000000000087bb8 0x8 - .text.__extenddftf2 - 0x0000000000087bc0 0x158 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - 0x0000000000087bc0 __extenddftf2 - .text 0x0000000000087d18 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - *fill* 0x0000000000087d18 0x8 - .text.__trunctfdf2 - 0x0000000000087d20 0x3c4 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - 0x0000000000087d20 __trunctfdf2 - .text 0x00000000000880e4 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o) - *fill* 0x00000000000880e4 0xc - .text.__sfp_handle_exceptions - 0x00000000000880f0 0x70 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o) - 0x00000000000880f0 __sfp_handle_exceptions - 0x0000000000088160 _etext = . - -.iplt 0x0000000000088160 0x0 - .iplt 0x0000000000088160 0x0 test/test03.o - -.rodata 0x0000000000088160 0xa40 - *(.rodata*) - .rodata 0x0000000000088160 0x22 test/test03.o - *fill* 0x0000000000088182 0x6 - .rodata 0x0000000000088188 0x6d ./libgilbraltar.a(kernel.o) - *fill* 0x00000000000881f5 0x3 - .rodata 0x00000000000881f8 0x10 ./libgilbraltar.a(interrupt_handler.o) - .rodata 0x0000000000088208 0x97 ./libgilbraltar.a(exception_handler.o) - *fill* 0x000000000008829f 0x1 - .rodata 0x00000000000882a0 0x23 ./libgilbraltar.a(crt.o) - *fill* 0x00000000000882c3 0x5 - .rodata 0x00000000000882c8 0x21 ./libgilbraltar.a(serial.o) - *fill* 0x00000000000882e9 0x7 - .rodata 0x00000000000882f0 0x8b ./libgilbraltar.a(tag.o) - *fill* 0x000000000008837b 0x5 - .rodata 0x0000000000088380 0x4b ./libgilbraltar.a(dtb.o) - *fill* 0x00000000000883cb 0x5 - .rodata 0x00000000000883d0 0x26 ./libgilbraltar.a(memory.o) - *fill* 0x00000000000883f6 0x2 - .rodata 0x00000000000883f8 0x9c ./libgilbraltar.a(pager.o) - *fill* 0x0000000000088494 0x4 - .rodata 0x0000000000088498 0x28 ./libgilbraltar.a(translation_table.o) - .rodata 0x00000000000884c0 0x1f ./libgilbraltar.a(mbox.o) - *fill* 0x00000000000884df 0x1 - .rodata 0x00000000000884e0 0x9b ./libgilbraltar.a(clock.o) - *fill* 0x000000000008857b 0x5 - .rodata 0x0000000000088580 0x2a ./libgilbraltar.a(spinlock.o) - *fill* 0x00000000000885aa 0x6 - .rodata 0x00000000000885b0 0xf2 ./libgilbraltar.a(synchronize.o) - *fill* 0x00000000000886a2 0x6 - .rodata.str1.8 - 0x00000000000886a8 0x297 nolibc/libnolibc.a(assert.o) - 0x23 (size before relaxing) - .rodata.str1.8 - 0x000000000008893f 0xa nolibc/libnolibc.a(sysdeps.o) - *fill* 0x000000000008893f 0x1 - .rodata 0x0000000000088940 0x260 nolibc/libnolibc.a(vfprintf.o) - .rodata.str1.8 - 0x0000000000088ba0 0x52 nolibc/libnolibc.a(vfprintf.o) - .rodata.str1.8 - 0x0000000000088ba0 0x207 nolibc/libnolibc.a(stubs.o) - -.rela.dyn 0x0000000000088ba0 0x0 - .rela.iplt 0x0000000000088ba0 0x0 test/test03.o - .rela.text 0x0000000000088ba0 0x0 test/test03.o - -.ARM.exidx 0x0000000000088ba0 0x0 - 0x0000000000088ba0 __exidx_start = . - *(.ARM.exidx*) - 0x0000000000088ba0 __exidx_end = . - -.eh_frame - *(.eh_frame*) - -.data 0x0000000000088ba0 0xc4 - *(.data*) - .data 0x0000000000088ba0 0x0 test/test03.o - .data 0x0000000000088ba0 0x4 ./libgilbraltar.a(log.o) - .data 0x0000000000088ba4 0x0 ./libgilbraltar.a(startup.o) - *fill* 0x0000000000088ba4 0x4 - .data 0x0000000000088ba8 0x20 ./libgilbraltar.a(exception_stub.o) - 0x0000000000088ba8 FIQ_data - 0x0000000000088bc0 IRQ_return_address - .data 0x0000000000088bc8 0x0 ./libgilbraltar.a(kernel.o) - .data 0x0000000000088bc8 0x0 ./libgilbraltar.a(interrupt_handler.o) - .data 0x0000000000088bc8 0x18 ./libgilbraltar.a(exception_handler.o) - .data 0x0000000000088be0 0x8 ./libgilbraltar.a(crt.o) - 0x0000000000088be0 __stack_chk_guard - .data 0x0000000000088be8 0x0 ./libgilbraltar.a(serial.o) - .data 0x0000000000088be8 0x0 ./libgilbraltar.a(power.o) - .data 0x0000000000088be8 0x0 ./libgilbraltar.a(tag.o) - .data 0x0000000000088be8 0x0 ./libgilbraltar.a(coherent_page.o) - .data 0x0000000000088be8 0x0 ./libgilbraltar.a(dtb.o) - .data 0x0000000000088be8 0x0 ./libgilbraltar.a(memory.o) - .data 0x0000000000088be8 0x0 ./libgilbraltar.a(pager.o) - .data 0x0000000000088be8 0x0 ./libgilbraltar.a(translation_table.o) - .data 0x0000000000088be8 0x0 ./libgilbraltar.a(mbox.o) - .data 0x0000000000088be8 0x0 ./libgilbraltar.a(clock.o) - .data 0x0000000000088be8 0x0 ./libgilbraltar.a(spinlock.o) - .data 0x0000000000088be8 0x0 ./libgilbraltar.a(synchronize.o) - .data 0x0000000000088be8 0x0 nolibc/libnolibc.a(assert.o) - .data 0x0000000000088be8 0x0 nolibc/libnolibc.a(memcpy.o) - .data 0x0000000000088be8 0x0 nolibc/libnolibc.a(memset.o) - .data 0x0000000000088be8 0x0 nolibc/libnolibc.a(strstr.o) - .data 0x0000000000088be8 0x0 nolibc/libnolibc.a(puts.o) - .data 0x0000000000088be8 0x0 nolibc/libnolibc.a(vsnprintf.o) - .data 0x0000000000088be8 0x28 nolibc/libnolibc.a(sysdeps.o) - 0x0000000000088be8 stdout - 0x0000000000088bf0 stderr - .data 0x0000000000088c10 0x0 nolibc/libnolibc.a(memchr.o) - .data 0x0000000000088c10 0x0 nolibc/libnolibc.a(memcmp.o) - .data 0x0000000000088c10 0x0 nolibc/libnolibc.a(strlen.o) - .data 0x0000000000088c10 0x0 nolibc/libnolibc.a(strchr.o) - .data 0x0000000000088c10 0x0 nolibc/libnolibc.a(strchrnul.o) - .data 0x0000000000088c10 0x0 nolibc/libnolibc.a(vfprintf.o) - .data 0x0000000000088c10 0x0 nolibc/libnolibc.a(ctype.o) - .data 0x0000000000088c10 0x54 nolibc/libnolibc.a(stubs.o) - .data 0x0000000000088c64 0x0 nolibc/libnolibc.a(printf.o) - .data 0x0000000000088c64 0x0 openlibm/libopenlibm.a(s_frexp.c.o) - .data 0x0000000000088c64 0x0 openlibm/libopenlibm.a(s_isfinite.c.o) - .data 0x0000000000088c64 0x0 openlibm/libopenlibm.a(s_signbit.c.o) - .data 0x0000000000088c64 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - .data 0x0000000000088c64 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - .data 0x0000000000088c64 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o) - -.igot.plt 0x0000000000088c68 0x0 - .igot.plt 0x0000000000088c68 0x0 test/test03.o - -.tdata 0x0000000000088c64 0x0 - 0x0000000000088c64 _stdata = . - *(.tdata) - 0x0000000000088c64 _edata = . - -.tbss - *(.tbss) - -.bss 0x0000000000088c70 0x1364 - 0x0000000000088c70 __bss_start = . - *(.bss*) - .bss 0x0000000000088c70 0x0 test/test03.o - .bss 0x0000000000088c70 0x0 ./libgilbraltar.a(log.o) - .bss 0x0000000000088c70 0x0 ./libgilbraltar.a(startup.o) - .bss 0x0000000000088c70 0x80 ./libgilbraltar.a(exception_stub.o) - .bss 0x0000000000088cf0 0x0 ./libgilbraltar.a(kernel.o) - .bss 0x0000000000088cf0 0x0 ./libgilbraltar.a(interrupt_handler.o) - .bss 0x0000000000088cf0 0x0 ./libgilbraltar.a(exception_handler.o) - .bss 0x0000000000088cf0 0x0 ./libgilbraltar.a(crt.o) - .bss 0x0000000000088cf0 0x100a ./libgilbraltar.a(serial.o) - .bss 0x0000000000089cfa 0x0 ./libgilbraltar.a(power.o) - .bss 0x0000000000089cfa 0x0 ./libgilbraltar.a(tag.o) - .bss 0x0000000000089cfa 0x0 ./libgilbraltar.a(coherent_page.o) - *fill* 0x0000000000089cfa 0x6 - .bss 0x0000000000089d00 0x8 ./libgilbraltar.a(dtb.o) - .bss 0x0000000000089d08 0x0 ./libgilbraltar.a(memory.o) - .bss 0x0000000000089d08 0x1c ./libgilbraltar.a(pager.o) - *fill* 0x0000000000089d24 0x4 - .bss 0x0000000000089d28 0x10 ./libgilbraltar.a(translation_table.o) - .bss 0x0000000000089d38 0x0 ./libgilbraltar.a(mbox.o) - .bss 0x0000000000089d38 0x0 ./libgilbraltar.a(clock.o) - .bss 0x0000000000089d38 0x1 ./libgilbraltar.a(spinlock.o) - *fill* 0x0000000000089d39 0x7 - .bss 0x0000000000089d40 0x290 ./libgilbraltar.a(synchronize.o) - .bss 0x0000000000089fd0 0x0 nolibc/libnolibc.a(assert.o) - .bss 0x0000000000089fd0 0x0 nolibc/libnolibc.a(memcpy.o) - .bss 0x0000000000089fd0 0x0 nolibc/libnolibc.a(memset.o) - .bss 0x0000000000089fd0 0x0 nolibc/libnolibc.a(strstr.o) - .bss 0x0000000000089fd0 0x0 nolibc/libnolibc.a(puts.o) - .bss 0x0000000000089fd0 0x0 nolibc/libnolibc.a(vsnprintf.o) - .bss 0x0000000000089fd0 0x4 nolibc/libnolibc.a(sysdeps.o) - 0x0000000000089fd0 errno - .bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(memchr.o) - .bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(memcmp.o) - .bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(strlen.o) - .bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(strchr.o) - .bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(strchrnul.o) - .bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(vfprintf.o) - .bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(ctype.o) - .bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(stubs.o) - .bss 0x0000000000089fd4 0x0 nolibc/libnolibc.a(printf.o) - .bss 0x0000000000089fd4 0x0 openlibm/libopenlibm.a(s_frexp.c.o) - .bss 0x0000000000089fd4 0x0 openlibm/libopenlibm.a(s_isfinite.c.o) - .bss 0x0000000000089fd4 0x0 openlibm/libopenlibm.a(s_signbit.c.o) - .bss 0x0000000000089fd4 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - .bss 0x0000000000089fd4 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - .bss 0x0000000000089fd4 0x0 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o) - *(COMMON) - 0x0000000000089fd4 _end = . -OUTPUT(test03.elf elf64-littleaarch64) -LOAD linker stubs - -.comment 0x0000000000000000 0x45 - .comment 0x0000000000000000 0x45 test/test03.o - 0x46 (size before relaxing) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(log.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(kernel.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(interrupt_handler.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(exception_handler.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(crt.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(serial.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(power.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(tag.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(coherent_page.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(dtb.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(memory.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(pager.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(translation_table.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(mbox.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(clock.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(spinlock.o) - .comment 0x0000000000000045 0x46 ./libgilbraltar.a(synchronize.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(assert.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(memcpy.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(memset.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(strstr.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(puts.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(vsnprintf.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(sysdeps.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(memchr.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(memcmp.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(strlen.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(strchr.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(strchrnul.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(vfprintf.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(ctype.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(stubs.o) - .comment 0x0000000000000045 0x46 nolibc/libnolibc.a(printf.o) - .comment 0x0000000000000045 0x46 openlibm/libopenlibm.a(s_frexp.c.o) - .comment 0x0000000000000045 0x46 openlibm/libopenlibm.a(s_isfinite.c.o) - .comment 0x0000000000000045 0x46 openlibm/libopenlibm.a(s_signbit.c.o) - .comment 0x0000000000000045 0x46 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - .comment 0x0000000000000045 0x46 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - .comment 0x0000000000000045 0x46 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o) - -.debug_info 0x0000000000000000 0x76a - .debug_info 0x0000000000000000 0x2ef /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - .debug_info 0x00000000000002ef 0x39e /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - .debug_info 0x000000000000068d 0xdd /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o) - -.debug_abbrev 0x0000000000000000 0x35e - .debug_abbrev 0x0000000000000000 0x159 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - .debug_abbrev 0x0000000000000159 0x183 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - .debug_abbrev 0x00000000000002dc 0x82 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o) - -.debug_loclists - 0x0000000000000000 0xacb - .debug_loclists - 0x0000000000000000 0x451 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - .debug_loclists - 0x0000000000000451 0x653 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - .debug_loclists - 0x0000000000000aa4 0x27 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o) - -.debug_aranges 0x0000000000000000 0x90 - .debug_aranges - 0x0000000000000000 0x30 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - .debug_aranges - 0x0000000000000030 0x30 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - .debug_aranges - 0x0000000000000060 0x30 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o) - -.debug_rnglists - 0x0000000000000000 0x1d6 - .debug_rnglists - 0x0000000000000000 0x84 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - .debug_rnglists - 0x0000000000000084 0x13b /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - .debug_rnglists - 0x00000000000001bf 0x17 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o) - -.debug_line 0x0000000000000000 0xb07 - .debug_line 0x0000000000000000 0x276 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - .debug_line 0x0000000000000276 0x7f9 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - .debug_line 0x0000000000000a6f 0x98 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o) - -.debug_str 0x0000000000000000 0x294 - .debug_str 0x0000000000000000 0x294 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - 0x1f3 (size before relaxing) - .debug_str 0x0000000000000294 0x252 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - .debug_str 0x0000000000000294 0x11c /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o) - -.debug_line_str - 0x0000000000000000 0x213 - .debug_line_str - 0x0000000000000000 0x213 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - 0x19c (size before relaxing) - .debug_line_str - 0x0000000000000213 0x199 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - .debug_line_str - 0x0000000000000213 0x193 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o) - -.debug_frame 0x0000000000000000 0xb0 - .debug_frame 0x0000000000000000 0x38 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(extenddftf2.o) - .debug_frame 0x0000000000000038 0x50 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(trunctfdf2.o) - .debug_frame 0x0000000000000088 0x28 /usr/bin/../lib/gcc/aarch64-none-elf/13.3.1/libgcc.a(sfp-exceptions.o)