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