Stop injecting symbols into host bionic binaries am: f04eb99acc

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1735453

Change-Id: Iad472fd7acfca99e5da994429fb62a66c1d6b719
This commit is contained in:
Colin Cross 2021-06-16 17:03:59 +00:00 committed by Automerger Merge Worker
commit dc6e968a3f
6 changed files with 32 additions and 56 deletions

View file

@ -401,16 +401,18 @@ func (binary *binaryDecorator) link(ctx ModuleContext,
} }
} }
var validations android.WritablePaths
// Handle host bionic linker symbols. // Handle host bionic linker symbols.
if ctx.Os() == android.LinuxBionic && !binary.static() { if ctx.Os() == android.LinuxBionic && !binary.static() {
injectedOutputFile := outputFile verifyFile := android.PathForModuleOut(ctx, "host_bionic_verify.stamp")
outputFile = android.PathForModuleOut(ctx, "prelinker", fileName)
if !deps.DynamicLinker.Valid() { if !deps.DynamicLinker.Valid() {
panic("Non-static host bionic modules must have a dynamic linker") panic("Non-static host bionic modules must have a dynamic linker")
} }
binary.injectHostBionicLinkerSymbols(ctx, outputFile, deps.DynamicLinker.Path(), injectedOutputFile) binary.verifyHostBionicLinker(ctx, outputFile, deps.DynamicLinker.Path(), verifyFile)
validations = append(validations, verifyFile)
} }
var sharedLibs android.Paths var sharedLibs android.Paths
@ -430,7 +432,7 @@ func (binary *binaryDecorator) link(ctx ModuleContext,
// Register link action. // Register link action.
transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, deps.StaticLibs, transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, deps.StaticLibs,
deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true, deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
builderFlags, outputFile, nil) builderFlags, outputFile, nil, validations)
objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...) objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...) objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
@ -532,19 +534,19 @@ func (binary *binaryDecorator) hostToolPath() android.OptionalPath {
} }
func init() { func init() {
pctx.HostBinToolVariable("hostBionicSymbolsInjectCmd", "host_bionic_inject") pctx.HostBinToolVariable("verifyHostBionicCmd", "host_bionic_verify")
} }
var injectHostBionicSymbols = pctx.AndroidStaticRule("injectHostBionicSymbols", var verifyHostBionic = pctx.AndroidStaticRule("verifyHostBionic",
blueprint.RuleParams{ blueprint.RuleParams{
Command: "$hostBionicSymbolsInjectCmd -i $in -l $linker -o $out", Command: "$verifyHostBionicCmd -i $in -l $linker && touch $out",
CommandDeps: []string{"$hostBionicSymbolsInjectCmd"}, CommandDeps: []string{"$verifyHostBionicCmd"},
}, "linker") }, "linker")
func (binary *binaryDecorator) injectHostBionicLinkerSymbols(ctx ModuleContext, in, linker android.Path, out android.WritablePath) { func (binary *binaryDecorator) verifyHostBionicLinker(ctx ModuleContext, in, linker android.Path, out android.WritablePath) {
ctx.Build(pctx, android.BuildParams{ ctx.Build(pctx, android.BuildParams{
Rule: injectHostBionicSymbols, Rule: verifyHostBionic,
Description: "inject host bionic symbols", Description: "verify host bionic",
Input: in, Input: in,
Implicit: linker, Implicit: linker,
Output: out, Output: out,

View file

@ -731,7 +731,8 @@ func transformObjToStaticLib(ctx android.ModuleContext,
// and shared libraries, to a shared library (.so) or dynamic executable // and shared libraries, to a shared library (.so) or dynamic executable
func transformObjToDynamicBinary(ctx android.ModuleContext, func transformObjToDynamicBinary(ctx android.ModuleContext,
objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs, deps android.Paths, objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs, deps android.Paths,
crtBegin, crtEnd android.OptionalPath, groupLate bool, flags builderFlags, outputFile android.WritablePath, implicitOutputs android.WritablePaths) { crtBegin, crtEnd android.OptionalPath, groupLate bool, flags builderFlags,
outputFile android.WritablePath, implicitOutputs android.WritablePaths, validations android.WritablePaths) {
ldCmd := "${config.ClangBin}/clang++" ldCmd := "${config.ClangBin}/clang++"
@ -805,6 +806,7 @@ func transformObjToDynamicBinary(ctx android.ModuleContext,
Inputs: objFiles, Inputs: objFiles,
Implicits: deps, Implicits: deps,
OrderOnly: sharedLibs, OrderOnly: sharedLibs,
Validations: validations.Paths(),
Args: args, Args: args,
}) })
} }

View file

@ -1406,7 +1406,7 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext,
linkerDeps = append(linkerDeps, objs.tidyFiles...) linkerDeps = append(linkerDeps, objs.tidyFiles...)
transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs) linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs, nil)
objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...) objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...) objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)

