diff --git a/booter/Makefile b/booter/Makefile index 28f31d46c..af992142d 100644 --- a/booter/Makefile +++ b/booter/Makefile @@ -17,8 +17,18 @@ BOOTVM_IMAGE_HEAP_SIZE := 0x1000000 all: hello should_crash should_pagefault bigio $(BOOTVM_PROG) -CFLAGS = $(OPTIMIZE) -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Wall -Werror -Wno-builtin-requires-header -g -I. -I$(INSTALLPATH)/include -I$(KERNELPATH)/include -LDFLAGS = -L$(INSTALLPATH)/lib -moslib=h2 -Qunused-arguments +ifeq ($(PICOLIBC),1) +OSLIB_FLAG = --target=hexagon-h2-picolibc +# Derive template path from the resolved compiler location: bin/../templates/staticExecutable/ +PICOLIBC_LCS := $(abspath $(dir $(shell which $(CC)))/../templates/staticExecutable/static-executable-h2-picolibc.lcs.template) +GUEST_LDSCRIPT = -Wl,--script=$(PICOLIBC_LCS) +else +OSLIB_FLAG = -moslib=h2 +GUEST_LDSCRIPT = +endif + +CFLAGS = $(OSLIB_FLAG) $(OPTIMIZE) -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Wall -Werror -Wno-builtin-requires-header -g -I. -I$(INSTALLPATH)/include -I$(KERNELPATH)/include +LDFLAGS = -L$(INSTALLPATH)/lib $(OSLIB_FLAG) -Qunused-arguments include $(H2DIR)/scripts/Makefile.inc.config include $(H2DIR)/scripts/Makefile.inc.opensource @@ -26,18 +36,18 @@ include $(H2DIR)/scripts/Makefile.inc.bootvm hello: hello.o - ${CC} $(LDFLAGS) $(CFLAGS) -Wl,--section-start=.start=$(H2K_GUEST_START) -o hello hello.o + ${CC} $(LDFLAGS) $(CFLAGS) $(GUEST_LDSCRIPT) -Wl,--section-start=.start=$(H2K_GUEST_START) -o hello hello.o should_pagefault: OPTIMIZE = -O0 should_pagefault: should_pagefault.o - ${CC} $(LDFLAGS) $(CFLAGS) -O0 -Wl,--section-start=.start=$(H2K_GUEST_START) -o should_pagefault should_pagefault.o + ${CC} $(LDFLAGS) $(CFLAGS) $(GUEST_LDSCRIPT) -O0 -Wl,--section-start=.start=$(H2K_GUEST_START) -o should_pagefault should_pagefault.o should_crash: OPTIMIZE = -O0 should_crash: should_crash.o - ${CC} $(LDFLAGS) $(CFLAGS) -O0 -Wl,--section-start=.start=$(H2K_GUEST_START) -o should_crash should_crash.o + ${CC} $(LDFLAGS) $(CFLAGS) $(GUEST_LDSCRIPT) -O0 -Wl,--section-start=.start=$(H2K_GUEST_START) -o should_crash should_crash.o bigio: bigio.o - ${CC} $(LDFLAGS) $(CFLAGS) -O0 -Wl,--section-start=.start=$(H2K_GUEST_START) -o bigio bigio.o + ${CC} $(LDFLAGS) $(CFLAGS) $(GUEST_LDSCRIPT) -O0 -Wl,--section-start=.start=$(H2K_GUEST_START) -o bigio bigio.o # %.o: %.c # ${CC} ${CFLAGS} -c -o $@ $< diff --git a/booter/booter.c b/booter/booter.c index e5afe65c4..447b4a8bd 100644 --- a/booter/booter.c +++ b/booter/booter.c @@ -671,7 +671,7 @@ void add_linear_trans(unsigned int idx, unsigned long va, unsigned long long pa, vm_params[idx].pmap_added = 1; } - if (NULL == (pmap->base.raw = (h2_u32_t)realloc((void *)(pmap->base.raw), sizeof(H2K_linear_fmt_t) * (end + npages + 1)))) { + if (0 == (pmap->base.raw = (h2_u32_t)realloc((void *)(pmap->base.raw), sizeof(H2K_linear_fmt_t) * (end + npages + 1)))) { error("realloc pmap->base", NULL); } base = (H2K_linear_fmt_t *)(pmap->base.raw); @@ -764,7 +764,7 @@ void clade_setup(unsigned int idx, long offset) { /* Copy high-prio exception data to TCM */ ex_hi_size = ex_hi_end - ex_hi_start; if (ex_hi_size && tcm_size) { - if (NULL == (vm_params[idx].clade_ex_hi = (unsigned int)h2_galloc(&tcm_alloc, ex_hi_size, 4096, 0))) { + if (0 == (vm_params[idx].clade_ex_hi = (unsigned int)h2_galloc(&tcm_alloc, ex_hi_size, 4096, 0))) { FAIL("\tgalloc ex_hi", ""); } // BOOTER_PRINTF("memcpy(0x%08x, 0x%08lx, 0x%08lx\n", vm_params[idx].clade_ex_hi, ex_hi_start + offset, ex_hi_size); @@ -2310,6 +2310,7 @@ unsigned int process_line(int argc, char **argv, unsigned int idx) { return idx; } +#ifndef __PICOLIBC__ size_t getline(char **lineptr, size_t *n, FILE *stream) { char *buf = NULL; @@ -2362,6 +2363,7 @@ size_t getline(char **lineptr, size_t *n, FILE *stream) { return p - buf - 1; } +#endif /* !__PICOLIBC__ */ int main(int argc, char **argv) { diff --git a/kernel/Makefile b/kernel/Makefile index 360b65435..40f07a628 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -5,6 +5,11 @@ H2DIR ?= .. include ../scripts/Makefile.inc.tools +# Ensure toolchain path override is honored even when kernel is built directly. +ifneq ($(TOOLCHAIN_BIN),) +export PATH := $(TOOLCHAIN_BIN):$(PATH) +endif + ifeq ($(USE_PKW),1) export PKW_VERSIONS := hexagon-tools=$(TOOLS_FLAVOR_KERNEL) arch=$(ARCH_FLAVOR) endif @@ -223,4 +228,3 @@ opt_install: info opt cp include/asm_offsets.h $(INSTALLPATH)/include # for state trap check: build/ref/libh2check.a - diff --git a/kernel/build/offsets/make.inc b/kernel/build/offsets/make.inc index 3ee9d2149..fa8fad0b2 100644 --- a/kernel/build/offsets/make.inc +++ b/kernel/build/offsets/make.inc @@ -1,5 +1,26 @@ # Yo. -*- Makefile -*- +# offsets is a target-side generator program (run under simulator) and uses +# libc headers like . When building with PICOLIBC, select the picolibc +# sysroot via the target triple. +ifeq ($(PICOLIBC),1) +OFFSETS_TARGET_FLAG := --target=hexagon-none-picolibc +else +OFFSETS_TARGET_FLAG := +endif + +ifeq ($(PICOLIBC),1) +# Provide heap symbols and default memory layout expected by picolibc's libc. +# Use the linker script from the selected toolchain sysroot. +ifneq ($(TOOLCHAIN_BIN),) +OFFSETS_LDSCRIPT := -Wl,-T,$(abspath $(TOOLCHAIN_BIN)/../target/hexagon-unknown-none-picolibc/lib/v$(ARCHV)/G0/picolibc.ld) +else +OFFSETS_LDSCRIPT := -Wl,-T,$(shell $(CC) $(OFFSETS_TARGET_FLAG) -print-file-name=picolibc.ld) +endif +else +OFFSETS_LDSCRIPT := +endif + include/asm_offsets.h: $(BUILD_DIR)/offsets ifeq ($(RUN), $(RUN_TOOLSIM)) $(RUN) $< -- $@ @@ -8,9 +29,8 @@ else endif $(BUILD_DIR)/offsets: $(DIR)offsets.ref.c includes - $(CC) $(CFLAGS) -o $@ $< + $(CC) $(OFFSETS_TARGET_FLAG) $(OFFSETS_LDSCRIPT) $(CFLAGS) -o $@ $< DEST_HFILES += include/asm_offsets.h CLEAN_EXTRAS += $(BUILD_DIR)/offsets - diff --git a/kernel/build/offsets/offsets.ref.c b/kernel/build/offsets/offsets.ref.c index 4c4864c6a..b44abe384 100644 --- a/kernel/build/offsets/offsets.ref.c +++ b/kernel/build/offsets/offsets.ref.c @@ -191,6 +191,7 @@ int main(int argc, char **argv) fprintf(outfile, "#define STATUS_INTBLOCKED %d\n",H2K_STATUS_INTBLOCKED); fprintf(outfile, "#define STATUS_VMWAIT %d\n",H2K_STATUS_VMWAIT); + fclose(outfile); return 0; } diff --git a/libs/blast/Makefile b/libs/blast/Makefile index a1d0646d7..279ac92e5 100644 --- a/libs/blast/Makefile +++ b/libs/blast/Makefile @@ -1,9 +1,18 @@ + + +# Picolibc support: if PICOLIBC=1, use --target=hexagon-h2-picolibc +ifeq ($(PICOLIBC),1) +TARGET_FLAG = --target=hexagon-h2-picolibc +else +TARGET_FLAG = +endif + CC = hexagon-clang AR = hexagon-ar -CFLAGS = -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Iinclude -Wall -I../h2/include -I../../kernel/include -g $(OPTIMIZE) $(OPT_ADD) -G0 -ASFLAGS = -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Iinclude -Wall -I../h2/include -I../../kernel/include +CFLAGS = $(TARGET_FLAG) -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Iinclude -Wall -I../h2/include -I../../kernel/include -g $(OPTIMIZE) $(OPT_ADD) -G0 +ASFLAGS = $(TARGET_FLAG) -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Iinclude -Wall -I../h2/include -I../../kernel/include OPTIMIZE := -O2 export BLAST_LIB_INCLUDE=$(shell pwd)/include diff --git a/libs/h2/Makefile b/libs/h2/Makefile index 2fe094bdf..2a9aab73c 100644 --- a/libs/h2/Makefile +++ b/libs/h2/Makefile @@ -1,9 +1,16 @@ ALL: dummy +# Picolibc support: if PICOLIBC=1, use --target=hexagon-h2-picolibc +ifeq ($(PICOLIBC),1) +TARGET_FLAG = --target=hexagon-h2-picolibc +else +TARGET_FLAG = +endif + OPTIMIZE := -Os -CFLAGS := -Iinclude -G0 $(OPTIMIZE) $(OPT_ADD) -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Wall -Wno-builtin-requires-header -Werror -g +CFLAGS := $(TARGET_FLAG) -Iinclude -G0 $(OPTIMIZE) $(OPT_ADD) -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Wall -Wno-builtin-requires-header -Werror -g ifdef DEBUG CFLAGS += -DDEBUG diff --git a/libs/h2_compat/Makefile b/libs/h2_compat/Makefile index 4a463a102..b289466af 100644 --- a/libs/h2_compat/Makefile +++ b/libs/h2_compat/Makefile @@ -3,7 +3,14 @@ ALL: dummy OPTIMIZE := -Os -CFLAGS := -Iinclude -I$(INSTALLPATH)/include -I../h2/include -I../posix/include -I../../libs/syscall/angel/include -G0 $(OPTIMIZE) $(OPT_ADD) -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Wall -Wno-builtin-requires-header -Werror -g +# Picolibc support: if PICOLIBC=1, use --target=hexagon-h2-picolibc +ifeq ($(PICOLIBC),1) +TARGET_FLAG = --target=hexagon-h2-picolibc +else +TARGET_FLAG = +endif + +CFLAGS := $(TARGET_FLAG) -Iinclude -I$(INSTALLPATH)/include -I../h2/include -I../posix/include -I../../libs/syscall/angel/include -G0 $(OPTIMIZE) $(OPT_ADD) -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Wall -Wno-builtin-requires-header -Werror -g ifdef DEBUG CFLAGS += -DDEBUG diff --git a/libs/h2_compat/alloc/h2_alloc.ref.c b/libs/h2_compat/alloc/h2_alloc.ref.c index 66ce0b7d6..3f518cfb1 100644 --- a/libs/h2_compat/alloc/h2_alloc.ref.c +++ b/libs/h2_compat/alloc/h2_alloc.ref.c @@ -6,6 +6,7 @@ #include #include #include +#include /* * h2_alloc.c diff --git a/libs/h2_compat/coproc/h2_coproc.ref.c b/libs/h2_compat/coproc/h2_coproc.ref.c index d37b08447..01e8a579e 100644 --- a/libs/h2_compat/coproc/h2_coproc.ref.c +++ b/libs/h2_compat/coproc/h2_coproc.ref.c @@ -6,9 +6,9 @@ #include #include -static unsigned int *configs[CFG_TYPE_MAX][CFG_SUBTYPE_MAX] = {NULL}; -static unsigned int nunits[CFG_TYPE_MAX][CFG_SUBTYPE_MAX] = {0}; -static unsigned int *counts[CFG_TYPE_MAX][CFG_SUBTYPE_MAX][CFG_MAX] = {NULL}; +static unsigned int *configs[CFG_TYPE_MAX][CFG_SUBTYPE_MAX] = {{NULL}}; +static unsigned int nunits[CFG_TYPE_MAX][CFG_SUBTYPE_MAX] = {{0}}; +static unsigned int *counts[CFG_TYPE_MAX][CFG_SUBTYPE_MAX][CFG_MAX] = {{{NULL}}}; static unsigned int oldstyle = 0; static unsigned int init_done = 0; diff --git a/libs/h2_compat/prof/h2_prof.ref.c b/libs/h2_compat/prof/h2_prof.ref.c index 8acf8ab0b..6dc822029 100644 --- a/libs/h2_compat/prof/h2_prof.ref.c +++ b/libs/h2_compat/prof/h2_prof.ref.c @@ -12,7 +12,7 @@ unsigned int h2_prof_sample(unsigned long long int **res) { unsigned int hthreads_mask; if (NULL == (*res = (unsigned long long int *)h2_malloc(sizeof(unsigned long long int) * 6))) { - return NULL; + return 0; } asm volatile diff --git a/libs/posix/Makefile b/libs/posix/Makefile index f89742749..3a284cc38 100644 --- a/libs/posix/Makefile +++ b/libs/posix/Makefile @@ -1,9 +1,16 @@ ALL: dummy +# Picolibc support: if PICOLIBC=1, use --target=hexagon-h2-picolibc +ifeq ($(PICOLIBC),1) +TARGET_FLAG = --target=hexagon-h2-picolibc +else +TARGET_FLAG = +endif + OPTIMIZE := -Os -CFLAGS := -Iinclude -I../h2/include -G0 $(OPTIMIZE) $(OPT_ADD) -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Wall -Wno-builtin-requires-header -Werror -g +CFLAGS := $(TARGET_FLAG) -Iinclude -I../h2/include -G0 $(OPTIMIZE) $(OPT_ADD) -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Wall -Wno-builtin-requires-header -Werror -g ifdef DEBUG CFLAGS += -DDEBUG diff --git a/libs/posix/pthread/misc/posix_time.h b/libs/posix/pthread/misc/posix_time.h index 9c3f7f1d3..878c86e15 100644 --- a/libs/posix/pthread/misc/posix_time.h +++ b/libs/posix/pthread/misc/posix_time.h @@ -7,6 +7,18 @@ #define H2_POSIX_TIME_H 1 #define _PROVIDE_POSIX_TIME_DECLS 1 +#ifdef __PICOLIBC__ +/* Enable POSIX clock IDs in Picolibc's time.h */ +#ifndef _POSIX_MONOTONIC_CLOCK +#define _POSIX_MONOTONIC_CLOCK 1 +#endif +#ifndef _POSIX_CPUTIME +#define _POSIX_CPUTIME 1 +#endif +#ifndef _POSIX_THREAD_CPUTIME +#define _POSIX_THREAD_CPUTIME 1 +#endif +#endif #include // dinkumware time.h, if we change c libraries we probably need to nuke this /* In case time.h was included early without defining diff --git a/libs/qurt/Makefile b/libs/qurt/Makefile index e27120b94..297d7b292 100644 --- a/libs/qurt/Makefile +++ b/libs/qurt/Makefile @@ -1,8 +1,14 @@ -CC = hexagon-clang -mv$(TOOLARCH) -Iinclude -Wall -Wno-builtin-requires-header -I../h2/include -I../posix/include -I../h2_compat/include +# Picolibc support: if PICOLIBC=1, use --target=hexagon-h2-picolibc +ifeq ($(PICOLIBC),1) +TARGET_FLAG = --target=hexagon-h2-picolibc +else +TARGET_FLAG = +endif + +CC = hexagon-clang $(TARGET_FLAG) -mv$(TOOLARCH) -Iinclude -Wall -Wno-builtin-requires-header -I../h2/include -I../posix/include -I../h2_compat/include AR = hexagon-ar - OPTIMIZE := -O2 CFLAGS = -g $(OPTIMIZE) $(OPT_ADD) -G0 diff --git a/libs/qurt/src/qurt_fd.c b/libs/qurt/src/qurt_fd.c index ccd685a6c..880a49388 100644 --- a/libs/qurt/src/qurt_fd.c +++ b/libs/qurt/src/qurt_fd.c @@ -5,6 +5,7 @@ #include #include +#include /* EJP: the best thing about this file is that most of the things are commented out. */ diff --git a/libs/syscall/angel/Makefile b/libs/syscall/angel/Makefile index 27ce53f5f..d6a5f3a2a 100644 --- a/libs/syscall/angel/Makefile +++ b/libs/syscall/angel/Makefile @@ -1,6 +1,15 @@ -CFLAGS = -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Iinclude -Wall -Wno-builtin-requires-header -Werror -I../../h2/include -I../../h2_compat/include -I../../posix/include -g $(OPTIMIZE) $(OPT_ADD) -G0 -ASFLAGS = -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Iinclude -Wall -I../../h2/include -I../../posix/include +# Picolibc support: if PICOLIBC=1, use --target=hexagon-h2-picolibc +ifeq ($(PICOLIBC),1) +TARGET_FLAG = --target=hexagon-h2-picolibc +# _STD_END/_STD_BEGIN are Dinkumware-specific macros; define them as no-ops +TARGET_FLAG += -D_STD_END= -D_STD_BEGIN= +else +TARGET_FLAG = +endif + +CFLAGS = $(TARGET_FLAG) -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Iinclude -Wall -Wno-builtin-requires-header -Werror -I../../h2/include -I../../h2_compat/include -I../../posix/include -g $(OPTIMIZE) $(OPT_ADD) -G0 +ASFLAGS = $(TARGET_FLAG) -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Iinclude -Wall -I../../h2/include -I../../posix/include CFLAGS += $(LIB_CFLAGS) $(H2_EXTRA_CFLAGS) diff --git a/libs/syscall/angel/include/angel.h b/libs/syscall/angel/include/angel.h index ab665618a..d889a0863 100644 --- a/libs/syscall/angel/include/angel.h +++ b/libs/syscall/angel/include/angel.h @@ -97,7 +97,6 @@ struct heap_info { /* heap information */ int stack_base; int stack_limit; }; - struct __sys_stat { unsigned long long int dev; @@ -113,6 +112,7 @@ struct __sys_stat unsigned long __pad2; }__attribute__ ((aligned (8))); + /* SYSTEM CALL FUNCTIONS */ errno_t sys_clock(void); errno_t sys_close(fd_t); diff --git a/libs/syscall/angel/src/sys_fstat.c b/libs/syscall/angel/src/sys_fstat.c index 3e2f19d1a..bf8f33326 100644 --- a/libs/syscall/angel/src/sys_fstat.c +++ b/libs/syscall/angel/src/sys_fstat.c @@ -5,7 +5,7 @@ #include "allsyscalls.h" -errno_t sys_fstat(fd_t fd, void *buffer) +sys_call_ret_t sys_fstat_internal(fd_t fd, void *buffer) { struct { fd_t fd; @@ -15,6 +15,9 @@ errno_t sys_fstat(fd_t fd, void *buffer) x.buf = ANGEL_OFFSET_PTR(buffer); clean(buffer, sizeof(struct __sys_stat) / 4); clean(&x, 2); - return ANGEL(SYS_FSTAT,&x,0); + return angel_with_err(SYS_FSTAT, &x, 0); } +errno_t sys_fstat(fd_t fd, void *buffer) { + return sys_fstat_internal(fd, buffer).ret_value; +} diff --git a/libs/syscall/wrapper/src/syscall_wrapper.c b/libs/syscall/wrapper/src/syscall_wrapper.c index f5133845d..d47dc75c6 100644 --- a/libs/syscall/wrapper/src/syscall_wrapper.c +++ b/libs/syscall/wrapper/src/syscall_wrapper.c @@ -100,8 +100,28 @@ __attribute__((weak)) off_t lseek(int fd, off_t offset, int whence) { return sys_ftell(fd); } -__attribute__((weak)) int fstat(int fd, struct stat *statbuf) { - return sys_fstat(fd, statbuf); +sys_call_ret_t sys_fstat_internal(int fd, void *buffer); + +__attribute__((weak)) int fstat(int fd, struct stat *__sbuf) { + + struct __sys_stat hexstat; + sys_call_ret_t res = sys_fstat_internal(fd, &hexstat); + int ret = (int)res.ret_value; + SET_LTS_ERROR(ret, (errno_t)res.err_value); + if(ret >= 0) + { + memset(__sbuf, 0, sizeof(*__sbuf)); + __sbuf->st_dev = hexstat.dev; + __sbuf->st_ino = hexstat.ino; + __sbuf->st_mode = hexstat.mode; + __sbuf->st_nlink = hexstat.nlink; + __sbuf->st_rdev = hexstat.rdev; + __sbuf->st_size = hexstat.size; + __sbuf->st_atime = hexstat.atime; + __sbuf->st_mtime = hexstat.mtime; + __sbuf->st_ctime = hexstat.ctime; + } + return ret; } __attribute__((weak)) void _exit(int status) { @@ -146,9 +166,23 @@ __attribute__((weak)) int get_cmdline(char *buffer, int count) { sys_call_ret_t sys_stat_internal(const char *name, void *buffer); __attribute__((weak)) int stat(const char *__restrict __path, struct stat *__restrict __sbuf) { - sys_call_ret_t res = sys_stat_internal(__path, __sbuf); + struct __sys_stat hexstat; + sys_call_ret_t res = sys_stat_internal(__path, &hexstat); int ret = (int)res.ret_value; SET_LTS_ERROR(ret, (errno_t)res.err_value); + if(ret >= 0) + { + memset(__sbuf, 0, sizeof(*__sbuf)); + __sbuf->st_dev = hexstat.dev; + __sbuf->st_ino = hexstat.ino; + __sbuf->st_mode = hexstat.mode; + __sbuf->st_nlink = hexstat.nlink; + __sbuf->st_rdev = hexstat.rdev; + __sbuf->st_size = hexstat.size; + __sbuf->st_atime = hexstat.atime; + __sbuf->st_mtime = hexstat.mtime; + __sbuf->st_ctime = hexstat.ctime; + } return ret; } @@ -174,9 +208,3 @@ __attribute__((weak)) int gettimeofday(struct timeval * __restrict __p, void * _ SET_LTS_ERROR(-1, ENOSYS); return -1; } - -/* libh2.a is still compiled with older libc which defines errno as a macro that - * expands to _Geterrno we can scrap this symbol once we start building H2 with - * Picolibc - */ -int _Geterrno(void) { return errno; } diff --git a/libs/syscall/wrapper/src/syscall_wrapper.h b/libs/syscall/wrapper/src/syscall_wrapper.h index 9e5ac1480..55d2665c0 100644 --- a/libs/syscall/wrapper/src/syscall_wrapper.h +++ b/libs/syscall/wrapper/src/syscall_wrapper.h @@ -23,6 +23,4 @@ #define SET_LTS_ERROR(ret, err) do {if (ret == -1) errno = sys_error_translation((err));} while(0) #endif -int _Geterrno(void); - #endif /*H2_SYSCALL_WRAPPER*/ diff --git a/scripts/Makefile.inc.bootvm b/scripts/Makefile.inc.bootvm index 1e66c5667..d81b15b6c 100644 --- a/scripts/Makefile.inc.bootvm +++ b/scripts/Makefile.inc.bootvm @@ -5,12 +5,20 @@ MAKE_INC_BOOTVM := 1 VAPA_KERNEL_X_IN := $(INSTALLPATH)/scripts/vapa_kernel.x.in VAPA_KERNEL := vapa_kernel.x +ifeq ($(PICOLIBC),1) +VAPA_BOOTVM := $(INSTALLPATH)/scripts/vapa_bootvm_picolibc.x +else VAPA_BOOTVM := $(INSTALLPATH)/scripts/vapa_bootvm.x +endif BOOTVM_S := $(INSTALLPATH)/src/bootvm.S BOOTVM_O := bootvm.o BOOTVM_IMAGE := bootvm_image BOOTVM_IMAGE_BIN := bootvm_image.bin +ifeq ($(PICOLIBC),1) +BOOTVM_ENTRY_S := $(INSTALLPATH)/src/bootvm_entry_picolibc.S +else BOOTVM_ENTRY_S := $(INSTALLPATH)/src/bootvm_entry.S +endif BOOTVM_ENTRY_O := bootvm_entry.o BOOTVM_SYMBOLS := bootvm_image.sym BOOTVM_PROG_TMP := $(BOOTVM_PROG)_tmp diff --git a/scripts/Makefile.inc.tools b/scripts/Makefile.inc.tools index a2d0c60c6..12c228b36 100644 --- a/scripts/Makefile.inc.tools +++ b/scripts/Makefile.inc.tools @@ -5,6 +5,15 @@ MAKE_INC_TOOLS := 1 export SHELL := /bin/bash +# Toolchain location override. +# If TOOLCHAIN_BIN is provided, prefer its hexagon-* tools. +TOOLCHAIN_BIN ?= +ifneq ($(TOOLCHAIN_BIN),) +# Ensure sub-makes inherit toolchain bin directory. +export TOOLCHAIN_BIN +export PATH := $(TOOLCHAIN_BIN):$(PATH) +endif + ifneq (,${Q6VERSION}) export ARCHV := $(patsubst 6%,60,$(subst v,,$(Q6VERSION))) else @@ -18,7 +27,10 @@ export CXX := hexagon-clang++ export AS := hexagon-clang export AR := hexagon-ar export RANLIB := hexagon-ranlib -export COV := $(shell PKW_VERSIONS=hexagon-tools=8.6.07 pkw --which hexagon-coverage) + +# pkw isn't always available (e.g. local toolchain drops it). Default to +# hexagon-coverage and let PATH resolution find it. +export COV ?= hexagon-coverage export LLVM_COV := hexagon-llvm-cov export OBJDUMP := hexagon-llvm-objdump export GMON_MERGE := hexagon-gmon-merge diff --git a/stake/bootvm_entry_picolibc.S b/stake/bootvm_entry_picolibc.S new file mode 100644 index 000000000..087f4224f --- /dev/null +++ b/stake/bootvm_entry_picolibc.S @@ -0,0 +1,25 @@ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * SPDX-License-Identifier: BSD-3-Clause-Clear + */ + +#include + +/* + * Picolibc variant of bootvm_entry.S. + * + * The original bootvm_entry.S jumps to hexagon_pre_main which is the + * Dinkumware (h2 oslib) CRT entry point. Picolibc does not provide + * hexagon_pre_main; its CRT entry point is _start (placed in + * .text.init.enter by crt0-noflash-hosted.o). _start sets up the + * stack pointer from the __stack linker-script symbol, initialises + * TLS and BSS, runs constructors via __libc_init_array, then calls + * main(). + */ +FUNC_START __bootvm_entry_point .entry .p2align 12 + // r0 has phys_offset + r1 = #__boot_net_phys_offset__ + memw(r1) = r0 + jump _start // picolibc CRT entry (replaces hexagon_pre_main) + +FUNC_END __bootvm_entry_point diff --git a/stake/makefile b/stake/makefile index 74f5075bb..ee2102616 100644 --- a/stake/makefile +++ b/stake/makefile @@ -20,12 +20,18 @@ include ../scripts/Makefile.inc.bootvm CONSTS := ./consts.pl SYMS := ./syms.pl -CFLAGS = $(OPTIMIZE) -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Wall -Werror -g -moslib=h2 -I$(INSTALLPATH)/include -I$(KERNELPATH)/include -L$(INSTALLPATH)/lib +ifeq ($(PICOLIBC),1) +OSLIB_FLAG = --target=hexagon-h2-picolibc +else +OSLIB_FLAG = -moslib=h2 +endif + +CFLAGS = $(OPTIMIZE) -mv$(TOOLARCH) -DARCHV=$(ARCHV) -Wall -Werror -g $(OSLIB_FLAG) -I$(INSTALLPATH)/include -I$(KERNELPATH)/include -L$(INSTALLPATH)/lib CFLAGS += -DH2K_KERNEL_PGSIZE=$(H2K_KERNEL_PGSIZE) -DH2K_KERNEL_ADDRBITS=$(H2K_KERNEL_ADDRBITS) -Qunused-arguments -SCRIPTS = $(CONSTS) $(SYMS) vapa_bootvm.x vapa_kernel.x.in -SRCFILES = bootvm_entry.S bootvm.S min_crt0.S +SCRIPTS = $(CONSTS) $(SYMS) vapa_bootvm.x vapa_bootvm_picolibc.x vapa_kernel.x.in +SRCFILES = bootvm_entry.S bootvm_entry_picolibc.S bootvm.S min_crt0.S BINFILES = kernel_tmp FILES := $(SCRIPTS) $(SRCFILES) $(BINFILES) diff --git a/stake/vapa_bootvm_picolibc.x b/stake/vapa_bootvm_picolibc.x new file mode 100644 index 000000000..176039e99 --- /dev/null +++ b/stake/vapa_bootvm_picolibc.x @@ -0,0 +1,302 @@ +/* + * vapa_bootvm_picolibc.x — bootvm image linker script for picolibc builds. + * + * Derived from vapa_bootvm.x with the following additions required by + * picolibc's crt0-noflash-hosted.o (_start / _cstart): + * + * __stack — top-of-stack; _start sets r29 = __stack + * __bss_start — already present in vapa_bootvm.x + * __bss_size — _cstart uses this to zero BSS via memset + * __tdata_source — source address of TLS initialised-data template + * __tdata_end — end of .tdata + * __tdata_size — size of .tdata + * __tbss_start/end/size/offset — TLS BSS bookkeeping + * __tls_base — per-thread TLS block for the main thread + * __tls_space_size — size of the per-thread TLS block + * __heap_start/end — used by picolibc's malloc sbrk implementation + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * SPDX-License-Identifier: BSD-3-Clause-Clear + */ + +OUTPUT_FORMAT("elf32-littlehexagon", "elf32-littlehexagon", + "elf32-littlehexagon") +ENTRY(__bootvm_entry_point) +SECTIONS +{ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0)); . = SEGMENT_START("text-segment", 0); + + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.init : { *(.rela.init) } + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } + .rela.fini : { *(.rela.fini) } + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } + .rela.data.rel.ro : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) } + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } + .rela.ctors : { *(.rela.ctors) } + .rela.dtors : { *(.rela.dtors) } + .rela.got : { *(.rela.got) } + .rela.sdata : { *(.rela.sdata .rela.lit[a48] .rela.sdata.* .rela.lit[a48].* .rela.gnu.linkonce.s.* .rela.gnu.linkonce.l[a48].*) } + .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } + .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } + .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .rela.iplt : + { + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .rela.plt : { *(.rela.plt) } + + /* Code — .entry placed at H2K_BOOTVM_OFFSET by -Wl,--section-start */ + . = ALIGN (DEFINED (TEXTALIGN) ? (TEXTALIGN * 1K) : CONSTANT (MAXPAGESIZE)); + .entry : { KEEP(*(.entry)) } + .start : + { + KEEP (*(.start)) + /* picolibc places _start in .text.init.enter; keep it right after .entry */ + KEEP (*(.text.init.enter)) + } =0x00c0007f + .init : { KEEP (*(.init)) } =0x00c0007f + .plt : { *(.plt) } + .iplt : { *(.iplt) } + . = ALIGN (. + CONSTANT (COMMONPAGESIZE), CONSTANT (COMMONPAGESIZE)); + .text : + { + *(.text.unlikely .text.*_unlikely) + *(.text.hot .text.hot.* .gnu.linkonce.t.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + *(.gnu.warning) + . = ALIGN(16); + __start___lcxx_override = .; + *(__lcxx_override) + __stop___lcxx_override = .; + } =0x00c0007f + .fini : { KEEP (*(.fini)) } =0x00c0007f + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + /* picolibc constructor/destructor arrays — must be contiguous for + __bothinit_array_start/end used by __libc_init_array */ + . = ALIGN(8); + PROVIDE_HIDDEN (__bothinit_array_start = .); + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .ctors : + { + PROVIDE_HIDDEN (__ctors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.ctors)) + PROVIDE_HIDDEN (__ctors_end = .); + } + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + } + PROVIDE_HIDDEN (__bothinit_array_end = .); + .dtors : + { + PROVIDE_HIDDEN (__dtors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.dtors)) + PROVIDE_HIDDEN (__dtors_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*))) + KEEP (*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + + /* Read-only data */ + . = ALIGN (. + CONSTANT (COMMONPAGESIZE), CONSTANT (COMMONPAGESIZE)); + .rodata : + { + *(.rodata.hot .rodata.hot.* .gnu.linkonce.r.hot.*) + *(.rodata .rodata.* .gnu.linkonce.r.*) + } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : + { + __eh_frame_hdr_start = .; + KEEP (*(.eh_frame_hdr)) + __eh_frame_hdr_end = .; + } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } + + /* Data segment */ + . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + . = ALIGN (DEFINED (DATAALIGN) ? (DATAALIGN * 1K) : CONSTANT (MAXPAGESIZE)); + + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + + /* ------------------------------------------------------------------ */ + /* TLS sections — required by picolibc _cstart / _init_tls / _set_tls */ + /* ------------------------------------------------------------------ */ + . = ALIGN(8); + .tdata : + { + __tdata_source = .; + __tdata_start = __tdata_source; + *(.tdata .tdata.* .gnu.linkonce.td.*) + } + __tdata_end = .; + __tdata_size = __tdata_end - __tdata_source; + + .tbss : + { + __tbss_start = .; + *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) + . = ALIGN(8); + __tbss_end = .; + } + __tbss_size = __tbss_end - __tbss_start; + __tbss_offset = __tbss_start - __tdata_start; + + /* Per-thread TLS space for the main thread */ + . = ALIGN(4K); + .tls_space (NOLOAD) : + { + __tls_base = .; + __tls_space_size = __tbss_end - __tdata_start; + . += __tls_space_size; + } + /* ------------------------------------------------------------------ */ + + . = ALIGN(4K); + .data : + { + *(.data.hot .data.hot.* .gnu.linkonce.d.hot.*) + *(.data .data.* .gnu.linkonce.d.*) + __start___llvm_prf_cnts = .; + KEEP(*(__llvm_prf_cnts)) + __stop___llvm_prf_cnts = .; + __start___llvm_prf_data = .; + KEEP(*(__llvm_prf_data)) + __stop___llvm_prf_data = .; + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _edata = .; PROVIDE (edata = .); + + . = ALIGN (64); + .sdata : + { + PROVIDE (_SDA_BASE_ = .); + *(.sdata.1 .sdata.1.* .gnu.linkonce.s.1.*) + *(.sbss.1 .sbss.1.* .gnu.linkonce.sb.1.*) + *(.scommon.1 .scommon.1.*) + *(.sdata.2 .sdata.2.* .gnu.linkonce.s.2.*) + *(.sbss.2 .sbss.2.* .gnu.linkonce.sb.2.*) + *(.scommon.2 .scommon.2.*) + *(.sdata.4 .sdata.4.* .gnu.linkonce.s.4.*) + *(.sbss.4 .sbss.4.* .gnu.linkonce.sb.4.*) + *(.scommon.4 .scommon.4.*) + *(.lit[a4] .lit[a4].* .gnu.linkonce.l[a4].*) + *(.sdata.8 .sdata.8.* .gnu.linkonce.s.8.*) + *(.sbss.8 .sbss.8.* .gnu.linkonce.sb.8.*) + *(.scommon.8 .scommon.8.*) + *(.lit8 .lit8.* .gnu.linkonce.l8.*) + *(.sdata.hot .sdata.hot.* .gnu.linkonce.s.hot.*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + .got : { *(.got) *(.igot) } + . = DATA_SEGMENT_RELRO_END (16, .); + .got.plt : { *(.got.plt) *(.igot.plt) } + + .sbss : + { + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + *(.dynsbss) + *(.sbss.hot .sbss.hot.* .gnu.linkonce.sb.hot.*) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon .scommon.*) + . = ALIGN (. != 0 ? 64 : 1); + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); + } + + . = ALIGN (64); + /* ------------------------------------------------------------------ */ + /* BSS — picolibc _cstart zeros [__bss_start .. __bss_start+__bss_size] */ + /* ------------------------------------------------------------------ */ + __bss_start = .; + .bss (NOLOAD) : + { + *(.dynbss) + *(.bss.hot .bss.hot.* .gnu.linkonce.b.hot.*) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (. != 0 ? 64 : 1); + } + __bss_end = .; + __bss_size = __bss_end - __bss_start; + /* ------------------------------------------------------------------ */ + + . = ALIGN (64); + _end = .; + PROVIDE (end = .); + + /* ------------------------------------------------------------------ */ + /* Heap — picolibc sbrk uses __heap_start / __heap_end */ + /* ------------------------------------------------------------------ */ + __heap_start = .; + .heap (NOLOAD) : + { + . += (DEFINED(HEAP_SIZE) ? HEAP_SIZE : 0x10000); + } + __heap_end = .; + /* ------------------------------------------------------------------ */ + + /* ------------------------------------------------------------------ */ + /* Stack — picolibc _start sets r29 = __stack (top of stack) */ + /* ------------------------------------------------------------------ */ + .stack (NOLOAD) : + { + . += (DEFINED(STACK_SIZE) ? STACK_SIZE : 0x1000); + } + __stack = .; + /* ------------------------------------------------------------------ */ + + . = DATA_SEGMENT_END (.); + + .hexagon.attributes 0 : { *(.hexagon.attributes) } + .comment 0 : { *(.comment) } + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.note.gnu.build-id) } +}