diff --git a/zircon/public/gn/config/BUILD.gn b/zircon/public/gn/config/BUILD.gn index f7ccccbb3a8d7524326f3d41fdf5edb3d99dcf16..23665bc2dac386c1cd5d568a1f7c094c501b81d2 100644 --- a/zircon/public/gn/config/BUILD.gn +++ b/zircon/public/gn/config/BUILD.gn @@ -520,11 +520,17 @@ config("user_executable") { compiler_flags = [ "-fPIE" ] asmflags = compiler_flags cflags = compiler_flags - ldflags = compiler_flags - ldflags += [ - "-Wl,-pie", - "-Wl,-dynamic-linker,ld.so.1", - ] + ldflags = compiler_flags + [ "-Wl,-pie" ] + } else { + ldflags = [] + } + + # Specify the dynamic linker if building a variant that uses a separate + # set of libraries. With GCC, the dynamic linker must be explicit even + # in the default case because the compiler driver is not inherently + # configured for Fuchsia as it is in Clang. + if (is_gcc || toolchain.libprefix != "") { + ldflags += [ "-Wl,-dynamic-linker,${toolchain.libprefix}ld.so.1" ] } } diff --git a/zircon/public/gn/config/standard.gni b/zircon/public/gn/config/standard.gni index dd303222d567fa6b84ddba7fb64083e1c9a4174c..9ea36bf1f7bbefd61c36627f31dde31e17778f57 100644 --- a/zircon/public/gn/config/standard.gni +++ b/zircon/public/gn/config/standard.gni @@ -233,9 +233,6 @@ standard_variants = [ add = [ "$zx/system/core/devmgr:driver_deps.$name" ] }, ] - toolchain_vars = { - libprefix = "asan/" - } tags = [ "instrumented", "useronly", diff --git a/zircon/public/gn/toolchain/environment.gni b/zircon/public/gn/toolchain/environment.gni index 6acbdf2dfb6ae05197908d5ae30e4c4fcdd666f7..13ee1b9ba2309a9e16b45c582ede40503e455341 100644 --- a/zircon/public/gn/toolchain/environment.gni +++ b/zircon/public/gn/toolchain/environment.gni @@ -38,19 +38,21 @@ declare_args() { # Selector scope parameters # # * variant - # - Required: The variant to use when this selector matches. If this is a - # string then it must match a fully-defined variant elsewhere in the - # list (or in $default_variants + $standard_variants, which is appended - # implicitly to the $variants list). If it's a scope then it defines a - # new variant (see details below). + # - Required: The variant to use when this selector matches. If this + # is a string then it must match a fully-defined variant elsewhere in + # the list (or in $default_variants + $standard_variants, which is + # appended implicitly to the $variants list). If it's a scope then + # it defines a new variant (see details below). # - Type: string or scope, described below # # * cpu - # - Optional: If nonempty, match only when $current_cpu is one in the list. + # - Optional: If nonempty, match only when $current_cpu is one in the + # - list. # - Type: list(string) # # * os - # - Optional: If nonempty, match only when $current_os is one in the list. + # - Optional: If nonempty, match only when $current_os is one in the + # - list. # - Type: list(string) # # * host @@ -82,8 +84,9 @@ declare_args() { # - Type: list(string) # # * target_type - # - Optional: If nonempty, a list of target types to match. This is one of - # "executable", "host_tool", "loadable_module", "driver", or "test". + # - Optional: If nonempty, a list of target types to match. This is + # one of "executable", "host_tool", "loadable_module", "driver", or + # "test". # Note, test_driver() matches as "driver". # - Type: list(string) # @@ -106,9 +109,10 @@ declare_args() { # - Type: list(label_no_toolchain) # # * output_name - # - Optional: If nonempty, match only when the `output_name` of the target - # is one in the list. Note `output_name` defaults to `target_name`, - # and does not include prefixes or suffixes like ".so" or ".exe". + # - Optional: If nonempty, match only when the `output_name` of the + # target is one in the list. Note `output_name` defaults to + # `target_name`, and does not include prefixes or suffixes like ".so" + # or ".exe". # - Type: list(string) # # An element with a scope for `.variant` defines a new variant. Each @@ -297,14 +301,23 @@ declare_args() { # This is just like $toolchain_args passed to toolchain() in bare GN. # # * toolchain_vars -# - Optional: A scope imported into the $toolchain scope in these toolchains. -# This can store useful toolchain-specific variables that should be -# available within the toolchain. $toolchain automatically contains -# `tool_dir`, `tool_prefix`, `cc, and `cxx`, from c_toolchain(). -# If `variant_suffix` is defined here, terminal targets in the environment -# will have "$target_name$variant_suffix" aliases that get the same thing -# but in that particular variant installed under the suffixed name. -# The default `variant_suffix` is ".$variant" in each variant. +# - Optional: A scope imported into the $toolchain scope in these +# toolchains. This can store useful toolchain-specific variables that +# should be available within the toolchain. $toolchain automatically +# contains `tool_dir`, `tool_prefix`, `cc, and `cxx`, from +# c_toolchain(). If `variant_suffix` is defined here, terminal targets +# in the environment will have "$target_name$variant_suffix" aliases +# that get the same thing but in that particular variant installed +# under the suffixed name. The default `variant_suffix` is ".$variant" +# in each variant. +# +# * variant_libprefix +# - Optional: If true, each variant's name is used to form the +# ${toolchain.libprefix} value in that variant. The final libprefix +# is "${toolchain_vars.libprefix}${toolchain.variant}/". By default, +# this is true *only* in variants that have the "instrumented" tag. +# If explicitly set to true or false, that applies to *all* variants. +# - Type: bool # # * variant_selectors # - Optional: A list in the schema of the $variants build argument. This @@ -324,7 +337,7 @@ declare_args() { # .variant scope. If any of these strings appears in a .variant scope, # then $variant_selectors elements using that variant will be silently # ignored in this environment's toolchains. e.g. an environment that is -# incompatbile with instrumentation could list the "instrumentation" tag +# incompatbile with instrumentation could list the "instrumented" tag # and variants that enable instrumentation will be defined with that tag. # Then simple `variants=["asan"]` user configurations that would apply # ordinarily to all targets don't break the special-case execution @@ -905,15 +918,21 @@ template("environment") { # `variant`, so it can't be used any more in this block.) variant = variant.name + if (!defined(libprefix)) { + libprefix = "" + } + if ((defined(invoker.variant_libprefix) && + invoker.variant_libprefix) || + (!defined(invoker.variant_libprefix) && + tags + [ "instrumented" ] - [ "instrumented" ] != tags)) { + libprefix += "$variant/" + } + # Plumb through the suffix of this variant and the list of others. if (!defined(variant_suffix)) { variant_suffix = ".$variant" } - if (!defined(libprefix)) { - libprefix = "" - } - other_variants = [] foreach(other_variant, toolchain_variants) { if (other_variant.name != variant) { diff --git a/zircon/third_party/ulib/musl/ldso/BUILD.gn b/zircon/third_party/ulib/musl/ldso/BUILD.gn index 71b4c4da4c6ce47290fb42cc3e2be85e6f78d361..493979e284092e90e7c19d2b6793dfcf1f893450 100644 --- a/zircon/third_party/ulib/musl/ldso/BUILD.gn +++ b/zircon/third_party/ulib/musl/ldso/BUILD.gn @@ -13,4 +13,11 @@ source_set("ldso") { "dynlink-sancov.S", "dynlink.c", ] + if (toolchain.libprefix != "") { + # The libprefix always ends with a / but that's not part of the + # "config" string in the loader-service protocol. + ldsvc_config = get_path_info("${toolchain.libprefix}libfoo.so", "dir") + assert(ldsvc_config != "" && ldsvc_config != ".") + defines = [ "DYNLINK_LDSVC_CONFIG=\"$ldsvc_config\"" ] + } } diff --git a/zircon/third_party/ulib/musl/ldso/dynlink.c b/zircon/third_party/ulib/musl/ldso/dynlink.c index ee8d26fad677071df36a3922c76a3c93c73be54b..bf7248076762aa63200db9bcd158598bc22f9eec 100644 --- a/zircon/third_party/ulib/musl/ldso/dynlink.c +++ b/zircon/third_party/ulib/musl/ldso/dynlink.c @@ -2090,6 +2090,11 @@ __NO_SAFESTACK NO_ASAN static dl_start_return_t __dls3(void* start_arg) { __NO_SAFESTACK NO_ASAN static void early_init(void) { #if __has_feature(address_sanitizer) __asan_early_init(); +#endif +#ifdef DYNLINK_LDSVC_CONFIG + // Inform the loader service to look for libraries of the right variant. + loader_svc_config(DYNLINK_LDSVC_CONFIG); +#elif __has_feature(address_sanitizer) // Inform the loader service that we prefer ASan-supporting libraries. loader_svc_config("asan"); #endif