github.com/gocuntian/go@v0.0.0-20160610041250-fee02d270bf8/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 int16 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 307 AMask = 1<<12 - 1 // AND with this to use the opcode as an array index. 308 ) 309 310 // An LSym is the sort of symbol that is written to an object file. 311 type LSym struct { 312 Name string 313 Type int16 314 Version int16 315 Dupok bool 316 Cfunc bool 317 Nosplit bool 318 Leaf bool 319 Seenglobl bool 320 Onlist bool 321 322 // ReflectMethod means the function may call reflect.Type.Method or 323 // reflect.Type.MethodByName. Matching is imprecise (as reflect.Type 324 // can be used through a custom interface), so ReflectMethod may be 325 // set in some cases when the reflect package is not called. 326 // 327 // Used by the linker to determine what methods can be pruned. 328 ReflectMethod bool 329 330 // Local means make the symbol local even when compiling Go code to reference Go 331 // symbols in other shared libraries, as in this mode symbols are global by 332 // default. "local" here means in the sense of the dynamic linker, i.e. not 333 // visible outside of the module (shared library or executable) that contains its 334 // definition. (When not compiling to support Go shared libraries, all symbols are 335 // local in this sense unless there is a cgo_export_* directive). 336 Local bool 337 338 RefIdx int // Index of this symbol in the symbol reference list. 339 Args int32 340 Locals int32 341 Size int64 342 Gotype *LSym 343 Autom *Auto 344 Text *Prog 345 Pcln *Pcln 346 P []byte 347 R []Reloc 348 } 349 350 // The compiler needs LSym to satisfy fmt.Stringer, because it stores 351 // an LSym in ssa.ExternSymbol. 352 func (s *LSym) String() string { 353 return s.Name 354 } 355 356 type Pcln struct { 357 Pcsp Pcdata 358 Pcfile Pcdata 359 Pcline Pcdata 360 Pcdata []Pcdata 361 Funcdata []*LSym 362 Funcdataoff []int64 363 File []*LSym 364 Lastfile *LSym 365 Lastindex int 366 } 367 368 // LSym.type 369 const ( 370 Sxxx = iota 371 STEXT 372 SELFRXSECT 373 374 STYPE 375 SSTRING 376 SGOSTRING 377 SGOSTRINGHDR 378 SGOFUNC 379 SGCBITS 380 SRODATA 381 SFUNCTAB 382 383 // Types STYPE-SFUNCTAB above are written to the .rodata section by default. 384 // When linking a shared object, some conceptually "read only" types need to 385 // be written to by relocations and putting them in a section called 386 // ".rodata" interacts poorly with the system linkers. The GNU linkers 387 // support this situation by arranging for sections of the name 388 // ".data.rel.ro.XXX" to be mprotected read only by the dynamic linker after 389 // relocations have applied, so when the Go linker is creating a shared 390 // object it checks all objects of the above types and bumps any object that 391 // has a relocation to it to the corresponding type below, which are then 392 // written to sections with appropriate magic names. 393 STYPERELRO 394 SSTRINGRELRO 395 SGOSTRINGRELRO 396 SGOSTRINGHDRRELRO 397 SGOFUNCRELRO 398 SGCBITSRELRO 399 SRODATARELRO 400 SFUNCTABRELRO 401 402 STYPELINK 403 SITABLINK 404 SSYMTAB 405 SPCLNTAB 406 SELFROSECT 407 SMACHOPLT 408 SELFSECT 409 SMACHO 410 SMACHOGOT 411 SWINDOWS 412 SELFGOT 413 SNOPTRDATA 414 SINITARR 415 SDATA 416 SBSS 417 SNOPTRBSS 418 STLSBSS 419 SXREF 420 SMACHOSYMSTR 421 SMACHOSYMTAB 422 SMACHOINDIRECTPLT 423 SMACHOINDIRECTGOT 424 SFILE 425 SFILEPATH 426 SCONST 427 SDYNIMPORT 428 SHOSTOBJ 429 SDWARFSECT 430 SDWARFINFO 431 SSUB = 1 << 8 432 SMASK = SSUB - 1 433 SHIDDEN = 1 << 9 434 SCONTAINER = 1 << 10 // has a sub-symbol 435 ) 436 437 type Reloc struct { 438 Off int32 439 Siz uint8 440 Type int32 441 Add int64 442 Sym *LSym 443 } 444 445 // Reloc.type 446 const ( 447 R_ADDR = 1 + iota 448 // R_ADDRPOWER relocates a pair of "D-form" instructions (instructions with 16-bit 449 // immediates in the low half of the instruction word), usually addis followed by 450 // another add or a load, inserting the "high adjusted" 16 bits of the address of 451 // the referenced symbol into the immediate field of the first instruction and the 452 // low 16 bits into that of the second instruction. 453 R_ADDRPOWER 454 // R_ADDRARM64 relocates an adrp, add pair to compute the address of the 455 // referenced symbol. 456 R_ADDRARM64 457 // R_ADDRMIPS (only used on mips64) resolves to the low 16 bits of an external 458 // address, by encoding it into the instruction. 459 R_ADDRMIPS 460 // R_ADDROFF resolves to a 32-bit offset from the beginning of the section 461 // holding the data being relocated to the referenced symbol. 462 R_ADDROFF 463 R_SIZE 464 R_CALL 465 R_CALLARM 466 R_CALLARM64 467 R_CALLIND 468 R_CALLPOWER 469 // R_CALLMIPS (only used on mips64) resolves to non-PC-relative target address 470 // of a CALL (JAL) instruction, by encoding the address into the instruction. 471 R_CALLMIPS 472 R_CONST 473 R_PCREL 474 // R_TLS_LE, used on 386, amd64, and ARM, resolves to the offset of the 475 // thread-local symbol from the thread local base and is used to implement the 476 // "local exec" model for tls access (r.Sym is not set on intel platforms but is 477 // set to a TLS symbol -- runtime.tlsg -- in the linker when externally linking). 478 R_TLS_LE 479 // R_TLS_IE, used 386, amd64, and ARM resolves to the PC-relative offset to a GOT 480 // slot containing the offset from the thread-local symbol from the thread local 481 // base and is used to implemented the "initial exec" model for tls access (r.Sym 482 // is not set on intel platforms but is set to a TLS symbol -- runtime.tlsg -- in 483 // the linker when externally linking). 484 R_TLS_IE 485 R_GOTOFF 486 R_PLT0 487 R_PLT1 488 R_PLT2 489 R_USEFIELD 490 // R_USETYPE resolves to an *rtype, but no relocation is created. The 491 // linker uses this as a signal that the pointed-to type information 492 // should be linked into the final binary, even if there are no other 493 // direct references. (This is used for types reachable by reflection.) 494 R_USETYPE 495 // R_METHODOFF resolves to a 32-bit offset from the beginning of the section 496 // holding the data being relocated to the referenced symbol. 497 // It is a variant of R_ADDROFF used when linking from the uncommonType of a 498 // *rtype, and may be set to zero by the linker if it determines the method 499 // text is unreachable by the linked program. 500 R_METHODOFF 501 R_POWER_TOC 502 R_GOTPCREL 503 // R_JMPMIPS (only used on mips64) resolves to non-PC-relative target address 504 // of a JMP instruction, by encoding the address into the instruction. 505 // The stack nosplit check ignores this since it is not a function call. 506 R_JMPMIPS 507 // R_DWARFREF resolves to the offset of the symbol from its section. 508 R_DWARFREF 509 510 // Platform dependent relocations. Architectures with fixed width instructions 511 // have the inherent issue that a 32-bit (or 64-bit!) displacement cannot be 512 // stuffed into a 32-bit instruction, so an address needs to be spread across 513 // several instructions, and in turn this requires a sequence of relocations, each 514 // updating a part of an instruction. This leads to relocation codes that are 515 // inherently processor specific. 516 517 // Arm64. 518 519 // Set a MOV[NZ] immediate field to bits [15:0] of the offset from the thread 520 // local base to the thread local variable defined by the referenced (thread 521 // local) symbol. Error if the offset does not fit into 16 bits. 522 R_ARM64_TLS_LE 523 524 // Relocates an ADRP; LD64 instruction sequence to load the offset between 525 // the thread local base and the thread local variable defined by the 526 // referenced (thread local) symbol from the GOT. 527 R_ARM64_TLS_IE 528 529 // R_ARM64_GOTPCREL relocates an adrp, ld64 pair to compute the address of the GOT 530 // slot of the referenced symbol. 531 R_ARM64_GOTPCREL 532 533 // PPC64. 534 535 // R_POWER_TLS_LE is used to implement the "local exec" model for tls 536 // access. It resolves to the offset of the thread-local symbol from the 537 // thread pointer (R13) and inserts this value into the low 16 bits of an 538 // instruction word. 539 R_POWER_TLS_LE 540 541 // R_POWER_TLS_IE is used to implement the "initial exec" model for tls access. It 542 // relocates a D-form, DS-form instruction sequence like R_ADDRPOWER_DS. It 543 // inserts to the offset of GOT slot for the thread-local symbol from the TOC (the 544 // GOT slot is filled by the dynamic linker with the offset of the thread-local 545 // symbol from the thread pointer (R13)). 546 R_POWER_TLS_IE 547 548 // R_POWER_TLS marks an X-form instruction such as "MOVD 0(R13)(R31*1), g" as 549 // accessing a particular thread-local symbol. It does not affect code generation 550 // but is used by the system linker when relaxing "initial exec" model code to 551 // "local exec" model code. 552 R_POWER_TLS 553 554 // R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second 555 // instruction is a "DS-form" instruction, which has an immediate field occupying 556 // bits [15:2] of the instruction word. Bits [15:2] of the address of the 557 // relocated symbol are inserted into this field; it is an error if the last two 558 // bits of the address are not 0. 559 R_ADDRPOWER_DS 560 561 // R_ADDRPOWER_PCREL relocates a D-form, DS-form instruction sequence like 562 // R_ADDRPOWER_DS but inserts the offset of the GOT slot for the referenced symbol 563 // from the TOC rather than the symbol's address. 564 R_ADDRPOWER_GOT 565 566 // R_ADDRPOWER_PCREL relocates two D-form instructions like R_ADDRPOWER, but 567 // inserts the displacement from the place being relocated to the address of the 568 // the relocated symbol instead of just its address. 569 R_ADDRPOWER_PCREL 570 571 // R_ADDRPOWER_TOCREL relocates two D-form instructions like R_ADDRPOWER, but 572 // inserts the offset from the TOC to the address of the the relocated symbol 573 // rather than the symbol's address. 574 R_ADDRPOWER_TOCREL 575 576 // R_ADDRPOWER_TOCREL relocates a D-form, DS-form instruction sequence like 577 // R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the the 578 // relocated symbol rather than the symbol's address. 579 R_ADDRPOWER_TOCREL_DS 580 581 // R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses. 582 // TODO(mundaym): remove once variants can be serialized - see issue 14218. 583 R_PCRELDBL 584 585 // R_ADDRMIPSU (only used on mips64) resolves to the sign-adjusted "upper" 16 586 // bits (bit 16-31) of an external address, by encoding it into the instruction. 587 R_ADDRMIPSU 588 // R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS 589 // address (offset from thread pointer), by encoding it into the instruction. 590 R_ADDRMIPSTLS 591 ) 592 593 type Auto struct { 594 Asym *LSym 595 Link *Auto 596 Aoffset int32 597 Name int16 598 Gotype *LSym 599 } 600 601 // Auto.name 602 const ( 603 A_AUTO = 1 + iota 604 A_PARAM 605 ) 606 607 type Pcdata struct { 608 P []byte 609 } 610 611 // symbol version, incremented each time a file is loaded. 612 // version==1 is reserved for savehist. 613 const ( 614 HistVersion = 1 615 ) 616 617 // Link holds the context for writing object code from a compiler 618 // to be linker input or for reading that input into the linker. 619 type Link struct { 620 Goarm int32 621 Headtype int 622 Arch *LinkArch 623 Debugasm int32 624 Debugvlog int32 625 Debugdivmod int32 626 Debugpcln int32 627 Flag_shared bool 628 Flag_dynlink bool 629 Flag_optimize bool 630 Bso *bufio.Writer 631 Pathname string 632 Goroot string 633 Goroot_final string 634 Hash map[SymVer]*LSym 635 LineHist LineHist 636 Imports []string 637 Plist *Plist 638 Plast *Plist 639 Sym_div *LSym 640 Sym_divu *LSym 641 Sym_mod *LSym 642 Sym_modu *LSym 643 Plan9privates *LSym 644 Curp *Prog 645 Printp *Prog 646 Blitrl *Prog 647 Elitrl *Prog 648 Rexflag int 649 Vexflag int 650 Rep int 651 Repn int 652 Lock int 653 Asmode int 654 AsmBuf AsmBuf // instruction buffer for x86 655 Instoffset int64 656 Autosize int32 657 Armsize int32 658 Pc int64 659 DiagFunc func(string, ...interface{}) 660 Mode int 661 Cursym *LSym 662 Version int 663 Textp *LSym 664 Etextp *LSym 665 Errors int 666 667 Framepointer_enabled bool 668 669 // state for writing objects 670 Text []*LSym 671 Data []*LSym 672 673 // Cache of Progs 674 allocIdx int 675 progs [10000]Prog 676 } 677 678 func (ctxt *Link) Diag(format string, args ...interface{}) { 679 ctxt.Errors++ 680 ctxt.DiagFunc(format, args...) 681 } 682 683 // The smallest possible offset from the hardware stack pointer to a local 684 // variable on the stack. Architectures that use a link register save its value 685 // on the stack in the function prologue and so always have a pointer between 686 // the hardware stack pointer and the local variable area. 687 func (ctxt *Link) FixedFrameSize() int64 { 688 switch ctxt.Arch.Family { 689 case sys.AMD64, sys.I386: 690 return 0 691 case sys.PPC64: 692 // PIC code on ppc64le requires 32 bytes of stack, and it's easier to 693 // just use that much stack always on ppc64x. 694 return int64(4 * ctxt.Arch.PtrSize) 695 default: 696 return int64(ctxt.Arch.PtrSize) 697 } 698 } 699 700 type SymVer struct { 701 Name string 702 Version int // TODO: make int16 to match LSym.Version? 703 } 704 705 // LinkArch is the definition of a single architecture. 706 type LinkArch struct { 707 *sys.Arch 708 Preprocess func(*Link, *LSym) 709 Assemble func(*Link, *LSym) 710 Follow func(*Link, *LSym) 711 Progedit func(*Link, *Prog) 712 UnaryDst map[As]bool // Instruction takes one operand, a destination. 713 } 714 715 /* executable header types */ 716 const ( 717 Hunknown = 0 + iota 718 Hdarwin 719 Hdragonfly 720 Hfreebsd 721 Hlinux 722 Hnacl 723 Hnetbsd 724 Hopenbsd 725 Hplan9 726 Hsolaris 727 Hwindows 728 ) 729 730 // AsmBuf is a simple buffer to assemble variable-length x86 instructions into. 731 type AsmBuf struct { 732 buf [100]byte 733 off int 734 } 735 736 // Put1 appends one byte to the end of the buffer. 737 func (a *AsmBuf) Put1(x byte) { 738 a.buf[a.off] = x 739 a.off++ 740 } 741 742 // Put2 appends two bytes to the end of the buffer. 743 func (a *AsmBuf) Put2(x, y byte) { 744 a.buf[a.off+0] = x 745 a.buf[a.off+1] = y 746 a.off += 2 747 } 748 749 // Put3 appends three bytes to the end of the buffer. 750 func (a *AsmBuf) Put3(x, y, z byte) { 751 a.buf[a.off+0] = x 752 a.buf[a.off+1] = y 753 a.buf[a.off+2] = z 754 a.off += 3 755 } 756 757 // Put4 appends four bytes to the end of the buffer. 758 func (a *AsmBuf) Put4(x, y, z, w byte) { 759 a.buf[a.off+0] = x 760 a.buf[a.off+1] = y 761 a.buf[a.off+2] = z 762 a.buf[a.off+3] = w 763 a.off += 4 764 } 765 766 // PutInt16 writes v into the buffer using little-endian encoding. 767 func (a *AsmBuf) PutInt16(v int16) { 768 a.buf[a.off+0] = byte(v) 769 a.buf[a.off+1] = byte(v >> 8) 770 a.off += 2 771 } 772 773 // PutInt32 writes v into the buffer using little-endian encoding. 774 func (a *AsmBuf) PutInt32(v int32) { 775 a.buf[a.off+0] = byte(v) 776 a.buf[a.off+1] = byte(v >> 8) 777 a.buf[a.off+2] = byte(v >> 16) 778 a.buf[a.off+3] = byte(v >> 24) 779 a.off += 4 780 } 781 782 // PutInt64 writes v into the buffer using little-endian encoding. 783 func (a *AsmBuf) PutInt64(v int64) { 784 a.buf[a.off+0] = byte(v) 785 a.buf[a.off+1] = byte(v >> 8) 786 a.buf[a.off+2] = byte(v >> 16) 787 a.buf[a.off+3] = byte(v >> 24) 788 a.buf[a.off+4] = byte(v >> 32) 789 a.buf[a.off+5] = byte(v >> 40) 790 a.buf[a.off+6] = byte(v >> 48) 791 a.buf[a.off+7] = byte(v >> 56) 792 a.off += 8 793 } 794 795 // Put copies b into the buffer. 796 func (a *AsmBuf) Put(b []byte) { 797 copy(a.buf[a.off:], b) 798 a.off += len(b) 799 } 800 801 // Insert inserts b at offset i. 802 func (a *AsmBuf) Insert(i int, b byte) { 803 a.off++ 804 copy(a.buf[i+1:a.off], a.buf[i:a.off-1]) 805 a.buf[i] = b 806 } 807 808 // Last returns the byte at the end of the buffer. 809 func (a *AsmBuf) Last() byte { return a.buf[a.off-1] } 810 811 // Len returns the length of the buffer. 812 func (a *AsmBuf) Len() int { return a.off } 813 814 // Bytes returns the contents of the buffer. 815 func (a *AsmBuf) Bytes() []byte { return a.buf[:a.off] } 816 817 // Reset empties the buffer. 818 func (a *AsmBuf) Reset() { a.off = 0 } 819 820 // Peek returns the byte at offset i. 821 func (a *AsmBuf) Peek(i int) byte { return a.buf[i] }