View file

@ -17,8 +17,7 @@ package {
} }
blueprint_go_binary { blueprint_go_binary {
name: "host_bionic_inject", name: "host_bionic_verify",
deps: ["soong-symbol_inject"], srcs: ["host_bionic_verify.go"],
srcs: ["host_bionic_inject.go"], testSrcs: ["host_bionic_verify_test.go"],
testSrcs: ["host_bionic_inject_test.go"],
} }

View file

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Verifies a host bionic executable with an embedded linker, then injects // Verifies a host bionic executable with an embedded linker.
// the address of the _start function for the linker_wrapper to use.
package main package main
import ( import (
@ -22,19 +21,16 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"android/soong/symbol_inject"
) )
func main() { func main() {
var inputFile, linkerFile, outputFile string var inputFile, linkerFile string
flag.StringVar(&inputFile, "i", "", "Input file") flag.StringVar(&inputFile, "i", "", "Input file")
flag.StringVar(&linkerFile, "l", "", "Linker file") flag.StringVar(&linkerFile, "l", "", "Linker file")
flag.StringVar(&outputFile, "o", "", "Output file")
flag.Parse() flag.Parse()
if inputFile == "" || linkerFile == "" || outputFile == "" || flag.NArg() != 0 { if inputFile == "" || linkerFile == "" || flag.NArg() != 0 {
flag.Usage() flag.Usage()
os.Exit(1) os.Exit(1)
} }
@ -46,75 +42,52 @@ func main() {
} }
defer r.Close() defer r.Close()
file, err := symbol_inject.OpenFile(r)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(3)
}
linker, err := elf.Open(linkerFile) linker, err := elf.Open(linkerFile)
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err.Error()) fmt.Fprintln(os.Stderr, err.Error())
os.Exit(4) os.Exit(4)
} }
startAddr, err := parseElf(r, linker) err = checkElf(r, linker)
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err.Error()) fmt.Fprintln(os.Stderr, err.Error())
os.Exit(5) os.Exit(5)
} }
w, err := os.OpenFile(outputFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(6)
}
defer w.Close()
err = symbol_inject.InjectUint64Symbol(file, w, "__dlwrap_original_start", startAddr)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(7)
}
} }
// Check the ELF file, and return the address to the _start function // Check the ELF file, and return the address to the _start function
func parseElf(r io.ReaderAt, linker *elf.File) (uint64, error) { func checkElf(r io.ReaderAt, linker *elf.File) error {
file, err := elf.NewFile(r) file, err := elf.NewFile(r)
if err != nil { if err != nil {
return 0, err return err
} }
symbols, err := file.Symbols() symbols, err := file.Symbols()
if err != nil { if err != nil {
return 0, err return err
} }
for _, prog := range file.Progs { for _, prog := range file.Progs {
if prog.Type == elf.PT_INTERP { if prog.Type == elf.PT_INTERP {
return 0, fmt.Errorf("File should not have a PT_INTERP header") return fmt.Errorf("File should not have a PT_INTERP header")
} }
} }
if dlwrap_start, err := findSymbol(symbols, "__dlwrap__start"); err != nil { if dlwrap_start, err := findSymbol(symbols, "__dlwrap__start"); err != nil {
return 0, err return err
} else if dlwrap_start.Value != file.Entry { } else if dlwrap_start.Value != file.Entry {
return 0, fmt.Errorf("Expected file entry(0x%x) to point to __dlwrap_start(0x%x)", return fmt.Errorf("Expected file entry(0x%x) to point to __dlwrap_start(0x%x)",
file.Entry, dlwrap_start.Value) file.Entry, dlwrap_start.Value)
} }
err = checkLinker(file, linker, symbols) err = checkLinker(file, linker, symbols)
if err != nil { if err != nil {
return 0, fmt.Errorf("Linker executable failed verification against app embedded linker: %s\n"+ return fmt.Errorf("Linker executable failed verification against app embedded linker: %s\n"+
"linker might not be in sync with crtbegin_dynamic.o.", "linker might not be in sync with crtbegin_dynamic.o.",
err) err)
} }
start, err := findSymbol(symbols, "_start") return nil
if err != nil {
return 0, fmt.Errorf("Failed to find _start symbol")
}
return start.Value, nil
} }
func findSymbol(symbols []elf.Symbol, name string) (elf.Symbol, error) { func findSymbol(symbols []elf.Symbol, name string) (elf.Symbol, error) {