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 (a] 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 (a] 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 obj 32 33 import "encoding/binary" 34 35 // An Addr is an argument to an instruction. 36 // The general forms and their encodings are: 37 // 38 // symoffset(symkind)(reg)(index*scale) 39 // Memory reference at address &sym(symkind) + offset + reg + index*scale. 40 // Any of sym(symkind), offset, (reg), (index*scale), and *scale can be omitted. 41 // If (reg) and *scale are both omitted, the resulting expression (index) is parsed as (reg). 42 // To force a parsing as index*scale, write (index*1). 43 // Encoding: 44 // type = TYPE_MEM 45 // name = symkind (NAME_AUTO, ...) or 0 (NAME_NONE) 46 // sym = sym 47 // offset = offset 48 // reg = reg (REG_*) 49 // index = index (REG_*) 50 // scale = scale (1, 2, 4, 8) 51 // 52 // $<mem> 53 // Effective address of memory reference <mem>, defined above. 54 // Encoding: same as memory reference, but type = TYPE_ADDR. 55 // 56 // $<integer value> 57 // This is a special case of $<mem>, in which only offset is present. 58 // It has a separate type for easy recognition. 59 // Encoding: 60 // type = TYPE_CONST 61 // offset = integer value 62 // 63 // *<mem> 64 // Indirect reference through memory reference <mem>, defined above. 65 // Only used on x86 for CALL/JMP *sym(SB), which calls/jumps to a function 66 // pointer stored in the data word sym(SB), not a function named sym(SB). 67 // Encoding: same as above, but type = TYPE_INDIR. 68 // 69 // $*$<mem> 70 // No longer used. 71 // On machines with actual SB registers, $*$<mem> forced the 72 // instruction encoding to use a full 32-bit constant, never a 73 // reference relative to SB. 74 // 75 // $<floating point literal> 76 // Floating point constant value. 77 // Encoding: 78 // type = TYPE_FCONST 79 // val = floating point value 80 // 81 // $<string literal, up to 8 chars> 82 // String literal value (raw bytes used for DATA instruction). 83 // Encoding: 84 // type = TYPE_SCONST 85 // val = string 86 // 87 // <register name> 88 // Any register: integer, floating point, control, segment, and so on. 89 // If looking for specific register kind, must check type and reg value range. 90 // Encoding: 91 // type = TYPE_REG 92 // reg = reg (REG_*) 93 // 94 // x(PC) 95 // Encoding: 96 // type = TYPE_BRANCH 97 // val = Prog* reference OR ELSE offset = target pc (branch takes priority) 98 // 99 // $x-y 100 // Final argument to TEXT, specifying local frame size x and argument size y. 101 // In this form, x and y are integer literals only, not arbitrary expressions. 102 // This avoids parsing ambiguities due to the use of - as a separator. 103 // The are optional. 104 // If the final argument to TEXT omits the -y, the encoding should still 105 // use TYPE_TEXTSIZE (not TYPE_CONST), with u.argsize = ArgsSizeUnknown. 106 // Encoding: 107 // type = TYPE_TEXTSIZE 108 // offset = x 109 // val = int32(y) 110 // 111 // reg<<shift, reg>>shift, reg->shift, reg@>shift 112 // Shifted register value, for ARM. 113 // In this form, reg must be a register and shift can be a register or an integer constant. 114 // Encoding: 115 // type = TYPE_SHIFT 116 // offset = (reg&15) | shifttype<<5 | count 117 // shifttype = 0, 1, 2, 3 for <<, >>, ->, @> 118 // count = (reg&15)<<8 | 1<<4 for a register shift count, (n&31)<<7 for an integer constant. 119 // 120 // (reg, reg) 121 // A destination register pair. When used as the last argument of an instruction, 122 // this form makes clear that both registers are destinations. 123 // Encoding: 124 // type = TYPE_REGREG 125 // reg = first register 126 // offset = second register 127 // 128 // [reg, reg, reg-reg] 129 // Register list for ARM. 130 // Encoding: 131 // type = TYPE_REGLIST 132 // offset = bit mask of registers in list; R0 is low bit. 133 // 134 // reg, reg 135 // Register pair for ARM. 136 // TYPE_REGREG2 137 // 138 // (reg+reg) 139 // Register pair for PPC64. 140 // Encoding: 141 // type = TYPE_MEM 142 // reg = first register 143 // index = second register 144 // scale = 1 145 // 146 type Addr struct { 147 Type int16 148 Reg int16 149 Index int16 150 Scale int16 // Sometimes holds a register. 151 Name int8 152 Class int8 153 Etype uint8 154 Offset int64 155 Width int64 156 Sym *LSym 157 Gotype *LSym 158 159 // argument value: 160 // for TYPE_SCONST, a string 161 // for TYPE_FCONST, a float64 162 // for TYPE_BRANCH, a *Prog (optional) 163 // for TYPE_TEXTSIZE, an int32 (optional) 164 Val interface{} 165 166 Node interface{} // for use by compiler 167 } 168 169 const ( 170 NAME_NONE = 0 + iota 171 NAME_EXTERN 172 NAME_STATIC 173 NAME_AUTO 174 NAME_PARAM 175 // A reference to name@GOT(SB) is a reference to the entry in the global offset 176 // table for 'name'. 177 NAME_GOTREF 178 ) 179 180 const ( 181 TYPE_NONE = 0 182 ) 183 184 const ( 185 TYPE_BRANCH = 5 + iota 186 TYPE_TEXTSIZE 187 TYPE_MEM 188 TYPE_CONST 189 TYPE_FCONST 190 TYPE_SCONST 191 TYPE_REG 192 TYPE_ADDR 193 TYPE_SHIFT 194 TYPE_REGREG 195 TYPE_REGREG2 196 TYPE_INDIR 197 TYPE_REGLIST 198 ) 199 200 // TODO(rsc): Describe prog. 201 // TODO(rsc): Describe TEXT/GLOBL flag in from3, DATA width in from3. 202 type Prog struct { 203 Ctxt *Link 204 Link *Prog 205 From Addr 206 From3 *Addr // optional 207 To Addr 208 Opt interface{} 209 Forwd *Prog 210 Pcond *Prog 211 Rel *Prog // Source of forward jumps on x86; pcrel on arm 212 Pc int64 213 Lineno int32 214 Spadj int32 215 As int16 216 Reg int16 217 RegTo2 int16 // 2nd register output operand 218 Mark uint16 219 Optab uint16 220 Scond uint8 221 Back uint8 222 Ft uint8 223 Tt uint8 224 Isize uint8 225 Mode int8 226 227 Info ProgInfo 228 } 229 230 // From3Type returns From3.Type, or TYPE_NONE when From3 is nil. 231 func (p *Prog) From3Type() int16 { 232 if p.From3 == nil { 233 return TYPE_NONE 234 } 235 return p.From3.Type 236 } 237 238 // From3Offset returns From3.Offset, or 0 when From3 is nil. 239 func (p *Prog) From3Offset() int64 { 240 if p.From3 == nil { 241 return 0 242 } 243 return p.From3.Offset 244 } 245 246 // ProgInfo holds information about the instruction for use 247 // by clients such as the compiler. The exact meaning of this 248 // data is up to the client and is not interpreted by the cmd/internal/obj/... packages. 249 type ProgInfo struct { 250 Flags uint32 // flag bits 251 Reguse uint64 // registers implicitly used by this instruction 252 Regset uint64 // registers implicitly set by this instruction 253 Regindex uint64 // registers used by addressing mode 254 } 255 256 // Prog.as opcodes. 257 // These are the portable opcodes, common to all architectures. 258 // Each architecture defines many more arch-specific opcodes, 259 // with values starting at A_ARCHSPECIFIC. 260 // Each architecture adds an offset to this so each machine has 261 // distinct space for its instructions. The offset is a power of 262 // two so it can be masked to return to origin zero. 263 // See the definitions of ABase386 etc. 264 const ( 265 AXXX = 0 + iota 266 ACALL 267 ACHECKNIL 268 ADATA 269 ADUFFCOPY 270 ADUFFZERO 271 AEND 272 AFUNCDATA 273 AGLOBL 274 AJMP 275 ANOP 276 APCDATA 277 ARET 278 ATEXT 279 ATYPE 280 AUNDEF 281 AUSEFIELD 282 AVARDEF 283 AVARKILL 284 A_ARCHSPECIFIC 285 ) 286 287 // An LSym is the sort of symbol that is written to an object file. 288 type LSym struct { 289 Name string 290 Type int16 291 Version int16 292 Dupok uint8 293 Cfunc uint8 294 Nosplit uint8 295 Leaf uint8 296 Seenglobl uint8 297 Onlist uint8 298 // Local means make the symbol local even when compiling Go code to reference Go 299 // symbols in other shared libraries, as in this mode symbols are global by 300 // default. "local" here means in the sense of the dynamic linker, i.e. not 301 // visible outside of the module (shared library or executable) that contains its 302 // definition. (When not compiling to support Go shared libraries, all symbols are 303 // local in this sense unless there is a cgo_export_* directive). 304 Local bool 305 Args int32 306 Locals int32 307 Value int64 308 Size int64 309 Next *LSym 310 Gotype *LSym 311 Autom *Auto 312 Text *Prog 313 Etext *Prog 314 Pcln *Pcln 315 P []byte 316 R []Reloc 317 } 318 319 type Pcln struct { 320 Pcsp Pcdata 321 Pcfile Pcdata 322 Pcline Pcdata 323 Pcdata []Pcdata 324 Funcdata []*LSym 325 Funcdataoff []int64 326 File []*LSym 327 Lastfile *LSym 328 Lastindex int 329 } 330 331 // LSym.type 332 const ( 333 Sxxx = iota 334 STEXT 335 SELFRXSECT 336 STYPE 337 SSTRING 338 SGOSTRING 339 SGOFUNC 340 SGCBITS 341 SRODATA 342 SFUNCTAB 343 STYPELINK 344 SSYMTAB 345 SPCLNTAB 346 SELFROSECT 347 SMACHOPLT 348 SELFSECT 349 SMACHO 350 SMACHOGOT 351 SWINDOWS 352 SELFGOT 353 SNOPTRDATA 354 SINITARR 355 SDATA 356 SBSS 357 SNOPTRBSS 358 STLSBSS 359 SXREF 360 SMACHOSYMSTR 361 SMACHOSYMTAB 362 SMACHOINDIRECTPLT 363 SMACHOINDIRECTGOT 364 SFILE 365 SFILEPATH 366 SCONST 367 SDYNIMPORT 368 SHOSTOBJ 369 SSUB = 1 << 8 370 SMASK = SSUB - 1 371 SHIDDEN = 1 << 9 372 SCONTAINER = 1 << 10 // has a sub-symbol 373 ) 374 375 type Reloc struct { 376 Off int32 377 Siz uint8 378 Type int32 379 Add int64 380 Sym *LSym 381 } 382 383 // Reloc.type 384 const ( 385 R_ADDR = 1 + iota 386 R_ADDRPOWER 387 R_ADDRARM64 388 R_SIZE 389 R_CALL 390 R_CALLARM 391 R_CALLARM64 392 R_CALLIND 393 R_CALLPOWER 394 R_CONST 395 R_PCREL 396 // R_TLS (only used on arm currently, and not on android and darwin where tlsg is 397 // a regular variable) resolves to data needed to access the thread-local g. It is 398 // interpreted differently depending on toolchain flags to implement either the 399 // "local exec" or "inital exec" model for tls access. 400 // TODO(mwhudson): change to use R_TLS_LE or R_TLS_IE as appropriate, not having 401 // R_TLS do double duty. 402 R_TLS 403 // R_TLS_LE (only used on 386 and amd64 currently) resolves to the offset of the 404 // thread-local g from the thread local base and is used to implement the "local 405 // exec" model for tls access (r.Sym is not set by the compiler for this case but 406 // is set to Tlsg in the linker when externally linking). 407 R_TLS_LE 408 // R_TLS_IE (only used on 386 and amd64 currently) resolves to the PC-relative 409 // offset to a GOT slot containing the offset the thread-local g from the thread 410 // local base and is used to implemented the "initial exec" model for tls access 411 // (r.Sym is not set by the compiler for this case but is set to Tlsg in the 412 // linker when externally linking). 413 R_TLS_IE 414 R_GOTOFF 415 R_PLT0 416 R_PLT1 417 R_PLT2 418 R_USEFIELD 419 R_POWER_TOC 420 R_GOTPCREL 421 ) 422 423 type Auto struct { 424 Asym *LSym 425 Link *Auto 426 Aoffset int32 427 Name int16 428 Gotype *LSym 429 } 430 431 // Auto.name 432 const ( 433 A_AUTO = 1 + iota 434 A_PARAM 435 ) 436 437 type Pcdata struct { 438 P []byte 439 } 440 441 // Pcdata iterator. 442 // for(pciterinit(ctxt, &it, &pcd); !it.done; pciternext(&it)) { it.value holds in [it.pc, it.nextpc) } 443 type Pciter struct { 444 d Pcdata 445 p []byte 446 pc uint32 447 nextpc uint32 448 pcscale uint32 449 value int32 450 start int 451 done int 452 } 453 454 // symbol version, incremented each time a file is loaded. 455 // version==1 is reserved for savehist. 456 const ( 457 HistVersion = 1 458 ) 459 460 // Link holds the context for writing object code from a compiler 461 // to be linker input or for reading that input into the linker. 462 type Link struct { 463 Goarm int32 464 Headtype int 465 Arch *LinkArch 466 Debugasm int32 467 Debugvlog int32 468 Debugzerostack int32 469 Debugdivmod int32 470 Debugpcln int32 471 Flag_shared int32 472 Flag_dynlink bool 473 Bso *Biobuf 474 Pathname string 475 Windows int32 476 Goroot string 477 Goroot_final string 478 Enforce_data_order int32 479 Hash map[SymVer]*LSym 480 LineHist LineHist 481 Imports []string 482 Plist *Plist 483 Plast *Plist 484 Sym_div *LSym 485 Sym_divu *LSym 486 Sym_mod *LSym 487 Sym_modu *LSym 488 Tlsg *LSym 489 Plan9privates *LSym 490 Curp *Prog 491 Printp *Prog 492 Blitrl *Prog 493 Elitrl *Prog 494 Rexflag int 495 Rep int 496 Repn int 497 Lock int 498 Asmode int 499 Andptr []byte 500 And [100]uint8 501 Instoffset int64 502 Autosize int32 503 Armsize int32 504 Pc int64 505 Tlsoffset int 506 Diag func(string, ...interface{}) 507 Mode int 508 Cursym *LSym 509 Version int 510 Textp *LSym 511 Etextp *LSym 512 } 513 514 type SymVer struct { 515 Name string 516 Version int // TODO: make int16 to match LSym.Version? 517 } 518 519 // LinkArch is the definition of a single architecture. 520 type LinkArch struct { 521 ByteOrder binary.ByteOrder 522 Name string 523 Thechar int 524 Preprocess func(*Link, *LSym) 525 Assemble func(*Link, *LSym) 526 Follow func(*Link, *LSym) 527 Progedit func(*Link, *Prog) 528 UnaryDst map[int]bool // Instruction takes one operand, a destination. 529 Minlc int 530 Ptrsize int 531 Regsize int 532 } 533 534 /* executable header types */ 535 const ( 536 Hunknown = 0 + iota 537 Hdarwin 538 Hdragonfly 539 Helf 540 Hfreebsd 541 Hlinux 542 Hnacl 543 Hnetbsd 544 Hopenbsd 545 Hplan9 546 Hsolaris 547 Hwindows 548 ) 549 550 type Plist struct { 551 Name *LSym 552 Firstpc *Prog 553 Recur int 554 Link *Plist 555 } 556 557 /* 558 * start a new Prog list. 559 */ 560 func Linknewplist(ctxt *Link) *Plist { 561 pl := new(Plist) 562 if ctxt.Plist == nil { 563 ctxt.Plist = pl 564 } else { 565 ctxt.Plast.Link = pl 566 } 567 ctxt.Plast = pl 568 return pl 569 } 570