1// ========================================================
2// linker_wrapper - Linux Bionic (on the host)
3// ========================================================
4
5// This is used for bionic on (host) Linux to bootstrap our linker embedded into
6// a binary.
7//
8// Host bionic binaries do not have a PT_INTERP section, instead this gets
9// embedded as the entry point, and the linker is embedded as ELF sections in
10// each binary. There's a linker script that sets all of that up (generated by
11// extract_linker), and defines the extern symbols used in this file.
12package {
13    default_applicable_licenses: ["bionic_linker_license"],
14}
15
16license {
17    name: "bionic_linker_license",
18    visibility: [":__subpackages__"],
19    license_kinds: [
20        "SPDX-license-identifier-BSD",
21    ],
22    license_text: [
23        "NOTICE",
24    ],
25}
26
27cc_object {
28    name: "linker_wrapper",
29    host_supported: true,
30    device_supported: false,
31    target: {
32        linux_bionic: {
33            enabled: true,
34        },
35        linux_glibc: {
36            enabled: false,
37        },
38        darwin: {
39            enabled: false,
40        },
41    },
42
43    cflags: [
44        "-fno-stack-protector",
45        "-Wstrict-overflow=5",
46        "-fvisibility=hidden",
47        "-Wall",
48        "-Wextra",
49        "-Wno-unused",
50        "-Werror",
51    ],
52
53    srcs: [
54        "linker_wrapper.cpp",
55    ],
56    arch: {
57        arm64: {
58            srcs: ["arch/arm64/begin.S"],
59        },
60        x86_64: {
61            srcs: ["arch/x86_64/begin.S"],
62        },
63    },
64
65    prefix_symbols: "__dlwrap_",
66
67    header_libs: ["libc_headers"],
68
69    // We need to access Bionic private headers in the linker.
70    include_dirs: ["bionic/libc"],
71
72    // b/182338959
73    bazel_module: { bp2build_available: false },
74}
75
76// ========================================================
77// linker default configuration
78// ========================================================
79
80// Configuration for the linker binary and any of its static libraries.
81cc_defaults {
82    name: "linker_defaults",
83    arch: {
84        arm: {
85            cflags: ["-D__work_around_b_24465209__"],
86        },
87        x86: {
88            cflags: ["-D__work_around_b_24465209__"],
89        },
90    },
91
92    cflags: [
93        "-fno-stack-protector",
94        "-Wstrict-overflow=5",
95        "-fvisibility=hidden",
96        "-Wall",
97        "-Wextra",
98        "-Wunused",
99        "-Werror",
100    ],
101
102    // TODO: split out the asflags.
103    asflags: [
104        "-fno-stack-protector",
105        "-Wstrict-overflow=5",
106        "-fvisibility=hidden",
107        "-Wall",
108        "-Wextra",
109        "-Wunused",
110        "-Werror",
111    ],
112
113    product_variables: {
114        debuggable: {
115            cppflags: ["-DUSE_LD_CONFIG_FILE"],
116        },
117    },
118
119    cppflags: ["-Wold-style-cast"],
120
121    static_libs: [
122        "libziparchive",
123        "libbase",
124        "libz",
125
126        "libasync_safe",
127
128        "liblog",
129    ],
130
131    // We need to access Bionic private headers in the linker.
132    include_dirs: ["bionic/libc"],
133}
134
135// ========================================================
136// linker components
137// ========================================================
138
139// Enable a module on all targets the linker runs on (ordinary Android targets, Linux Bionic, and
140// native bridge implementations).
141cc_defaults {
142    name: "linker_all_targets",
143    defaults: ["linux_bionic_supported"],
144    recovery_available: true,
145    vendor_ramdisk_available: true,
146    native_bridge_supported: true,
147}
148
149cc_library_static {
150    name: "liblinker_main",
151    defaults: ["linker_defaults", "linker_all_targets"],
152    srcs: ["linker_main.cpp"],
153
154    // Ensure that the compiler won't insert string function calls before ifuncs are resolved.
155    cflags: ["-ffreestanding"],
156}
157
158cc_library_static {
159    name: "liblinker_malloc",
160    defaults: ["linker_defaults", "linker_all_targets"],
161    srcs: ["linker_memory.cpp"],
162}
163
164cc_library_static {
165    name: "liblinker_debuggerd_stub",
166    defaults: ["linker_defaults", "linker_all_targets"],
167    srcs: ["linker_debuggerd_stub.cpp"],
168}
169
170// ========================================================
171// template for the linker binary
172// ========================================================
173
174filegroup {
175    name: "linker_sources",
176    srcs: [
177        "dlfcn.cpp",
178        "linker.cpp",
179        "linker_block_allocator.cpp",
180        "linker_dlwarning.cpp",
181        "linker_cfi.cpp",
182        "linker_config.cpp",
183        "linker_debug.cpp",
184        "linker_gdb_support.cpp",
185        "linker_globals.cpp",
186        "linker_libc_support.c",
187        "linker_libcxx_support.cpp",
188        "linker_namespaces.cpp",
189        "linker_logger.cpp",
190        "linker_mapped_file_fragment.cpp",
191        "linker_note_gnu_property.cpp",
192        "linker_phdr.cpp",
193        "linker_relocate.cpp",
194        "linker_sdk_versions.cpp",
195        "linker_soinfo.cpp",
196        "linker_transparent_hugepage_support.cpp",
197        "linker_tls.cpp",
198        "linker_utils.cpp",
199        "rt.cpp",
200    ],
201}
202
203filegroup {
204    name: "linker_sources_arm",
205    srcs: [
206        "arch/arm/begin.S",
207        "arch/arm_neon/linker_gnu_hash_neon.cpp",
208    ],
209}
210
211filegroup {
212    name: "linker_sources_arm64",
213    srcs: [
214        "arch/arm64/begin.S",
215        "arch/arm64/tlsdesc_resolver.S",
216        "arch/arm_neon/linker_gnu_hash_neon.cpp",
217    ],
218}
219
220filegroup {
221    name: "linker_sources_x86",
222    srcs: [
223        "arch/x86/begin.S",
224    ],
225}
226
227filegroup {
228    name: "linker_sources_x86_64",
229    srcs: [
230        "arch/x86_64/begin.S",
231    ],
232}
233
234cc_defaults {
235    name: "linker_version_script_overlay",
236    arch: {
237        arm:    { version_script: "linker.arm.map"      },
238        arm64:  { version_script: "linker.generic.map"  },
239        x86:    { version_script: "linker.generic.map"  },
240        x86_64: { version_script: "linker.generic.map"  },
241    },
242}
243
244// A template for the linker binary. May be inherited by native bridge implementations.
245cc_defaults {
246    name: "linker_bin_template",
247    defaults: ["linker_defaults"],
248
249    srcs: [":linker_sources"],
250
251    arch: {
252        arm: {
253            srcs: [":linker_sources_arm"],
254        },
255        arm64: {
256            srcs: [":linker_sources_arm64"],
257        },
258        x86: {
259            srcs: [":linker_sources_x86"],
260        },
261        x86_64: {
262            srcs: [":linker_sources_x86_64"],
263        },
264    },
265
266    // -shared is used to overwrite the -Bstatic and -static flags triggered by enabling
267    // static_executable. This dynamic linker is actually a shared object linked with static
268    // libraries.
269    ldflags: [
270        "-shared",
271        "-Wl,-Bsymbolic",
272        "-Wl,--exclude-libs,ALL",
273        "-Wl,-soname,ld-android.so",
274    ],
275
276    // we are going to link libc++_static manually because
277    // when stl is not set to "none" build system adds libdl
278    // to the list of static libraries which needs to be
279    // avoided in the case of building loader.
280    stl: "none",
281
282    // we don't want crtbegin.o (because we have begin.o), so unset it
283    // just for this module
284    nocrt: true,
285
286    static_executable: true,
287
288    // Leave the symbols in the shared library so that stack unwinders can produce
289    // meaningful name resolution.
290    strip: {
291        keep_symbols: true,
292    },
293
294    // Insert an extra objcopy step to add prefix to symbols. This is needed to prevent gdb
295    // looking up symbols in the linker by mistake.
296    prefix_symbols: "__dl_",
297
298    sanitize: {
299        hwaddress: false,
300    },
301
302    static_libs: [
303        "liblinker_main",
304        "liblinker_malloc",
305
306        "libc++_static",
307        "libc_nomalloc",
308        "libc_dynamic_dispatch",
309        "libm",
310        "libunwind",
311    ],
312
313    // Ensure that if the linker needs __gnu_Unwind_Find_exidx, then the linker will have a
314    // definition of the symbol. The linker links against libgcc.a, whose arm32 unwinder has a weak
315    // reference to __gnu_Unwind_Find_exidx, which isn't sufficient to pull in the strong definition
316    // of __gnu_Unwind_Find_exidx from libc. An unresolved weak reference would create a
317    // non-relative dynamic relocation in the linker binary, which complicates linker startup.
318    //
319    // This line should be unnecessary because the linker's dependency on libunwind_llvm.a should
320    // override libgcc.a, but this line provides a simpler guarantee. It can be removed once the
321    // linker stops linking against libgcc.a's arm32 unwinder.
322    whole_static_libs: ["libc_unwind_static"],
323
324    system_shared_libs: [],
325
326    // Opt out of native_coverage when opting out of system_shared_libs
327    native_coverage: false,
328}
329
330// ========================================================
331// linker[_asan][64] binary
332// ========================================================
333
334cc_binary {
335    name: "linker",
336    defaults: [
337        "linker_bin_template",
338        "linux_bionic_supported",
339        "linker_version_script_overlay",
340    ],
341
342    srcs: [
343        "linker_translate_path.cpp",
344    ],
345
346    symlinks: ["linker_asan"],
347    multilib: {
348        lib64: {
349            suffix: "64",
350        },
351    },
352
353    compile_multilib: "both",
354
355    recovery_available: true,
356    vendor_ramdisk_available: true,
357    apex_available: [
358        "//apex_available:platform",
359        "com.android.runtime",
360    ],
361
362    target: {
363        android: {
364            srcs: [
365                "linker_debuggerd_android.cpp",
366            ],
367            static_libs: [
368                "libc++demangle",
369                "libdebuggerd_handler_fallback",
370            ],
371        },
372        linux_bionic: {
373            static_libs: [
374                "liblinker_debuggerd_stub",
375            ],
376        },
377        android_arm64: {
378            pgo: {
379                profile_file: "bionic/linker_arm_arm64.profdata",
380            },
381        },
382        android_arm: {
383            pgo: {
384                profile_file: "bionic/linker_arm_arm64.profdata",
385            },
386        },
387        android_x86_64: {
388            pgo: {
389                profile_file: "bionic/linker_x86_x86_64.profdata",
390            },
391        },
392        android_x86: {
393            pgo: {
394                profile_file: "bionic/linker_x86_x86_64.profdata",
395            },
396        },
397    },
398
399    lto: {
400        never: true,
401    },
402    pgo: {
403        sampling: true,
404    },
405}
406
407// ========================================================
408// assorted modules
409// ========================================================
410
411sh_binary {
412    name: "ldd",
413    src: "ldd.sh",
414    bazel_module: { bp2build_available: true },
415}
416
417// Used to generate binaries that can be backed by transparent hugepages.
418cc_defaults {
419    name: "linker_hugepage_aligned",
420    arch: {
421        arm64: {
422            ldflags: ["-z max-page-size=0x200000"],
423        },
424        x86_64: {
425            ldflags: ["-z max-page-size=0x200000"],
426        },
427    },
428}
429
430cc_library {
431    // NOTE: --exclude-libs=libgcc.a makes sure that any symbols ld-android.so pulls from
432    // libgcc.a are made static to ld-android.so.  This in turn ensures that libraries that
433    // a) pull symbols from libgcc.a and b) depend on ld-android.so will not rely on ld-android.so
434    // to provide those symbols, but will instead pull them from libgcc.a.  Specifically,
435    // we use this property to make sure libc.so has its own copy of the code from
436    // libgcc.a it uses.
437    //
438    // DO NOT REMOVE --exclude-libs!
439
440    ldflags: [
441        "-Wl,--exclude-libs=libgcc.a",
442        "-Wl,--exclude-libs=libgcc_stripped.a",
443        "-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
444        "-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
445        "-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
446        "-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
447    ],
448
449    // for x86, exclude libgcc_eh.a for the same reasons as above
450    arch: {
451        x86: {
452            ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
453        },
454        x86_64: {
455            ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
456        },
457    },
458
459    srcs: ["ld_android.cpp"],
460    cflags: [
461        "-Wall",
462        "-Wextra",
463        "-Wunused",
464        "-Werror",
465    ],
466    stl: "none",
467
468    name: "ld-android",
469    defaults: ["linux_bionic_supported", "linker_version_script_overlay"],
470    ramdisk_available: true,
471    vendor_ramdisk_available: true,
472    recovery_available: true,
473    native_bridge_supported: true,
474
475    nocrt: true,
476    system_shared_libs: [],
477    header_libs: ["libc_headers"],
478
479    // Opt out of native_coverage when opting out of system_shared_libs
480    native_coverage: false,
481
482    sanitize: {
483        never: true,
484    },
485
486    apex_available: [
487        "//apex_available:platform",
488        "com.android.runtime",
489    ],
490
491    lto: {
492        never: true,
493    },
494}
495
496cc_test {
497    name: "linker-unit-tests",
498
499    cflags: [
500        "-g",
501        "-Wall",
502        "-Wextra",
503        "-Wunused",
504        "-Werror",
505    ],
506
507    // We need to access Bionic private headers in the linker.
508    include_dirs: ["bionic/libc"],
509
510    srcs: [
511        // Tests.
512        "linker_block_allocator_test.cpp",
513        "linker_config_test.cpp",
514        "linked_list_test.cpp",
515        "linker_note_gnu_property_test.cpp",
516        "linker_sleb128_test.cpp",
517        "linker_utils_test.cpp",
518        "linker_gnu_hash_test.cpp",
519
520        // Parts of the linker that we're testing.
521        "linker_block_allocator.cpp",
522        "linker_config.cpp",
523        "linker_debug.cpp",
524        "linker_note_gnu_property.cpp",
525        "linker_test_globals.cpp",
526        "linker_utils.cpp",
527    ],
528
529    static_libs: [
530        "libasync_safe",
531        "libbase",
532        "liblog",
533    ],
534
535    arch: {
536        arm: {
537            srcs: ["arch/arm_neon/linker_gnu_hash_neon.cpp"],
538        },
539        arm64: {
540            srcs: ["arch/arm_neon/linker_gnu_hash_neon.cpp"],
541        },
542    },
543}
544
545cc_benchmark {
546    name: "linker-benchmarks",
547
548    srcs: [
549        "linker_gnu_hash_benchmark.cpp",
550    ],
551
552    arch: {
553        arm: {
554            srcs: ["arch/arm_neon/linker_gnu_hash_neon.cpp"],
555        },
556        arm64: {
557            srcs: ["arch/arm_neon/linker_gnu_hash_neon.cpp"],
558        },
559    },
560}
561