// - writing out the architecture specific pieces.
// This function handles the first part.
func asmb(ctxt *Link) {
- ctxt.loader.InitOutData()
if ctxt.IsExternal() && !ctxt.StreamExtRelocs() {
ctxt.loader.InitExtRelocs()
}
out.WriteStringPad("", int(val-addr), pad)
addr = val
}
- out.WriteSym(ldr, s)
- st.relocsym(s, ldr.OutData(s))
- addr += int64(len(ldr.Data(s)))
+ P := out.WriteSym(ldr, s)
+ st.relocsym(s, P)
+ addr += int64(len(P))
siz := ldr.SymSize(s)
if addr < val+siz {
out.WriteStringPad("", int(val+siz-addr), pad)
if relocs.Count() != 0 {
relocbuf = append(relocbuf[:0], P...)
P = relocbuf
+ st.relocsym(s, P)
}
- st.relocsym(s, P)
if _, err := z.Write(P); err != nil {
log.Fatalf("compression failed: %s", err)
}
// Generator symbols shouldn't grow the symbol size, and might be called in
// parallel in the future.
//
-// Generator Symbols have their Data and OutData set to the mmapped area when
-// the generator is called.
+// Generator Symbols have their Data set to the mmapped area when the
+// generator is called.
type generatorFunc func(*Link, loader.Sym)
// createGeneratorSymbol is a convenience method for creating a generator
}
}
-// WriteSym writes the content of a Symbol, then changes the Symbol's content
-// to point to the output buffer that we just wrote, so we can apply further
-// edit to the symbol content.
-// If the output file is not Mmap'd, just writes the content.
-func (out *OutBuf) WriteSym(ldr *loader.Loader, s loader.Sym) {
+// WriteSym writes the content of a Symbol, and returns the output buffer
+// that we just wrote, so we can apply further edit to the symbol content.
+// For generator symbols, it also sets the symbol's Data to the output
+// buffer.
+func (out *OutBuf) WriteSym(ldr *loader.Loader, s loader.Sym) []byte {
if !ldr.IsGeneratedSym(s) {
P := ldr.Data(s)
n := int64(len(P))
pos, buf := out.writeLoc(n)
copy(buf[pos:], P)
out.off += n
- ldr.SetOutData(s, buf[pos:pos+n])
+ ldr.FreeData(s)
+ return buf[pos : pos+n]
} else {
n := ldr.SymSize(s)
pos, buf := out.writeLoc(n)
out.off += n
- ldr.SetOutData(s, buf[pos:pos+n])
ldr.MakeSymbolUpdater(s).SetData(buf[pos : pos+n])
+ return buf[pos : pos+n]
}
}
align []uint8 // symbol 2^N alignment, indexed by global index
- outdata [][]byte // symbol's data in the output buffer
extRelocs [][]ExtReloc // symbol's external relocations
itablink map[Sym]struct{} // itablink[j] defined if j is go.itablink.*
return r.Data(li)
}
-// Returns the data of the i-th symbol in the output buffer.
-func (l *Loader) OutData(i Sym) []byte {
- if int(i) < len(l.outdata) && l.outdata[i] != nil {
- return l.outdata[i]
- }
- return l.Data(i)
-}
-
-// SetOutData sets the position of the data of the i-th symbol in the output buffer.
+// FreeData clears the symbol data of an external symbol, allowing the memory
+// to be freed earlier. No-op for non-external symbols.
// i is global index.
-func (l *Loader) SetOutData(i Sym, data []byte) {
+func (l *Loader) FreeData(i Sym) {
if l.IsExternal(i) {
pp := l.getPayload(i)
if pp != nil {
- pp.data = data
- return
+ pp.data = nil
}
}
- l.outdata[i] = data
-}
-
-// InitOutData initializes the slice used to store symbol output data.
-func (l *Loader) InitOutData() {
- l.outdata = make([][]byte, l.extStart)
}
// SetExtRelocs sets the external relocations of the i-th symbol. i is global index.
}
func applyrel(arch *sys.Arch, ldr *loader.Loader, rt objabi.RelocType, off int32, s loader.Sym, val int64, t int64) int64 {
- o := arch.ByteOrder.Uint32(ldr.OutData(s)[off:])
+ o := uint32(val)
switch rt {
case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSTLS:
return int64(o&0xffff0000 | uint32(t)&0xffff)
case objabi.R_ADDRMIPS,
objabi.R_ADDRMIPSU:
t := ldr.SymValue(rs) + r.Add()
- o1 := target.Arch.ByteOrder.Uint32(ldr.OutData(s)[r.Off():])
if r.Type() == objabi.R_ADDRMIPS {
- return int64(o1&0xffff0000 | uint32(t)&0xffff), noExtReloc, isOk
+ return int64(val&0xffff0000 | t&0xffff), noExtReloc, isOk
}
- return int64(o1&0xffff0000 | uint32((t+1<<15)>>16)&0xffff), noExtReloc, isOk
+ return int64(val&0xffff0000 | ((t+1<<15)>>16)&0xffff), noExtReloc, isOk
case objabi.R_ADDRMIPSTLS:
// thread pointer is at 0x7000 offset from the start of TLS data area
t := ldr.SymValue(rs) + r.Add() - 0x7000
if t < -32768 || t >= 32678 {
ldr.Errorf(s, "TLS offset out of range %d", t)
}
- o1 := target.Arch.ByteOrder.Uint32(ldr.OutData(s)[r.Off():])
- return int64(o1&0xffff0000 | uint32(t)&0xffff), noExtReloc, isOk
+ return int64(val&0xffff0000 | t&0xffff), noExtReloc, isOk
case objabi.R_CALLMIPS,
objabi.R_JMPMIPS:
// Low 26 bits = (S + A) >> 2
t := ldr.SymValue(rs) + r.Add()
- o1 := target.Arch.ByteOrder.Uint32(ldr.OutData(s)[r.Off():])
- return int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000), noExtReloc, isOk
+ return int64(val&0xfc000000 | (t>>2)&^0xfc000000), noExtReloc, isOk
}
return val, 0, false