aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link/internal/ld/lib.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/link/internal/ld/lib.go')
-rw-r--r--src/cmd/link/internal/ld/lib.go302
1 files changed, 168 insertions, 134 deletions
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index 5616700445..53428bb1c6 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -33,7 +33,9 @@ package ld
import (
"bufio"
"bytes"
+ "cmd/internal/bio"
"cmd/internal/obj"
+ "cmd/internal/sys"
"crypto/sha1"
"debug/elf"
"encoding/binary"
@@ -82,14 +84,9 @@ import (
// THE SOFTWARE.
type Arch struct {
- Thechar int
- Ptrsize int
- Intsize int
- Regsize int
Funcalign int
Maxalign int
Minalign int
- Minlc int
Dwarfregsp int
Dwarfreglr int
Linuxdynld string
@@ -133,7 +130,6 @@ func (r *Rpath) String() string {
var (
Thearch Arch
- datap *LSym
Debug [128]int
Lcsize int32
rpath Rpath
@@ -191,8 +187,7 @@ func UseRelro() bool {
}
var (
- Thestring string
- Thelinkarch *LinkArch
+ SysArch *sys.Arch
outfile string
dynexp []*LSym
dynlib []string
@@ -201,6 +196,7 @@ var (
Funcalign int
iscgo bool
elfglobalsymndx int
+ flag_dumpdep bool
flag_installsuffix string
flag_race int
flag_msan int
@@ -245,9 +241,10 @@ const (
var (
headstring string
// buffered output
- Bso obj.Biobuf
+ Bso *bufio.Writer
)
+// TODO(dfc) outBuf duplicates bio.Writer
type outBuf struct {
w *bufio.Writer
f *os.File
@@ -472,7 +469,7 @@ func loadinternal(name string) {
if Linkshared {
shlibname := filepath.Join(Ctxt.Libdir[i], name+".shlibname")
if Debug['v'] != 0 {
- fmt.Fprintf(&Bso, "searching for %s.a in %s\n", name, shlibname)
+ fmt.Fprintf(Bso, "searching for %s.a in %s\n", name, shlibname)
}
if _, err := os.Stat(shlibname); err == nil {
addlibpath(Ctxt, "internal", "internal", "", name, shlibname)
@@ -482,7 +479,7 @@ func loadinternal(name string) {
}
pname := filepath.Join(Ctxt.Libdir[i], name+".a")
if Debug['v'] != 0 {
- fmt.Fprintf(&Bso, "searching for %s.a in %s\n", name, pname)
+ fmt.Fprintf(Bso, "searching for %s.a in %s\n", name, pname)
}
if _, err := os.Stat(pname); err == nil {
addlibpath(Ctxt, "internal", "internal", pname, name, "")
@@ -492,7 +489,7 @@ func loadinternal(name string) {
}
if found == 0 {
- fmt.Fprintf(&Bso, "warning: unable to find %s.a\n", name)
+ fmt.Fprintf(Bso, "warning: unable to find %s.a\n", name)
}
}
@@ -509,7 +506,7 @@ func loadlib() {
}
loadinternal("runtime")
- if Thearch.Thechar == '5' {
+ if SysArch.Family == sys.ARM {
loadinternal("math")
}
if flag_race != 0 {
@@ -524,7 +521,7 @@ func loadlib() {
iscgo = iscgo || Ctxt.Library[i].Pkg == "runtime/cgo"
if Ctxt.Library[i].Shlib == "" {
if Debug['v'] > 1 {
- fmt.Fprintf(&Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].File, Ctxt.Library[i].Objref)
+ fmt.Fprintf(Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].File, Ctxt.Library[i].Objref)
}
objfile(Ctxt.Library[i])
}
@@ -533,7 +530,7 @@ func loadlib() {
for i = 0; i < len(Ctxt.Library); i++ {
if Ctxt.Library[i].Shlib != "" {
if Debug['v'] > 1 {
- fmt.Fprintf(&Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].Shlib, Ctxt.Library[i].Objref)
+ fmt.Fprintf(Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].Shlib, Ctxt.Library[i].Objref)
}
ldshlibsyms(Ctxt.Library[i].Shlib)
}
@@ -562,7 +559,7 @@ func loadlib() {
// dependency problems when compiling natively (external linking requires
// runtime/cgo, runtime/cgo requires cmd/cgo, but cmd/cgo needs to be
// compiled using external linking.)
- if (Thearch.Thechar == '5' || Thearch.Thechar == '7') && HEADTYPE == obj.Hdarwin && iscgo {
+ if SysArch.InFamily(sys.ARM, sys.ARM64) && HEADTYPE == obj.Hdarwin && iscgo {
Linkmode = LinkExternal
}
@@ -621,7 +618,7 @@ func loadlib() {
// a variable to hold g in assembly (currently only intel).
if tlsg.Type == 0 {
tlsg.Type = obj.STLSBSS
- tlsg.Size = int64(Thearch.Ptrsize)
+ tlsg.Size = int64(SysArch.PtrSize)
} else if tlsg.Type != obj.SDYNIMPORT {
Diag("internal error: runtime declared tlsg variable %d", tlsg.Type)
}
@@ -639,7 +636,7 @@ func loadlib() {
// In addition, on ARM, the runtime depends on the linker
// recording the value of GOARM.
- if Thearch.Thechar == '5' {
+ if SysArch.Family == sys.ARM {
s := Linklookup(Ctxt, "runtime.goarm", 0)
s.Type = obj.SRODATA
@@ -696,13 +693,13 @@ func loadlib() {
args := hostlinkArchArgs()
args = append(args, "--print-libgcc-file-name")
if Debug['v'] != 0 {
- fmt.Fprintf(&Bso, "%s %v\n", extld, args)
+ fmt.Fprintf(Bso, "%s %v\n", extld, args)
}
out, err := exec.Command(extld, args...).Output()
if err != nil {
if Debug['v'] != 0 {
- fmt.Fprintln(&Bso, "not using a libgcc file because compiler failed")
- fmt.Fprintf(&Bso, "%v\n%s\n", err, out)
+ fmt.Fprintln(Bso, "not using a libgcc file because compiler failed")
+ fmt.Fprintf(Bso, "%v\n%s\n", err, out)
}
libgccfile = "none"
} else {
@@ -743,17 +740,17 @@ func loadlib() {
* look for the next file in an archive.
* adapted from libmach.
*/
-func nextar(bp *obj.Biobuf, off int64, a *ArHdr) int64 {
+func nextar(bp *bio.Reader, off int64, a *ArHdr) int64 {
if off&1 != 0 {
off++
}
- obj.Bseek(bp, off, 0)
- buf := make([]byte, SAR_HDR)
- if n := obj.Bread(bp, buf); n < len(buf) {
- if n >= 0 {
- return 0
+ bp.Seek(off, 0)
+ var buf [SAR_HDR]byte
+ if n, err := io.ReadFull(bp, buf[:]); err != nil {
+ if n == 0 && err != io.EOF {
+ return -1
}
- return -1
+ return 0
}
a.name = artrim(buf[0:16])
@@ -768,35 +765,38 @@ func nextar(bp *obj.Biobuf, off int64, a *ArHdr) int64 {
if arsize&1 != 0 {
arsize++
}
- return int64(arsize) + SAR_HDR
+ return arsize + SAR_HDR
}
func objfile(lib *Library) {
pkg := pathtoprefix(lib.Pkg)
if Debug['v'] > 1 {
- fmt.Fprintf(&Bso, "%5.2f ldobj: %s (%s)\n", obj.Cputime(), lib.File, pkg)
+ fmt.Fprintf(Bso, "%5.2f ldobj: %s (%s)\n", obj.Cputime(), lib.File, pkg)
}
Bso.Flush()
- f, err := obj.Bopenr(lib.File)
+ f, err := bio.Open(lib.File)
if err != nil {
Exitf("cannot open file %s: %v", lib.File, err)
}
- magbuf := make([]byte, len(ARMAG))
- if obj.Bread(f, magbuf) != len(magbuf) || !strings.HasPrefix(string(magbuf), ARMAG) {
+ for i := 0; i < len(ARMAG); i++ {
+ if c, err := f.ReadByte(); err == nil && c == ARMAG[i] {
+ continue
+ }
+
/* load it as a regular file */
- l := obj.Bseek(f, 0, 2)
+ l := f.Seek(0, 2)
- obj.Bseek(f, 0, 0)
+ f.Seek(0, 0)
ldobj(f, pkg, l, lib.File, lib.File, FileObj)
- obj.Bterm(f)
+ f.Close()
return
}
/* process __.PKGDEF */
- off := obj.Boffset(f)
+ off := f.Offset()
var arhdr ArHdr
l := nextar(f, off, &arhdr)
@@ -812,12 +812,14 @@ func objfile(lib *Library) {
}
if Buildmode == BuildmodeShared {
- before := obj.Boffset(f)
+ before := f.Offset()
pkgdefBytes := make([]byte, atolwhex(arhdr.size))
- obj.Bread(f, pkgdefBytes)
+ if _, err := io.ReadFull(f, pkgdefBytes); err != nil {
+ Diag("%s: short read on archive file symbol header: %v", lib.File, err)
+ }
hash := sha1.Sum(pkgdefBytes)
lib.hash = hash[:]
- obj.Bseek(f, before, 0)
+ f.Seek(before, 0)
}
off += l
@@ -853,11 +855,11 @@ func objfile(lib *Library) {
}
out:
- obj.Bterm(f)
+ f.Close()
}
type Hostobj struct {
- ld func(*obj.Biobuf, string, int64, string)
+ ld func(*bio.Reader, string, int64, string)
pkg string
pn string
file string
@@ -878,7 +880,7 @@ var internalpkg = []string{
"runtime/msan",
}
-func ldhostobj(ld func(*obj.Biobuf, string, int64, string), f *obj.Biobuf, pkg string, length int64, pn string, file string) *Hostobj {
+func ldhostobj(ld func(*bio.Reader, string, int64, string), f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj {
isinternal := false
for i := 0; i < len(internalpkg); i++ {
if pkg == internalpkg[i] {
@@ -909,26 +911,24 @@ func ldhostobj(ld func(*obj.Biobuf, string, int64, string), f *obj.Biobuf, pkg s
h.pkg = pkg
h.pn = pn
h.file = file
- h.off = obj.Boffset(f)
+ h.off = f.Offset()
h.length = length
return h
}
func hostobjs() {
- var f *obj.Biobuf
var h *Hostobj
for i := 0; i < len(hostobj); i++ {
h = &hostobj[i]
- var err error
- f, err = obj.Bopenr(h.file)
- if f == nil {
+ f, err := bio.Open(h.file)
+ if err != nil {
Exitf("cannot reopen %s: %v", h.pn, err)
}
- obj.Bseek(f, h.off, 0)
+ f.Seek(h.off, 0)
h.ld(f, h.pkg, h.length, h.pn)
- obj.Bterm(f)
+ f.Close()
}
}
@@ -1040,7 +1040,7 @@ func archive() {
argv = append(argv, hostobjCopy()...)
if Debug['v'] != 0 {
- fmt.Fprintf(&Bso, "archive: %s\n", strings.Join(argv, " "))
+ fmt.Fprintf(Bso, "archive: %s\n", strings.Join(argv, " "))
Bso.Flush()
}
@@ -1117,6 +1117,23 @@ func hostlink() {
// because lazy PLT resolution can use large amounts of stack at
// times we cannot allow it to do so.
argv = append(argv, "-Wl,-znow")
+
+ // Do not let the host linker generate COPY relocations. These
+ // can move symbols out of sections that rely on stable offsets
+ // from the beginning of the section (like STYPE).
+ argv = append(argv, "-Wl,-znocopyreloc")
+
+ if SysArch.InFamily(sys.ARM, sys.ARM64) {
+ // On ARM, the GNU linker will generate COPY relocations
+ // even with -znocopyreloc set.
+ // https://sourceware.org/bugzilla/show_bug.cgi?id=19962
+ //
+ // On ARM64, the GNU linker will fail instead of
+ // generating COPY relocations.
+ //
+ // In both cases, switch to gold.
+ argv = append(argv, "-fuse-ld=gold")
+ }
}
if Iself && len(buildinfo) > 0 {
@@ -1187,6 +1204,24 @@ func hostlink() {
argv = append(argv, ldflag...)
+ if flag_race != 0 {
+ // On a system where the toolchain creates position independent
+ // executables by default, tsan initialization can fail. So we pass
+ // -no-pie here, but support for that flag is quite new and we test
+ // for its support first.
+ src := filepath.Join(tmpdir, "trivial.c")
+ if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
+ Ctxt.Diag("WriteFile trivial.c failed: %v", err)
+ }
+ cmd := exec.Command(argv[0], "-no-pie", "trivial.c")
+ cmd.Dir = tmpdir
+ out, err := cmd.CombinedOutput()
+ supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
+ if supported {
+ argv = append(argv, "-no-pie")
+ }
+ }
+
for _, p := range strings.Fields(extldflags) {
argv = append(argv, p)
@@ -1209,24 +1244,24 @@ func hostlink() {
}
if Debug['v'] != 0 {
- fmt.Fprintf(&Bso, "host link:")
+ fmt.Fprintf(Bso, "host link:")
for _, v := range argv {
- fmt.Fprintf(&Bso, " %q", v)
+ fmt.Fprintf(Bso, " %q", v)
}
- fmt.Fprintf(&Bso, "\n")
+ fmt.Fprintf(Bso, "\n")
Bso.Flush()
}
if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
Exitf("running %s failed: %v\n%s", argv[0], err, out)
} else if Debug['v'] != 0 && len(out) > 0 {
- fmt.Fprintf(&Bso, "%s", out)
+ fmt.Fprintf(Bso, "%s", out)
Bso.Flush()
}
if Debug['s'] == 0 && debug_s == 0 && HEADTYPE == obj.Hdarwin {
// Skip combining dwarf on arm.
- if Thearch.Thechar != '5' && Thearch.Thechar != '7' {
+ if !SysArch.InFamily(sys.ARM, sys.ARM64) {
dsym := filepath.Join(tmpdir, "go.dwarf")
if out, err := exec.Command("dsymutil", "-f", outfile, "-o", dsym).CombinedOutput(); err != nil {
Ctxt.Cursym = nil
@@ -1254,14 +1289,14 @@ func hostlink() {
// hostlinkArchArgs returns arguments to pass to the external linker
// based on the architecture.
func hostlinkArchArgs() []string {
- switch Thearch.Thechar {
- case '8':
+ switch SysArch.Family {
+ case sys.I386:
return []string{"-m32"}
- case '6', '9', 'z':
+ case sys.AMD64, sys.PPC64, sys.S390X:
return []string{"-m64"}
- case '5':
+ case sys.ARM:
return []string{"-marm"}
- case '7':
+ case sys.ARM64:
// nothing needed
}
return nil
@@ -1270,15 +1305,15 @@ func hostlinkArchArgs() []string {
// ldobj loads an input object. If it is a host object (an object
// compiled by a non-Go compiler) it returns the Hostobj pointer. If
// it is a Go object, it returns nil.
-func ldobj(f *obj.Biobuf, pkg string, length int64, pn string, file string, whence int) *Hostobj {
- eof := obj.Boffset(f) + length
+func ldobj(f *bio.Reader, pkg string, length int64, pn string, file string, whence int) *Hostobj {
+ eof := f.Offset() + length
- start := obj.Boffset(f)
- c1 := obj.Bgetc(f)
- c2 := obj.Bgetc(f)
- c3 := obj.Bgetc(f)
- c4 := obj.Bgetc(f)
- obj.Bseek(f, start, 0)
+ start := f.Offset()
+ c1 := bgetc(f)
+ c2 := bgetc(f)
+ c3 := bgetc(f)
+ c4 := bgetc(f)
+ f.Seek(start, 0)
magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
if magic == 0x7f454c46 { // \x7F E L F
@@ -1294,22 +1329,19 @@ func ldobj(f *obj.Biobuf, pkg string, length int64, pn string, file string, when
}
/* check the header */
- line := obj.Brdline(f, '\n')
- if line == "" {
- if obj.Blinelen(f) > 0 {
- Diag("%s: not an object file", pn)
- return nil
- }
- Diag("truncated object file: %s", pn)
+ line, err := f.ReadString('\n')
+ if err != nil {
+ Diag("truncated object file: %s: %v", pn, err)
return nil
}
if !strings.HasPrefix(line, "go object ") {
if strings.HasSuffix(pn, ".go") {
- Exitf("%cl: input %s is not .%c file (use %cg to compile .go files)", Thearch.Thechar, pn, Thearch.Thechar, Thearch.Thechar)
+ Exitf("%s: uncompiled .go source file", pn)
+ return nil
}
- if line == Thestring {
+ if line == SysArch.Name {
// old header format: just $GOOS
Diag("%s: stale object file", pn)
return nil
@@ -1341,28 +1373,28 @@ func ldobj(f *obj.Biobuf, pkg string, length int64, pn string, file string, when
}
/* skip over exports and other info -- ends with \n!\n */
- import0 := obj.Boffset(f)
+ import0 := f.Offset()
c1 = '\n' // the last line ended in \n
- c2 = obj.Bgetc(f)
- c3 = obj.Bgetc(f)
+ c2 = bgetc(f)
+ c3 = bgetc(f)
for c1 != '\n' || c2 != '!' || c3 != '\n' {
c1 = c2
c2 = c3
- c3 = obj.Bgetc(f)
- if c3 == obj.Beof {
+ c3 = bgetc(f)
+ if c3 == -1 {
Diag("truncated object file: %s", pn)
return nil
}
}
- import1 := obj.Boffset(f)
+ import1 := f.Offset()
- obj.Bseek(f, import0, 0)
+ f.Seek(import0, 0)
ldpkg(f, pkg, import1-import0-2, pn, whence) // -2 for !\n
- obj.Bseek(f, import1, 0)
+ f.Seek(import1, 0)
- LoadObjFile(Ctxt, f, pkg, eof-obj.Boffset(f), pn)
+ LoadObjFile(Ctxt, f, pkg, eof-f.Offset(), pn)
return nil
}
@@ -1500,12 +1532,12 @@ func ldshlibsyms(shlib string) {
// the type data.
if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") {
lsym.P = readelfsymboldata(f, &elfsym)
- gcdata_locations[elfsym.Value+2*uint64(Thearch.Ptrsize)+8+1*uint64(Thearch.Ptrsize)] = lsym
+ gcdata_locations[elfsym.Value+2*uint64(SysArch.PtrSize)+8+1*uint64(SysArch.PtrSize)] = lsym
}
}
}
gcdata_addresses := make(map[*LSym]uint64)
- if Thearch.Thechar == '7' {
+ if SysArch.Family == sys.ARM64 {
for _, sect := range f.Sections {
if sect.Type == elf.SHT_RELA {
var rela elf.Rela64
@@ -1532,30 +1564,14 @@ func ldshlibsyms(shlib string) {
// We might have overwritten some functions above (this tends to happen for the
// autogenerated type equality/hashing functions) and we don't want to generated
- // pcln table entries for these any more so unstitch them from the Textp linked
- // list.
- var last *LSym
-
- for s := Ctxt.Textp; s != nil; s = s.Next {
- if s.Type == obj.SDYNIMPORT {
- continue
- }
-
- if last == nil {
- Ctxt.Textp = s
- } else {
- last.Next = s
+ // pcln table entries for these any more so remove them from Textp.
+ textp := make([]*LSym, 0, len(Ctxt.Textp))
+ for _, s := range Ctxt.Textp {
+ if s.Type != obj.SDYNIMPORT {
+ textp = append(textp, s)
}
- last = s
- }
-
- if last == nil {
- Ctxt.Textp = nil
- Ctxt.Etextp = nil
- } else {
- last.Next = nil
- Ctxt.Etextp = last
}
+ Ctxt.Textp = textp
Ctxt.Shlibs = append(Ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdata_addresses: gcdata_addresses})
}
@@ -1564,10 +1580,6 @@ func mywhatsys() {
goroot = obj.Getgoroot()
goos = obj.Getgoos()
goarch = obj.Getgoarch()
-
- if !strings.HasPrefix(goarch, Thestring) {
- log.Fatalf("cannot use %cc with GOARCH=%s", Thearch.Thechar, goarch)
- }
}
// Copied from ../gc/subr.c:/^pathtoprefix; must stay in sync.
@@ -1608,7 +1620,7 @@ func addsection(seg *Segment, name string, rwx int) *Section {
sect.Rwx = uint8(rwx)
sect.Name = name
sect.Seg = seg
- sect.Align = int32(Thearch.Ptrsize) // everything is at least pointer-aligned
+ sect.Align = int32(SysArch.PtrSize) // everything is at least pointer-aligned
*l = sect
return sect
}
@@ -1652,7 +1664,7 @@ func callsize() int {
if haslinkregister() {
return 0
}
- return Thearch.Regsize
+ return SysArch.RegSize
}
func dostkcheck() {
@@ -1673,7 +1685,7 @@ func dostkcheck() {
// Check every function, but do the nosplit functions in a first pass,
// to make the printed failure chains as short as possible.
- for s := Ctxt.Textp; s != nil; s = s.Next {
+ for _, s := range Ctxt.Textp {
// runtime.racesymbolizethunk is called from gcc-compiled C
// code running on the operating system thread stack.
// It uses more than the usual amount of stack but that's okay.
@@ -1688,7 +1700,7 @@ func dostkcheck() {
}
}
- for s := Ctxt.Textp; s != nil; s = s.Next {
+ for _, s := range Ctxt.Textp {
if !s.Attr.NoSplit() {
Ctxt.Cursym = s
ch.sym = s
@@ -1717,7 +1729,7 @@ func stkcheck(up *Chain, depth int) int {
return -1
}
- if s.Attr.External() || s.Pcln == nil {
+ if s.Attr.External() || s.FuncInfo == nil {
// external function.
// should never be called directly.
// only diagnose the direct caller.
@@ -1754,7 +1766,11 @@ func stkcheck(up *Chain, depth int) int {
return 0
}
// Raise limit to allow frame.
- limit = int(obj.StackLimit+s.Locals) + int(Ctxt.FixedFrameSize())
+ locals := int32(0)
+ if s.FuncInfo != nil {
+ locals = s.FuncInfo.Locals
+ }
+ limit = int(obj.StackLimit+locals) + int(Ctxt.FixedFrameSize())
}
// Walk through sp adjustments in function, consuming relocs.
@@ -1764,7 +1780,7 @@ func stkcheck(up *Chain, depth int) int {
var ch1 Chain
var pcsp Pciter
var r *Reloc
- for pciterinit(Ctxt, &pcsp, &s.Pcln.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
+ for pciterinit(Ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
// Check stack size in effect for this span.
@@ -1956,7 +1972,7 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
continue
}
if len(s.P) > 0 {
- Diag("%s should not be bss (size=%d type=%d special=%v)", s.Name, int(len(s.P)), s.Type, s.Attr.Special())
+ Diag("%s should not be bss (size=%d type=%d special=%v)", s.Name, len(s.P), s.Type, s.Attr.Special())
}
put(s, s.Name, 'B', Symaddr(s), s.Size, int(s.Version), s.Gotype)
@@ -1982,13 +1998,20 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
}
var off int32
- for s := Ctxt.Textp; s != nil; s = s.Next {
+ for _, s := range Ctxt.Textp {
put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), s.Gotype)
+ locals := int32(0)
+ if s.FuncInfo != nil {
+ locals = s.FuncInfo.Locals
+ }
// NOTE(ality): acid can't produce a stack trace without .frame symbols
- put(nil, ".frame", 'm', int64(s.Locals)+int64(Thearch.Ptrsize), 0, 0, nil)
+ put(nil, ".frame", 'm', int64(locals)+int64(SysArch.PtrSize), 0, 0, nil)
- for _, a := range s.Autom {
+ if s.FuncInfo == nil {
+ continue
+ }
+ for _, a := range s.FuncInfo.Autom {
// Emit a or p according to actual offset, even if label is wrong.
// This avoids negative offsets, which cannot be encoded.
if a.Name != obj.A_AUTO && a.Name != obj.A_PARAM {
@@ -1999,7 +2022,7 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
if a.Name == obj.A_PARAM {
off = a.Aoffset
} else {
- off = a.Aoffset - int32(Thearch.Ptrsize)
+ off = a.Aoffset - int32(SysArch.PtrSize)
}
// FP
@@ -2009,8 +2032,8 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
}
// SP
- if off <= int32(-Thearch.Ptrsize) {
- put(nil, a.Asym.Name, 'a', -(int64(off) + int64(Thearch.Ptrsize)), 0, 0, a.Gotype)
+ if off <= int32(-SysArch.PtrSize) {
+ put(nil, a.Asym.Name, 'a', -(int64(off) + int64(SysArch.PtrSize)), 0, 0, a.Gotype)
continue
}
}
@@ -2019,7 +2042,7 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
// Otherwise, off is addressing the saved program counter.
// Something underhanded is going on. Say nothing.
if Debug['v'] != 0 || Debug['n'] != 0 {
- fmt.Fprintf(&Bso, "%5.2f symsize = %d\n", obj.Cputime(), uint32(Symsize))
+ fmt.Fprintf(Bso, "%5.2f symsize = %d\n", obj.Cputime(), uint32(Symsize))
}
Bso.Flush()
}
@@ -2085,10 +2108,10 @@ func undefsym(s *LSym) {
}
func undef() {
- for s := Ctxt.Textp; s != nil; s = s.Next {
+ for _, s := range Ctxt.Textp {
undefsym(s)
}
- for s := datap; s != nil; s = s.Next {
+ for _, s := range datap {
undefsym(s)
}
if nerrors > 0 {
@@ -2103,14 +2126,14 @@ func callgraph() {
var i int
var r *Reloc
- for s := Ctxt.Textp; s != nil; s = s.Next {
+ for _, s := range Ctxt.Textp {
for i = 0; i < len(s.R); i++ {
r = &s.R[i]
if r.Sym == nil {
continue
}
if (r.Type == obj.R_CALL || r.Type == obj.R_CALLARM || r.Type == obj.R_CALLPOWER || r.Type == obj.R_CALLMIPS) && r.Sym.Type == obj.STEXT {
- fmt.Fprintf(&Bso, "%s calls %s\n", s.Name, r.Sym.Name)
+ fmt.Fprintf(Bso, "%s calls %s\n", s.Name, r.Sym.Name)
}
}
}
@@ -2145,3 +2168,14 @@ func Rnd(v int64, r int64) int64 {
v -= c
return v
}
+
+func bgetc(r *bio.Reader) int {
+ c, err := r.ReadByte()
+ if err != nil {
+ if err != io.EOF {
+ log.Fatalf("reading input: %v", err)
+ }
+ return -1
+ }
+ return int(c)
+}