tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cargo-linker (2707B)


      1 #!/usr/bin/env python3
      2 
      3 # If you want to use a custom linker with Cargo, Cargo requires that you
      4 # specify it in Cargo.toml or via the matching environment variable.
      5 # Passing extra options to the linker is possible with Cargo via
      6 # RUSTFLAGS='-C link-args', but testing showed that doing this reliably
      7 # was difficult.
      8 #
      9 # Our solution to these problems is to use this wrapper script.  We pass
     10 # in the LD and the LDFLAGS to use via environment variables.
     11 #
     12 # * MOZ_CARGO_WRAP_LD is equivalent to CC on Unix-y platforms, and CC
     13 #   frequently has additional arguments in addition to the compiler
     14 #   itself.
     15 #
     16 # * MOZ_CARGO_WRAP_LDFLAGS contains space-separated arguments to pass,
     17 #   and not quoting it ensures that each of those arguments is passed
     18 #   as a separate argument to the actual LD.
     19 #
     20 # * In rare cases, we also need MOZ_CARGO_WRAP_LD_CXX, which is the
     21 #   equivalent of CXX, when linking C++ code. Usually, this should
     22 #   simply work by the use of CC and -lstdc++ (added by cc-rs).
     23 #   However, in the case of sanitizer runtimes, there is a separate
     24 #   runtime for C and C++ and linking C++ code with the C runtime can
     25 #   fail if the requested feature is in the C++ runtime only (bug 1747298).
     26 
     27 import os
     28 import sys
     29 
     30 # This is not necessarily run with a virtualenv python, so add
     31 # the necessary directory for the mozshellutil module.
     32 base_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
     33 sys.path.insert(0, os.path.join(base_dir, "testing", "mozbase", "mozshellutil"))
     34 from mozshellutil import split
     35 
     36 
     37 SANITIZERS = {
     38     "asan": "address",
     39     "hwasan": "hwaddress",
     40     "lsan": "leak",
     41     "msan": "memory",
     42     "tsan": "thread",
     43 }
     44 
     45 use_clang_sanitizer = os.environ.get("MOZ_CLANG_NEWER_THAN_RUSTC_LLVM")
     46 wrap_ld = os.environ["MOZ_CARGO_WRAP_LD"]
     47 args = []
     48 for arg in sys.argv[1:]:
     49     if arg in ["-lc++", "-lstdc++"]:
     50         wrap_ld = os.environ["MOZ_CARGO_WRAP_LD_CXX"]
     51     elif use_clang_sanitizer and arg.endswith("san.a"):
     52         # When clang is newer than rustc's LLVM, we replace rust's sanitizer
     53         # runtimes with clang's.
     54         filename = os.path.basename(arg)
     55         prefix, dot, suffix = filename[:-2].rpartition(".")
     56         if (
     57             prefix.startswith("librustc-")
     58             and prefix.endswith("_rt") and dot == "."
     59         ):
     60             args.append(f"-fsanitize={SANITIZERS[suffix]}")
     61             continue
     62     args.append(arg)
     63 args.extend(split(os.environ["MOZ_CARGO_WRAP_LDFLAGS"]))
     64 
     65 wrap_ld = split(wrap_ld)
     66 if sys.platform == "win32":
     67     # For some reason, os.execvp doesn't handle arguments properly on Windows.
     68     import subprocess
     69     sys.exit(subprocess.run(wrap_ld + args).returncode)
     70 
     71 os.execvp(wrap_ld[0], wrap_ld + args)