Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(8)

Delta Between Two Patch Sets: src/cmd/link/prog.go

Issue 48870044: code review 48870044: cmd/link: intial skeleton of linker written in Go (Closed)
Left Patch Set: Created 11 years, 2 months ago
Right Patch Set: diff -r e4b3e3c1edda https://code.google.com/p/go/ Created 11 years, 2 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
LEFTRIGHT
(no file at all)
1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package main
6
7 import (
8 "debug/goobj"
9 "fmt"
10 "go/build"
11 "io"
12 "os"
13 )
14
15 // A Prog holds state for constructing an executable (program) image.
16 //
17 // The usual sequence of operations on a Prog is:
18 //
19 // p.init()
20 // p.scan(file)
21 // p.dead()
22 // p.runtime()
23 // p.layout()
24 // p.load()
25 // p.debug()
26 // p.write(w)
27 //
28 // p.init is in this file. The rest of the methods are in files
29 // named for the method. The convenience method p.link runs
30 // this sequence.
31 //
32 type Prog struct {
33 // Context
34 GOOS string // target operating system
35 GOARCH string // target architecture
36 Format string // desired file format ("elf", "macho", ...)
37 formatter formatter
38 Error func(string) // called to report an error (if set)
39 NumError int // number of errors printed
40
41 // Input
42 Packages map[string]*Package // loaded packages, by import path
43 Syms map[goobj.SymID]*Sym // defined symbols, by symbol ID
44 Missing map[goobj.SymID]bool // missing symbols, by symbol ID
45 MaxVersion int // max SymID.Version, for generating fre sh symbol IDs
46
47 // Output
48 UnmappedSize Addr // size of unmapped region at address 0
49 HeaderSize Addr // size of object file header
50 Entry Addr // virtual address where execution begins
51 Segments []*Segment // loaded memory segments
52 }
53
54 // startSymID is the symbol where program execution begins.
55 var startSymID = goobj.SymID{Name: "_rt0_go"}
56
57 // A formatter takes care of the details of generating a particular
58 // kind of executable file.
59 type formatter interface {
60 // headerSize returns the footprint of the header for p
61 // in both virtual address space and file bytes.
62 // The footprint does not include any bytes stored at the
63 // end of the file.
64 headerSize(p *Prog) (virt, file Addr)
65
66 // write writes the executable file for p to w.
67 write(w io.Writer, p *Prog)
68 }
69
70 // An Addr represents a virtual memory address, a file address, or a size.
71 // It must be a uint64, not a uintptr, so that a 32-bit linker can still generat e a 64-bit binary.
72 // It must be unsigned in order to link programs placed at very large start addr esses.
73 // Math involving Addrs must be checked carefully not to require negative number s.
74 type Addr uint64
75
76 // A Package is a Go package loaded from a file.
77 type Package struct {
78 *goobj.Package // table of contents
79 File string // file name for reopening
80 Syms []*Sym // symbols defined by this package
81 }
82
83 // A Sym is a symbol defined in a loaded package.
84 type Sym struct {
85 *goobj.Sym // symbol metadata from package file
86 Package *Package // package defining symbol
87 Section *Section // section where symbol is placed in output program
88 Addr Addr // virtual address of symbol in output program
89 }
90
91 // A Segment is a loaded memory segment.
92 // A Prog is expected to have segments named "text" and optionally "data",
93 // in that order, before any other segments.
94 type Segment struct {
95 Name string // name of segment: "text", "data", ...
96 VirtAddr Addr // virtual memory address of segment base
97 VirtSize Addr // size of segment in memory
98 FileOffset Addr // file offset of segment base
99 FileSize Addr // size of segment in file; can be less than VirtS ize
100 Sections []*Section // sections inside segment
101 Data []byte // raw data of segment image
102 }
103
104 // A Section is part of a loaded memory segment.
105 type Section struct {
106 Name string // name of section: "text", "rodata", "noptrbss", and so on
107 VirtAddr Addr // virtual memory address of section base
108 Size Addr // size of section in memory
109 Align Addr // required alignment
110 InFile bool // section has image data in file (like data, unlike b ss)
111 Syms []*Sym // symbols stored in section
112 Segment *Segment // segment containing section
113 }
114
115 func (p *Prog) errorf(format string, args ...interface{}) {
116 if p.Error != nil {
117 p.Error(fmt.Sprintf(format, args...))
118 } else {
119 fmt.Fprintf(os.Stderr, format+"\n", args...)
120 }
121 p.NumError++
122 }
123
124 // link is the one-stop convenience method for running a link.
125 // It writes to w the object file generated from using mainFile as the main pack age.
126 func (p *Prog) link(w io.Writer, mainFile string) {
127 p.init()
128 p.scan(mainFile)
129 if p.NumError > 0 {
130 return
131 }
132 p.dead()
133 p.runtime()
134 p.layout()
135 if p.NumError > 0 {
136 return
137 }
138 p.load()
139 if p.NumError > 0 {
140 return
141 }
142 p.debug()
143 if p.NumError > 0 {
144 return
145 }
146 p.write(w)
147 }
148
149 // init initializes p for use by the other methods.
150 func (p *Prog) init() {
151 // Set default context if not overridden.
152 if p.GOOS == "" {
153 p.GOOS = build.Default.GOOS
154 }
155 if p.GOARCH == "" {
156 p.GOARCH = build.Default.GOARCH
157 }
158 if p.Format == "" {
159 p.Format = goosFormat[p.GOOS]
160 if p.Format == "" {
161 p.errorf("no default file format for GOOS %q", p.GOOS)
162 return
163 }
164 }
165
166 // Derive internal context.
167 p.formatter = formatters[p.Format]
168 if p.formatter == nil {
169 p.errorf("unknown output file format %q", p.Format)
170 return
171 }
172 }
173
174 // goosFormat records the default format for each known GOOS value.
175 var goosFormat = map[string]string{
176 "darwin": "darwin",
177 }
178
179 // formatters records the format implementation for each known format value.
180 var formatters = map[string]formatter{
181 "darwin": machoFormat{},
182 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b