Rework how linux_bionic is built with LLD
In order to simplify the wrapper function, and stop using a linker
script, generate a set of flags to pass to LLD. Then run
host_bionic_inject on the linked binary in order to verify the
embedding, and give the wrapper function the address of the original
entry point (_start).
Bug: 31559095
Test: build host bionic with prebuilts/build-tools/build-prebuilts.sh
Change-Id: I53e326050e0f9caa562c6cf6f76c4d0337bb6faf
diff --git a/cc/binary.go b/cc/binary.go
index 5fa501e..15db2ad 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -15,6 +15,8 @@
package cc
import (
+ "github.com/google/blueprint"
+
"android/soong/android"
)
@@ -154,7 +156,8 @@
}
if ctx.Os() == android.LinuxBionic && !binary.static() {
- deps.LinkerScript = "host_bionic_linker_script"
+ deps.DynamicLinker = "linker"
+ deps.LinkerFlagsFile = "host_bionic_linker_flags"
}
}
@@ -244,14 +247,23 @@
switch ctx.Os() {
case android.Android:
flags.DynamicLinker = "/system/bin/linker"
+ if flags.Toolchain.Is64Bit() {
+ flags.DynamicLinker += "64"
+ }
case android.LinuxBionic:
flags.DynamicLinker = ""
default:
ctx.ModuleErrorf("unknown dynamic linker")
}
- if flags.Toolchain.Is64Bit() {
- flags.DynamicLinker += "64"
- }
+ }
+
+ if ctx.Os() == android.LinuxBionic {
+ // Use the dlwrap entry point, but keep _start around so
+ // that it can be used by host_bionic_inject
+ flags.LdFlags = append(flags.LdFlags,
+ "-Wl,--entry=__dlwrap__start",
+ "-Wl,--undefined=_start",
+ )
}
}
@@ -262,7 +274,6 @@
"-Wl,--gc-sections",
"-Wl,-z,nocopyreloc",
)
-
}
} else {
if binary.static() {
@@ -288,13 +299,15 @@
sharedLibs := deps.SharedLibs
sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
- if deps.LinkerScript.Valid() {
- flags.LdFlags = append(flags.LdFlags, "-Wl,-T,"+deps.LinkerScript.String())
- linkerDeps = append(linkerDeps, deps.LinkerScript.Path())
+ if deps.LinkerFlagsFile.Valid() {
+ flags.LdFlags = append(flags.LdFlags, "$$(cat "+deps.LinkerFlagsFile.String()+")")
+ linkerDeps = append(linkerDeps, deps.LinkerFlagsFile.Path())
}
if flags.DynamicLinker != "" {
- flags.LdFlags = append(flags.LdFlags, " -Wl,-dynamic-linker,"+flags.DynamicLinker)
+ flags.LdFlags = append(flags.LdFlags, "-Wl,-dynamic-linker,"+flags.DynamicLinker)
+ } else if ctx.toolchain().Bionic() && !binary.static() {
+ flags.LdFlags = append(flags.LdFlags, "-Wl,--no-dynamic-linker")
}
builderFlags := flagsToBuilderFlags(flags)
@@ -323,6 +336,17 @@
binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
}
+ if ctx.Os() == android.LinuxBionic && !binary.static() {
+ injectedOutputFile := outputFile
+ outputFile = android.PathForModuleOut(ctx, "prelinker", fileName)
+
+ if !deps.DynamicLinker.Valid() {
+ panic("Non-static host bionic modules must have a dynamic linker")
+ }
+
+ binary.injectHostBionicLinkerSymbols(ctx, outputFile, deps.DynamicLinker.Path(), injectedOutputFile)
+ }
+
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
linkerDeps = append(linkerDeps, objs.tidyFiles...)
@@ -367,3 +391,26 @@
func (binary *binaryDecorator) hostToolPath() android.OptionalPath {
return binary.toolPath
}
+
+func init() {
+ pctx.HostBinToolVariable("hostBionicSymbolsInjectCmd", "host_bionic_inject")
+}
+
+var injectHostBionicSymbols = pctx.AndroidStaticRule("injectHostBionicSymbols",
+ blueprint.RuleParams{
+ Command: "$hostBionicSymbolsInjectCmd -i $in -l $linker -o $out",
+ CommandDeps: []string{"$hostBionicSymbolsInjectCmd"},
+ }, "linker")
+
+func (binary *binaryDecorator) injectHostBionicLinkerSymbols(ctx ModuleContext, in, linker android.Path, out android.WritablePath) {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: injectHostBionicSymbols,
+ Description: "inject host bionic symbols",
+ Input: in,
+ Implicit: linker,
+ Output: out,
+ Args: map[string]string{
+ "linker": linker.String(),
+ },
+ })
+}