Rework how linux_bionic is built with LLD
In order to simplify the wrapper function, and stop using a linker script, generate a set of flags to pass to LLD. Then run host_bionic_inject on the linked binary in order to verify the embedding, and give the wrapper function the address of the original entry point (_start). Bug: 31559095 Test: build host bionic with prebuilts/build-tools/build-prebuilts.sh Change-Id: I53e326050e0f9caa562c6cf6f76c4d0337bb6faf
This commit is contained in:
@@ -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 script which will embed those segments as sections
|
||||
// assembly file and linker flags which will embed those segments as sections
|
||||
// in another binary.
|
||||
package main
|
||||
|
||||
@@ -26,38 +26,15 @@ import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"text/template"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var linkerScriptTemplate = template.Must(template.New("linker_script").Parse(`
|
||||
ENTRY(__dlwrap__start)
|
||||
SECTIONS {
|
||||
__dlwrap_original_start = _start;
|
||||
/DISCARD/ : { *(.interp) }
|
||||
|
||||
{{range .}}
|
||||
. = {{ printf "0x%x" .Vaddr }};
|
||||
{{.Name}} : { KEEP(*({{.Name}})) }
|
||||
{{end}}
|
||||
|
||||
.text : { *(.text .text.*) }
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.data : { *(.data .data.* .gnu.linkonce.d.*) }
|
||||
.bss : { *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) }
|
||||
}
|
||||
`))
|
||||
|
||||
type LinkerSection struct {
|
||||
Name string
|
||||
Vaddr uint64
|
||||
}
|
||||
|
||||
func main() {
|
||||
var asmPath string
|
||||
var scriptPath string
|
||||
var flagsPath string
|
||||
|
||||
flag.StringVar(&asmPath, "s", "", "Path to save the assembly file")
|
||||
flag.StringVar(&scriptPath, "T", "", "Path to save the linker script")
|
||||
flag.StringVar(&flagsPath, "f", "", "Path to save the linker flags")
|
||||
flag.Parse()
|
||||
|
||||
f, err := os.Open(flag.Arg(0))
|
||||
@@ -72,19 +49,21 @@ func main() {
|
||||
}
|
||||
|
||||
asm := &bytes.Buffer{}
|
||||
|
||||
fmt.Fprintln(asm, ".globl __dlwrap_linker_entry")
|
||||
fmt.Fprintf(asm, ".set __dlwrap_linker_entry, 0x%x\n\n", ef.Entry)
|
||||
|
||||
baseLoadAddr := uint64(0x1000)
|
||||
sections := []LinkerSection{}
|
||||
load := 0
|
||||
linkFlags := []string{}
|
||||
|
||||
fmt.Fprintln(asm, ".globl __dlwrap_linker_offset")
|
||||
fmt.Fprintf(asm, ".set __dlwrap_linker_offset, 0x%x\n", baseLoadAddr)
|
||||
|
||||
for _, prog := range ef.Progs {
|
||||
if prog.Type != elf.PT_LOAD {
|
||||
continue
|
||||
}
|
||||
|
||||
sectionName := fmt.Sprintf(".linker.sect%d", load)
|
||||
symName := fmt.Sprintf("__dlwrap_linker_sect%d", load)
|
||||
|
||||
flags := ""
|
||||
if prog.Flags&elf.PF_W != 0 {
|
||||
flags += "w"
|
||||
@@ -94,10 +73,12 @@ func main() {
|
||||
}
|
||||
fmt.Fprintf(asm, ".section %s, \"a%s\"\n", sectionName, flags)
|
||||
|
||||
if load == 0 {
|
||||
fmt.Fprintln(asm, ".globl __dlwrap_linker_code_start")
|
||||
fmt.Fprintln(asm, "__dlwrap_linker_code_start:")
|
||||
}
|
||||
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))
|
||||
|
||||
buffer, _ := ioutil.ReadAll(prog.Open())
|
||||
bytesToAsm(asm, buffer)
|
||||
@@ -113,11 +94,6 @@ func main() {
|
||||
}
|
||||
fmt.Fprintln(asm)
|
||||
|
||||
sections = append(sections, LinkerSection{
|
||||
Name: sectionName,
|
||||
Vaddr: baseLoadAddr + prog.Vaddr,
|
||||
})
|
||||
|
||||
load += 1
|
||||
}
|
||||
|
||||
@@ -127,13 +103,10 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
if scriptPath != "" {
|
||||
buf := &bytes.Buffer{}
|
||||
if err := linkerScriptTemplate.Execute(buf, sections); err != nil {
|
||||
log.Fatalf("Failed to create linker script: %v", err)
|
||||
}
|
||||
if err := ioutil.WriteFile(scriptPath, buf.Bytes(), 0777); err != nil {
|
||||
log.Fatalf("Unable to write %q: %v", scriptPath, 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user