• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1package {
2    default_team: "trendy_team_native_tools_libraries",
3    default_applicable_licenses: ["bionic_linker_license"],
4}
5
6license {
7    name: "bionic_linker_license",
8    visibility: [":__subpackages__"],
9    license_kinds: [
10        "SPDX-license-identifier-BSD",
11    ],
12    license_text: [
13        "NOTICE",
14    ],
15}
16
17linker_common_flags = [
18    "-fno-stack-protector",
19    "-Wstrict-overflow=5",
20    "-fvisibility=hidden",
21    "-Wall",
22    "-Wextra",
23    "-Wunused",
24    "-Werror",
25]
26
27// ========================================================
28// linker_wrapper - Linux Bionic (on the host)
29// ========================================================
30
31// This is used for bionic on (host) Linux to bootstrap our linker embedded into
32// a binary.
33//
34// Host bionic binaries do not have a PT_INTERP section, instead this gets
35// embedded as the entry point, and the linker is embedded as ELF sections in
36// each binary. There's a linker script that sets all of that up (generated by
37// extract_linker), and defines the extern symbols used in this file.
38cc_object {
39    name: "linker_wrapper",
40    host_supported: true,
41    device_supported: false,
42    enabled: false,
43    target: {
44        linux_bionic: {
45            enabled: true,
46        },
47    },
48
49    cflags: linker_common_flags,
50
51    srcs: [
52        "linker_wrapper.cpp",
53    ],
54    arch: {
55        arm64: {
56            srcs: ["arch/arm64/linker_wrapper_begin.S"],
57        },
58        riscv64: {
59            srcs: ["arch/riscv64/linker_wrapper_begin.S"],
60        },
61        x86_64: {
62            srcs: ["arch/x86_64/linker_wrapper_begin.S"],
63        },
64    },
65
66    header_libs: ["libc_headers"],
67
68    // We need to access Bionic private headers in the linker.
69    include_dirs: ["bionic/libc"],
70}
71
72// ========================================================
73// linker default configuration
74// ========================================================
75
76// Configuration for the linker binary and any of its static libraries.
77cc_defaults {
78    name: "linker_defaults",
79
80    cflags: linker_common_flags,
81    asflags: linker_common_flags,
82
83    product_variables: {
84        debuggable: {
85            cppflags: ["-DUSE_LD_CONFIG_FILE"],
86        },
87    },
88
89    cppflags: ["-Wold-style-cast"],
90
91    static_libs: [
92        "libziparchive",
93        "libbase",
94        "libz",
95
96        "libasync_safe",
97
98        "liblog_for_runtime_apex",
99    ],
100
101    // We need to access Bionic private headers in the linker.
102    include_dirs: ["bionic/libc"],
103
104    sanitize: {
105        // Supporting memtag_globals in the linker would be tricky,
106        // because it relocates itself very early.
107        memtag_globals: false,
108    },
109}
110
111// ========================================================
112// linker components
113// ========================================================
114
115// Enable a module on all targets the linker runs on (ordinary Android targets, Linux Bionic, and
116// native bridge implementations).
117cc_defaults {
118    name: "linker_all_targets",
119    defaults: ["linux_bionic_supported"],
120    recovery_available: true,
121    vendor_ramdisk_available: true,
122    native_bridge_supported: true,
123}
124
125cc_library_static {
126    name: "liblinker_main",
127    defaults: [
128        "linker_defaults",
129        "linker_all_targets",
130    ],
131    srcs: ["linker_main.cpp"],
132
133    // Ensure that the compiler won't insert string function calls before ifuncs are resolved.
134    cflags: ["-ffreestanding"],
135    apex_available: [
136        "com.android.runtime",
137    ],
138}
139
140cc_library_static {
141    name: "liblinker_malloc",
142    defaults: [
143        "linker_defaults",
144        "linker_all_targets",
145    ],
146    srcs: ["linker_memory.cpp"],
147    apex_available: [
148        "com.android.runtime",
149    ],
150}
151
152cc_library_static {
153    name: "liblinker_debuggerd_stub",
154    defaults: [
155        "linker_defaults",
156        "linker_all_targets",
157    ],
158    srcs: ["linker_debuggerd_stub.cpp"],
159}
160
161// ========================================================
162// template for the linker binary
163// ========================================================
164
165filegroup {
166    name: "linker_sources",
167    srcs: [
168        "dlfcn.cpp",
169        "linker.cpp",
170        "linker_auxv.cpp",
171        "linker_block_allocator.cpp",
172        "linker_dlwarning.cpp",
173        "linker_cfi.cpp",
174        "linker_config.cpp",
175        "linker_debug.cpp",
176        "linker_gdb_support.cpp",
177        "linker_globals.cpp",
178        "linker_libc_support.c",
179        "linker_libcxx_support.cpp",
180        "linker_namespaces.cpp",
181        "linker_logger.cpp",
182        "linker_mapped_file_fragment.cpp",
183        "linker_note_gnu_property.cpp",
184        "linker_phdr.cpp",
185        "linker_phdr_16kib_compat.cpp",
186        "linker_relocate.cpp",
187        "linker_sdk_versions.cpp",
188        "linker_soinfo.cpp",
189        "linker_transparent_hugepage_support.cpp",
190        "linker_tls.cpp",
191        "linker_utils.cpp",
192        "rt.cpp",
193    ],
194}
195
196filegroup {
197    name: "linker_sources_arm",
198    srcs: [
199        "arch/arm/begin.S",
200        "arch/arm_neon/linker_gnu_hash_neon.cpp",
201    ],
202}
203
204filegroup {
205    name: "linker_sources_arm64",
206    srcs: [
207        "arch/arm64/begin.S",
208        "arch/arm64/tlsdesc_resolver.S",
209        "arch/arm_neon/linker_gnu_hash_neon.cpp",
210    ],
211}
212
213filegroup {
214    name: "linker_sources_riscv64",
215    srcs: [
216        "arch/riscv64/begin.S",
217        "arch/riscv64/tlsdesc_resolver.S",
218    ],
219}
220
221filegroup {
222    name: "linker_sources_x86",
223    srcs: [
224        "arch/x86/begin.S",
225    ],
226}
227
228filegroup {
229    name: "linker_sources_x86_64",
230    srcs: [
231        "arch/x86_64/begin.S",
232    ],
233}
234
235cc_defaults {
236    name: "linker_version_script_overlay",
237    arch: {
238        arm: {
239            version_script: "linker.arm.map",
240        },
241        arm64: {
242            version_script: "linker.generic.map",
243        },
244        riscv64: {
245            version_script: "linker.generic.map",
246        },
247        x86: {
248            version_script: "linker.generic.map",
249        },
250        x86_64: {
251            version_script: "linker.generic.map",
252        },
253    },
254}
255
256// A template for the linker binary. May be inherited by native bridge implementations.
257cc_defaults {
258    name: "linker_bin_template",
259    defaults: [
260        "linker_defaults",
261        "keep_symbols",
262    ],
263
264    srcs: [":linker_sources"],
265
266    arch: {
267        arm: {
268            srcs: [":linker_sources_arm"],
269        },
270        arm64: {
271            srcs: [":linker_sources_arm64"],
272        },
273        riscv64: {
274            srcs: [":linker_sources_riscv64"],
275        },
276        x86: {
277            srcs: [":linker_sources_x86"],
278        },
279        x86_64: {
280            srcs: [":linker_sources_x86_64"],
281        },
282    },
283
284    static_executable: true,
285
286    // -shared is used to overwrite the -Bstatic and -static flags triggered by enabling
287    // static_executable. The dynamic linker is actually a shared object linked with static
288    // libraries.
289    ldflags: [
290        "-shared",
291        "-Wl,-Bsymbolic",
292        "-Wl,--exclude-libs,ALL",
293        "-Wl,-soname,ld-android.so",
294        // When the linker applies its own IRELATIVE relocations, it will only read DT_REL[A] and
295        // DT_JMPREL, not DT_ANDROID_REL[A], which can also theoretically contain IRELATIVE
296        // relocations. lld has been taught to not store them there as a bug workaround (see
297        // https://llvm.org/pr86751) but the workaround could be removed at some point in the
298        // future. So we explicitly prevent it from doing so by disabling DT_ANDROID_REL[A] when
299        // linking the linker (DT_RELR cannot encode IRELATIVE relocations).
300        "-Wl,--pack-dyn-relocs=relr",
301    ],
302
303    // We link libc++_static manually because otherwise the build system will
304    // automatically add libdl to the list of static libraries.
305    stl: "none",
306
307    // We don't want crtbegin.o (because we have our own arch/*/begin.o),
308    // so unset it just for this module.
309    nocrt: true,
310
311    // Insert an extra objcopy step to add prefix to symbols. This is needed to prevent gdb
312    // looking up symbols in the linker by mistake.
313    prefix_symbols: "__dl_",
314
315    sanitize: {
316        hwaddress: false,
317        memtag_stack: false,
318    },
319
320    static_libs: [
321        "liblinker_main",
322        "liblinker_malloc",
323
324        // We use a version of libc++ built without exceptions,
325        // because accessing EH globals uses ELF TLS,
326        // which is not supported in the loader.
327        "libc++_static_noexcept",
328
329        "libc_nomalloc",
330        "libc_dynamic_dispatch",
331        "libm",
332        "libunwind",
333    ],
334
335    system_shared_libs: [],
336
337    // Opt out of native_coverage when opting out of system_shared_libs
338    native_coverage: false,
339}
340
341// ========================================================
342// linker[_asan][64] binary
343// ========================================================
344
345cc_defaults {
346    name: "linker_binary_defaults",
347    defaults: [
348        "linker_bin_template",
349        "linker_version_script_overlay",
350    ],
351
352    srcs: [
353        "linker_translate_path.cpp",
354    ],
355
356    symlinks: ["linker_asan"],
357    arch: {
358        arm64: {
359            symlinks: ["linker_hwasan"],
360        },
361    },
362    multilib: {
363        lib64: {
364            suffix: "64",
365        },
366    },
367
368    compile_multilib: "both",
369
370    apex_available: [
371        "//apex_available:platform",
372        "com.android.runtime",
373    ],
374
375    target: {
376        android: {
377            srcs: [
378                "linker_debuggerd_android.cpp",
379            ],
380            static_libs: [
381                "libc++demangle_noexcept",
382                "libdebuggerd_handler_fallback",
383            ],
384        },
385        linux_bionic: {
386            static_libs: [
387                "liblinker_debuggerd_stub",
388            ],
389        },
390    },
391
392    afdo: true,
393}
394
395cc_binary {
396    name: "linker",
397    defaults: [
398        "linux_bionic_supported",
399        "linker_binary_defaults",
400    ],
401
402    vendor_ramdisk_available: true,
403}
404
405cc_binary {
406    name: "linker.recovery",
407    defaults: [
408        "linker_binary_defaults",
409    ],
410
411    recovery: true,
412    stem: "linker",
413}
414
415// ========================================================
416// assorted modules
417// ========================================================
418
419sh_binary {
420    name: "ldd",
421    src: "ldd.sh",
422}
423
424// Used to generate binaries that can be backed by transparent hugepages.
425cc_defaults {
426    name: "linker_hugepage_aligned",
427    arch: {
428        arm64: {
429            ldflags: ["-z max-page-size=0x200000"],
430        },
431        x86_64: {
432            ldflags: ["-z max-page-size=0x200000"],
433        },
434    },
435}
436
437cc_library {
438    srcs: ["ld_android.cpp"],
439    cflags: [
440        "-Wall",
441        "-Wextra",
442        "-Wunused",
443        "-Werror",
444    ],
445    stl: "none",
446
447    name: "ld-android",
448    defaults: [
449        "linux_bionic_supported",
450        "linker_version_script_overlay",
451    ],
452    ramdisk_available: true,
453    vendor_ramdisk_available: true,
454    recovery_available: true,
455    native_bridge_supported: true,
456
457    nocrt: true,
458    system_shared_libs: [],
459    header_libs: ["libc_headers"],
460
461    // Opt out of native_coverage when opting out of system_shared_libs
462    native_coverage: false,
463
464    sanitize: {
465        never: true,
466    },
467
468    apex_available: [
469        "//apex_available:platform",
470        "com.android.runtime",
471    ],
472}
473
474cc_test {
475    name: "linker-unit-tests",
476    test_suites: ["device-tests"],
477
478    cflags: [
479        "-g",
480        "-Wall",
481        "-Wextra",
482        "-Wunused",
483        "-Werror",
484    ],
485
486    // We need to access Bionic private headers in the linker.
487    include_dirs: ["bionic/libc"],
488
489    srcs: [
490        // Tests.
491        "linker_block_allocator_test.cpp",
492        "linker_config_test.cpp",
493        "linked_list_test.cpp",
494        "linker_note_gnu_property_test.cpp",
495        "linker_sleb128_test.cpp",
496        "linker_utils_test.cpp",
497        "linker_gnu_hash_test.cpp",
498        "linker_crt_pad_segment_test.cpp",
499
500        // Parts of the linker that we're testing.
501        ":elf_note_sources",
502        "linker_block_allocator.cpp",
503        "linker_config.cpp",
504        "linker_debug.cpp",
505        "linker_note_gnu_property.cpp",
506        "linker_test_globals.cpp",
507        "linker_utils.cpp",
508        "linker_phdr.cpp",
509        "linker_mapped_file_fragment.cpp",
510        "linker_sdk_versions.cpp",
511        "linker_dlwarning.cpp",
512        "linker_phdr_16kib_compat.cpp"
513    ],
514
515    static_libs: [
516        "libasync_safe",
517        "libbase",
518        "liblog_for_runtime_apex",
519        "libprocinfo", // For procinfo::MappedFileSize()
520    ],
521
522    data_libs: [
523        "crt_pad_segment_disabled",
524        "crt_pad_segment_enabled",
525        "no_crt_pad_segment",
526    ],
527
528    arch: {
529        arm: {
530            srcs: ["arch/arm_neon/linker_gnu_hash_neon.cpp"],
531        },
532        arm64: {
533            srcs: ["arch/arm_neon/linker_gnu_hash_neon.cpp"],
534        },
535    },
536}
537
538cc_benchmark {
539    name: "linker-benchmarks",
540
541    srcs: [
542        "linker_gnu_hash_benchmark.cpp",
543    ],
544
545    arch: {
546        arm: {
547            srcs: ["arch/arm_neon/linker_gnu_hash_neon.cpp"],
548        },
549        arm64: {
550            srcs: ["arch/arm_neon/linker_gnu_hash_neon.cpp"],
551        },
552    },
553}
554
555cc_fuzz {
556    name: "ElfReader_fuzzer",
557    srcs: [
558        "ElfReader_fuzzer.cpp",
559        "linker.cpp",
560        "linker_block_allocator.cpp",
561        "linker_debug.cpp",
562        "linker_dlwarning.cpp",
563        "linker_globals.cpp",
564        "linker_mapped_file_fragment.cpp",
565        "linker_phdr.cpp",
566        "linker_phdr_16kib_compat.cpp",
567        "linker_sdk_versions.cpp",
568        "linker_utils.cpp",
569        ":elf_note_sources",
570    ],
571    static_libs: [
572        "libasync_safe",
573        "libbase",
574        "libziparchive",
575    ],
576    include_dirs: ["bionic/libc"],
577    // TODO: use all the architectures' files.
578    // We'll either need to give them unique names across architectures,
579    // or change soong to preserve subdirectories in `corpus:`,
580    // and maybe also the [deprecated] LLVM fuzzer infrastructure?
581    corpus: [":bionic_prebuilt_test_elf_files_arm64"],
582}
583