summaryrefslogtreecommitdiff
path: root/src/third_party/unwind/SConscript
blob: 9f4de94375ba0fa81e26f38d93ce0880e3300c4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# -*- 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),
)