# -*- mode: python -*- Import("env") Import("has_option") Import("debugBuild") # https://www.nongnu.org/libunwind/man/libunwind(3).html#section_1 # For local unwinding (introspection, which is all we want), include # libunwind.h and link with '-lunwind'. We only need to build enough # for that to work. # # Supported: # linux_x86_64 # linux_aarch64 env = env.Clone( # Libunwind wants to interpose (for better or for worse) on the # libc `backtrace`. Building with hidden visibility probably # breaks that. It also seems to interfere with building with the # sanitizers, which use linker maps that reference backtrace. This # may be an ld.gold bug. DISALLOW_VISHIDDEN=True, ) unwind_root = env.Dir(".").srcnode() unwind_platform = unwind_root.Dir("platform/${TARGET_OS}_${TARGET_ARCH}") unwind_src_dir = env.Dir("dist/src") if env['TARGET_ARCH'] == 'ppc64le': env['UNWIND_TARGET_ARCH'] = 'ppc64' env['UNWIND_TARGET_ARCH_ALT'] = 'ppc' else: env['UNWIND_TARGET_ARCH'] = env['TARGET_ARCH'] env['UNWIND_TARGET_ARCH_ALT'] = env['TARGET_ARCH'] # Generated by a manual process: # - Run "scripts/host_config.sh |tee host_config.out". # - Gather .o dependencies of the libunwind.a target. # - Some .o are from prereq libraries, they have .lax paths. # Replace the `*.lax/$PREREQ/*.o` dependencies with the # corresponding .o from that $PREREQ library. # - Replace each .o with the source file (.c or .S) that generated it. # - Ensure the the ${CC} arguments are preserved by SCons. # Note you can skip NDEBUG defines as those should be inherited. unwind_common_sources = [ 'dwarf/global.c', 'dwarf/Lexpr.c', 'dwarf/Lfde.c', 'dwarf/Lfind_proc_info-lsb.c', 'dwarf/Lfind_unwind_table.c', 'dwarf/Lparser.c', 'dwarf/Lpe.c', "dl-iterate-phdr.c", 'elf64.c', 'mi/backtrace.c', 'mi/dyn-cancel.c', 'mi/dyn-info-list.c', 'mi/dyn-register.c', 'mi/flush_cache.c', 'mi/init.c', 'mi/Ldestroy_addr_space.c', 'mi/Ldyn-extract.c', 'mi/Lfind_dynamic_proc_info.c', 'mi/Lget_accessors.c', 'mi/Lget_fpreg.c', 'mi/Lget_proc_info_by_ip.c', 'mi/Lget_proc_name.c', 'mi/Lget_reg.c', 'mi/Lput_dynamic_unwind_info.c', 'mi/Lset_cache_size.c', 'mi/Lset_caching_policy.c', 'mi/Lset_fpreg.c', 'mi/Lset_reg.c', 'mi/mempool.c', 'mi/strerror.c', 'os-${TARGET_OS}.c', ] unwind_platform_sources = [ '${UNWIND_TARGET_ARCH}/is_fpreg.c', '${UNWIND_TARGET_ARCH}/Lapply_reg_state.c', '${UNWIND_TARGET_ARCH}/Lcreate_addr_space.c', '${UNWIND_TARGET_ARCH_ALT}/Lget_proc_info.c', '${UNWIND_TARGET_ARCH_ALT}/Lget_save_loc.c', '${UNWIND_TARGET_ARCH}/Lglobal.c', '${UNWIND_TARGET_ARCH}/Linit.c', '${UNWIND_TARGET_ARCH_ALT}/Linit_local.c', '${UNWIND_TARGET_ARCH_ALT}/Linit_remote.c', '${UNWIND_TARGET_ARCH}/Lregs.c', '${UNWIND_TARGET_ARCH}/Lreg_states_iterate.c', '${UNWIND_TARGET_ARCH}/Lresume.c', '${UNWIND_TARGET_ARCH}/Lstep.c', '${UNWIND_TARGET_ARCH}/regname.c', ] if env['TARGET_ARCH'] == 'x86_64': unwind_platform_sources += [ "${UNWIND_TARGET_ARCH}/Los-${TARGET_OS}.c", '${UNWIND_TARGET_ARCH}/Lstash_frame.c', '${UNWIND_TARGET_ARCH}/Ltrace.c', "${UNWIND_TARGET_ARCH}/getcontext.S", "${UNWIND_TARGET_ARCH}/setcontext.S", ] elif env['TARGET_ARCH'] == 'aarch64': unwind_platform_sources += [ "${UNWIND_TARGET_ARCH}/Lis_signal_frame.c", "${UNWIND_TARGET_ARCH}/Lstash_frame.c", "${UNWIND_TARGET_ARCH}/Ltrace.c", "${UNWIND_TARGET_ARCH}/getcontext.S", ] elif env['TARGET_ARCH'] == 'ppc64le': unwind_platform_sources += [ "${UNWIND_TARGET_ARCH}/get_func_addr.c", "${UNWIND_TARGET_ARCH_ALT}/Lis_signal_frame.c", ] elif env['TARGET_ARCH'] == 's390x': unwind_platform_sources += [ "${UNWIND_TARGET_ARCH}/Lis_signal_frame.c", "${UNWIND_TARGET_ARCH}/getcontext.S", "${UNWIND_TARGET_ARCH}/setcontext.S", ] else: env.FatalError(f"{env['TARGET_ARCH']} unsupported by libunwind.") env.Append(CCFLAGS=[ '-fexceptions', '-Wno-unused-result', '-Wno-pointer-sign', '-Wno-incompatible-pointer-types', '-Wno-unused-variable', ]) if env.ToolchainIs('gcc'): env.Append(CCFLAGS=[ '-Wno-uninitialized', ]) if env['TARGET_ARCH'] == 'ppc64le': env.Append(CCFLAGS=[ '-Wno-unused-value', ]) if env.ToolchainIs('clang'): env.Append(CCFLAGS=['-Wno-header-guard']) if env['TARGET_ARCH'] == 'aarch64': env.Append(CCFLAGS=['-Wno-absolute-value']) env.Append(CPPPATH=[ unwind_platform.Dir("build/include"), unwind_root.Dir("dist/src"), unwind_root.Dir("dist/include"), unwind_root.Dir("dist/include/tdep-${UNWIND_TARGET_ARCH}"), ]) # propagates to consumers that inject (depend on) unwind. env.RegisterConsumerModifications( CPPPATH=[unwind_platform.Dir("install/include")], SYSLIBDEPS_PRIVATE=[env['LIBDEPS_LZMA_SYSLIBDEP']], ) env.Append(SYSLIBDEPS_PRIVATE=[env['LIBDEPS_LZMA_SYSLIBDEP']]) env.Append(CPPDEFINES=[ 'HAVE_CONFIG_H', '_GNU_SOURCE', ]) unwind_sources = unwind_common_sources + unwind_platform_sources env.Library( target='unwind', source=env.File(unwind_sources, unwind_src_dir), )