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
This commit is contained in:
65
cc/binary.go
65
cc/binary.go
@@ -15,6 +15,8 @@
|
||||
package cc
|
||||
|
||||
import (
|
||||
"github.com/google/blueprint"
|
||||
|
||||
"android/soong/android"
|
||||
)
|
||||
|
||||
@@ -154,7 +156,8 @@ func (binary *binaryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
||||
}
|
||||
|
||||
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 @@ func (binary *binaryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags
|
||||
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 @@ func (binary *binaryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags
|
||||
"-Wl,--gc-sections",
|
||||
"-Wl,-z,nocopyreloc",
|
||||
)
|
||||
|
||||
}
|
||||
} else {
|
||||
if binary.static() {
|
||||
@@ -288,13 +299,15 @@ func (binary *binaryDecorator) link(ctx ModuleContext,
|
||||
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 @@ func (binary *binaryDecorator) link(ctx ModuleContext,
|
||||
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) install(ctx ModuleContext, file android.Path) {
|
||||
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(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user