Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f04eb99a authored by Colin Cross's avatar Colin Cross
Browse files

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
parent a4d9b86c
Loading
Loading
Loading
Loading
+13 −11
Original line number Diff line number Diff line
@@ -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,
+3 −1
Original line number Diff line number Diff line
@@ -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,
	})
}
+1 −1
Original line number Diff line number Diff line
@@ -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...)
+3 −4
Original line number Diff line number Diff line
@@ -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"],
}
+12 −39
Original line number Diff line number Diff line
@@ -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) {
Loading