Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 1 | // Derived from Inferno utils/6l/l.h and related files. |
| 2 | // http://code.google.com/p/inferno-os/source/browse/utils/6l/l.h |
| 3 | // |
| 4 | // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. |
| 5 | // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) |
| 6 | // Portions Copyright © 1997-1999 Vita Nuova Limited |
| 7 | // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) |
| 8 | // Portions Copyright © 2004,2006 Bruce Ellis |
| 9 | // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) |
| 10 | // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others |
| 11 | // Portions Copyright © 2009 The Go Authors. All rights reserved. |
| 12 | // |
| 13 | // Permission is hereby granted, free of charge, to any person obtaining a copy |
| 14 | // of this software and associated documentation files (the "Software"), to deal |
| 15 | // in the Software without restriction, including without limitation the rights |
| 16 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 17 | // copies of the Software, and to permit persons to whom the Software is |
| 18 | // furnished to do so, subject to the following conditions: |
| 19 | // |
| 20 | // The above copyright notice and this permission notice shall be included in |
| 21 | // all copies or substantial portions of the Software. |
| 22 | // |
| 23 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 24 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 25 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 26 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 27 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 28 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 29 | // THE SOFTWARE. |
| 30 | |
| 31 | package ld |
| 32 | |
Dave Cheney | 71274e4 | 2015-05-02 12:44:49 +1000 | [diff] [blame] | 33 | import ( |
| 34 | "cmd/internal/obj" |
Michael Hudson-Doyle | 9f5d0bf | 2015-05-05 16:10:12 +1200 | [diff] [blame] | 35 | "debug/elf" |
Dave Cheney | 71274e4 | 2015-05-02 12:44:49 +1000 | [diff] [blame] | 36 | "encoding/binary" |
Russ Cox | 512f75e | 2015-05-08 01:43:18 -0400 | [diff] [blame] | 37 | "fmt" |
Dave Cheney | 71274e4 | 2015-05-02 12:44:49 +1000 | [diff] [blame] | 38 | ) |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 39 | |
| 40 | type LSym struct { |
Michael Hudson-Doyle | 9f5d0bf | 2015-05-05 16:10:12 +1200 | [diff] [blame] | 41 | Name string |
| 42 | Extname string |
| 43 | Type int16 |
| 44 | Version int16 |
| 45 | Dupok uint8 |
| 46 | Cfunc uint8 |
| 47 | External uint8 |
| 48 | Nosplit uint8 |
| 49 | Reachable bool |
| 50 | Cgoexport uint8 |
| 51 | Special uint8 |
| 52 | Stkcheck uint8 |
| 53 | Hide uint8 |
| 54 | Leaf uint8 |
| 55 | Localentry uint8 |
| 56 | Onlist uint8 |
| 57 | // ElfType is set for symbols read from shared libraries by ldshlibsyms. It |
| 58 | // is not set for symbols defined by the packages being linked or by symbols |
| 59 | // read by ldelf (and so is left as elf.STT_NOTYPE). |
| 60 | ElfType elf.SymType |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 61 | Dynid int32 |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 62 | Plt int32 |
| 63 | Got int32 |
| 64 | Align int32 |
| 65 | Elfsym int32 |
| 66 | Args int32 |
| 67 | Locals int32 |
| 68 | Value int64 |
| 69 | Size int64 |
| 70 | Hash *LSym |
| 71 | Allsym *LSym |
| 72 | Next *LSym |
| 73 | Sub *LSym |
| 74 | Outer *LSym |
| 75 | Gotype *LSym |
| 76 | Reachparent *LSym |
| 77 | Queue *LSym |
| 78 | File string |
| 79 | Dynimplib string |
| 80 | Dynimpvers string |
Michael Hudson-Doyle | cf2736c | 2015-05-27 12:04:25 +1200 | [diff] [blame] | 81 | Sect *Section |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 82 | Autom *Auto |
| 83 | Pcln *Pcln |
| 84 | P []byte |
| 85 | R []Reloc |
Michael Hudson-Doyle | 00bc19e | 2015-03-30 02:59:10 +0000 | [diff] [blame] | 86 | Local bool |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 87 | } |
| 88 | |
Russ Cox | 512f75e | 2015-05-08 01:43:18 -0400 | [diff] [blame] | 89 | func (s *LSym) String() string { |
| 90 | if s.Version == 0 { |
| 91 | return s.Name |
| 92 | } |
| 93 | return fmt.Sprintf("%s<%d>", s.Name, s.Version) |
| 94 | } |
| 95 | |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 96 | type Reloc struct { |
| 97 | Off int32 |
| 98 | Siz uint8 |
| 99 | Done uint8 |
| 100 | Type int32 |
| 101 | Variant int32 |
| 102 | Add int64 |
| 103 | Xadd int64 |
| 104 | Sym *LSym |
| 105 | Xsym *LSym |
| 106 | } |
| 107 | |
| 108 | type Auto struct { |
| 109 | Asym *LSym |
| 110 | Link *Auto |
| 111 | Aoffset int32 |
| 112 | Name int16 |
| 113 | Gotype *LSym |
| 114 | } |
| 115 | |
Michael Hudson-Doyle | 77fc03f | 2015-04-11 12:05:21 +0800 | [diff] [blame] | 116 | type Shlib struct { |
| 117 | Path string |
| 118 | Hash []byte |
Michael Hudson-Doyle | bcc1870 | 2015-05-25 14:51:02 +1200 | [diff] [blame] | 119 | Deps []string |
Michael Hudson-Doyle | c949cff | 2015-05-25 16:13:50 +1200 | [diff] [blame] | 120 | File *elf.File |
Michael Hudson-Doyle | 77fc03f | 2015-04-11 12:05:21 +0800 | [diff] [blame] | 121 | } |
| 122 | |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 123 | type Link struct { |
Michael Hudson-Doyle | 7f9e443 | 2015-08-19 13:34:33 +1200 | [diff] [blame] | 124 | Thechar int32 |
| 125 | Thestring string |
| 126 | Goarm int32 |
| 127 | Headtype int |
| 128 | Arch *LinkArch |
| 129 | Debugasm int32 |
| 130 | Debugvlog int32 |
| 131 | Bso *obj.Biobuf |
| 132 | Windows int32 |
| 133 | Goroot string |
| 134 | Hash map[symVer]*LSym |
| 135 | Allsym *LSym |
| 136 | Nsymbol int32 |
| 137 | Tlsg *LSym |
| 138 | Libdir []string |
| 139 | Library []*Library |
| 140 | Shlibs []Shlib |
| 141 | Tlsoffset int |
| 142 | Diag func(string, ...interface{}) |
| 143 | Cursym *LSym |
| 144 | Version int |
| 145 | Textp *LSym |
| 146 | Etextp *LSym |
| 147 | Nhistfile int32 |
| 148 | Filesyms *LSym |
| 149 | Moduledata *LSym |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 150 | } |
| 151 | |
Michael Hudson-Doyle | d66f6c2c | 2015-10-12 12:19:20 +1300 | [diff] [blame^] | 152 | // The smallest possible offset from the hardware stack pointer to a local |
| 153 | // variable on the stack. Architectures that use a link register save its value |
| 154 | // on the stack in the function prologue and so always have a pointer between |
| 155 | // the hardware stack pointer and the local variable area. |
| 156 | func (ctxt *Link) FixedFrameSize() int64 { |
| 157 | switch ctxt.Arch.Thechar { |
| 158 | case '6', '8': |
| 159 | return 0 |
| 160 | default: |
| 161 | return int64(ctxt.Arch.Ptrsize) |
| 162 | } |
| 163 | } |
| 164 | |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 165 | type LinkArch struct { |
| 166 | ByteOrder binary.ByteOrder |
| 167 | Name string |
| 168 | Thechar int |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 169 | Minlc int |
| 170 | Ptrsize int |
| 171 | Regsize int |
| 172 | } |
| 173 | |
| 174 | type Library struct { |
| 175 | Objref string |
| 176 | Srcref string |
| 177 | File string |
| 178 | Pkg string |
Michael Hudson-Doyle | 75c0566 | 2015-04-01 14:57:34 +1300 | [diff] [blame] | 179 | Shlib string |
Michael Hudson-Doyle | 77fc03f | 2015-04-11 12:05:21 +0800 | [diff] [blame] | 180 | hash []byte |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 181 | } |
| 182 | |
| 183 | type Pcln struct { |
| 184 | Pcsp Pcdata |
| 185 | Pcfile Pcdata |
| 186 | Pcline Pcdata |
| 187 | Pcdata []Pcdata |
| 188 | Npcdata int |
| 189 | Funcdata []*LSym |
| 190 | Funcdataoff []int64 |
| 191 | Nfuncdata int |
| 192 | File []*LSym |
| 193 | Nfile int |
| 194 | Mfile int |
| 195 | Lastfile *LSym |
| 196 | Lastindex int |
| 197 | } |
| 198 | |
| 199 | type Pcdata struct { |
| 200 | P []byte |
| 201 | } |
| 202 | |
| 203 | type Pciter struct { |
| 204 | d Pcdata |
| 205 | p []byte |
| 206 | pc uint32 |
| 207 | nextpc uint32 |
| 208 | pcscale uint32 |
| 209 | value int32 |
| 210 | start int |
| 211 | done int |
| 212 | } |
| 213 | |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 214 | // Reloc.variant |
| 215 | const ( |
| 216 | RV_NONE = iota |
| 217 | RV_POWER_LO |
| 218 | RV_POWER_HI |
| 219 | RV_POWER_HA |
| 220 | RV_POWER_DS |
| 221 | RV_CHECK_OVERFLOW = 1 << 8 |
| 222 | RV_TYPE_MASK = RV_CHECK_OVERFLOW - 1 |
| 223 | ) |
| 224 | |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 225 | // Pcdata iterator. |
| 226 | // for(pciterinit(ctxt, &it, &pcd); !it.done; pciternext(&it)) { it.value holds in [it.pc, it.nextpc) } |
| 227 | |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 228 | // Link holds the context for writing object code from a compiler |
| 229 | // to be linker input or for reading that input into the linker. |
| 230 | |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 231 | // LinkArch is the definition of a single architecture. |
| 232 | |
Russ Cox | 1f9dbb6 | 2015-02-27 22:57:28 -0500 | [diff] [blame] | 233 | const ( |
| 234 | LinkAuto = 0 + iota |
| 235 | LinkInternal |
| 236 | LinkExternal |
| 237 | ) |