diff options
author | Dan Willemsen <dwillemsen@google.com> | 2018-10-12 00:24:23 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@google.com> | 2018-10-22 15:46:03 -0700 |
commit | a0790e35c7b275ee3b8288cf5453c15390850458 (patch) | |
tree | 1952cc9a1d0229ab60a8c0e36e593f3716113c5a /cmd/extract_linker | |
parent | 9ff34c0ca8bc4f8b26424c58978b89eb25fd1564 (diff) | |
download | build_soong-a0790e35c7b275ee3b8288cf5453c15390850458.tar.gz build_soong-a0790e35c7b275ee3b8288cf5453c15390850458.tar.bz2 build_soong-a0790e35c7b275ee3b8288cf5453c15390850458.zip |
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
Diffstat (limited to 'cmd/extract_linker')
-rw-r--r-- | cmd/extract_linker/main.go | 69 |
1 files changed, 21 insertions, 48 deletions
diff --git a/cmd/extract_linker/main.go b/cmd/extract_linker/main.go index 3f24ab2d..ea0bf4ee 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 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) } } } |