diff options
Diffstat (limited to 'src/cmd/newlink/load.go')
-rw-r--r-- | src/cmd/newlink/load.go | 108 |
1 files changed, 0 insertions, 108 deletions
diff --git a/src/cmd/newlink/load.go b/src/cmd/newlink/load.go deleted file mode 100644 index 50602b82a1..0000000000 --- a/src/cmd/newlink/load.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Loading of code and data fragments from package files into final image. - -package main - -import ( - "cmd/internal/obj" - "os" -) - -// load allocates segment images, populates them with data -// read from package files, and applies relocations to the data. -func (p *Prog) load() { - // TODO(rsc): mmap the output file and store the data directly. - // That will make writing the output file more efficient. - for _, seg := range p.Segments { - seg.Data = make([]byte, seg.FileSize) - } - for _, pkg := range p.Packages { - p.loadPackage(pkg) - } -} - -// loadPackage loads and relocates data for all the -// symbols needed in the given package. -func (p *Prog) loadPackage(pkg *Package) { - if pkg.File == "" { - // This "package" contains internally generated symbols only. - // All such symbols have a sym.Bytes field holding the actual data - // (if any), plus relocations. - for _, sym := range pkg.Syms { - if sym.Bytes == nil { - continue - } - seg := sym.Section.Segment - off := sym.Addr - seg.VirtAddr - data := seg.Data[off : off+Addr(sym.Size)] - copy(data, sym.Bytes) - p.relocateSym(sym, data) - } - return - } - - // Package stored in file. - f, err := os.Open(pkg.File) - if err != nil { - p.errorf("%v", err) - return - } - defer f.Close() - - // TODO(rsc): Mmap file into memory. - - for _, sym := range pkg.Syms { - if sym.Data.Size == 0 { - continue - } - // TODO(rsc): If not using mmap, at least coalesce nearby reads. - if sym.Section == nil { - p.errorf("internal error: missing section for %s", sym.Name) - } - seg := sym.Section.Segment - off := sym.Addr - seg.VirtAddr - if off >= Addr(len(seg.Data)) || off+Addr(sym.Data.Size) > Addr(len(seg.Data)) { - p.errorf("internal error: allocated space for %s too small: %d bytes for %d+%d (%d)", sym, len(seg.Data), off, sym.Data.Size, sym.Size) - } - data := seg.Data[off : off+Addr(sym.Data.Size)] - _, err := f.ReadAt(data, sym.Data.Offset) - if err != nil { - p.errorf("reading %v: %v", sym.SymID, err) - } - p.relocateSym(sym, data) - } -} - -// relocateSym applies relocations to sym's data. -func (p *Prog) relocateSym(sym *Sym, data []byte) { - for i := range sym.Reloc { - r := &sym.Reloc[i] - targ := p.Syms[r.Sym] - if targ == nil { - p.errorf("%v: reference to undefined symbol %v", sym, r.Sym) - continue - } - val := targ.Addr + Addr(r.Add) - switch r.Type { - default: - p.errorf("%v: unknown relocation type %d", sym, r.Type) - case obj.R_ADDR, obj.R_CALLIND: - // ok - case obj.R_PCREL, obj.R_CALL: - val -= sym.Addr + Addr(r.Offset+r.Size) - } - frag := data[r.Offset : r.Offset+r.Size] - switch r.Size { - default: - p.errorf("%v: unknown relocation size %d", sym, r.Size) - case 4: - // TODO(rsc): Check for overflow? - p.byteorder.PutUint32(frag, uint32(val)) - case 8: - p.byteorder.PutUint64(frag, uint64(val)) - } - } -} |