Commit f7ad3a04 authored by David Crawshaw's avatar David Crawshaw

cmd/link: move ldmacho to its own package

For #22095

Change-Id: I660080279692b74669c45f42c28cccff71bd33b5
Reviewed-on: https://go-review.googlesource.com/68930Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 840f2c16
...@@ -67,6 +67,7 @@ var bootstrapDirs = []string{ ...@@ -67,6 +67,7 @@ var bootstrapDirs = []string{
"cmd/link/internal/arm", "cmd/link/internal/arm",
"cmd/link/internal/arm64", "cmd/link/internal/arm64",
"cmd/link/internal/ld", "cmd/link/internal/ld",
"cmd/link/internal/loadmacho",
"cmd/link/internal/mips", "cmd/link/internal/mips",
"cmd/link/internal/mips64", "cmd/link/internal/mips64",
"cmd/link/internal/objfile", "cmd/link/internal/objfile",
......
...@@ -45,83 +45,6 @@ import ( ...@@ -45,83 +45,6 @@ import (
"sync" "sync"
) )
/*
* divide-and-conquer list-link (by Sub) sort of sym.Symbol* by Value.
* Used for sub-symbols when loading host objects (see e.g. ldelf.go).
*/
func listsort(l *sym.Symbol) *sym.Symbol {
if l == nil || l.Sub == nil {
return l
}
l1 := l
l2 := l
for {
l2 = l2.Sub
if l2 == nil {
break
}
l2 = l2.Sub
if l2 == nil {
break
}
l1 = l1.Sub
}
l2 = l1.Sub
l1.Sub = nil
l1 = listsort(l)
l2 = listsort(l2)
/* set up lead element */
if l1.Value < l2.Value {
l = l1
l1 = l1.Sub
} else {
l = l2
l2 = l2.Sub
}
le := l
for {
if l1 == nil {
for l2 != nil {
le.Sub = l2
le = l2
l2 = l2.Sub
}
le.Sub = nil
break
}
if l2 == nil {
for l1 != nil {
le.Sub = l1
le = l1
l1 = l1.Sub
}
break
}
if l1.Value < l2.Value {
le.Sub = l1
le = l1
l1 = l1.Sub
} else {
le.Sub = l2
le = l2
l2 = l2.Sub
}
}
le.Sub = nil
return l
}
// isRuntimeDepPkg returns whether pkg is the runtime package or its dependency // isRuntimeDepPkg returns whether pkg is the runtime package or its dependency
func isRuntimeDepPkg(pkg string) bool { func isRuntimeDepPkg(pkg string) bool {
switch pkg { switch pkg {
......
...@@ -832,7 +832,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -832,7 +832,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
continue continue
} }
if s.Sub != nil { if s.Sub != nil {
s.Sub = listsort(s.Sub) s.Sub = sym.SortSub(s.Sub)
} }
if s.Type == sym.STEXT { if s.Type == sym.STEXT {
if s.Attr.OnList() { if s.Attr.OnList() {
...@@ -947,7 +947,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -947,7 +947,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
} }
//print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add); //print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add);
sort.Sort(rbyoff(r[:n])) sort.Sort(sym.RelocByOff(r[:n]))
// just in case // just in case
s := sect.sym s := sect.sym
...@@ -1100,28 +1100,6 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, ...@@ -1100,28 +1100,6 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int,
return nil return nil
} }
type rbyoff []sym.Reloc
func (x rbyoff) Len() int {
return len(x)
}
func (x rbyoff) Swap(i, j int) {
x[i], x[j] = x[j], x[i]
}
func (x rbyoff) Less(i, j int) bool {
a := &x[i]
b := &x[j]
if a.Off < b.Off {
return true
}
if a.Off > b.Off {
return false
}
return false
}
func relSize(ctxt *Link, pn string, elftype uint32) uint8 { func relSize(ctxt *Link, pn string, elftype uint32) uint8 {
// TODO(mdempsky): Replace this with a struct-valued switch statement // TODO(mdempsky): Replace this with a struct-valued switch statement
// once golang.org/issue/15164 is fixed or found to not impair cmd/link // once golang.org/issue/15164 is fixed or found to not impair cmd/link
......
...@@ -272,7 +272,7 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin ...@@ -272,7 +272,7 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
} }
} }
sort.Sort(rbyoff(rs[:rsect.NumberOfRelocations])) sort.Sort(sym.RelocByOff(rs[:rsect.NumberOfRelocations]))
s := sectsyms[rsect] s := sectsyms[rsect]
s.R = rs s.R = rs
...@@ -367,7 +367,7 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin ...@@ -367,7 +367,7 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
continue continue
} }
if s.Sub != nil { if s.Sub != nil {
s.Sub = listsort(s.Sub) s.Sub = sym.SortSub(s.Sub)
} }
if s.Type == sym.STEXT { if s.Type == sym.STEXT {
if s.Attr.OnList() { if s.Attr.OnList() {
......
...@@ -36,6 +36,7 @@ import ( ...@@ -36,6 +36,7 @@ import (
"cmd/internal/bio" "cmd/internal/bio"
"cmd/internal/objabi" "cmd/internal/objabi"
"cmd/internal/sys" "cmd/internal/sys"
"cmd/link/internal/loadmacho"
"cmd/link/internal/objfile" "cmd/link/internal/objfile"
"cmd/link/internal/sym" "cmd/link/internal/sym"
"crypto/sha1" "crypto/sha1"
...@@ -1384,6 +1385,14 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, ...@@ -1384,6 +1385,14 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string,
} }
if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe { if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe {
ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
textp, err := loadmacho.Load(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
if err != nil {
Errorf(nil, "%v", err)
return
}
ctxt.Textp = append(ctxt.Textp, textp...)
}
return ldhostobj(ldmacho, f, pkg, length, pn, file) return ldhostobj(ldmacho, f, pkg, length, pn, file)
} }
......
...@@ -95,3 +95,22 @@ func RelocName(arch *sys.Arch, r objabi.RelocType) string { ...@@ -95,3 +95,22 @@ func RelocName(arch *sys.Arch, r objabi.RelocType) string {
return r.String() return r.String()
} }
// RelocByOff implements sort.Interface for sorting relocations by offset.
type RelocByOff []Reloc
func (x RelocByOff) Len() int { return len(x) }
func (x RelocByOff) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x RelocByOff) Less(i, j int) bool {
a := &x[i]
b := &x[j]
if a.Off < b.Off {
return true
}
if a.Off > b.Off {
return false
}
return false
}
...@@ -264,6 +264,80 @@ func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64 ...@@ -264,6 +264,80 @@ func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64
return off + wid return off + wid
} }
// SortSub sorts a linked-list (by Sub) of *Symbol by Value.
// Used for sub-symbols when loading host objects (see e.g. ldelf.go).
func SortSub(l *Symbol) *Symbol {
if l == nil || l.Sub == nil {
return l
}
l1 := l
l2 := l
for {
l2 = l2.Sub
if l2 == nil {
break
}
l2 = l2.Sub
if l2 == nil {
break
}
l1 = l1.Sub
}
l2 = l1.Sub
l1.Sub = nil
l1 = SortSub(l)
l2 = SortSub(l2)
/* set up lead element */
if l1.Value < l2.Value {
l = l1
l1 = l1.Sub
} else {
l = l2
l2 = l2.Sub
}
le := l
for {
if l1 == nil {
for l2 != nil {
le.Sub = l2
le = l2
l2 = l2.Sub
}
le.Sub = nil
break
}
if l2 == nil {
for l1 != nil {
le.Sub = l1
le = l1
l1 = l1.Sub
}
break
}
if l1.Value < l2.Value {
le.Sub = l1
le = l1
l1 = l1.Sub
} else {
le.Sub = l2
le = l2
l2 = l2.Sub
}
}
le.Sub = nil
return l
}
type FuncInfo struct { type FuncInfo struct {
Args int32 Args int32
Locals int32 Locals int32
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment