From 9cfe6119fe9713fd80d5a4c08868000fc6f646ce Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 11 Jun 2021 18:02:22 -0700 Subject: [PATCH] Use a linker script for host bionic embedded linker sections Use an implicit linker script instead of flags in a file to specify the locations of the host bionic embedded linker and to prevent it from being stripped. Test: build and run host bionic binary Change-Id: I64e12118d33c67bab5e657cbc3ea8cde8f0fd7e6 --- Android.bp | 6 +++--- cc/binary.go | 8 +------- cc/cc.go | 21 +-------------------- cc/testing.go | 4 ++-- cmd/extract_linker/main.go | 28 ++++++++++++++++------------ 5 files changed, 23 insertions(+), 44 deletions(-) diff --git a/Android.bp b/Android.bp index 8f7f3e225..45e661e78 100644 --- a/Android.bp +++ b/Android.bp @@ -92,7 +92,7 @@ cc_genrule { } cc_genrule { - name: "host_bionic_linker_flags", + name: "host_bionic_linker_script", host_supported: true, device_supported: false, target: { @@ -107,9 +107,9 @@ cc_genrule { }, }, tools: ["extract_linker"], - cmd: "$(location) -f $(out) $(in)", + cmd: "$(location) -T $(out) $(in)", srcs: [":linker"], - out: ["linker.flags"], + out: ["linker.script"], } // Instantiate the dex_bootjars singleton module. diff --git a/cc/binary.go b/cc/binary.go index 201fdccc9..3aa3fdf01 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -178,7 +178,7 @@ func (binary *binaryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { // the kernel before jumping to the embedded linker. if ctx.Os() == android.LinuxBionic && !binary.static() { deps.DynamicLinker = "linker" - deps.LinkerFlagsFile = "host_bionic_linker_flags" + deps.CrtBegin = append(deps.CrtBegin, "host_bionic_linker_script") } } @@ -345,12 +345,6 @@ func (binary *binaryDecorator) link(ctx ModuleContext, var linkerDeps android.Paths - // Add flags from linker flags file. - if deps.LinkerFlagsFile.Valid() { - flags.Local.LdFlags = append(flags.Local.LdFlags, "$$(cat "+deps.LinkerFlagsFile.String()+")") - linkerDeps = append(linkerDeps, deps.LinkerFlagsFile.Path()) - } - if flags.DynamicLinker != "" { flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-dynamic-linker,"+flags.DynamicLinker) } else if ctx.toolchain().Bionic() && !binary.static() { diff --git a/cc/cc.go b/cc/cc.go index ef503afb2..6e9518d14 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -129,8 +129,7 @@ type Deps struct { CrtBegin, CrtEnd []string // Used for host bionic - LinkerFlagsFile string - DynamicLinker string + DynamicLinker string // List of libs that need to be excluded for APEX variant ExcludeLibsForApex []string @@ -179,9 +178,6 @@ type PathDeps struct { // Paths to crt*.o files CrtBegin, CrtEnd android.Paths - // Path to the file container flags to use with the linker - LinkerFlagsFile android.OptionalPath - // Path to the dynamic linker binary DynamicLinker android.OptionalPath } @@ -717,7 +713,6 @@ var ( genHeaderDepTag = dependencyTag{name: "gen header"} genHeaderExportDepTag = dependencyTag{name: "gen header export"} objDepTag = dependencyTag{name: "obj"} - linkerFlagsDepTag = dependencyTag{name: "linker flags file"} dynamicLinkerDepTag = installDependencyTag{name: "dynamic linker"} reuseObjTag = dependencyTag{name: "reuse objects"} staticVariantTag = dependencyTag{name: "static variant"} @@ -2254,9 +2249,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { actx.AddVariationDependencies(crtVariations, CrtEndDepTag, RewriteSnapshotLib(crt, GetSnapshot(c, &snapshotInfo, actx).Objects)) } - if deps.LinkerFlagsFile != "" { - actx.AddDependency(c, linkerFlagsDepTag, deps.LinkerFlagsFile) - } if deps.DynamicLinker != "" { actx.AddDependency(c, dynamicLinkerDepTag, deps.DynamicLinker) } @@ -2555,17 +2547,6 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } else { ctx.ModuleErrorf("module %q is not a genrule", depName) } - case linkerFlagsDepTag: - if genRule, ok := dep.(genrule.SourceFileGenerator); ok { - files := genRule.GeneratedSourceFiles() - if len(files) == 1 { - depPaths.LinkerFlagsFile = android.OptionalPathForPath(files[0]) - } else if len(files) > 1 { - ctx.ModuleErrorf("module %q can only generate a single file if used for a linker flag file", depName) - } - } else { - ctx.ModuleErrorf("module %q is not a genrule", depName) - } case CrtBeginDepTag: depPaths.CrtBegin = append(depPaths.CrtBegin, android.OutputFileForModule(ctx, dep, "")) case CrtEndDepTag: diff --git a/cc/testing.go b/cc/testing.go index f5c5ec5b1..bee170f1d 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -490,7 +490,7 @@ func withLinuxBionic() string { } cc_genrule { - name: "host_bionic_linker_flags", + name: "host_bionic_linker_script", host_supported: true, device_supported: false, target: { @@ -501,7 +501,7 @@ func withLinuxBionic() string { enabled: true, }, }, - out: ["linker.flags"], + out: ["linker.script"], } cc_defaults { diff --git a/cmd/extract_linker/main.go b/cmd/extract_linker/main.go index d62dea1c0..2dcb8948e 100644 --- a/cmd/extract_linker/main.go +++ b/cmd/extract_linker/main.go @@ -13,7 +13,7 @@ // limitations under the License. // This tool extracts ELF LOAD segments from our linker binary, and produces an -// assembly file and linker flags which will embed those segments as sections +// assembly file and linker script which will embed those segments as sections // in another binary. package main @@ -31,10 +31,10 @@ import ( func main() { var asmPath string - var flagsPath string + var scriptPath string flag.StringVar(&asmPath, "s", "", "Path to save the assembly file") - flag.StringVar(&flagsPath, "f", "", "Path to save the linker flags") + flag.StringVar(&scriptPath, "T", "", "Path to save the linker script") flag.Parse() f, err := os.Open(flag.Arg(0)) @@ -49,13 +49,16 @@ func main() { } asm := &bytes.Buffer{} + script := &bytes.Buffer{} baseLoadAddr := uint64(0x1000) load := 0 - linkFlags := []string{} fmt.Fprintln(asm, ".globl __dlwrap_linker_offset") fmt.Fprintf(asm, ".set __dlwrap_linker_offset, 0x%x\n", baseLoadAddr) + fmt.Fprintln(script, "ENTRY(__dlwrap__start)") + fmt.Fprintln(script, "SECTIONS {") + for _, prog := range ef.Progs { if prog.Type != elf.PT_LOAD { continue @@ -82,10 +85,9 @@ func main() { fmt.Fprintf(asm, ".globl %s\n%s:\n\n", symName, symName) - linkFlags = append(linkFlags, - fmt.Sprintf("-Wl,--undefined=%s", symName), - fmt.Sprintf("-Wl,--section-start=%s=0x%x", - sectionName, baseLoadAddr+prog.Vaddr)) + fmt.Fprintf(script, " %s %d : {\n", sectionName, baseLoadAddr+prog.Vaddr) + fmt.Fprintf(script, " KEEP(*(%s));\n", sectionName) + fmt.Fprintln(script, " }") buffer, _ := ioutil.ReadAll(prog.Open()) bytesToAsm(asm, buffer) @@ -104,16 +106,18 @@ func main() { load += 1 } + fmt.Fprintln(script, "}") + fmt.Fprintln(script, "INSERT BEFORE .note.android.ident;") + if asmPath != "" { if err := ioutil.WriteFile(asmPath, asm.Bytes(), 0777); err != nil { log.Fatalf("Unable to write %q: %v", asmPath, err) } } - if flagsPath != "" { - flags := strings.Join(linkFlags, " ") - if err := ioutil.WriteFile(flagsPath, []byte(flags), 0777); err != nil { - log.Fatalf("Unable to write %q: %v", flagsPath, err) + if scriptPath != "" { + if err := ioutil.WriteFile(scriptPath, script.Bytes(), 0777); err != nil { + log.Fatalf("Unable to write %q: %v", scriptPath, err) } } }