mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 00:32:11 +00:00
Bug 1839740 - Hook relrhack in the build system. r=firefox-build-system-reviewers,andi
Disabled by default for now. Differential Revision: https://phabricator.services.mozilla.com/D187090
This commit is contained in:
parent
90c8c29f23
commit
0971a7a2da
@ -1940,7 +1940,8 @@ def linker_ldflags_tmpl(host_or_target):
|
||||
linker_ldflags = linker_ldflags_tmpl(target)
|
||||
add_old_configure_assignment("LINKER_LDFLAGS", linker_ldflags)
|
||||
|
||||
add_old_configure_assignment("HOST_LINKER_LDFLAGS", linker_ldflags_tmpl(host))
|
||||
host_linker_ldflags = linker_ldflags_tmpl(host)
|
||||
add_old_configure_assignment("HOST_LINKER_LDFLAGS", host_linker_ldflags)
|
||||
|
||||
|
||||
# There's a wrinkle with MinGW: linker configuration is not enabled, so
|
||||
|
@ -209,6 +209,12 @@ netwerk/test/http3server/target: security/target
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef RELRHACK
|
||||
# When building with RELR-based ELF hack, we need to build the relevant parts
|
||||
# before any target.
|
||||
$(filter %/target,$(compile_targets)): build/unix/elfhack/host build/unix/elfhack/inject/target-objects
|
||||
endif
|
||||
|
||||
ifdef MOZ_USING_WASM_SANDBOXING
|
||||
security/rlbox/pre-compile: config/external/wasm2c_sandbox_compiler/host
|
||||
dom/media/ogg/target-objects extensions/spellcheck/hunspell/glue/target-objects gfx/thebes/target-objects parser/expat/target-objects parser/htmlparser/target-objects gfx/ots/src/target-objects dom/media/target-objects dom/media/mediasink/target-objects: security/rlbox/pre-compile
|
||||
|
@ -523,7 +523,7 @@ endif
|
||||
$(SHARED_LIBRARY): $(OBJS) $(call resfile,$(SHARED_LIBRARY)) $(STATIC_LIBS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
$(RM) $@
|
||||
$(MKSHLIB) $($@_OBJS) $(filter %.res,$^) $(LDFLAGS) $(STATIC_LIBS) $(SHARED_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS)
|
||||
$(MKSHLIB) $($@_OBJS) $(filter %.res,$^) $(RELRHACK_LDFLAGS) $(LDFLAGS) $(STATIC_LIBS) $(SHARED_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS)
|
||||
$(call py_action,check_binary,$@)
|
||||
|
||||
ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
|
||||
|
@ -160,8 +160,8 @@ class TestToolkitMozConfigure(BaseConfigureTest):
|
||||
|
||||
return (
|
||||
sandbox._value_for(sandbox["select_linker"]).KIND,
|
||||
sandbox._value_for(sandbox["pack_relative_relocs"]),
|
||||
sandbox._value_for(sandbox["use_elf_hack"]),
|
||||
sandbox._value_for(sandbox["pack_relative_relocs_flags"]),
|
||||
sandbox._value_for(sandbox["which_elf_hack"]),
|
||||
)
|
||||
|
||||
PACK = ["-Wl,-z,pack-relative-relocs"]
|
||||
@ -181,17 +181,36 @@ class TestToolkitMozConfigure(BaseConfigureTest):
|
||||
):
|
||||
self.assertEqual(get_values(mockcc, readelf), ("lld", None, None))
|
||||
self.assertEqual(
|
||||
get_values(mockcc, readelf, ["--enable-release"]), ("bfd", None, True)
|
||||
get_values(mockcc, readelf, ["--enable-release"]),
|
||||
("bfd", None, "legacy"),
|
||||
)
|
||||
# LLD is picked by default and enabling elfhack fails because of that.
|
||||
with self.assertRaises(SystemExit):
|
||||
get_values(mockcc, readelf, ["--enable-elf-hack"])
|
||||
with self.assertRaises(SystemExit):
|
||||
get_values(mockcc, readelf, ["--enable-elf-hack=legacy"])
|
||||
if readelf.with_relr:
|
||||
# Explicitly enabling relrhack works because pack-relative-relocs are supported.
|
||||
self.assertEqual(
|
||||
get_values(mockcc, readelf, ["--enable-elf-hack=relr"]),
|
||||
("lld", None, "relr"),
|
||||
)
|
||||
else:
|
||||
# relrhack doesn't work without pack-relative-relocs support.
|
||||
with self.assertRaises(SystemExit):
|
||||
get_values(mockcc, readelf, ["--enable-elf-hack=relr"])
|
||||
# If we force to use BFD ld, it works.
|
||||
self.assertEqual(
|
||||
get_values(
|
||||
mockcc, readelf, ["--enable-elf-hack", "--enable-linker=bfd"]
|
||||
),
|
||||
("bfd", None, True),
|
||||
("bfd", None, "legacy"),
|
||||
)
|
||||
self.assertEqual(
|
||||
get_values(
|
||||
mockcc, readelf, ["--enable-elf-hack=legacy", "--enable-linker=bfd"]
|
||||
),
|
||||
("bfd", None, "legacy"),
|
||||
)
|
||||
|
||||
# Linker supports pack-relative-relocs, and glibc too. We use pack-relative-relocs
|
||||
@ -205,10 +224,23 @@ class TestToolkitMozConfigure(BaseConfigureTest):
|
||||
# LLD is picked by default and enabling elfhack fails because of that.
|
||||
with self.assertRaises(SystemExit):
|
||||
get_values(mockcc, readelf, ["--enable-elf-hack"])
|
||||
with self.assertRaises(SystemExit):
|
||||
get_values(mockcc, readelf, ["--enable-elf-hack=legacy"])
|
||||
# If we force to use BFD ld, it works.
|
||||
self.assertEqual(
|
||||
get_values(mockcc, readelf, ["--enable-elf-hack", "--enable-linker=bfd"]),
|
||||
("bfd", None, True),
|
||||
("bfd", None, "legacy"),
|
||||
)
|
||||
self.assertEqual(
|
||||
get_values(
|
||||
mockcc, readelf, ["--enable-elf-hack=legacy", "--enable-linker=bfd"]
|
||||
),
|
||||
("bfd", None, "legacy"),
|
||||
)
|
||||
# Explicitly enabling relrhack works because pack-relative-relocs are supported.
|
||||
self.assertEqual(
|
||||
get_values(mockcc, readelf, ["--enable-elf-hack=relr"]),
|
||||
("lld", None, "relr"),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1497,36 +1497,38 @@ with only_when("--enable-compile-environment"):
|
||||
and target.cpu in ("arm", "aarch64", "x86", "x86_64")
|
||||
)
|
||||
|
||||
@depends("--enable-release", enable_linker)
|
||||
def default_elfhack(release, linker):
|
||||
# Disable elfhack when explicitly building with --enable-linker=lld
|
||||
if linker and linker.origin != "default" and linker[0] in ("lld", "mold"):
|
||||
return False
|
||||
return bool(release)
|
||||
|
||||
option(
|
||||
"--disable-elf-hack",
|
||||
default=default_elfhack,
|
||||
nargs="?",
|
||||
choices=("legacy", "relr"),
|
||||
help="{Enable|Disable} elf hacks",
|
||||
when=has_elfhack,
|
||||
)
|
||||
|
||||
@depends("--enable-elf-hack", when=has_elfhack)
|
||||
def may_enable_legacy_elfhack(enable):
|
||||
if enable and enable != ("relr",):
|
||||
return enable
|
||||
|
||||
@depends("--enable-elf-hack", when=has_elfhack)
|
||||
def may_enable_relrhack(enable):
|
||||
# For now, only enable relrhack when explicitly given with
|
||||
# --enable-elf-hack=relr
|
||||
if enable == ("relr",):
|
||||
return enable
|
||||
|
||||
@depends(
|
||||
have_arc4random,
|
||||
android_version,
|
||||
depends("--enable-elf-hack", when=has_elfhack)(lambda x: x),
|
||||
when=target_has_linux_kernel,
|
||||
)
|
||||
def may_use_pack_relative_relocs(have_arc4random, android_version, elfhack):
|
||||
def may_use_pack_relative_relocs(have_arc4random, android_version):
|
||||
# Packed relative relocations are only supported on Android since
|
||||
# version 11 (API 30), and in glibc since version 2.36.
|
||||
# glibc 2.36 also added the arc4random function, which is our proxy
|
||||
# to detect this (or newer) version being used.
|
||||
# When targetting those newer versions, we allow ourselves to use
|
||||
# packed relative relocations rather than elfhack. We still prefer
|
||||
# elfhack when explicitly enabled.
|
||||
if elfhack and elfhack.origin != "default":
|
||||
return False
|
||||
# packed relative relocations rather than elfhack.
|
||||
if android_version:
|
||||
return android_version >= 30
|
||||
return have_arc4random
|
||||
@ -1536,14 +1538,14 @@ with only_when("--enable-compile-environment"):
|
||||
extra_toolchain_flags,
|
||||
linker_ldflags,
|
||||
readelf,
|
||||
when=may_use_pack_relative_relocs,
|
||||
when=may_use_pack_relative_relocs | may_enable_relrhack,
|
||||
)
|
||||
@checking("for -z pack-relative-relocs option to ld", bool)
|
||||
@imports(_from="__builtin__", _import="FileNotFoundError")
|
||||
@imports("os")
|
||||
@imports(_from="tempfile", _import="mkstemp")
|
||||
@imports("textwrap")
|
||||
def pack_relative_relocs(
|
||||
def has_pack_relative_relocs(
|
||||
c_compiler,
|
||||
extra_toolchain_flags,
|
||||
linker_ldflags,
|
||||
@ -1603,28 +1605,125 @@ with only_when("--enable-compile-environment"):
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
add_old_configure_assignment("PACK_REL_RELOC_FLAGS", pack_relative_relocs)
|
||||
@depends(
|
||||
has_pack_relative_relocs,
|
||||
may_enable_legacy_elfhack,
|
||||
may_enable_relrhack,
|
||||
may_use_pack_relative_relocs,
|
||||
when=has_pack_relative_relocs,
|
||||
)
|
||||
def pack_relative_relocs_flags(
|
||||
flags,
|
||||
may_enable_legacy_elfhack,
|
||||
may_enable_relrhack,
|
||||
may_use_pack_relative_relocs,
|
||||
):
|
||||
# When relrhack is enabled, we don't pass the flag to the linker because
|
||||
# relrhack will take care of it.
|
||||
if may_enable_relrhack and may_enable_relrhack.origin != "default":
|
||||
return None
|
||||
# if elfhack is explicitly enabled instead of relrhack, we prioritize it
|
||||
# over packed relative relocs.
|
||||
if may_enable_legacy_elfhack and may_enable_legacy_elfhack.origin != "default":
|
||||
return None
|
||||
if may_use_pack_relative_relocs:
|
||||
return flags
|
||||
|
||||
add_old_configure_assignment("PACK_REL_RELOC_FLAGS", pack_relative_relocs_flags)
|
||||
|
||||
@depends(
|
||||
select_linker,
|
||||
pack_relative_relocs,
|
||||
"--enable-elf-hack",
|
||||
pack_relative_relocs_flags,
|
||||
has_pack_relative_relocs,
|
||||
may_enable_legacy_elfhack,
|
||||
may_enable_relrhack,
|
||||
when=has_elfhack,
|
||||
)
|
||||
def use_elf_hack(linker, pack_relative_relocs, elfhack):
|
||||
if elfhack:
|
||||
# If elfhack was not manually enabled and packed relative relocations
|
||||
# can be used, then don't enable elfhack even if it would normally have.
|
||||
if elfhack.origin == "default" and pack_relative_relocs:
|
||||
return
|
||||
if linker and linker.KIND == "lld":
|
||||
def which_elf_hack(
|
||||
linker,
|
||||
pack_relative_relocs_flags,
|
||||
has_pack_relative_relocs,
|
||||
may_enable_legacy_elfhack,
|
||||
may_enable_relrhack,
|
||||
):
|
||||
if pack_relative_relocs_flags:
|
||||
return
|
||||
if may_enable_relrhack:
|
||||
if has_pack_relative_relocs:
|
||||
return "relr"
|
||||
elif (
|
||||
may_enable_relrhack.origin != "default"
|
||||
and not may_enable_legacy_elfhack
|
||||
):
|
||||
die(
|
||||
"Cannot enable elfhack with lld."
|
||||
" Use --enable-linker=bfd, --enable-linker=gold, or --disable-elf-hack"
|
||||
"Cannot enable relrhack without linker support for -z pack-relative-relocs"
|
||||
)
|
||||
return True
|
||||
if may_enable_legacy_elfhack:
|
||||
if linker and linker.KIND in ("lld", "mold"):
|
||||
if may_enable_legacy_elfhack.origin != "default":
|
||||
die(
|
||||
f"Cannot enable elfhack with {linker.KIND}."
|
||||
" Use --enable-linker=bfd, --enable-linker=gold, or --disable-elf-hack"
|
||||
)
|
||||
else:
|
||||
return "legacy"
|
||||
|
||||
set_config("USE_ELF_HACK", use_elf_hack)
|
||||
set_config(
|
||||
"USE_ELF_HACK", True, when=depends(which_elf_hack)(lambda x: x == "legacy")
|
||||
)
|
||||
|
||||
use_relrhack = depends(which_elf_hack)(lambda x: x == "relr")
|
||||
set_config("RELRHACK", True, when=use_relrhack)
|
||||
|
||||
@depends(c_compiler, linker_ldflags, when=use_relrhack)
|
||||
def relrhack_real_linker(c_compiler, linker_ldflags):
|
||||
ld = "ld"
|
||||
for flag in linker_ldflags:
|
||||
if flag.startswith("-fuse-ld="):
|
||||
ld = "ld." + flag[len("-fuse-ld=") :]
|
||||
ld = check_cmd_output(
|
||||
c_compiler.compiler, f"--print-prog-name={ld}", *c_compiler.flags
|
||||
)
|
||||
return ld.rstrip()
|
||||
|
||||
@depends(relrhack_real_linker, when=use_relrhack)
|
||||
def relrhack_linker(ld):
|
||||
return os.path.basename(ld)
|
||||
|
||||
set_config("RELRHACK_LINKER", relrhack_linker)
|
||||
|
||||
std_filesystem = host_cxx_compiler.try_run(
|
||||
header="#include <filesystem>",
|
||||
body='auto foo = std::filesystem::absolute("");',
|
||||
flags=host_linker_ldflags,
|
||||
when=use_relrhack,
|
||||
onerror=lambda: None,
|
||||
)
|
||||
|
||||
stdcxxfs = host_cxx_compiler.try_run(
|
||||
header="#include <filesystem>",
|
||||
body='auto foo = std::filesystem::absolute("");',
|
||||
flags=depends(host_linker_ldflags)(
|
||||
lambda flags: (flags or []) + ["-lstdc++fs"]
|
||||
),
|
||||
check_msg="whether std::filesystem requires -lstdc++fs",
|
||||
when=use_relrhack & depends(std_filesystem)(lambda x: not x),
|
||||
onerror=lambda: None,
|
||||
)
|
||||
|
||||
set_config("RELRHACK_LIBS", ["stdc++fs"], when=stdcxxfs)
|
||||
|
||||
@depends(build_environment, relrhack_real_linker, when=use_relrhack)
|
||||
def relrhack_ldflags(build_env, ld):
|
||||
flags = [
|
||||
"-B",
|
||||
os.path.join(build_env.topobjdir, "build", "unix", "elfhack"),
|
||||
]
|
||||
if os.path.basename(ld) != ld:
|
||||
flags.append(f"-Wl,--real-linker,{ld}")
|
||||
return flags
|
||||
|
||||
set_config("RELRHACK_LDFLAGS", relrhack_ldflags)
|
||||
|
||||
|
||||
@depends(build_environment)
|
||||
|
Loading…
Reference in New Issue
Block a user