[clang] Add support for dynamic libraries in CLANG_BOLT (PR #127020)

via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 20 05:50:52 PST 2025


================
@@ -574,47 +591,67 @@ def bolt_optimize(args):
 
     opts = parser.parse_args(args)
 
-    output = subprocess.check_output(
-        [opts.readelf, "-WS", opts.input], universal_newlines=True
-    )
+    inputs = opts.input.split(";")
+    instrumented_outputs = opts.instrumented_output.split(";")
+    assert len(inputs) == len(
+        instrumented_outputs
+    ), "inconsistent --input / --instrumented-output arguments"
 
-    # This binary has already been bolt-optimized, so skip further processing.
-    if re.search("\\.bolt\\.org\\.text", output, re.MULTILINE):
+    inputs, instrumented_outputs = filter_bolt_optimized(inputs, instrumented_outputs)
+    if not inputs:
         return 0
 
+    environ = os.environ.copy()
     if opts.method == "INSTRUMENT":
-        process = subprocess.run(
-            [
+        preloads = []
+        for input, instrumented_output in zip(inputs, instrumented_outputs):
+            args = [
                 opts.bolt,
-                opts.input,
+                input,
                 "-o",
-                opts.instrumented_output,
+                instrumented_output,
                 "-instrument",
                 "--instrumentation-file-append-pid",
                 f"--instrumentation-file={opts.fdata}",
-            ],
-            stdout=subprocess.PIPE,
-            stderr=subprocess.STDOUT,
-            text=True,
-        )
+            ]
+            print("Running: " + " ".join(args))
+            process = subprocess.run(
+                args,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.STDOUT,
+                text=True,
+            )
 
-        print(process.args)
-        for line in process.stdout:
-            sys.stdout.write(line)
-        process.check_returncode()
+            for line in process.stdout:
+                sys.stdout.write(line)
+            process.check_returncode()
 
+            output = subprocess.check_output(
+                [opts.readelf, "--file-header", input], universal_newlines=True
+            )
+            if re.search(r"Type:\s*((Shared)|(DYN))", output):
+                # force using the instrumented version
+                preloads.append(instrumented_output)
+
+        if preloads:
+            print("Patching execution environment for dynamic library")
+            environ["LD_PRELOAD"] = os.pathsep.join(preloads)
----------------
serge-sans-paille wrote:

The instrumented binary is still linked to the non-instrumented libraries. `LD_PRELOAD` makes sure we use symbol from the instrumented libraries instead.

https://github.com/llvm/llvm-project/pull/127020


More information about the cfe-commits mailing list