Merge "Use a linker script for host bionic embedded linker sections" am: 956e32c1be
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1735344 Change-Id: I3f6af1b09775859aa40ffae64fe477fb33845310
This commit is contained in:
@@ -92,7 +92,7 @@ cc_genrule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cc_genrule {
|
cc_genrule {
|
||||||
name: "host_bionic_linker_flags",
|
name: "host_bionic_linker_script",
|
||||||
host_supported: true,
|
host_supported: true,
|
||||||
device_supported: false,
|
device_supported: false,
|
||||||
target: {
|
target: {
|
||||||
@@ -107,9 +107,9 @@ cc_genrule {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
tools: ["extract_linker"],
|
tools: ["extract_linker"],
|
||||||
cmd: "$(location) -f $(out) $(in)",
|
cmd: "$(location) -T $(out) $(in)",
|
||||||
srcs: [":linker"],
|
srcs: [":linker"],
|
||||||
out: ["linker.flags"],
|
out: ["linker.script"],
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instantiate the dex_bootjars singleton module.
|
// Instantiate the dex_bootjars singleton module.
|
||||||
|
@@ -178,7 +178,7 @@ func (binary *binaryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
|||||||
// the kernel before jumping to the embedded linker.
|
// the kernel before jumping to the embedded linker.
|
||||||
if ctx.Os() == android.LinuxBionic && !binary.static() {
|
if ctx.Os() == android.LinuxBionic && !binary.static() {
|
||||||
deps.DynamicLinker = "linker"
|
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
|
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 != "" {
|
if flags.DynamicLinker != "" {
|
||||||
flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-dynamic-linker,"+flags.DynamicLinker)
|
flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-dynamic-linker,"+flags.DynamicLinker)
|
||||||
} else if ctx.toolchain().Bionic() && !binary.static() {
|
} else if ctx.toolchain().Bionic() && !binary.static() {
|
||||||
|
19
cc/cc.go
19
cc/cc.go
@@ -129,7 +129,6 @@ type Deps struct {
|
|||||||
CrtBegin, CrtEnd []string
|
CrtBegin, CrtEnd []string
|
||||||
|
|
||||||
// Used for host bionic
|
// Used for host bionic
|
||||||
LinkerFlagsFile string
|
|
||||||
DynamicLinker string
|
DynamicLinker string
|
||||||
|
|
||||||
// List of libs that need to be excluded for APEX variant
|
// List of libs that need to be excluded for APEX variant
|
||||||
@@ -179,9 +178,6 @@ type PathDeps struct {
|
|||||||
// Paths to crt*.o files
|
// Paths to crt*.o files
|
||||||
CrtBegin, CrtEnd android.Paths
|
CrtBegin, CrtEnd android.Paths
|
||||||
|
|
||||||
// Path to the file container flags to use with the linker
|
|
||||||
LinkerFlagsFile android.OptionalPath
|
|
||||||
|
|
||||||
// Path to the dynamic linker binary
|
// Path to the dynamic linker binary
|
||||||
DynamicLinker android.OptionalPath
|
DynamicLinker android.OptionalPath
|
||||||
}
|
}
|
||||||
@@ -726,7 +722,6 @@ var (
|
|||||||
genHeaderDepTag = dependencyTag{name: "gen header"}
|
genHeaderDepTag = dependencyTag{name: "gen header"}
|
||||||
genHeaderExportDepTag = dependencyTag{name: "gen header export"}
|
genHeaderExportDepTag = dependencyTag{name: "gen header export"}
|
||||||
objDepTag = dependencyTag{name: "obj"}
|
objDepTag = dependencyTag{name: "obj"}
|
||||||
linkerFlagsDepTag = dependencyTag{name: "linker flags file"}
|
|
||||||
dynamicLinkerDepTag = installDependencyTag{name: "dynamic linker"}
|
dynamicLinkerDepTag = installDependencyTag{name: "dynamic linker"}
|
||||||
reuseObjTag = dependencyTag{name: "reuse objects"}
|
reuseObjTag = dependencyTag{name: "reuse objects"}
|
||||||
staticVariantTag = dependencyTag{name: "static variant"}
|
staticVariantTag = dependencyTag{name: "static variant"}
|
||||||
@@ -2272,9 +2267,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
actx.AddVariationDependencies(crtVariations, CrtEndDepTag,
|
actx.AddVariationDependencies(crtVariations, CrtEndDepTag,
|
||||||
RewriteSnapshotLib(crt, GetSnapshot(c, &snapshotInfo, actx).Objects))
|
RewriteSnapshotLib(crt, GetSnapshot(c, &snapshotInfo, actx).Objects))
|
||||||
}
|
}
|
||||||
if deps.LinkerFlagsFile != "" {
|
|
||||||
actx.AddDependency(c, linkerFlagsDepTag, deps.LinkerFlagsFile)
|
|
||||||
}
|
|
||||||
if deps.DynamicLinker != "" {
|
if deps.DynamicLinker != "" {
|
||||||
actx.AddDependency(c, dynamicLinkerDepTag, deps.DynamicLinker)
|
actx.AddDependency(c, dynamicLinkerDepTag, deps.DynamicLinker)
|
||||||
}
|
}
|
||||||
@@ -2573,17 +2565,6 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
} else {
|
} else {
|
||||||
ctx.ModuleErrorf("module %q is not a genrule", depName)
|
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:
|
case CrtBeginDepTag:
|
||||||
depPaths.CrtBegin = append(depPaths.CrtBegin, android.OutputFileForModule(ctx, dep, ""))
|
depPaths.CrtBegin = append(depPaths.CrtBegin, android.OutputFileForModule(ctx, dep, ""))
|
||||||
case CrtEndDepTag:
|
case CrtEndDepTag:
|
||||||
|
@@ -490,7 +490,7 @@ func withLinuxBionic() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cc_genrule {
|
cc_genrule {
|
||||||
name: "host_bionic_linker_flags",
|
name: "host_bionic_linker_script",
|
||||||
host_supported: true,
|
host_supported: true,
|
||||||
device_supported: false,
|
device_supported: false,
|
||||||
target: {
|
target: {
|
||||||
@@ -501,7 +501,7 @@ func withLinuxBionic() string {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
out: ["linker.flags"],
|
out: ["linker.script"],
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_defaults {
|
cc_defaults {
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// This tool extracts ELF LOAD segments from our linker binary, and produces an
|
// 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.
|
// in another binary.
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -31,10 +31,10 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var asmPath string
|
var asmPath string
|
||||||
var flagsPath string
|
var scriptPath string
|
||||||
|
|
||||||
flag.StringVar(&asmPath, "s", "", "Path to save the assembly file")
|
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()
|
flag.Parse()
|
||||||
|
|
||||||
f, err := os.Open(flag.Arg(0))
|
f, err := os.Open(flag.Arg(0))
|
||||||
@@ -49,13 +49,16 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
asm := &bytes.Buffer{}
|
asm := &bytes.Buffer{}
|
||||||
|
script := &bytes.Buffer{}
|
||||||
baseLoadAddr := uint64(0x1000)
|
baseLoadAddr := uint64(0x1000)
|
||||||
load := 0
|
load := 0
|
||||||
linkFlags := []string{}
|
|
||||||
|
|
||||||
fmt.Fprintln(asm, ".globl __dlwrap_linker_offset")
|
fmt.Fprintln(asm, ".globl __dlwrap_linker_offset")
|
||||||
fmt.Fprintf(asm, ".set __dlwrap_linker_offset, 0x%x\n", baseLoadAddr)
|
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 {
|
for _, prog := range ef.Progs {
|
||||||
if prog.Type != elf.PT_LOAD {
|
if prog.Type != elf.PT_LOAD {
|
||||||
continue
|
continue
|
||||||
@@ -82,10 +85,9 @@ func main() {
|
|||||||
|
|
||||||
fmt.Fprintf(asm, ".globl %s\n%s:\n\n", symName, symName)
|
fmt.Fprintf(asm, ".globl %s\n%s:\n\n", symName, symName)
|
||||||
|
|
||||||
linkFlags = append(linkFlags,
|
fmt.Fprintf(script, " %s %d : {\n", sectionName, baseLoadAddr+prog.Vaddr)
|
||||||
fmt.Sprintf("-Wl,--undefined=%s", symName),
|
fmt.Fprintf(script, " KEEP(*(%s));\n", sectionName)
|
||||||
fmt.Sprintf("-Wl,--section-start=%s=0x%x",
|
fmt.Fprintln(script, " }")
|
||||||
sectionName, baseLoadAddr+prog.Vaddr))
|
|
||||||
|
|
||||||
buffer, _ := ioutil.ReadAll(prog.Open())
|
buffer, _ := ioutil.ReadAll(prog.Open())
|
||||||
bytesToAsm(asm, buffer)
|
bytesToAsm(asm, buffer)
|
||||||
@@ -104,16 +106,18 @@ func main() {
|
|||||||
load += 1
|
load += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Fprintln(script, "}")
|
||||||
|
fmt.Fprintln(script, "INSERT BEFORE .note.android.ident;")
|
||||||
|
|
||||||
if asmPath != "" {
|
if asmPath != "" {
|
||||||
if err := ioutil.WriteFile(asmPath, asm.Bytes(), 0777); err != nil {
|
if err := ioutil.WriteFile(asmPath, asm.Bytes(), 0777); err != nil {
|
||||||
log.Fatalf("Unable to write %q: %v", asmPath, err)
|
log.Fatalf("Unable to write %q: %v", asmPath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if flagsPath != "" {
|
if scriptPath != "" {
|
||||||
flags := strings.Join(linkFlags, " ")
|
if err := ioutil.WriteFile(scriptPath, script.Bytes(), 0777); err != nil {
|
||||||
if err := ioutil.WriteFile(flagsPath, []byte(flags), 0777); err != nil {
|
log.Fatalf("Unable to write %q: %v", scriptPath, err)
|
||||||
log.Fatalf("Unable to write %q: %v", flagsPath, err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user