aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/extract_linker
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2018-10-12 00:24:23 -0700
committerDan Willemsen <dwillemsen@google.com>2018-10-22 15:46:03 -0700
commita0790e35c7b275ee3b8288cf5453c15390850458 (patch)
tree1952cc9a1d0229ab60a8c0e36e593f3716113c5a /cmd/extract_linker
parent9ff34c0ca8bc4f8b26424c58978b89eb25fd1564 (diff)
downloadbuild_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.go69
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)
}
}
}