Commit 3ed7301e authored by Nelson Billing's avatar Nelson Billing Committed by Commit Bot

Implement DWARF Fission support in Chrome Android.

- This is a fixed version of
https://chromium-review.googlesource.com/c/chromium/src/+/1995743
which was reverted because it caused a build failure for ToTLinux.
-Build failure in ToTLinux is fixed by only adding "--generate-dwp" for
the Android toolchain when building for Android OS.
- Modify some compiler build definitions to allow symbol_level=2 with
Chrome Android 32bit, and to make the build respect use_debug_fission in
those cases.
- Modify "link" and "solink" tools in Android toolchain so that DWP
files can be generated for builds with use_debug_fission.
- Modify partitioned_shared_library template/script so that DWP files
can be generated for partitioned libs when use_debug_fission is set.

Change-Id: I7f023de42e46aca1e8c56c9edf3858617e2ab5ad

Cq-Include-Trybots: chromium/try:mac_chromium_asan_rel_ng
Cq-Include-Trybots: chromium/try:linux_chromium_cfi_rel_ng
Cq-Include-Trybots: chromium/try:linux_chromium_chromeos_asan_rel_ng
Cq-Include-Trybots: chromium/try:linux_chromium_msan_rel_ng
Cq-Include-Trybots: chromium/try:linux_chromium_chromeos_msan_rel_ng
Cq-Include-Trybots: chromium/try:linux-chromeos-dbg,win-asan
Cq-Include-Trybots: chromium/try:chromeos-amd64-generic-cfi-thin-lto-rel
Cq-Include-Trybots: chromium/try:linux_chromium_compile_dbg_32_ng
Cq-Include-Trybots: chromium/try:win7-rel,win-angle-deqp-rel-32
Cq-Include-Trybots: chromium/try:linux_angle_deqp_rel_ng
Cq-Include-Trybots: chromium/try:win-angle-deqp-rel-64
Cq-Include-Trybots: chromium/try:dawn-win10-x86-deps-rel
Cq-Include-Trybots: chrome/try:linux-chromeos-chrome
Cq-Include-Trybots: chrome/try:mac-chrome
Change-Id: I7f023de42e46aca1e8c56c9edf3858617e2ab5ad
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2330810
Commit-Queue: Nelson Billing <nbilling@google.com>
Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Cr-Commit-Position: refs/heads/master@{#801271}
parent 163a87b7
......@@ -2317,10 +2317,12 @@ config("symbols") {
swiftflags = [ "-g" ]
}
if (use_debug_fission && !is_nacl && !is_android) {
if (use_debug_fission && !is_nacl &&
(!is_android || target_os == "android")) {
# NOTE: Some Chrome OS builds globally set |use_debug_fission| to true,
# but they also build some targets against Android toolchains which aren't
# compatible with it.
# but they also build some targets whose toolchains aren't
# compatible with it. In particular don't turn it on for Android
# toolchain if not building for Android OS.
#
# TODO(https://crbug.com/837032): See if we can clean this up by e.g. not
# setting use_debug_fission globally.
......@@ -2329,6 +2331,16 @@ config("symbols") {
asmflags = cflags
ldflags = []
if (use_debug_fission && is_android && target_os == "android") {
# NOTE: This flag is for use by the link wrapper scripts. They are also
# expected to remove it before sending the rest of ldflags to the actual
# linker. Only expect Android Chrome build on Android OS to need this.
ldflags += [
"--generate-dwp",
"-gsplit-dwarf",
]
}
# TODO(thakis): Figure out if there's a way to make this go for 32-bit,
# currently we get "warning:
# obj/native_client/src/trusted/service_runtime/sel_asm/nacl_switch_32.o:
......
......@@ -194,8 +194,8 @@ declare_args() {
!use_lld && !(is_chromecast && is_linux &&
(current_cpu == "arm" || current_cpu == "mipsel")) &&
((is_linux && (current_cpu == "x64" || current_cpu == "x86" ||
current_cpu == "arm" || current_cpu == "arm64" ||
current_cpu == "mipsel" || current_cpu == "mips64el")) ||
current_cpu == "arm" || current_cpu == "arm64" ||
current_cpu == "mipsel" || current_cpu == "mips64el")) ||
(is_android && (current_cpu == "x86" || current_cpu == "x64" ||
current_cpu == "arm" || current_cpu == "arm64")))
}
......@@ -210,8 +210,8 @@ declare_args() {
# deterministic builds to reduce compile times, so this is less relevant for
# official builders.
strip_absolute_paths_from_debug_symbols_default =
is_android || is_fuchsia || is_nacl || (is_win && use_lld) || is_linux || is_chromeos ||
(is_mac && !enable_dsyms) || ios_use_goma_rbe
is_android || is_fuchsia || is_nacl || (is_win && use_lld) || is_linux ||
is_chromeos || (is_mac && !enable_dsyms) || ios_use_goma_rbe
# If the platform uses stripped absolute paths by default, then we don't expose
# it as a configuration option. If this is causing problems, please file a bug.
......@@ -226,7 +226,8 @@ if (strip_absolute_paths_from_debug_symbols_default) {
# If it wasn't manually set, set to an appropriate default.
assert(symbol_level >= -1 && symbol_level <= 2, "Invalid symbol_level")
if (symbol_level == -1) {
if (is_android && !is_component_build) {
if (is_android && !is_component_build &&
!(use_debug_fission != "default" && use_debug_fission)) {
# Reduce symbol level when it will cause invalid elf files to be created
# (due to file size). https://crbug.com/648948.
symbol_level = 1
......@@ -247,8 +248,9 @@ if (symbol_level == -1) {
# info or variable info, so we can leave that out to speed up the build.
# Sanitizers also require symbols for filename suppressions to work.
symbol_level = 1
} else if ((!is_nacl && !is_linux && !is_chromeos && !is_fuchsia && current_os != "aix") ||
is_debug || is_official_build || is_chromecast) {
} else if ((!is_nacl && !is_linux && !is_chromeos && !is_fuchsia &&
current_os != "aix") || is_debug || is_official_build ||
is_chromecast) {
# Linux builds slower by having symbols as part of the target binary,
# whereas Mac and Windows have them separate, so in Release Linux, default
# them off, but keep them on for Official builds and Chromecast builds.
......@@ -273,9 +275,11 @@ if (forbid_non_component_debug_builds) {
# Assert that the configuration isn't going to hit https://crbug.com/648948.
# An exception is made when target_os == "chromeos" as we only use the Android
# toolchain there to build relatively small binaries.
assert(ignore_elf32_limitations || !is_android || target_os == "chromeos" ||
is_component_build || symbol_level < 2,
"Android 32-bit non-component builds cannot have symbol_level=2 " +
"due to 4GiB file size limit, see https://crbug.com/648948. " +
"If you really want to try this out, " +
"set ignore_elf32_limitations=true.")
assert(
ignore_elf32_limitations || !is_android || target_os == "chromeos" ||
is_component_build || symbol_level < 2 ||
(use_debug_fission != "default" && use_debug_fission),
"Android 32-bit non-component builds without DWARF Fission cannot " +
"have symbol_level=2 due to 4GiB file size limit, see " +
"https://crbug.com/648948. " + "If you really want to try this out, " +
"set ignore_elf32_limitations=true.")
......@@ -30,6 +30,7 @@ def main():
required=True,
help='Stripped output file',
metavar='FILE')
parser.add_argument('--dwp', help='Path to dwp binary', metavar='FILE')
parser.add_argument('input', help='Input file')
args = parser.parse_args()
......@@ -46,6 +47,13 @@ def main():
]
subprocess.check_call(objcopy_args)
if args.dwp:
dwp_args = [
args.dwp, '-e', args.unstripped_output, '-o',
args.stripped_output + '.dwp'
]
subprocess.check_call(dwp_args)
if __name__ == '__main__':
sys.exit(main())
......@@ -3,7 +3,9 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/android/config.gni")
import("//build/config/clang/clang.gni")
import("//build/config/compiler/compiler.gni")
# This template creates a set of shared libraries, by linking a single
# "partitioned" shared library, then splitting it into multiple pieces.
......@@ -97,6 +99,16 @@ template("partitioned_shared_library") {
"${invoker.partition}",
]
}
# Restrict to Android OS because ChromeOS uses the Android toolchain with
# use_debug_fission set globally, which isn't reliable across all
# possible build configs with Android.
if (is_android && target_os == "android" &&
use_debug_fission != "default" && use_debug_fission) {
dwp = rebase_path("${android_tool_prefix}dwp", root_build_dir)
args += [ "--dwp=${dwp}" ]
outputs += [ invoker.stripped_output + ".dwp" ]
}
args += [ rebase_path(sources[0], root_build_dir) ]
}
}
......
......@@ -42,6 +42,7 @@ template("android_clang_toolchain") {
ld = cxx
readelf = _tool_prefix + "readelf"
nm = _tool_prefix + "nm"
dwp = _tool_prefix + "dwp"
strip = rebase_path("//buildtools/third_party/eu-strip/bin/eu-strip",
root_build_dir)
use_unstripped_as_runtime_outputs = android_unstripped_runtime_outputs
......
......@@ -45,6 +45,7 @@ def main():
help=('Use --Wl,-Map to generate a map file. Will be '
'gzipped if extension ends with .gz'),
metavar='FILE')
parser.add_argument('--dwp', help=('The dwp binary to run'), metavar='FILE')
parser.add_argument('--output',
required=True,
help='Final output executable file',
......@@ -53,6 +54,10 @@ def main():
help='Linking command')
args = parser.parse_args()
generate_dwp = '--generate-dwp' in args.command
if generate_dwp:
args.command.remove('--generate-dwp')
# Work-around for gold being slow-by-default. http://crbug.com/632230
fast_env = dict(os.environ)
fast_env['LC_ALL'] = 'C'
......@@ -61,12 +66,29 @@ def main():
if result != 0:
return result
# If dwp is set, then package debug info for this exe.
dwp_proc = None
if generate_dwp:
if not args.dwp:
parser.error('--generate-dwp requireds --dwp')
exe_file = args.output
if args.unstripped_file:
exe_file = args.unstripped_file
dwp_proc = subprocess.Popen(
wrapper_utils.CommandToRun(
[args.dwp, '-e', exe_file, '-o', args.output + '.dwp']))
# Finally, strip the linked executable (if desired).
if args.strip:
result = subprocess.call(CommandToRun([
args.strip, '-o', args.output, args.unstripped_file
]))
if dwp_proc:
dwp_result = dwp_proc.wait()
if dwp_result != 0:
return dwp_result
return result
......
......@@ -93,6 +93,7 @@ def main():
parser.add_argument('--strip',
help='The strip binary to run',
metavar='PATH')
parser.add_argument('--dwp', help='The dwp binary to run', metavar='PATH')
parser.add_argument('--sofile',
required=True,
help='Shared object file produced by linking command',
......@@ -121,6 +122,16 @@ def main():
# https://crbug.com/954311 tracks finding a better way to plumb these.
link_only = InterceptFlag('--link-only', args.command)
collect_inputs_only = InterceptFlag('--collect-inputs-only', args.command)
generate_dwp = InterceptFlag('--generate-dwp', args.command)
# First, run the actual link.
command = wrapper_utils.CommandToRun(args.command)
result = wrapper_utils.RunLinkWithOptionalMapFile(command,
env=fast_env,
map_file=args.map_file)
if result != 0:
return result
# If only linking, we are likely generating a partitioned .so that will be
# split apart later. In that case:
......@@ -158,6 +169,15 @@ def main():
if result != 0 or link_only:
return result
# If dwp is set, then package debug info for this SO.
dwp_proc = None
if generate_dwp:
if not args.dwp:
parser.error('--generate-dwp requireds --dwp')
dwp_proc = subprocess.Popen(
wrapper_utils.CommandToRun(
[args.dwp, '-e', args.sofile, '-o', args.output + '.dwp']))
# Next, generate the contents of the TOC file.
result, toc = CollectTOC(args)
if result != 0:
......@@ -172,6 +192,11 @@ def main():
result = subprocess.call(wrapper_utils.CommandToRun(
[args.strip, '-o', args.output, args.sofile]))
if dwp_proc:
dwp_result = dwp_proc.wait()
if dwp_result != 0:
return dwp_result
return result
......
......@@ -237,6 +237,11 @@ template("gcc_toolchain") {
} else {
nm = "nm"
}
if (defined(invoker.dwp)) {
dwp = invoker.dwp
} else {
dwp = "dwp"
}
if (defined(invoker.shlib_extension)) {
default_shlib_extension = invoker.shlib_extension
......@@ -398,7 +403,7 @@ template("gcc_toolchain") {
# The host might not have a POSIX shell and utilities (e.g. Windows).
solink_wrapper =
rebase_path("//build/toolchain/gcc_solink_wrapper.py", root_build_dir)
command = "$python_path \"$solink_wrapper\" --readelf=\"$readelf\" --nm=\"$nm\" $strip_switch--sofile=\"$unstripped_sofile\" --tocfile=\"$tocfile\"$map_switch --output=\"$sofile\" -- $link_command"
command = "$python_path \"$solink_wrapper\" --readelf=\"$readelf\" --nm=\"$nm\" $strip_switch--dwp=\"${dwp}\" --sofile=\"$unstripped_sofile\" --tocfile=\"$tocfile\"$map_switch --output=\"$sofile\" -- $link_command"
if (target_cpu == "mipsel" && is_component_build && is_android) {
rspfile_content = "-Wl,--start-group -Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}} -Wl,--end-group"
......@@ -528,13 +533,9 @@ template("gcc_toolchain") {
strip_switch = " --strip=\"${invoker.strip}\" --unstripped-file=\"$unstripped_outfile\""
}
if (strip_switch != "" || map_switch != "") {
link_wrapper =
rebase_path("//build/toolchain/gcc_link_wrapper.py", root_build_dir)
command = "$python_path \"$link_wrapper\" --output=\"$outfile\"$strip_switch$map_switch -- $link_command"
} else {
command = link_command
}
link_wrapper =
rebase_path("//build/toolchain/gcc_link_wrapper.py", root_build_dir)
command = "$python_path \"$link_wrapper\" --output=\"$outfile\"$strip_switch$map_switch --dwp=\"${dwp}\" -- $link_command"
description = "LINK $outfile"
rspfile_content = "{{inputs}}"
......@@ -596,6 +597,7 @@ template("clang_toolchain") {
readelf = "${toolprefix}readelf"
ar = "${prefix}/llvm-ar"
nm = "${toolprefix}nm"
dwp = "${toolprefix}dwp"
forward_variables_from(invoker,
[
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment