From f04eb99acce1c95c9ecc9da501898fb8ad00731d Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 11 Jun 2021 15:22:41 -0700 Subject: [PATCH] Stop injecting symbols into host bionic binaries The host bionic bootstrapping no longer needs an injected symbol. Replace host_bionic_inject with host_bionic_verify that validates the resulting binary, and add it as a validation dependency of the binary. Test: build and run host bionic binary Change-Id: I3e303d2a164b6eef851bdc8075e6ee456c05b0a8 --- cc/binary.go | 24 +++++---- cc/builder.go | 4 +- cc/library.go | 2 +- .../Android.bp | 7 ++- .../host_bionic_verify.go} | 51 +++++-------------- .../host_bionic_verify_test.go} | 0 6 files changed, 32 insertions(+), 56 deletions(-) rename cmd/{host_bionic_inject => host_bionic_verify}/Android.bp (82%) rename cmd/{host_bionic_inject/host_bionic_inject.go => host_bionic_verify/host_bionic_verify.go} (69%) rename cmd/{host_bionic_inject/host_bionic_inject_test.go => host_bionic_verify/host_bionic_verify_test.go} (100%) diff --git a/cc/binary.go b/cc/binary.go index 999b82c24..4db25db24 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -401,16 +401,18 @@ func (binary *binaryDecorator) link(ctx ModuleContext, } } + var validations android.WritablePaths + // Handle host bionic linker symbols. if ctx.Os() == android.LinuxBionic && !binary.static() { - injectedOutputFile := outputFile - outputFile = android.PathForModuleOut(ctx, "prelinker", fileName) + verifyFile := android.PathForModuleOut(ctx, "host_bionic_verify.stamp") if !deps.DynamicLinker.Valid() { 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 @@ -430,7 +432,7 @@ func (binary *binaryDecorator) link(ctx ModuleContext, // Register link action. transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, deps.StaticLibs, 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.WholeStaticLibObjs.coverageFiles...) @@ -532,19 +534,19 @@ func (binary *binaryDecorator) hostToolPath() android.OptionalPath { } 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{ - Command: "$hostBionicSymbolsInjectCmd -i $in -l $linker -o $out", - CommandDeps: []string{"$hostBionicSymbolsInjectCmd"}, + Command: "$verifyHostBionicCmd -i $in -l $linker && touch $out", + CommandDeps: []string{"$verifyHostBionicCmd"}, }, "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{ - Rule: injectHostBionicSymbols, - Description: "inject host bionic symbols", + Rule: verifyHostBionic, + Description: "verify host bionic", Input: in, Implicit: linker, Output: out, diff --git a/cc/builder.go b/cc/builder.go index fae9522f2..cf782eb29 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -731,7 +731,8 @@ func transformObjToStaticLib(ctx android.ModuleContext, // and shared libraries, to a shared library (.so) or dynamic executable func transformObjToDynamicBinary(ctx android.ModuleContext, 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++" @@ -805,6 +806,7 @@ func transformObjToDynamicBinary(ctx android.ModuleContext, Inputs: objFiles, Implicits: deps, OrderOnly: sharedLibs, + Validations: validations.Paths(), Args: args, }) } diff --git a/cc/library.go b/cc/library.go index 93bd56c6f..9bff77889 100644 --- a/cc/library.go +++ b/cc/library.go @@ -1343,7 +1343,7 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext, linkerDeps = append(linkerDeps, objs.tidyFiles...) transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, 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.WholeStaticLibObjs.coverageFiles...) diff --git a/cmd/host_bionic_inject/Android.bp b/cmd/host_bionic_verify/Android.bp similarity index 82% rename from cmd/host_bionic_inject/Android.bp rename to cmd/host_bionic_verify/Android.bp index 16bc1793c..4e7c3792a 100644 --- a/cmd/host_bionic_inject/Android.bp +++ b/cmd/host_bionic_verify/Android.bp @@ -17,8 +17,7 @@ package { } blueprint_go_binary { - name: "host_bionic_inject", - deps: ["soong-symbol_inject"], - srcs: ["host_bionic_inject.go"], - testSrcs: ["host_bionic_inject_test.go"], + name: "host_bionic_verify", + srcs: ["host_bionic_verify.go"], + testSrcs: ["host_bionic_verify_test.go"], } diff --git a/cmd/host_bionic_inject/host_bionic_inject.go b/cmd/host_bionic_verify/host_bionic_verify.go similarity index 69% rename from cmd/host_bionic_inject/host_bionic_inject.go rename to cmd/host_bionic_verify/host_bionic_verify.go index ce8b062b7..52400a393 100644 --- a/cmd/host_bionic_inject/host_bionic_inject.go +++ b/cmd/host_bionic_verify/host_bionic_verify.go @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Verifies a host bionic executable with an embedded linker, then injects -// the address of the _start function for the linker_wrapper to use. +// Verifies a host bionic executable with an embedded linker. package main import ( @@ -22,19 +21,16 @@ import ( "fmt" "io" "os" - - "android/soong/symbol_inject" ) func main() { - var inputFile, linkerFile, outputFile string + var inputFile, linkerFile string flag.StringVar(&inputFile, "i", "", "Input file") flag.StringVar(&linkerFile, "l", "", "Linker file") - flag.StringVar(&outputFile, "o", "", "Output file") flag.Parse() - if inputFile == "" || linkerFile == "" || outputFile == "" || flag.NArg() != 0 { + if inputFile == "" || linkerFile == "" || flag.NArg() != 0 { flag.Usage() os.Exit(1) } @@ -46,75 +42,52 @@ func main() { } 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) if err != nil { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(4) } - startAddr, err := parseElf(r, linker) + err = checkElf(r, linker) if err != nil { fmt.Fprintln(os.Stderr, err.Error()) 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 -func parseElf(r io.ReaderAt, linker *elf.File) (uint64, error) { +func checkElf(r io.ReaderAt, linker *elf.File) error { file, err := elf.NewFile(r) if err != nil { - return 0, err + return err } symbols, err := file.Symbols() if err != nil { - return 0, err + return err } for _, prog := range file.Progs { 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 { - return 0, err + return err } 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) } err = checkLinker(file, linker, symbols) 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.", err) } - start, err := findSymbol(symbols, "_start") - if err != nil { - return 0, fmt.Errorf("Failed to find _start symbol") - } - return start.Value, nil + return nil } func findSymbol(symbols []elf.Symbol, name string) (elf.Symbol, error) { diff --git a/cmd/host_bionic_inject/host_bionic_inject_test.go b/cmd/host_bionic_verify/host_bionic_verify_test.go similarity index 100% rename from cmd/host_bionic_inject/host_bionic_inject_test.go rename to cmd/host_bionic_verify/host_bionic_verify_test.go