github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/cmd/internal/obj/link.go (about) 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 obj 32 33 import ( 34 "bufio" 35 "cmd/internal/sys" 36 ) 37 38 // An Addr is an argument to an instruction. 39 // The general forms and their encodings are: 40 // 41 // sym±offset(symkind)(reg)(index*scale) 42 // Memory reference at address &sym(symkind) + offset + reg + index*scale. 43 // Any of sym(symkind), ±offset, (reg), (index*scale), and *scale can be omitted. 44 // If (reg) and *scale are both omitted, the resulting expression (index) is parsed as (reg). 45 // To force a parsing as index*scale, write (index*1). 46 // Encoding: 47 // type = TYPE_MEM 48 // name = symkind (NAME_AUTO, ...) or 0 (NAME_NONE) 49 // sym = sym 50 // offset = ±offset 51 // reg = reg (REG_*) 52 // index = index (REG_*) 53 // scale = scale (1, 2, 4, 8) 54 // 55 // $<mem> 56 // Effective address of memory reference <mem>, defined above. 57 // Encoding: same as memory reference, but type = TYPE_ADDR. 58 // 59 // $<±integer value> 60 // This is a special case of $<mem>, in which only ±offset is present. 61 // It has a separate type for easy recognition. 62 // Encoding: 63 // type = TYPE_CONST 64 // offset = ±integer value 65 // 66 // *<mem> 67 // Indirect reference through memory reference <mem>, defined above. 68 // Only used on x86 for CALL/JMP *sym(SB), which calls/jumps to a function 69 // pointer stored in the data word sym(SB), not a function named sym(SB). 70 // Encoding: same as above, but type = TYPE_INDIR. 71 // 72 // $*$<mem> 73 // No longer used. 74 // On machines with actual SB registers, $*$<mem> forced the 75 // instruction encoding to use a full 32-bit constant, never a 76 // reference relative to SB. 77 // 78 // $<floating point literal> 79 // Floating point constant value. 80 // Encoding: 81 // type = TYPE_FCONST 82 // val = floating point value 83 // 84 // $<string literal, up to 8 chars> 85 // String literal value (raw bytes used for DATA instruction). 86 // Encoding: 87 // type = TYPE_SCONST 88 // val = string 89 // 90 // <register name> 91 // Any register: integer, floating point, control, segment, and so on. 92 // If looking for specific register kind, must check type and reg value range. 93 // Encoding: 94 // type = TYPE_REG 95 // reg = reg (REG_*) 96 // 97 // x(PC) 98 // Encoding: 99 // type = TYPE_BRANCH 100 // val = Prog* reference OR ELSE offset = target pc (branch takes priority) 101 // 102 // $±x-±y 103 // Final argument to TEXT, specifying local frame size x and argument size y. 104 // In this form, x and y are integer literals only, not arbitrary expressions. 105 // This avoids parsing ambiguities due to the use of - as a separator. 106 // The ± are optional. 107 // If the final argument to TEXT omits the -±y, the encoding should still 108 // use TYPE_TEXTSIZE (not TYPE_CONST), with u.argsize = ArgsSizeUnknown. 109 // Encoding: 110 // type = TYPE_TEXTSIZE 111 // offset = x 112 // val = int32(y) 113 // 114 // reg<<shift, reg>>shift, reg->shift, reg@>shift 115 // Shifted register value, for ARM. 116 // In this form, reg must be a register and shift can be a register or an integer constant. 117 // Encoding: 118 // type = TYPE_SHIFT 119 // offset = (reg&15) | shifttype<<5 | count 120 // shifttype = 0, 1, 2, 3 for <<, >>, ->, @> 121 // count = (reg&15)<<8 | 1<<4 for a register shift count, (n&31)<<7 for an integer constant. 122 // 123 // (reg, reg) 124 // A destination register pair. When used as the last argument of an instruction, 125 // this form makes clear that both registers are destinations. 126 // Encoding: 127 // type = TYPE_REGREG 128 // reg = first register 129 // offset = second register 130 // 131 // [reg, reg, reg-reg] 132 // Register list for ARM. 133 // Encoding: 134 // type = TYPE_REGLIST 135 // offset = bit mask of registers in list; R0 is low bit. 136 // 137 // reg, reg 138 // Register pair for ARM. 139 // TYPE_REGREG2 140 // 141 // (reg+reg) 142 // Register pair for PPC64. 143 // Encoding: 144 // type = TYPE_MEM 145 // reg = first register 146 // index = second register 147 // scale = 1 148 // 149 type Addr struct { 150 Reg int16 151 Index int16 152 Scale int16 // Sometimes holds a register. 153 Type AddrType 154 Name int8 155 Class int8 156 Etype uint8 157 Offset int64 158 Width int64 159 Sym *LSym 160 Gotype *LSym 161 162 // argument value: 163 // for TYPE_SCONST, a string 164 // for TYPE_FCONST, a float64 165 // for TYPE_BRANCH, a *Prog (optional) 166 // for TYPE_TEXTSIZE, an int32 (optional) 167 Val interface{} 168 169 Node interface{} // for use by compiler 170 } 171 172 type AddrType uint8 173 174 const ( 175 NAME_NONE = 0 + iota 176 NAME_EXTERN 177 NAME_STATIC 178 NAME_AUTO 179 NAME_PARAM 180 // A reference to name@GOT(SB) is a reference to the entry in the global offset 181 // table for 'name'. 182 NAME_GOTREF 183 ) 184 185 const ( 186 TYPE_NONE AddrType = 0 187 188 TYPE_BRANCH AddrType = 5 + iota 189 TYPE_TEXTSIZE 190 TYPE_MEM 191 TYPE_CONST 192 TYPE_FCONST 193 TYPE_SCONST 194 TYPE_REG 195 TYPE_ADDR 196 TYPE_SHIFT 197 TYPE_REGREG 198 TYPE_REGREG2 199 TYPE_INDIR 200 TYPE_REGLIST 201 ) 202 203 // TODO(rsc): Describe prog. 204 // TODO(rsc): Describe TEXT/GLOBL flag in from3 205 type Prog struct { 206 Ctxt *Link 207 Link *Prog 208 From Addr 209 From3 *Addr // optional 210 To Addr 211 Opt interface{} 212 Forwd *Prog 213 Pcond *Prog 214 Rel *Prog // Source of forward jumps on x86; pcrel on arm 215 Pc int64 216 Lineno int32 217 Spadj int32 218 As As // Assembler opcode. 219 Reg int16 220 RegTo2 int16 // 2nd register output operand 221 Mark uint16 // bitmask of arch-specific items 222 Optab uint16 223 Scond uint8 224 Back uint8 225 Ft uint8 226 Tt uint8 227 Isize uint8 // size of the instruction in bytes (x86 only) 228 Mode int8 229 230 Info ProgInfo 231 } 232 233 // From3Type returns From3.Type, or TYPE_NONE when From3 is nil. 234 func (p *Prog) From3Type() AddrType { 235 if p.From3 == nil { 236 return TYPE_NONE 237 } 238 return p.From3.Type 239 } 240 241 // From3Offset returns From3.Offset, or 0 when From3 is nil. 242 func (p *Prog) From3Offset() int64 { 243 if p.From3 == nil { 244 return 0 245 } 246 return p.From3.Offset 247 } 248 249 // ProgInfo holds information about the instruction for use 250 // by clients such as the compiler. The exact meaning of this 251 // data is up to the client and is not interpreted by the cmd/internal/obj/... packages. 252 type ProgInfo struct { 253 _ struct{} // to prevent unkeyed literals. Trailing zero-sized field will take space. 254 Flags uint32 // flag bits 255 Reguse uint64 // registers implicitly used by this instruction 256 Regset uint64 // registers implicitly set by this instruction 257 Regindex uint64 // registers used by addressing mode 258 } 259 260 // An As denotes an assembler opcode. 261 // There are some portable opcodes, declared here in package obj, 262 // that are common to all architectures. 263 // However, the majority of opcodes are arch-specific 264 // and are declared in their respective architecture's subpackage. 265 type As int32 266 267 // These are the portable opcodes. 268 const ( 269 AXXX As = iota 270 ACALL 271 ACHECKNIL 272 ADUFFCOPY 273 ADUFFZERO 274 AEND 275 AFUNCDATA 276 AGLOBL 277 AJMP 278 ANOP 279 APCDATA 280 ARET 281 ATEXT 282 ATYPE 283 AUNDEF 284 AUSEFIELD 285 AVARDEF 286 AVARKILL 287 AVARLIVE 288 A_ARCHSPECIFIC 289 ) 290 291 // Each architecture is allotted a distinct subspace of opcode values 292 // for declaring its arch-specific opcodes. 293 // Within this subspace, the first arch-specific opcode should be 294 // at offset A_ARCHSPECIFIC. 295 // 296 // Subspaces are aligned to a power of two so opcodes can be masked 297 // with AMask and used as compact array indices. 298 const ( 299 ABase386 = (1 + iota) << 12 300 ABaseARM 301 ABaseAMD64 302 ABasePPC64 303 ABaseARM64 304 ABaseMIPS64 305 ABaseS390X 306 ABaseSPARC64 307 308 AMask = 1<<12 - 1 // AND with this to use the opcode as an array index. 309 ) 310 311 // An LSym is the sort of symbol that is written to an object file. 312 type LSym struct { 313 Name string 314 Type int16 315 Version int16 316 Dupok bool 317 Cfunc bool 318 Nosplit bool 319 Leaf bool 320 Seenglobl bool 321 Onlist bool 322 323 // ReflectMethod means the function may call reflect.Type.Method or 324 // reflect.Type.MethodByName. Matching is imprecise (as reflect.Type 325 // can be used through a custom interface), so ReflectMethod may be 326 // set in some cases when the reflect package is not called. 327 // 328 // Used by the linker to determine what methods can be pruned. 329 ReflectMethod bool 330 331 // Local means make the symbol local even when compiling Go code to reference Go 332 // symbols in other shared libraries, as in this mode symbols are global by 333 // default. "local" here means in the sense of the dynamic linker, i.e. not 334 // visible outside of the module (shared library or executable) that contains its 335 // definition. (When not compiling to support Go shared libraries, all symbols are 336 // local in this sense unless there is a cgo_export_* directive). 337 Local bool 338 339 RefIdx int // Index of this symbol in the symbol reference list. 340 Args int32 341 Locals int32 342 Size int64 343 Gotype *LSym 344 Autom *Auto 345 Text *Prog 346 Pcln *Pcln 347 P []byte 348 R []Reloc 349 } 350 351 // The compiler needs LSym to satisfy fmt.Stringer, because it stores 352 // an LSym in ssa.ExternSymbol. 353 func (s *LSym) String() string { 354 return s.Name 355 } 356 357 type Pcln struct { 358 Pcsp Pcdata 359 Pcfile Pcdata 360 Pcline Pcdata 361 Pcdata []Pcdata 362 Funcdata []*LSym 363 Funcdataoff []int64 364 File []*LSym 365 Lastfile *LSym 366 Lastindex int 367 } 368 369 // LSym.type 370 const ( 371 Sxxx = iota 372 STEXT 373 SELFRXSECT 374 375 STYPE 376 SSTRING 377 SGOSTRING 378 SGOSTRINGHDR 379 SGOFUNC 380 SGCBITS 381 SRODATA 382 SFUNCTAB 383 384 // Types STYPE-SFUNCTAB above are written to the .rodata section by default. 385 // When linking a shared object, some conceptually "read only" types need to 386 // be written to by relocations and putting them in a section called 387 // ".rodata" interacts poorly with the system linkers. The GNU linkers 388 // support this situation by arranging for sections of the name 389 // ".data.rel.ro.XXX" to be mprotected read only by the dynamic linker after 390 // relocations have applied, so when the Go linker is creating a shared 391 // object it checks all objects of the above types and bumps any object that 392 // has a relocation to it to the corresponding type below, which are then 393 // written to sections with appropriate magic names. 394 STYPERELRO 395 SSTRINGRELRO 396 SGOSTRINGRELRO 397 SGOSTRINGHDRRELRO 398 SGOFUNCRELRO 399 SGCBITSRELRO 400 SRODATARELRO 401 SFUNCTABRELRO 402 403 STYPELINK 404 SITABLINK 405 SSYMTAB 406 SPCLNTAB 407 SELFROSECT 408 SMACHOPLT 409 SELFSECT 410 SMACHO 411 SMACHOGOT 412 SWINDOWS 413 SELFGOT 414 SNOPTRDATA 415 SINITARR 416 SDATA 417 SBSS 418 SNOPTRBSS 419 STLSBSS 420 SXREF 421 SMACHOSYMSTR 422 SMACHOSYMTAB 423 SMACHOINDIRECTPLT 424 SMACHOINDIRECTGOT 425 SFILE 426 SFILEPATH 427 SCONST 428 SDYNIMPORT 429 SHOSTOBJ 430 SDWARFSECT 431 SDWARFINFO 432 SSUB = 1 << 8 433 SMASK = SSUB - 1 434 SHIDDEN = 1 << 9 435 SCONTAINER = 1 << 10 // has a sub-symbol 436 ) 437 438 type Reloc struct { 439 Off int32 440 Siz uint8 441 Type int32 442 Add int64 443 Sym *LSym 444 } 445 446 // Reloc.type 447 const ( 448 R_ADDR = 1 + iota 449 // R_ADDRPOWER relocates a pair of "D-form" instructions (instructions with 16-bit 450 // immediates in the low half of the instruction word), usually addis followed by 451 // another add or a load, inserting the "high adjusted" 16 bits of the address of 452 // the referenced symbol into the immediate field of the first instruction and the 453 // low 16 bits into that of the second instruction. 454 R_ADDRPOWER 455 // R_ADDRARM64 relocates an adrp, add pair to compute the address of the 456 // referenced symbol. 457 R_ADDRARM64 458 // R_ADDRMIPS (only used on mips64) resolves to the low 16 bits of an external 459 // address, by encoding it into the instruction. 460 R_ADDRMIPS 461 // R_ADDROFF resolves to a 32-bit offset from the beginning of the section 462 // holding the data being relocated to the referenced symbol. 463 R_ADDROFF 464 // R_ADDRSPARC64LO (only used on sparc64) resolves to low 32bits of a 465 // 64-bit address, by loading the address into a register with two instructions. 466 R_ADDRSPARC64LO 467 // R_ADDRSPARC64HI (only used on sparc64) resolves to high 32bits of a 468 // 64-bit address, by loading the address into a register with two instructions. 469 R_ADDRSPARC64HI 470 R_SIZE 471 R_CALL 472 R_CALLARM 473 R_CALLARM64 474 R_CALLIND 475 R_CALLPOWER 476 // R_CALLMIPS (only used on mips64) resolves to non-PC-relative target address 477 // of a CALL (JAL) instruction, by encoding the address into the instruction. 478 R_CALLMIPS 479 R_CALLSPARC64 480 R_CONST 481 R_PCREL 482 // R_TLS_LE, used on 386, amd64, and ARM, resolves to the offset of the 483 // thread-local symbol from the thread local base and is used to implement the 484 // "local exec" model for tls access (r.Sym is not set on intel platforms but is 485 // set to a TLS symbol -- runtime.tlsg -- in the linker when externally linking). 486 R_TLS_LE 487 // R_TLS_IE, used 386, amd64, and ARM resolves to the PC-relative offset to a GOT 488 // slot containing the offset from the thread-local symbol from the thread local 489 // base and is used to implemented the "initial exec" model for tls access (r.Sym 490 // is not set on intel platforms but is set to a TLS symbol -- runtime.tlsg -- in 491 // the linker when externally linking). 492 R_TLS_IE 493 // R_SPARC64_TLS_LE is used to implement the "local exec" model for tls 494 // access. It resolves to the offset of the thread-local symbol from the 495 // thread pointer (R7) and inserts this value into a pair of instruction words. 496 R_SPARC64_TLS_LE 497 R_GOTOFF 498 R_PLT0 499 R_PLT1 500 R_PLT2 501 R_USEFIELD 502 // R_USETYPE resolves to an *rtype, but no relocation is created. The 503 // linker uses this as a signal that the pointed-to type information 504 // should be linked into the final binary, even if there are no other 505 // direct references. (This is used for types reachable by reflection.) 506 R_USETYPE 507 // R_METHODOFF resolves to a 32-bit offset from the beginning of the section 508 // holding the data being relocated to the referenced symbol. 509 // It is a variant of R_ADDROFF used when linking from the uncommonType of a 510 // *rtype, and may be set to zero by the linker if it determines the method 511 // text is unreachable by the linked program. 512 R_METHODOFF 513 R_POWER_TOC 514 R_GOTPCREL 515 // R_JMPMIPS (only used on mips64) resolves to non-PC-relative target address 516 // of a JMP instruction, by encoding the address into the instruction. 517 // The stack nosplit check ignores this since it is not a function call. 518 R_JMPMIPS 519 // R_DWARFREF resolves to the offset of the symbol from its section. 520 R_DWARFREF 521 522 // Platform dependent relocations. Architectures with fixed width instructions 523 // have the inherent issue that a 32-bit (or 64-bit!) displacement cannot be 524 // stuffed into a 32-bit instruction, so an address needs to be spread across 525 // several instructions, and in turn this requires a sequence of relocations, each 526 // updating a part of an instruction. This leads to relocation codes that are 527 // inherently processor specific. 528 529 // Arm64. 530 531 // Set a MOV[NZ] immediate field to bits [15:0] of the offset from the thread 532 // local base to the thread local variable defined by the referenced (thread 533 // local) symbol. Error if the offset does not fit into 16 bits. 534 R_ARM64_TLS_LE 535 536 // Relocates an ADRP; LD64 instruction sequence to load the offset between 537 // the thread local base and the thread local variable defined by the 538 // referenced (thread local) symbol from the GOT. 539 R_ARM64_TLS_IE 540 541 // R_ARM64_GOTPCREL relocates an adrp, ld64 pair to compute the address of the GOT 542 // slot of the referenced symbol. 543 R_ARM64_GOTPCREL 544 545 // PPC64. 546 547 // R_POWER_TLS_LE is used to implement the "local exec" model for tls 548 // access. It resolves to the offset of the thread-local symbol from the 549 // thread pointer (R13) and inserts this value into the low 16 bits of an 550 // instruction word. 551 R_POWER_TLS_LE 552 553 // R_POWER_TLS_IE is used to implement the "initial exec" model for tls access. It 554 // relocates a D-form, DS-form instruction sequence like R_ADDRPOWER_DS. It 555 // inserts to the offset of GOT slot for the thread-local symbol from the TOC (the 556 // GOT slot is filled by the dynamic linker with the offset of the thread-local 557 // symbol from the thread pointer (R13)). 558 R_POWER_TLS_IE 559 560 // R_POWER_TLS marks an X-form instruction such as "MOVD 0(R13)(R31*1), g" as 561 // accessing a particular thread-local symbol. It does not affect code generation 562 // but is used by the system linker when relaxing "initial exec" model code to 563 // "local exec" model code. 564 R_POWER_TLS 565 566 // R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second 567 // instruction is a "DS-form" instruction, which has an immediate field occupying 568 // bits [15:2] of the instruction word. Bits [15:2] of the address of the 569 // relocated symbol are inserted into this field; it is an error if the last two 570 // bits of the address are not 0. 571 R_ADDRPOWER_DS 572 573 // R_ADDRPOWER_PCREL relocates a D-form, DS-form instruction sequence like 574 // R_ADDRPOWER_DS but inserts the offset of the GOT slot for the referenced symbol 575 // from the TOC rather than the symbol's address. 576 R_ADDRPOWER_GOT 577 578 // R_ADDRPOWER_PCREL relocates two D-form instructions like R_ADDRPOWER, but 579 // inserts the displacement from the place being relocated to the address of the 580 // the relocated symbol instead of just its address. 581 R_ADDRPOWER_PCREL 582 583 // R_ADDRPOWER_TOCREL relocates two D-form instructions like R_ADDRPOWER, but 584 // inserts the offset from the TOC to the address of the the relocated symbol 585 // rather than the symbol's address. 586 R_ADDRPOWER_TOCREL 587 588 // R_ADDRPOWER_TOCREL relocates a D-form, DS-form instruction sequence like 589 // R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the the 590 // relocated symbol rather than the symbol's address. 591 R_ADDRPOWER_TOCREL_DS 592 593 // R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses. 594 // TODO(mundaym): remove once variants can be serialized - see issue 14218. 595 R_PCRELDBL 596 597 // R_ADDRMIPSU (only used on mips64) resolves to the sign-adjusted "upper" 16 598 // bits (bit 16-31) of an external address, by encoding it into the instruction. 599 R_ADDRMIPSU 600 // R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS 601 // address (offset from thread pointer), by encoding it into the instruction. 602 R_ADDRMIPSTLS 603 ) 604 605 type Auto struct { 606 Asym *LSym 607 Link *Auto 608 Aoffset int32 609 Name int16 610 Gotype *LSym 611 } 612 613 // Auto.name 614 const ( 615 A_AUTO = 1 + iota 616 A_PARAM 617 ) 618 619 type Pcdata struct { 620 P []byte 621 } 622 623 // symbol version, incremented each time a file is loaded. 624 // version==1 is reserved for savehist. 625 const ( 626 HistVersion = 1 627 ) 628 629 // Link holds the context for writing object code from a compiler 630 // to be linker input or for reading that input into the linker. 631 type Link struct { 632 Goarm int32 633 Headtype int 634 Arch *LinkArch 635 Debugasm int32 636 Debugvlog int32 637 Debugdivmod int32 638 Debugpcln int32 639 Flag_shared bool 640 Flag_dynlink bool 641 Flag_optimize bool 642 Bso *bufio.Writer 643 Pathname string 644 Goroot string 645 Goroot_final string 646 Hash map[SymVer]*LSym 647 LineHist LineHist 648 Imports []string 649 Plist *Plist 650 Plast *Plist 651 Sym_div *LSym 652 Sym_divu *LSym 653 Sym_mod *LSym 654 Sym_modu *LSym 655 Plan9privates *LSym 656 Curp *Prog 657 Printp *Prog 658 Blitrl *Prog 659 Elitrl *Prog 660 Rexflag int 661 Vexflag int 662 Rep int 663 Repn int 664 Lock int 665 Asmode int 666 AsmBuf AsmBuf // instruction buffer for x86 667 Instoffset int64 668 Autosize int32 669 Armsize int32 670 Pc int64 671 DiagFunc func(string, ...interface{}) 672 Mode int 673 Cursym *LSym 674 Version int 675 Textp *LSym 676 Etextp *LSym 677 Errors int 678 679 Framepointer_enabled bool 680 681 // state for writing objects 682 Text []*LSym 683 Data []*LSym 684 685 // Cache of Progs 686 allocIdx int 687 progs [10000]Prog 688 } 689 690 func (ctxt *Link) Diag(format string, args ...interface{}) { 691 ctxt.Errors++ 692 ctxt.DiagFunc(format, args...) 693 } 694 695 // The smallest possible offset from the hardware stack pointer to a local 696 // variable on the stack. Architectures that use a link register save its value 697 // on the stack in the function prologue and so always have a pointer between 698 // the hardware stack pointer and the local variable area. 699 func (ctxt *Link) FixedFrameSize() int64 { 700 switch ctxt.Arch.Family { 701 case sys.AMD64, sys.I386: 702 return 0 703 case sys.PPC64: 704 // PIC code on ppc64le requires 32 bytes of stack, and it's easier to 705 // just use that much stack always on ppc64x. 706 return int64(4 * ctxt.Arch.PtrSize) 707 case sys.SPARC64: 708 // requires a minimum of 176 bytes of stack. 709 return int64(16*8 + 6*8) 710 default: 711 return int64(ctxt.Arch.PtrSize) 712 } 713 } 714 715 type SymVer struct { 716 Name string 717 Version int // TODO: make int16 to match LSym.Version? 718 } 719 720 // LinkArch is the definition of a single architecture. 721 type LinkArch struct { 722 *sys.Arch 723 Preprocess func(*Link, *LSym) 724 Assemble func(*Link, *LSym) 725 Follow func(*Link, *LSym) 726 Progedit func(*Link, *Prog) 727 UnaryDst map[As]bool // Instruction takes one operand, a destination. 728 } 729 730 /* executable header types */ 731 const ( 732 Hunknown = 0 + iota 733 Hdarwin 734 Hdragonfly 735 Hfreebsd 736 Hlinux 737 Hnacl 738 Hnetbsd 739 Hopenbsd 740 Hplan9 741 Hsolaris 742 Hwindows 743 ) 744 745 // AsmBuf is a simple buffer to assemble variable-length x86 instructions into. 746 type AsmBuf struct { 747 buf [100]byte 748 off int 749 } 750 751 // Put1 appends one byte to the end of the buffer. 752 func (a *AsmBuf) Put1(x byte) { 753 a.buf[a.off] = x 754 a.off++ 755 } 756 757 // Put2 appends two bytes to the end of the buffer. 758 func (a *AsmBuf) Put2(x, y byte) { 759 a.buf[a.off+0] = x 760 a.buf[a.off+1] = y 761 a.off += 2 762 } 763 764 // Put3 appends three bytes to the end of the buffer. 765 func (a *AsmBuf) Put3(x, y, z byte) { 766 a.buf[a.off+0] = x 767 a.buf[a.off+1] = y 768 a.buf[a.off+2] = z 769 a.off += 3 770 } 771 772 // Put4 appends four bytes to the end of the buffer. 773 func (a *AsmBuf) Put4(x, y, z, w byte) { 774 a.buf[a.off+0] = x 775 a.buf[a.off+1] = y 776 a.buf[a.off+2] = z 777 a.buf[a.off+3] = w 778 a.off += 4 779 } 780 781 // PutInt16 writes v into the buffer using little-endian encoding. 782 func (a *AsmBuf) PutInt16(v int16) { 783 a.buf[a.off+0] = byte(v) 784 a.buf[a.off+1] = byte(v >> 8) 785 a.off += 2 786 } 787 788 // PutInt32 writes v into the buffer using little-endian encoding. 789 func (a *AsmBuf) PutInt32(v int32) { 790 a.buf[a.off+0] = byte(v) 791 a.buf[a.off+1] = byte(v >> 8) 792 a.buf[a.off+2] = byte(v >> 16) 793 a.buf[a.off+3] = byte(v >> 24) 794 a.off += 4 795 } 796 797 // PutInt64 writes v into the buffer using little-endian encoding. 798 func (a *AsmBuf) PutInt64(v int64) { 799 a.buf[a.off+0] = byte(v) 800 a.buf[a.off+1] = byte(v >> 8) 801 a.buf[a.off+2] = byte(v >> 16) 802 a.buf[a.off+3] = byte(v >> 24) 803 a.buf[a.off+4] = byte(v >> 32) 804 a.buf[a.off+5] = byte(v >> 40) 805 a.buf[a.off+6] = byte(v >> 48) 806 a.buf[a.off+7] = byte(v >> 56) 807 a.off += 8 808 } 809 810 // Put copies b into the buffer. 811 func (a *AsmBuf) Put(b []byte) { 812 copy(a.buf[a.off:], b) 813 a.off += len(b) 814 } 815 816 // Insert inserts b at offset i. 817 func (a *AsmBuf) Insert(i int, b byte) { 818 a.off++ 819 copy(a.buf[i+1:a.off], a.buf[i:a.off-1]) 820 a.buf[i] = b 821 } 822 823 // Last returns the byte at the end of the buffer. 824 func (a *AsmBuf) Last() byte { return a.buf[a.off-1] } 825 826 // Len returns the length of the buffer. 827 func (a *AsmBuf) Len() int { return a.off } 828 829 // Bytes returns the contents of the buffer. 830 func (a *AsmBuf) Bytes() []byte { return a.buf[:a.off] } 831 832 // Reset empties the buffer. 833 func (a *AsmBuf) Reset() { a.off = 0 } 834 835 // Peek returns the byte at offset i. 836 func (a *AsmBuf) Peek(i int) byte { return a.buf[i] }