diff options
Diffstat (limited to 'src/cmd/newlink/layout.go')
-rw-r--r-- | src/cmd/newlink/layout.go | 180 |
1 files changed, 0 insertions, 180 deletions
diff --git a/src/cmd/newlink/layout.go b/src/cmd/newlink/layout.go deleted file mode 100644 index d5c291e255..0000000000 --- a/src/cmd/newlink/layout.go +++ /dev/null @@ -1,180 +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. - -// Executable image layout - address assignment. - -package main - -import ( - "cmd/internal/goobj" -) - -// A layoutSection describes a single section to add to the -// final executable. Go binaries only have a fixed set of possible -// sections, and the symbol kind determines the section. -type layoutSection struct { - Segment string - Section string - Kind goobj.SymKind - Index int -} - -// layout defines the layout of the generated Go executable. -// The order of entries here is the order in the executable. -// Entries with the same Segment name must be contiguous. -var layout = []layoutSection{ - {Segment: "text", Section: "text", Kind: goobj.STEXT}, - {Segment: "rodata", Section: "rodata", Kind: goobj.SRODATA}, - {Segment: "rodata", Section: "functab", Kind: goobj.SPCLNTAB}, - {Segment: "rodata", Section: "typelink", Kind: goobj.STYPELINK}, - {Segment: "data", Section: "noptrdata", Kind: goobj.SNOPTRDATA}, - {Segment: "data", Section: "data", Kind: goobj.SDATA}, - {Segment: "data", Section: "bss", Kind: goobj.SBSS}, - {Segment: "data", Section: "noptrbss", Kind: goobj.SNOPTRBSS}, - - // Later: - // {"rodata", "type", goobj.STYPE}, - // {"rodata", "string", goobj.SSTRING}, - // {"rodata", "gostring", goobj.SGOSTRING}, - // {"rodata", "gofunc", goobj.SGOFUNC}, -} - -// layoutByKind maps from SymKind to an entry in layout. -var layoutByKind []*layoutSection - -func init() { - // Build index from symbol type to layout entry. - max := 0 - for _, sect := range layout { - if max <= int(sect.Kind) { - max = int(sect.Kind) + 1 - } - } - layoutByKind = make([]*layoutSection, max) - for i := range layout { - sect := &layout[i] - layoutByKind[sect.Kind] = sect - sect.Index = i - } -} - -// layout arranges symbols into sections and sections into segments, -// and then it assigns addresses to segments, sections, and symbols. -func (p *Prog) layout() { - sections := make([]*Section, len(layout)) - - // Assign symbols to sections using index, creating sections as needed. - // Could keep sections separated by type during input instead. - for _, sym := range p.SymOrder { - kind := sym.Kind - if kind < 0 || int(kind) >= len(layoutByKind) || layoutByKind[kind] == nil { - p.errorf("%s: unexpected symbol kind %v", sym.SymID, kind) - continue - } - lsect := layoutByKind[kind] - sect := sections[lsect.Index] - if sect == nil { - sect = &Section{ - Name: lsect.Section, - Align: 1, - } - sections[lsect.Index] = sect - } - if sym.Data.Size > 0 || len(sym.Bytes) > 0 { - sect.InFile = true - } - sym.Section = sect - sect.Syms = append(sect.Syms, sym) - - // TODO(rsc): Incorporate alignment information. - // First that information needs to be added to the object files. - // - // if sect.Align < Addr(sym.Align) { - // sect.Align = Addr(sym.Align) - // } - } - - // Assign sections to segments, creating segments as needed. - var seg *Segment - for i, sect := range sections { - if sect == nil { - continue - } - segName := layout[i].Segment - - // Special case: Mach-O does not support "rodata" segment, - // so store read-only data in text segment. - if p.GOOS == "darwin" && segName == "rodata" { - segName = "text" - } - - if seg == nil || seg.Name != segName { - seg = &Segment{ - Name: segName, - } - p.Segments = append(p.Segments, seg) - } - sect.Segment = seg - seg.Sections = append(seg.Sections, sect) - } - - // Assign addresses. - - // TODO(rsc): This choice needs to be informed by both - // the formatter and the target architecture. - // And maybe eventually a command line flag (sigh). - const segAlign = 4096 - - // TODO(rsc): Use a larger amount on most systems, which will let the - // compiler eliminate more nil checks. - if p.UnmappedSize == 0 { - p.UnmappedSize = segAlign - } - - // TODO(rsc): addr := Addr(0) when generating a shared library or PIE. - addr := p.UnmappedSize - - // Account for initial file header. - hdrVirt, hdrFile := p.formatter.headerSize(p) - addr += hdrVirt - - // Assign addresses to segments, sections, symbols. - // Assign sizes to segments, sections. - startVirt := addr - startFile := hdrFile - for _, seg := range p.Segments { - addr = round(addr, segAlign) - seg.VirtAddr = addr - seg.FileOffset = startFile + seg.VirtAddr - startVirt - for _, sect := range seg.Sections { - addr = round(addr, sect.Align) - sect.VirtAddr = addr - for _, sym := range sect.Syms { - // TODO(rsc): Respect alignment once we have that information. - sym.Addr = addr - addr += Addr(sym.Size) - } - sect.Size = addr - sect.VirtAddr - if sect.InFile { - seg.FileSize = addr - seg.VirtAddr - } - } - seg.VirtSize = addr - seg.VirtAddr - } - - // Define symbols for section names. - var progEnd Addr - for i, sect := range sections { - name := layout[i].Section - var start, end Addr - if sect != nil { - start = sect.VirtAddr - end = sect.VirtAddr + sect.Size - } - p.defineConst("runtime."+name, start) - p.defineConst("runtime.e"+name, end) - progEnd = end - } - p.defineConst("runtime.end", progEnd) -} |