diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -132,6 +132,7 @@ LLVM_ASSERTIONS \ LLVM_COV \ LLVM_CXXFILT \ + LOADER_BACKTRACE \ LOADER_GELI \ LOADER_KBOOT \ LOADER_LUA \ @@ -318,6 +319,12 @@ .if ${__T:Mpowerpc*} BROKEN_OPTIONS+=LOADER_GELI LOADER_LUA .endif +# Backtrace doesn't work on powerpc, alas +.if ${__T:Mpowerpc*} +BROKEN_OPTIONS+=LOADER_BACKTRACE +.endif + + # Kernel TLS is enabled by default on amd64 and aarch64 .if ${__T} == "aarch64" || ${__T} == "amd64" diff --git a/stand/Makefile b/stand/Makefile --- a/stand/Makefile +++ b/stand/Makefile @@ -24,6 +24,7 @@ S.${MK_FORTH}+= forth S.${MK_LOADER_LUA}+= liblua S.${MK_LOADER_LUA}+= lua +S.${MK_LOADER_BACKTRACE}+=libbacktrace S.yes+= defaults S.yes+= fonts S.yes+= images diff --git a/stand/defs.mk b/stand/defs.mk --- a/stand/defs.mk +++ b/stand/defs.mk @@ -71,6 +71,14 @@ LIBSA32= ${BOOTOBJ}/libsa32/libsa32.a .endif +# Backtrace doesn't work everywhere, so allow it to be disabled. +.if ${MK_LOADER_BACKTRACE} == "yes" +LIBBACKTRACE= ${BOOTOBJ}/libbacktrace/libbacktrace.a # Nothing when not configured +CFLAGS+= -DLOADER_BACKTRACE +LIBEXECINFO= ${SRCTOP}/contrib/libexecinfo +CFLAGS+= -I${LIBEXECINFO} +.endif + # Standard options: CFLAGS+= -nostdinc # Allow CFLAGS_EARLY.file/target so that code that needs specific stack diff --git a/stand/libbacktrace/Makefile b/stand/libbacktrace/Makefile new file mode 100644 --- /dev/null +++ b/stand/libbacktrace/Makefile @@ -0,0 +1,87 @@ +# $FreeBSD$ + +# Note: This pulls together libgcc_eh (basically libunwind) and libexecinfo, or +# at least the bits that are needed to work in the reduced-space of libstand +# programs + +#LOADER_NO_SPIKE=t + +.include + +LIB= backtrace +NO_PIC= +MK_SSP= no +WARNS?= 2 + +## From libgcc_eh (Makefile and Makefile.inc merged with tweaks for loader env) + +COMPILERRTDIR= ${SRCTOP}/contrib/llvm-project/compiler-rt +UNWINDINCDIR= ${SRCTOP}/contrib/llvm-project/libunwind/include +UNWINDSRCDIR= ${SRCTOP}/contrib/llvm-project/libunwind/src + +SRCS_EXC+= int_util.c + +STATIC_CFLAGS+=${PICFLAG} -fvisibility=hidden -DVISIBILITY_HIDDEN +STATIC_CXXFLAGS+= -fvisibility=hidden -fPIC + +.PATH: ${COMPILERRTDIR}/lib/builtins +.PATH: ${UNWINDSRCDIR} +SRCS_EXC+= gcc_personality_v0.c +SRCS_EXC+= Unwind-EHABI.cpp +SRCS_EXC+= Unwind-sjlj.c +SRCS_EXC+= UnwindLevel1-gcc-ext.c +SRCS_EXC+= UnwindLevel1.c +SRCS_EXC+= UnwindRegistersRestore.S +SRCS_EXC+= UnwindRegistersSave.S +SRCS_EXC+= libunwind.cpp + +SRCS+= ${SRCS_EXC} + +FLAGS_EXC= -include ${.CURDIR}/unwind-hacks.h \ + -fno-exceptions \ + -funwind-tables \ + -I${UNWINDINCDIR} + +.for file in ${SRCS_EXC:M*.c} +CFLAGS.${file}+= ${FLAGS_EXC} +. if ${MK_ASAN} != "no" +# False-positives during stack unwinding +CFLAGS.${file}+= -fno-sanitize=address +. endif +.endfor + +.for file in ${SRCS_EXC:M*.cpp} +CXXFLAGS.${file}+= ${FLAGS_EXC} +CXXFLAGS.${file}+= -fno-rtti +. if ${MK_ASAN} != "no" +# False-positives during stack unwinding +CXXFLAGS.${file}+= -fno-sanitize=address +. endif +.endfor +CXXSTD?= c++11 + +# We do ugly things to make floats and doubles look like ints, this works except +# for a format that's hard to fix w/o hacking the format. Since the arg is +# really a float, and is the same size as a float for all our ABIs, just +# suppress the warning: Things will work at intended. +CXXFLAGS.libunwind.cpp+= -Wno-format + +# Probably need to just move this earlier or use CXXFLAGS +# XXX likely want to hoist it up into defs.mk -- if it's even needed +.if ${MK_DIRDEPS_BUILD} == "yes" +# Avoid dependency on lib/libc++ +CFLAGS+= -isystem ${SRCTOP}/contrib/llvm-project/libcxx/include -nostdinc++ +.endif + +## From libexecinfo for backtrace, et al + +LIBEXECINFO= ${SRCTOP}/contrib/libexecinfo +.PATH: ${LIBEXECINFO} +SRCS_EI= unwind.c +# XXX these need libelf SRCS_EI+= backtrace.c symtab.c +.for file in ${SRCS_EI} +CFLAGS.${file}+= -I${UNWINDINCDIR} +.endfor +SRCS+=${SRCS_EI} + +.include diff --git a/stand/libbacktrace/Makefile.depend b/stand/libbacktrace/Makefile.depend new file mode 100644 --- /dev/null +++ b/stand/libbacktrace/Makefile.depend @@ -0,0 +1,13 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + include \ + include/xlocale \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/stand/libbacktrace/unwind-hacks.h b/stand/libbacktrace/unwind-hacks.h new file mode 100644 --- /dev/null +++ b/stand/libbacktrace/unwind-hacks.h @@ -0,0 +1,40 @@ +/* Hacks for libunwind */ +#define fprintf(f, fmt...) printf(fmt) +#define fflush(x) (0) + +/* + * Note: Although we RUN on Linux when we're inside of loader.kboot, we compile on + * FreeBSD, and the #ifdefs that are in libunwind and compiler-rt are all compile-time + * not runtime. + * + * libexecinfo's backtrace, however, does need a __linux__ #define for a + * specific location. This file isn't needed for libexecinfo, though. + */ + +/* + * Limit subset of features that are appropriate for boot loader. + */ +#define _LIBUNWIND_IS_NATIVE_ONLY +#define _LIBUNWIND_USE_FRAME_HEADER_CACHE +#define _LIBUNWIND_IS_BAREMETAL +#define _LIBUNWIND_HAS_NO_THREADS + +/* + * libunwind uses alloca by default, so rediret it to the builtin one. This + * allows it to allocate space in more situations (the alternative is to + * allocate it from the heap, which is unsafe in some situations). + */ +#define alloca __builtin_alloca + +/* + * Noramlly, the boot loader defines double and float to ensure they aren't used + * at all. However, there's code in libunwind to cope with the FPU state. We + * don't really need this functionality for out use-case, so we redefine + * double/float as an integer of the same size. We don't need to worry about the + * 'long double' swamp, which is harder to do with no-code-changes to the + * upstream code. + */ +#undef double +#undef float +#define double uint64_t +#define float uint32_t diff --git a/tools/build/options/WITHOUT_LOADER_BACKTRACE b/tools/build/options/WITHOUT_LOADER_BACKTRACE new file mode 100644 --- /dev/null +++ b/tools/build/options/WITHOUT_LOADER_BACKTRACE @@ -0,0 +1,2 @@ +Do not build backtrace support for the bootloader. + diff --git a/tools/build/options/WITH_LOADER_BACKTRACE b/tools/build/options/WITH_LOADER_BACKTRACE new file mode 100644 --- /dev/null +++ b/tools/build/options/WITH_LOADER_BACKTRACE @@ -0,0 +1,2 @@ +Build backtrace support for the bootloader. +This option does does not work on all powerpc platforms, though, and cannot be enabled.