[dev.link] all: merge branch 'master' into dev.link

Clean merge.

Change-Id: Id03e6f00790ad52e0202111bbbc35f5c05567427
diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go
index 991f552..0f0dcc4 100644
--- a/src/cmd/link/internal/amd64/asm.go
+++ b/src/cmd/link/internal/amd64/asm.go
@@ -98,6 +98,14 @@
 	initarray_entry.AddAddr(ctxt.Arch, initfunc)
 }
 
+// makeWritable makes a readonly symbol writable if we do opcode rewriting.
+func makeWritable(s *sym.Symbol) {
+	if s.Attr.ReadOnly() {
+		s.Attr.Set(sym.AttrReadOnly, false)
+		s.P = append([]byte(nil), s.P...)
+	}
+}
+
 func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
 	targ := r.Sym
 
@@ -219,6 +227,7 @@
 				return false
 			}
 
+			makeWritable(s)
 			s.P[r.Off-2] = 0x8d
 			r.Type = objabi.R_PCREL
 			return true
diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go
index c0fa5fa..4fa0d5d 100644
--- a/src/cmd/link/internal/loader/loader.go
+++ b/src/cmd/link/internal/loader/loader.go
@@ -1058,7 +1058,7 @@
 				rs = 0
 				sz = 0
 			}
-			if rs != 0 && l.SymType(rs) == sym.SABIALIAS {
+			if rs != 0 && l.Syms[rs] != nil && l.Syms[rs].Type == sym.SABIALIAS {
 				rsrelocs := l.Relocs(rs)
 				rs = rsrelocs.At(0).Sym
 			}
diff --git a/src/cmd/link/internal/loadmacho/ldmacho.go b/src/cmd/link/internal/loadmacho/ldmacho.go
index 85a1ebc..deea27b 100644
--- a/src/cmd/link/internal/loadmacho/ldmacho.go
+++ b/src/cmd/link/internal/loadmacho/ldmacho.go
@@ -14,7 +14,6 @@
 	"cmd/link/internal/sym"
 	"encoding/binary"
 	"fmt"
-	"io"
 	"sort"
 )
 
@@ -320,10 +319,9 @@
 		return 0
 	}
 	rel := make([]ldMachoRel, sect.nreloc)
-	n := int(sect.nreloc * 8)
-	buf := make([]byte, n)
 	m.f.MustSeek(m.base+int64(sect.reloff), 0)
-	if _, err := io.ReadFull(m.f, buf); err != nil {
+	buf, _, err := m.f.Slice(uint64(sect.nreloc * 8))
+	if err != nil {
 		return -1
 	}
 	for i := uint32(0); i < sect.nreloc; i++ {
@@ -364,10 +362,9 @@
 
 func macholoaddsym(m *ldMachoObj, d *ldMachoDysymtab) int {
 	n := int(d.nindirectsyms)
-
-	p := make([]byte, n*4)
 	m.f.MustSeek(m.base+int64(d.indirectsymoff), 0)
-	if _, err := io.ReadFull(m.f, p); err != nil {
+	p, _, err := m.f.Slice(uint64(n * 4))
+	if err != nil {
 		return -1
 	}
 
@@ -383,9 +380,9 @@
 		return 0
 	}
 
-	strbuf := make([]byte, symtab.strsize)
 	m.f.MustSeek(m.base+int64(symtab.stroff), 0)
-	if _, err := io.ReadFull(m.f, strbuf); err != nil {
+	strbuf, _, err := m.f.Slice(uint64(symtab.strsize))
+	if err != nil {
 		return -1
 	}
 
@@ -394,9 +391,9 @@
 		symsize = 16
 	}
 	n := int(symtab.nsym * uint32(symsize))
-	symbuf := make([]byte, n)
 	m.f.MustSeek(m.base+int64(symtab.symoff), 0)
-	if _, err := io.ReadFull(m.f, symbuf); err != nil {
+	symbuf, _, err := m.f.Slice(uint64(n))
+	if err != nil {
 		return -1
 	}
 	sym := make([]ldMachoSym, symtab.nsym)
@@ -444,8 +441,8 @@
 
 	base := f.Offset()
 
-	var hdr [7 * 4]uint8
-	if _, err := io.ReadFull(f, hdr[:]); err != nil {
+	hdr, _, err := f.Slice(7 * 4)
+	if err != nil {
 		return errorf("reading hdr: %v", err)
 	}
 
@@ -499,8 +496,8 @@
 	}
 
 	m.cmd = make([]ldMachoCmd, ncmd)
-	cmdp := make([]byte, cmdsz)
-	if _, err := io.ReadFull(f, cmdp); err != nil {
+	cmdp, _, err := f.Slice(uint64(cmdsz))
+	if err != nil {
 		return errorf("reading cmds: %v", err)
 	}
 
@@ -559,8 +556,8 @@
 	}
 
 	f.MustSeek(m.base+int64(c.seg.fileoff), 0)
-	dat := make([]byte, c.seg.filesz)
-	if _, err := io.ReadFull(f, dat); err != nil {
+	dat, readOnly, err := f.Slice(uint64(c.seg.filesz))
+	if err != nil {
 		return errorf("cannot load object data: %v", err)
 	}
 
@@ -581,6 +578,7 @@
 		if sect.flags&0xff == 1 { // S_ZEROFILL
 			s.P = make([]byte, sect.size)
 		} else {
+			s.Attr.Set(sym.AttrReadOnly, readOnly)
 			s.P = dat[sect.addr-c.seg.vmaddr:][:sect.size]
 		}
 		s.Size = int64(len(s.P))