[dev.cc] cmd/internal/obj: convert liblink C to Go

This CL adds the real cmd/internal/obj packages.
Collectively they correspond to the liblink library.
The conversion was done using rsc.io/c2go's run script
at rsc.io/c2go repo version 706fac7.

This is not the final conversion, just the first working draft.
There will be more updates, but this works well enough
to use with go tool objwriter and pass all.bash.

Change-Id: I9359e835425f995a392bb2fcdbebf29511477bed
Reviewed-on: https://go-review.googlesource.com/3046
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Russ Cox 2015-01-19 14:34:58 -05:00
parent db52315c88
commit d6f6e420fc
40 changed files with 27998 additions and 7 deletions

View file

@ -1192,6 +1192,9 @@ var buildorder = []string{
"go/doc",
"go/build",
"cmd/internal/obj",
"cmd/internal/obj/arm",
"cmd/internal/obj/i386",
"cmd/internal/obj/ppc64",
"cmd/internal/obj/x86",
"cmd/objwriter",
"cmd/go",

View file

@ -24,6 +24,9 @@ import (
// packages supporting the commands.
var bootstrapDirs = []string{
"internal/obj",
"internal/obj/arm",
"internal/obj/i386",
"internal/obj/ppc64",
"internal/obj/x86",
"objwriter",
}

View file

@ -0,0 +1,305 @@
// Inferno utils/5c/5.out.h
// http://code.google.com/p/inferno-os/source/browse/utils/5c/5.out.h
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package arm
// list[5689].c
// obj.c
// objfile.c
// pass.c
// pcln.c
// sym.c
// TODO(ality): remove this workaround.
// It's here because Pconv in liblink/list?.c references %L.
const (
NSNAME = 8
NSYM = 50
NREG = 16
)
/* -1 disables use of REGARG */
const (
REGARG = -1
)
const (
REGRET = 0
REGEXT = 10
REGG = REGEXT - 0
REGM = REGEXT - 1
REGTMP = 11
REGSP = 13
REGLINK = 14
REGPC = 15
NFREG = 16
FREGRET = 0
FREGEXT = 7
FREGTMP = 15
)
/* compiler allocates register variables F0 up */
/* compiler allocates external registers F7 down */
const (
C_NONE = iota
C_REG
C_REGREG
C_REGREG2
C_SHIFT
C_FREG
C_PSR
C_FCR
C_RCON
C_NCON
C_SCON
C_LCON
C_LCONADDR
C_ZFCON
C_SFCON
C_LFCON
C_RACON
C_LACON
C_SBRA
C_LBRA
C_HAUTO
C_FAUTO
C_HFAUTO
C_SAUTO
C_LAUTO
C_HOREG
C_FOREG
C_HFOREG
C_SOREG
C_ROREG
C_SROREG
C_LOREG
C_PC
C_SP
C_HREG
C_ADDR
C_GOK
C_NCLASS
)
const (
AXXX = iota
AAND
AEOR
ASUB
ARSB
AADD
AADC
ASBC
ARSC
ATST
ATEQ
ACMP
ACMN
AORR
ABIC
AMVN
AB
ABL
ABEQ
ABNE
ABCS
ABHS
ABCC
ABLO
ABMI
ABPL
ABVS
ABVC
ABHI
ABLS
ABGE
ABLT
ABGT
ABLE
AMOVWD
AMOVWF
AMOVDW
AMOVFW
AMOVFD
AMOVDF
AMOVF
AMOVD
ACMPF
ACMPD
AADDF
AADDD
ASUBF
ASUBD
AMULF
AMULD
ADIVF
ADIVD
ASQRTF
ASQRTD
AABSF
AABSD
ASRL
ASRA
ASLL
AMULU
ADIVU
AMUL
ADIV
AMOD
AMODU
AMOVB
AMOVBS
AMOVBU
AMOVH
AMOVHS
AMOVHU
AMOVW
AMOVM
ASWPBU
ASWPW
ANOP
ARFE
ASWI
AMULA
ADATA
AGLOBL
AGOK
AHISTORY
ANAME
ARET
ATEXT
AWORD
ADYNT_
AINIT_
ABCASE
ACASE
AEND
AMULL
AMULAL
AMULLU
AMULALU
ABX
ABXRET
ADWORD
ASIGNAME
ALDREX
ASTREX
ALDREXD
ASTREXD
APLD
AUNDEF
ACLZ
AMULWT
AMULWB
AMULAWT
AMULAWB
AUSEFIELD
ATYPE
AFUNCDATA
APCDATA
ACHECKNIL
AVARDEF
AVARKILL
ADUFFCOPY
ADUFFZERO
ADATABUNDLE
ADATABUNDLEEND
AMRC
ALAST
)
/* scond byte */
const (
C_SCOND = (1 << 4) - 1
C_SBIT = 1 << 4
C_PBIT = 1 << 5
C_WBIT = 1 << 6
C_FBIT = 1 << 7
C_UBIT = 1 << 7
C_SCOND_EQ = 0
C_SCOND_NE = 1
C_SCOND_HS = 2
C_SCOND_LO = 3
C_SCOND_MI = 4
C_SCOND_PL = 5
C_SCOND_VS = 6
C_SCOND_VC = 7
C_SCOND_HI = 8
C_SCOND_LS = 9
C_SCOND_GE = 10
C_SCOND_LT = 11
C_SCOND_GT = 12
C_SCOND_LE = 13
C_SCOND_NONE = 14
C_SCOND_NV = 15
SHIFT_LL = 0 << 5
SHIFT_LR = 1 << 5
SHIFT_AR = 2 << 5
SHIFT_RR = 3 << 5
)
const (
D_GOK = 0
D_NONE = 1
D_BRANCH = D_NONE + 1
D_OREG = D_NONE + 2
D_CONST = D_NONE + 7
D_FCONST = D_NONE + 8
D_SCONST = D_NONE + 9
D_PSR = D_NONE + 10
D_REG = D_NONE + 12
D_FREG = D_NONE + 13
D_FILE = D_NONE + 16
D_OCONST = D_NONE + 17
D_FILE1 = D_NONE + 18
D_SHIFT = D_NONE + 19
D_FPCR = D_NONE + 20
D_REGREG = D_NONE + 21
D_ADDR = D_NONE + 22
D_SBIG = D_NONE + 23
D_CONST2 = D_NONE + 24
D_REGREG2 = D_NONE + 25
D_EXTERN = D_NONE + 3
D_STATIC = D_NONE + 4
D_AUTO = D_NONE + 5
D_PARAM = D_NONE + 6
D_LAST = D_NONE + 26
)
/*
* this is the ranlib header
*/
var SYMDEF string

View file

@ -0,0 +1,196 @@
package arm
var anames5 = []string{
"XXX",
"AND",
"EOR",
"SUB",
"RSB",
"ADD",
"ADC",
"SBC",
"RSC",
"TST",
"TEQ",
"CMP",
"CMN",
"ORR",
"BIC",
"MVN",
"B",
"BL",
"BEQ",
"BNE",
"BCS",
"BHS",
"BCC",
"BLO",
"BMI",
"BPL",
"BVS",
"BVC",
"BHI",
"BLS",
"BGE",
"BLT",
"BGT",
"BLE",
"MOVWD",
"MOVWF",
"MOVDW",
"MOVFW",
"MOVFD",
"MOVDF",
"MOVF",
"MOVD",
"CMPF",
"CMPD",
"ADDF",
"ADDD",
"SUBF",
"SUBD",
"MULF",
"MULD",
"DIVF",
"DIVD",
"SQRTF",
"SQRTD",
"ABSF",
"ABSD",
"SRL",
"SRA",
"SLL",
"MULU",
"DIVU",
"MUL",
"DIV",
"MOD",
"MODU",
"MOVB",
"MOVBS",
"MOVBU",
"MOVH",
"MOVHS",
"MOVHU",
"MOVW",
"MOVM",
"SWPBU",
"SWPW",
"NOP",
"RFE",
"SWI",
"MULA",
"DATA",
"GLOBL",
"GOK",
"HISTORY",
"NAME",
"RET",
"TEXT",
"WORD",
"DYNT_",
"INIT_",
"BCASE",
"CASE",
"END",
"MULL",
"MULAL",
"MULLU",
"MULALU",
"BX",
"BXRET",
"DWORD",
"SIGNAME",
"LDREX",
"STREX",
"LDREXD",
"STREXD",
"PLD",
"UNDEF",
"CLZ",
"MULWT",
"MULWB",
"MULAWT",
"MULAWB",
"USEFIELD",
"TYPE",
"FUNCDATA",
"PCDATA",
"CHECKNIL",
"VARDEF",
"VARKILL",
"DUFFCOPY",
"DUFFZERO",
"DATABUNDLE",
"DATABUNDLEEND",
"MRC",
"LAST",
}
var cnames5 = []string{
"NONE",
"REG",
"REGREG",
"REGREG2",
"SHIFT",
"FREG",
"PSR",
"FCR",
"RCON",
"NCON",
"SCON",
"LCON",
"LCONADDR",
"ZFCON",
"SFCON",
"LFCON",
"RACON",
"LACON",
"SBRA",
"LBRA",
"HAUTO",
"FAUTO",
"HFAUTO",
"SAUTO",
"LAUTO",
"HOREG",
"FOREG",
"HFOREG",
"SOREG",
"ROREG",
"SROREG",
"LOREG",
"PC",
"SP",
"HREG",
"ADDR",
"GOK",
"NCLASS",
"SCOND = (1<<4)-1",
"SBIT = 1<<4",
"PBIT = 1<<5",
"WBIT = 1<<6",
"FBIT = 1<<7",
"UBIT = 1<<7",
"SCOND_EQ = 0",
"SCOND_NE = 1",
"SCOND_HS = 2",
"SCOND_LO = 3",
"SCOND_MI = 4",
"SCOND_PL = 5",
"SCOND_VS = 6",
"SCOND_VC = 7",
"SCOND_HI = 8",
"SCOND_LS = 9",
"SCOND_GE = 10",
"SCOND_LT = 11",
"SCOND_GT = 12",
"SCOND_LE = 13",
"SCOND_NONE = 14",
"SCOND_NV = 15",
}
var dnames5 = []string{
D_GOK: "GOK",
D_NONE: "NONE",
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,311 @@
// Inferno utils/5c/list.c
// http://code.google.com/p/inferno-os/source/browse/utils/5c/list.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package arm
import (
"cmd/internal/obj"
"fmt"
)
const (
STRINGSZ = 1000
)
var extra = []string{
".EQ",
".NE",
".CS",
".CC",
".MI",
".PL",
".VS",
".VC",
".HI",
".LS",
".GE",
".LT",
".GT",
".LE",
"",
".NV",
}
var bigP *obj.Prog
func Pconv(p *obj.Prog) string {
var str string
var sc string
var fp string
var a int
var s int
a = int(p.As)
s = int(p.Scond)
sc = extra[s&C_SCOND]
if s&C_SBIT != 0 {
sc += ".S"
}
if s&C_PBIT != 0 {
sc += ".P"
}
if s&C_WBIT != 0 {
sc += ".W"
}
if s&C_UBIT != 0 { /* ambiguous with FBIT */
sc += ".U"
}
if a == AMOVM {
if p.From.Type_ == D_CONST {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, RAconv(&p.From), Dconv(p, 0, &p.To))
} else if p.To.Type_ == D_CONST {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), RAconv(&p.To))
} else {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
}
} else if a == ADATA {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
} else if p.As == ATEXT {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
} else if p.Reg == NREG {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
} else if p.From.Type_ != D_FREG {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,R%d,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
} else {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,F%d,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
}
fp += str
return fp
}
func Aconv(a int) string {
var s string
var fp string
s = "???"
if a >= AXXX && a < ALAST {
s = anames5[a]
}
fp += s
return fp
}
func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
var str string
var fp string
var op string
var v int
switch a.Type_ {
default:
str = fmt.Sprintf("GOK-type(%d)", a.Type_)
case D_NONE:
str = ""
if a.Name != D_NONE || a.Reg != NREG || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(NONE)", Mconv(a), a.Reg)
}
case D_CONST:
if a.Reg != NREG {
str = fmt.Sprintf("$%v(R%d)", Mconv(a), a.Reg)
} else {
str = fmt.Sprintf("$%v", Mconv(a))
}
case D_CONST2:
str = fmt.Sprintf("$%d-%d", a.Offset, a.Offset2)
case D_SHIFT:
v = int(a.Offset)
op = string("<<>>->@>"[((v>>5)&3)<<1:])
if v&(1<<4) != 0 {
str = fmt.Sprintf("R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15)
} else {
str = fmt.Sprintf("R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31)
}
if a.Reg != NREG {
str += fmt.Sprintf("(R%d)", a.Reg)
}
case D_OREG:
if a.Reg != NREG {
str = fmt.Sprintf("%v(R%d)", Mconv(a), a.Reg)
} else {
str = fmt.Sprintf("%v", Mconv(a))
}
case D_REG:
str = fmt.Sprintf("R%d", a.Reg)
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(REG)", Mconv(a), a.Reg)
}
case D_FREG:
str = fmt.Sprintf("F%d", a.Reg)
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(REG)", Mconv(a), a.Reg)
}
case D_PSR:
str = fmt.Sprintf("PSR")
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(PSR)(REG)", Mconv(a))
}
case D_BRANCH:
if a.Sym != nil {
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
} else if p != nil && p.Pcond != nil {
str = fmt.Sprintf("%d", p.Pcond.Pc)
} else if a.U.Branch != nil {
str = fmt.Sprintf("%d", a.U.Branch.Pc)
} else {
str = fmt.Sprintf("%d(PC)", a.Offset) /*-pc*/
}
case D_FCONST:
str = fmt.Sprintf("$%.17g", a.U.Dval)
case D_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
break
}
fp += str
return fp
}
func RAconv(a *obj.Addr) string {
var str string
var fp string
var i int
var v int
str = fmt.Sprintf("GOK-reglist")
switch a.Type_ {
case D_CONST,
D_CONST2:
if a.Reg != NREG {
break
}
if a.Sym != nil {
break
}
v = int(a.Offset)
str = ""
for i = 0; i < NREG; i++ {
if v&(1<<uint(i)) != 0 {
if str[0] == 0 {
str += "[R"
} else {
str += ",R"
}
str += fmt.Sprintf("%d", i)
}
}
str += "]"
}
fp += str
return fp
}
func Rconv(r int) string {
var fp string
var str string
str = fmt.Sprintf("R%d", r)
fp += str
return fp
}
func DRconv(a int) string {
var s string
var fp string
s = "C_??"
if a >= C_NONE && a <= C_NCLASS {
s = cnames5[a]
}
fp += s
return fp
}
func Mconv(a *obj.Addr) string {
var str string
var fp string
var s *obj.LSym
s = a.Sym
if s == nil {
str = fmt.Sprintf("%d", int(a.Offset))
goto out
}
switch a.Name {
default:
str = fmt.Sprintf("GOK-name(%d)", a.Name)
case D_NONE:
str = fmt.Sprintf("%d", a.Offset)
case D_EXTERN:
str = fmt.Sprintf("%s+%d(SB)", s.Name, int(a.Offset))
case D_STATIC:
str = fmt.Sprintf("%s<>+%d(SB)", s.Name, int(a.Offset))
case D_AUTO:
str = fmt.Sprintf("%s-%d(SP)", s.Name, int(-a.Offset))
case D_PARAM:
str = fmt.Sprintf("%s+%d(FP)", s.Name, int(a.Offset))
break
}
out:
fp += str
return fp
}

File diff suppressed because it is too large Load diff

View file

@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Dummy placeholder for the real obj package.
package arm
package obj
var Exported bool
func bool2int(b bool) int {
if b {
return 1
}
return 0
}

View file

@ -0,0 +1,292 @@
// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
// http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.c
// http://code.google.com/p/inferno-os/source/browse/utils/6l/span.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package obj
import (
"log"
"math"
)
func mangle(file string) {
log.Fatalf("%s: mangled input file", file)
}
func Symgrow(ctxt *Link, s *LSym, lsiz int64) {
var siz int
siz = int(lsiz)
if int64(siz) != lsiz {
log.Fatal("Symgrow size %d too long", lsiz)
}
if len(s.P) >= siz {
return
}
for cap(s.P) < siz {
s.P = append(s.P[:cap(s.P)], 0)
}
s.P = s.P[:siz]
}
func savedata(ctxt *Link, s *LSym, p *Prog, pn string) {
off := int32(p.From.Offset)
siz := int32(ctxt.Arch.Datasize(p))
if off < 0 || siz < 0 || off >= 1<<30 || siz >= 100 {
mangle(pn)
}
if ctxt.Enforce_data_order != 0 && off < int32(len(s.P)) {
ctxt.Diag("data out of order (already have %d)\n%P", len(s.P), p)
}
Symgrow(ctxt, s, int64(off+siz))
switch int(p.To.Type_) {
default:
ctxt.Diag("bad data: %P", p)
case ctxt.Arch.D_FCONST:
switch siz {
default:
ctxt.Diag("unexpected %d-byte floating point constant", siz)
case 4:
flt := math.Float32bits(float32(p.To.U.Dval))
ctxt.Arch.ByteOrder.PutUint32(s.P[off:], flt)
case 8:
flt := math.Float64bits(p.To.U.Dval)
ctxt.Arch.ByteOrder.PutUint64(s.P[off:], flt)
}
case ctxt.Arch.D_SCONST:
copy(s.P[off:off+siz], p.To.U.Sval)
case ctxt.Arch.D_CONST, ctxt.Arch.D_ADDR:
if p.To.Sym != nil || int(p.To.Type_) == ctxt.Arch.D_ADDR {
r := Addrel(s)
r.Off = off
r.Siz = uint8(siz)
r.Sym = p.To.Sym
r.Type_ = R_ADDR
r.Add = p.To.Offset
break
}
o := p.To.Offset
switch siz {
default:
ctxt.Diag("unexpected %d-byte integer constant", siz)
case 1:
s.P[off] = byte(o)
case 2:
ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(o))
case 4:
ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(o))
case 8:
ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(o))
}
}
}
func Addrel(s *LSym) *Reloc {
s.R = append(s.R, Reloc{})
return &s.R[len(s.R)-1]
}
func setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 {
if s.Type_ == 0 {
s.Type_ = SDATA
}
s.Reachable = 1
if s.Size < off+wid {
s.Size = off + wid
Symgrow(ctxt, s, s.Size)
}
switch wid {
case 1:
s.P[off] = uint8(v)
case 2:
ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(v))
case 4:
ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(v))
case 8:
ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(v))
}
return off + wid
}
func adduintxx(ctxt *Link, s *LSym, v uint64, wid int) int64 {
var off int64
off = s.Size
setuintxx(ctxt, s, off, v, int64(wid))
return off
}
func adduint8(ctxt *Link, s *LSym, v uint8) int64 {
return adduintxx(ctxt, s, uint64(v), 1)
}
func adduint16(ctxt *Link, s *LSym, v uint16) int64 {
return adduintxx(ctxt, s, uint64(v), 2)
}
func Adduint32(ctxt *Link, s *LSym, v uint32) int64 {
return adduintxx(ctxt, s, uint64(v), 4)
}
func Adduint64(ctxt *Link, s *LSym, v uint64) int64 {
return adduintxx(ctxt, s, v, 8)
}
func setuint8(ctxt *Link, s *LSym, r int64, v uint8) int64 {
return setuintxx(ctxt, s, r, uint64(v), 1)
}
func setuint16(ctxt *Link, s *LSym, r int64, v uint16) int64 {
return setuintxx(ctxt, s, r, uint64(v), 2)
}
func setuint32(ctxt *Link, s *LSym, r int64, v uint32) int64 {
return setuintxx(ctxt, s, r, uint64(v), 4)
}
func setuint64(ctxt *Link, s *LSym, r int64, v uint64) int64 {
return setuintxx(ctxt, s, r, v, 8)
}
func addaddrplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
var i int64
var r *Reloc
if s.Type_ == 0 {
s.Type_ = SDATA
}
s.Reachable = 1
i = s.Size
s.Size += int64(ctxt.Arch.Ptrsize)
Symgrow(ctxt, s, s.Size)
r = Addrel(s)
r.Sym = t
r.Off = int32(i)
r.Siz = uint8(ctxt.Arch.Ptrsize)
r.Type_ = R_ADDR
r.Add = add
return i + int64(r.Siz)
}
func addpcrelplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
var i int64
var r *Reloc
if s.Type_ == 0 {
s.Type_ = SDATA
}
s.Reachable = 1
i = s.Size
s.Size += 4
Symgrow(ctxt, s, s.Size)
r = Addrel(s)
r.Sym = t
r.Off = int32(i)
r.Add = add
r.Type_ = R_PCREL
r.Siz = 4
return i + int64(r.Siz)
}
func addaddr(ctxt *Link, s *LSym, t *LSym) int64 {
return addaddrplus(ctxt, s, t, 0)
}
func setaddrplus(ctxt *Link, s *LSym, off int64, t *LSym, add int64) int64 {
var r *Reloc
if s.Type_ == 0 {
s.Type_ = SDATA
}
s.Reachable = 1
if off+int64(ctxt.Arch.Ptrsize) > s.Size {
s.Size = off + int64(ctxt.Arch.Ptrsize)
Symgrow(ctxt, s, s.Size)
}
r = Addrel(s)
r.Sym = t
r.Off = int32(off)
r.Siz = uint8(ctxt.Arch.Ptrsize)
r.Type_ = R_ADDR
r.Add = add
return off + int64(r.Siz)
}
func setaddr(ctxt *Link, s *LSym, off int64, t *LSym) int64 {
return setaddrplus(ctxt, s, off, t, 0)
}
func addsize(ctxt *Link, s *LSym, t *LSym) int64 {
var i int64
var r *Reloc
if s.Type_ == 0 {
s.Type_ = SDATA
}
s.Reachable = 1
i = s.Size
s.Size += int64(ctxt.Arch.Ptrsize)
Symgrow(ctxt, s, s.Size)
r = Addrel(s)
r.Sym = t
r.Off = int32(i)
r.Siz = uint8(ctxt.Arch.Ptrsize)
r.Type_ = R_SIZE
return i + int64(r.Siz)
}
func addaddrplus4(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
var i int64
var r *Reloc
if s.Type_ == 0 {
s.Type_ = SDATA
}
s.Reachable = 1
i = s.Size
s.Size += 4
Symgrow(ctxt, s, s.Size)
r = Addrel(s)
r.Sym = t
r.Off = int32(i)
r.Siz = 4
r.Type_ = R_ADDR
r.Add = add
return i + int64(r.Siz)
}

View file

@ -0,0 +1,60 @@
/*
* The authors of this software are Rob Pike and Ken Thompson.
* Copyright (c) 2002 by Lucent Technologies.
* Permission to use, copy, modify, and distribute this software for any
* purpose without fee is hereby granted, provided that this entire notice
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*/
package obj
// (The comments in this file were copied from the manpage files rune.3,
// isalpharune.3, and runestrcat.3. Some formatting changes were also made
// to conform to Google style. /JRM 11/11/05)
type Fmt struct {
runes uint8
start interface{}
to interface{}
stop interface{}
flush func(*Fmt) int
farg interface{}
nfmt int
args []interface{}
r uint
width int
prec int
flags uint32
decimal string
thousands string
grouping string
}
const (
FmtWidth = 1
FmtLeft = FmtWidth << 1
FmtPrec = FmtLeft << 1
FmtSharp = FmtPrec << 1
FmtSpace = FmtSharp << 1
FmtSign = FmtSpace << 1
FmtApost = FmtSign << 1
FmtZero = FmtApost << 1
FmtUnsigned = FmtZero << 1
FmtShort = FmtUnsigned << 1
FmtLong = FmtShort << 1
FmtVLong = FmtLong << 1
FmtComma = FmtVLong << 1
FmtByte = FmtComma << 1
FmtLDouble = FmtByte << 1
FmtFlag = FmtLDouble << 1
)
var fmtdoquote func(int) int
/* Edit .+1,/^$/ | cfn $PLAN9/src/lib9/fmt/?*.c | grep -v static |grep -v __ */

View file

@ -0,0 +1,78 @@
// cmd/9l/noop.c, cmd/9l/pass.c, cmd/9l/span.c from Vita Nuova.
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package obj
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file defines the IDs for PCDATA and FUNCDATA instructions
// in Go binaries. It is included by assembly sources, so it must
// be written using #defines.
//
// The Go compiler also #includes this file, for now.
//
// symtab.go also contains a copy of these constants.
// Pseudo-assembly statements.
// GO_ARGS, GO_RESULTS_INITIALIZED, and NO_LOCAL_POINTERS are macros
// that communicate to the runtime information about the location and liveness
// of pointers in an assembly function's arguments, results, and stack frame.
// This communication is only required in assembly functions that make calls
// to other functions that might be preempted or grow the stack.
// NOSPLIT functions that make no calls do not need to use these macros.
// GO_ARGS indicates that the Go prototype for this assembly function
// defines the pointer map for the function's arguments.
// GO_ARGS should be the first instruction in a function that uses it.
// It can be omitted if there are no arguments at all.
// GO_ARGS is inserted implicitly by the linker for any function
// that also has a Go prototype and therefore is usually not necessary
// to write explicitly.
// GO_RESULTS_INITIALIZED indicates that the assembly function
// has initialized the stack space for its results and that those results
// should be considered live for the remainder of the function.
// NO_LOCAL_POINTERS indicates that the assembly function stores
// no pointers to heap objects in its local stack variables.
// ArgsSizeUnknown is set in Func.argsize to mark all functions
// whose argument size is unknown (C vararg functions, and
// assembly code without an explicit specification).
// This value is generated by the compiler, assembler, or linker.
const (
PCDATA_StackMapIndex = 0
FUNCDATA_ArgsPointerMaps = 0
FUNCDATA_LocalsPointerMaps = 1
FUNCDATA_DeadValueMaps = 2
ArgsSizeUnknown = 0x80000000
)

View file

@ -0,0 +1,21 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package obj
import (
"math"
"strings"
)
// go-specific code shared across loaders (5l, 6l, 8l).
// replace all "". with pkg.
func expandpkg(t0 string, pkg string) string {
return strings.Replace(t0, `"".`, pkg+".", -1)
}
func double2ieee(ieee *uint64, f float64) {
*ieee = math.Float64bits(f)
}

View file

@ -0,0 +1,627 @@
// Inferno utils/8c/8.out.h
// http://code.google.com/p/inferno-os/source/browse/utils/8c/8.out.h
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package i386
const (
AXXX = iota
AAAA
AAAD
AAAM
AAAS
AADCB
AADCL
AADCW
AADDB
AADDL
AADDW
AADJSP
AANDB
AANDL
AANDW
AARPL
ABOUNDL
ABOUNDW
ABSFL
ABSFW
ABSRL
ABSRW
ABTL
ABTW
ABTCL
ABTCW
ABTRL
ABTRW
ABTSL
ABTSW
ABYTE
ACALL
ACLC
ACLD
ACLI
ACLTS
ACMC
ACMPB
ACMPL
ACMPW
ACMPSB
ACMPSL
ACMPSW
ADAA
ADAS
ADATA
ADECB
ADECL
ADECW
ADIVB
ADIVL
ADIVW
AENTER
AGLOBL
AGOK
AHISTORY
AHLT
AIDIVB
AIDIVL
AIDIVW
AIMULB
AIMULL
AIMULW
AINB
AINL
AINW
AINCB
AINCL
AINCW
AINSB
AINSL
AINSW
AINT
AINTO
AIRETL
AIRETW
AJCC
AJCS
AJCXZL
AJCXZW
AJEQ
AJGE
AJGT
AJHI
AJLE
AJLS
AJLT
AJMI
AJMP
AJNE
AJOC
AJOS
AJPC
AJPL
AJPS
ALAHF
ALARL
ALARW
ALEAL
ALEAW
ALEAVEL
ALEAVEW
ALOCK
ALODSB
ALODSL
ALODSW
ALONG
ALOOP
ALOOPEQ
ALOOPNE
ALSLL
ALSLW
AMOVB
AMOVL
AMOVW
AMOVQ
AMOVBLSX
AMOVBLZX
AMOVBWSX
AMOVBWZX
AMOVWLSX
AMOVWLZX
AMOVSB
AMOVSL
AMOVSW
AMULB
AMULL
AMULW
ANAME
ANEGB
ANEGL
ANEGW
ANOP
ANOTB
ANOTL
ANOTW
AORB
AORL
AORW
AOUTB
AOUTL
AOUTW
AOUTSB
AOUTSL
AOUTSW
APAUSE
APOPAL
APOPAW
APOPFL
APOPFW
APOPL
APOPW
APUSHAL
APUSHAW
APUSHFL
APUSHFW
APUSHL
APUSHW
ARCLB
ARCLL
ARCLW
ARCRB
ARCRL
ARCRW
AREP
AREPN
ARET
AROLB
AROLL
AROLW
ARORB
ARORL
ARORW
ASAHF
ASALB
ASALL
ASALW
ASARB
ASARL
ASARW
ASBBB
ASBBL
ASBBW
ASCASB
ASCASL
ASCASW
ASETCC
ASETCS
ASETEQ
ASETGE
ASETGT
ASETHI
ASETLE
ASETLS
ASETLT
ASETMI
ASETNE
ASETOC
ASETOS
ASETPC
ASETPL
ASETPS
ACDQ
ACWD
ASHLB
ASHLL
ASHLW
ASHRB
ASHRL
ASHRW
ASTC
ASTD
ASTI
ASTOSB
ASTOSL
ASTOSW
ASUBB
ASUBL
ASUBW
ASYSCALL
ATESTB
ATESTL
ATESTW
ATEXT
AVERR
AVERW
AWAIT
AWORD
AXCHGB
AXCHGL
AXCHGW
AXLAT
AXORB
AXORL
AXORW
AFMOVB
AFMOVBP
AFMOVD
AFMOVDP
AFMOVF
AFMOVFP
AFMOVL
AFMOVLP
AFMOVV
AFMOVVP
AFMOVW
AFMOVWP
AFMOVX
AFMOVXP
AFCOMB
AFCOMBP
AFCOMD
AFCOMDP
AFCOMDPP
AFCOMF
AFCOMFP
AFCOMI
AFCOMIP
AFCOML
AFCOMLP
AFCOMW
AFCOMWP
AFUCOM
AFUCOMI
AFUCOMIP
AFUCOMP
AFUCOMPP
AFADDDP
AFADDW
AFADDL
AFADDF
AFADDD
AFMULDP
AFMULW
AFMULL
AFMULF
AFMULD
AFSUBDP
AFSUBW
AFSUBL
AFSUBF
AFSUBD
AFSUBRDP
AFSUBRW
AFSUBRL
AFSUBRF
AFSUBRD
AFDIVDP
AFDIVW
AFDIVL
AFDIVF
AFDIVD
AFDIVRDP
AFDIVRW
AFDIVRL
AFDIVRF
AFDIVRD
AFXCHD
AFFREE
AFLDCW
AFLDENV
AFRSTOR
AFSAVE
AFSTCW
AFSTENV
AFSTSW
AF2XM1
AFABS
AFCHS
AFCLEX
AFCOS
AFDECSTP
AFINCSTP
AFINIT
AFLD1
AFLDL2E
AFLDL2T
AFLDLG2
AFLDLN2
AFLDPI
AFLDZ
AFNOP
AFPATAN
AFPREM
AFPREM1
AFPTAN
AFRNDINT
AFSCALE
AFSIN
AFSINCOS
AFSQRT
AFTST
AFXAM
AFXTRACT
AFYL2X
AFYL2XP1
AEND
ADYNT_
AINIT_
ASIGNAME
ACMPXCHGB
ACMPXCHGL
ACMPXCHGW
ACMPXCHG8B
ACPUID
ARDTSC
AXADDB
AXADDL
AXADDW
ACMOVLCC
ACMOVLCS
ACMOVLEQ
ACMOVLGE
ACMOVLGT
ACMOVLHI
ACMOVLLE
ACMOVLLS
ACMOVLLT
ACMOVLMI
ACMOVLNE
ACMOVLOC
ACMOVLOS
ACMOVLPC
ACMOVLPL
ACMOVLPS
ACMOVWCC
ACMOVWCS
ACMOVWEQ
ACMOVWGE
ACMOVWGT
ACMOVWHI
ACMOVWLE
ACMOVWLS
ACMOVWLT
ACMOVWMI
ACMOVWNE
ACMOVWOC
ACMOVWOS
ACMOVWPC
ACMOVWPL
ACMOVWPS
AFCMOVCC
AFCMOVCS
AFCMOVEQ
AFCMOVHI
AFCMOVLS
AFCMOVNE
AFCMOVNU
AFCMOVUN
ALFENCE
AMFENCE
ASFENCE
AEMMS
APREFETCHT0
APREFETCHT1
APREFETCHT2
APREFETCHNTA
ABSWAPL
AUNDEF
AADDPD
AADDPS
AADDSD
AADDSS
AANDNPD
AANDNPS
AANDPD
AANDPS
ACMPPD
ACMPPS
ACMPSD
ACMPSS
ACOMISD
ACOMISS
ACVTPL2PD
ACVTPL2PS
ACVTPD2PL
ACVTPD2PS
ACVTPS2PL
ACVTPS2PD
ACVTSD2SL
ACVTSD2SS
ACVTSL2SD
ACVTSL2SS
ACVTSS2SD
ACVTSS2SL
ACVTTPD2PL
ACVTTPS2PL
ACVTTSD2SL
ACVTTSS2SL
ADIVPD
ADIVPS
ADIVSD
ADIVSS
AMASKMOVOU
AMAXPD
AMAXPS
AMAXSD
AMAXSS
AMINPD
AMINPS
AMINSD
AMINSS
AMOVAPD
AMOVAPS
AMOVO
AMOVOU
AMOVHLPS
AMOVHPD
AMOVHPS
AMOVLHPS
AMOVLPD
AMOVLPS
AMOVMSKPD
AMOVMSKPS
AMOVNTO
AMOVNTPD
AMOVNTPS
AMOVSD
AMOVSS
AMOVUPD
AMOVUPS
AMULPD
AMULPS
AMULSD
AMULSS
AORPD
AORPS
APADDQ
APAND
APCMPEQB
APMAXSW
APMAXUB
APMINSW
APMINUB
APMOVMSKB
APSADBW
APSUBB
APSUBL
APSUBQ
APSUBSB
APSUBSW
APSUBUSB
APSUBUSW
APSUBW
APUNPCKHQDQ
APUNPCKLQDQ
APXOR
ARCPPS
ARCPSS
ARSQRTPS
ARSQRTSS
ASQRTPD
ASQRTPS
ASQRTSD
ASQRTSS
ASUBPD
ASUBPS
ASUBSD
ASUBSS
AUCOMISD
AUCOMISS
AUNPCKHPD
AUNPCKHPS
AUNPCKLPD
AUNPCKLPS
AXORPD
AXORPS
APSHUFHW
APSHUFL
APSHUFLW
AAESENC
APINSRD
APSHUFB
AUSEFIELD
ATYPE
AFUNCDATA
APCDATA
ACHECKNIL
AVARDEF
AVARKILL
ADUFFCOPY
ADUFFZERO
ALAST
)
const (
D_AL = 0 + iota
D_CL
D_DL
D_BL
D_AH = 4 + iota - 4
D_CH
D_DH
D_BH
D_AX = 8 + iota - 8
D_CX
D_DX
D_BX
D_SP
D_BP
D_SI
D_DI
D_F0 = 16
D_F7 = D_F0 + 7
D_CS = 24 + iota - 18
D_SS
D_DS
D_ES
D_FS
D_GS
D_GDTR
D_IDTR
D_LDTR
D_MSW
D_TASK
D_CR = 35
D_DR = 43
D_TR = 51
D_X0 = 59 + iota - 32
D_X1
D_X2
D_X3
D_X4
D_X5
D_X6
D_X7
D_TLS = 67
D_NONE = 68
D_BRANCH = 69
D_EXTERN = 70
D_STATIC = 71
D_AUTO = 72
D_PARAM = 73
D_CONST = 74
D_FCONST = 75
D_SCONST = 76
D_ADDR = 77 + iota - 50
D_INDIR
D_CONST2 = D_INDIR + D_INDIR + iota - 52
D_LAST
T_TYPE = 1 << 0
T_INDEX = 1 << 1
T_OFFSET = 1 << 2
T_FCONST = 1 << 3
T_SYM = 1 << 4
T_SCONST = 1 << 5
T_OFFSET2 = 1 << 6
T_GOTYPE = 1 << 7
REGARG = -1
REGRET = D_AX
FREGRET = D_F0
REGSP = D_SP
REGTMP = D_DI
)

View file

@ -0,0 +1,584 @@
package i386
/*
* this is the ranlib header
*/
var anames8 = []string{
"XXX",
"AAA",
"AAD",
"AAM",
"AAS",
"ADCB",
"ADCL",
"ADCW",
"ADDB",
"ADDL",
"ADDW",
"ADJSP",
"ANDB",
"ANDL",
"ANDW",
"ARPL",
"BOUNDL",
"BOUNDW",
"BSFL",
"BSFW",
"BSRL",
"BSRW",
"BTL",
"BTW",
"BTCL",
"BTCW",
"BTRL",
"BTRW",
"BTSL",
"BTSW",
"BYTE",
"CALL",
"CLC",
"CLD",
"CLI",
"CLTS",
"CMC",
"CMPB",
"CMPL",
"CMPW",
"CMPSB",
"CMPSL",
"CMPSW",
"DAA",
"DAS",
"DATA",
"DECB",
"DECL",
"DECW",
"DIVB",
"DIVL",
"DIVW",
"ENTER",
"GLOBL",
"GOK",
"HISTORY",
"HLT",
"IDIVB",
"IDIVL",
"IDIVW",
"IMULB",
"IMULL",
"IMULW",
"INB",
"INL",
"INW",
"INCB",
"INCL",
"INCW",
"INSB",
"INSL",
"INSW",
"INT",
"INTO",
"IRETL",
"IRETW",
"JCC",
"JCS",
"JCXZL",
"JCXZW",
"JEQ",
"JGE",
"JGT",
"JHI",
"JLE",
"JLS",
"JLT",
"JMI",
"JMP",
"JNE",
"JOC",
"JOS",
"JPC",
"JPL",
"JPS",
"LAHF",
"LARL",
"LARW",
"LEAL",
"LEAW",
"LEAVEL",
"LEAVEW",
"LOCK",
"LODSB",
"LODSL",
"LODSW",
"LONG",
"LOOP",
"LOOPEQ",
"LOOPNE",
"LSLL",
"LSLW",
"MOVB",
"MOVL",
"MOVW",
"MOVQ",
"MOVBLSX",
"MOVBLZX",
"MOVBWSX",
"MOVBWZX",
"MOVWLSX",
"MOVWLZX",
"MOVSB",
"MOVSL",
"MOVSW",
"MULB",
"MULL",
"MULW",
"NAME",
"NEGB",
"NEGL",
"NEGW",
"NOP",
"NOTB",
"NOTL",
"NOTW",
"ORB",
"ORL",
"ORW",
"OUTB",
"OUTL",
"OUTW",
"OUTSB",
"OUTSL",
"OUTSW",
"PAUSE",
"POPAL",
"POPAW",
"POPFL",
"POPFW",
"POPL",
"POPW",
"PUSHAL",
"PUSHAW",
"PUSHFL",
"PUSHFW",
"PUSHL",
"PUSHW",
"RCLB",
"RCLL",
"RCLW",
"RCRB",
"RCRL",
"RCRW",
"REP",
"REPN",
"RET",
"ROLB",
"ROLL",
"ROLW",
"RORB",
"RORL",
"RORW",
"SAHF",
"SALB",
"SALL",
"SALW",
"SARB",
"SARL",
"SARW",
"SBBB",
"SBBL",
"SBBW",
"SCASB",
"SCASL",
"SCASW",
"SETCC",
"SETCS",
"SETEQ",
"SETGE",
"SETGT",
"SETHI",
"SETLE",
"SETLS",
"SETLT",
"SETMI",
"SETNE",
"SETOC",
"SETOS",
"SETPC",
"SETPL",
"SETPS",
"CDQ",
"CWD",
"SHLB",
"SHLL",
"SHLW",
"SHRB",
"SHRL",
"SHRW",
"STC",
"STD",
"STI",
"STOSB",
"STOSL",
"STOSW",
"SUBB",
"SUBL",
"SUBW",
"SYSCALL",
"TESTB",
"TESTL",
"TESTW",
"TEXT",
"VERR",
"VERW",
"WAIT",
"WORD",
"XCHGB",
"XCHGL",
"XCHGW",
"XLAT",
"XORB",
"XORL",
"XORW",
"FMOVB",
"FMOVBP",
"FMOVD",
"FMOVDP",
"FMOVF",
"FMOVFP",
"FMOVL",
"FMOVLP",
"FMOVV",
"FMOVVP",
"FMOVW",
"FMOVWP",
"FMOVX",
"FMOVXP",
"FCOMB",
"FCOMBP",
"FCOMD",
"FCOMDP",
"FCOMDPP",
"FCOMF",
"FCOMFP",
"FCOMI",
"FCOMIP",
"FCOML",
"FCOMLP",
"FCOMW",
"FCOMWP",
"FUCOM",
"FUCOMI",
"FUCOMIP",
"FUCOMP",
"FUCOMPP",
"FADDDP",
"FADDW",
"FADDL",
"FADDF",
"FADDD",
"FMULDP",
"FMULW",
"FMULL",
"FMULF",
"FMULD",
"FSUBDP",
"FSUBW",
"FSUBL",
"FSUBF",
"FSUBD",
"FSUBRDP",
"FSUBRW",
"FSUBRL",
"FSUBRF",
"FSUBRD",
"FDIVDP",
"FDIVW",
"FDIVL",
"FDIVF",
"FDIVD",
"FDIVRDP",
"FDIVRW",
"FDIVRL",
"FDIVRF",
"FDIVRD",
"FXCHD",
"FFREE",
"FLDCW",
"FLDENV",
"FRSTOR",
"FSAVE",
"FSTCW",
"FSTENV",
"FSTSW",
"F2XM1",
"FABS",
"FCHS",
"FCLEX",
"FCOS",
"FDECSTP",
"FINCSTP",
"FINIT",
"FLD1",
"FLDL2E",
"FLDL2T",
"FLDLG2",
"FLDLN2",
"FLDPI",
"FLDZ",
"FNOP",
"FPATAN",
"FPREM",
"FPREM1",
"FPTAN",
"FRNDINT",
"FSCALE",
"FSIN",
"FSINCOS",
"FSQRT",
"FTST",
"FXAM",
"FXTRACT",
"FYL2X",
"FYL2XP1",
"END",
"DYNT_",
"INIT_",
"SIGNAME",
"CMPXCHGB",
"CMPXCHGL",
"CMPXCHGW",
"CMPXCHG8B",
"CPUID",
"RDTSC",
"XADDB",
"XADDL",
"XADDW",
"CMOVLCC",
"CMOVLCS",
"CMOVLEQ",
"CMOVLGE",
"CMOVLGT",
"CMOVLHI",
"CMOVLLE",
"CMOVLLS",
"CMOVLLT",
"CMOVLMI",
"CMOVLNE",
"CMOVLOC",
"CMOVLOS",
"CMOVLPC",
"CMOVLPL",
"CMOVLPS",
"CMOVWCC",
"CMOVWCS",
"CMOVWEQ",
"CMOVWGE",
"CMOVWGT",
"CMOVWHI",
"CMOVWLE",
"CMOVWLS",
"CMOVWLT",
"CMOVWMI",
"CMOVWNE",
"CMOVWOC",
"CMOVWOS",
"CMOVWPC",
"CMOVWPL",
"CMOVWPS",
"FCMOVCC",
"FCMOVCS",
"FCMOVEQ",
"FCMOVHI",
"FCMOVLS",
"FCMOVNE",
"FCMOVNU",
"FCMOVUN",
"LFENCE",
"MFENCE",
"SFENCE",
"EMMS",
"PREFETCHT0",
"PREFETCHT1",
"PREFETCHT2",
"PREFETCHNTA",
"BSWAPL",
"UNDEF",
"ADDPD",
"ADDPS",
"ADDSD",
"ADDSS",
"ANDNPD",
"ANDNPS",
"ANDPD",
"ANDPS",
"CMPPD",
"CMPPS",
"CMPSD",
"CMPSS",
"COMISD",
"COMISS",
"CVTPL2PD",
"CVTPL2PS",
"CVTPD2PL",
"CVTPD2PS",
"CVTPS2PL",
"CVTPS2PD",
"CVTSD2SL",
"CVTSD2SS",
"CVTSL2SD",
"CVTSL2SS",
"CVTSS2SD",
"CVTSS2SL",
"CVTTPD2PL",
"CVTTPS2PL",
"CVTTSD2SL",
"CVTTSS2SL",
"DIVPD",
"DIVPS",
"DIVSD",
"DIVSS",
"MASKMOVOU",
"MAXPD",
"MAXPS",
"MAXSD",
"MAXSS",
"MINPD",
"MINPS",
"MINSD",
"MINSS",
"MOVAPD",
"MOVAPS",
"MOVO",
"MOVOU",
"MOVHLPS",
"MOVHPD",
"MOVHPS",
"MOVLHPS",
"MOVLPD",
"MOVLPS",
"MOVMSKPD",
"MOVMSKPS",
"MOVNTO",
"MOVNTPD",
"MOVNTPS",
"MOVSD",
"MOVSS",
"MOVUPD",
"MOVUPS",
"MULPD",
"MULPS",
"MULSD",
"MULSS",
"ORPD",
"ORPS",
"PADDQ",
"PAND",
"PCMPEQB",
"PMAXSW",
"PMAXUB",
"PMINSW",
"PMINUB",
"PMOVMSKB",
"PSADBW",
"PSUBB",
"PSUBL",
"PSUBQ",
"PSUBSB",
"PSUBSW",
"PSUBUSB",
"PSUBUSW",
"PSUBW",
"PUNPCKHQDQ",
"PUNPCKLQDQ",
"PXOR",
"RCPPS",
"RCPSS",
"RSQRTPS",
"RSQRTSS",
"SQRTPD",
"SQRTPS",
"SQRTSD",
"SQRTSS",
"SUBPD",
"SUBPS",
"SUBSD",
"SUBSS",
"UCOMISD",
"UCOMISS",
"UNPCKHPD",
"UNPCKHPS",
"UNPCKLPD",
"UNPCKLPS",
"XORPD",
"XORPS",
"PSHUFHW",
"PSHUFL",
"PSHUFLW",
"AESENC",
"PINSRD",
"PSHUFB",
"USEFIELD",
"TYPE",
"FUNCDATA",
"PCDATA",
"CHECKNIL",
"VARDEF",
"VARKILL",
"DUFFCOPY",
"DUFFZERO",
"LAST",
}
var dnames8 = []string{
D_AL: "AL",
D_CL: "CL",
D_DL: "DL",
D_BL: "BL",
D_AH: "AH",
D_CH: "CH",
D_DH: "DH",
D_BH: "BH",
D_AX: "AX",
D_CX: "CX",
D_DX: "DX",
D_BX: "BX",
D_SP: "SP",
D_BP: "BP",
D_SI: "SI",
D_DI: "DI",
D_F0: "F0",
D_CS: "CS",
D_SS: "SS",
D_DS: "DS",
D_ES: "ES",
D_FS: "FS",
D_GS: "GS",
D_GDTR: "GDTR",
D_IDTR: "IDTR",
D_LDTR: "LDTR",
D_MSW: "MSW",
D_TASK: "TASK",
D_CR: "CR",
D_DR: "DR",
D_TR: "TR",
D_X0: "X0",
D_X1: "X1",
D_X2: "X2",
D_X3: "X3",
D_X4: "X4",
D_X5: "X5",
D_X6: "X6",
D_X7: "X7",
D_TLS: "TLS",
D_NONE: "NONE",
D_BRANCH: "BRANCH",
D_EXTERN: "EXTERN",
D_STATIC: "STATIC",
D_AUTO: "AUTO",
D_PARAM: "PARAM",
D_CONST: "CONST",
D_FCONST: "FCONST",
D_SCONST: "SCONST",
D_ADDR: "ADDR",
D_INDIR: "INDIR",
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,273 @@
// Inferno utils/8c/list.c
// http://code.google.com/p/inferno-os/source/browse/utils/8c/list.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package i386
import (
"cmd/internal/obj"
"fmt"
)
const (
STRINGSZ = 1000
)
var bigP *obj.Prog
func Pconv(p *obj.Prog) string {
var str string
var fp string
switch p.As {
case ADATA:
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, 0, &p.To))
case ATEXT:
if p.From.Scale != 0 {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, fmtLong, &p.To))
break
}
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, fmtLong, &p.To))
default:
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
break
}
fp += str
return fp
}
func Aconv(i int) string {
var fp string
fp += anames8[i]
return fp
}
func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
var str string
var s string
var fp string
var i int
i = int(a.Type_)
if flag&fmtLong != 0 /*untyped*/ {
if i == D_CONST2 {
str = fmt.Sprintf("$%d-%d", a.Offset, a.Offset2)
} else {
// ATEXT dst is not constant
str = fmt.Sprintf("!!%v", Dconv(p, 0, a))
}
goto brk
}
if i >= D_INDIR {
if a.Offset != 0 {
str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(i-D_INDIR))
} else {
str = fmt.Sprintf("(%v)", Rconv(i-D_INDIR))
}
goto brk
}
switch i {
default:
if a.Offset != 0 {
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(i))
} else {
str = fmt.Sprintf("%v", Rconv(i))
}
case D_NONE:
str = ""
case D_BRANCH:
if a.Sym != nil {
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
} else if p != nil && p.Pcond != nil {
str = fmt.Sprintf("%d", p.Pcond.Pc)
} else if a.U.Branch != nil {
str = fmt.Sprintf("%d", a.U.Branch.Pc)
} else {
str = fmt.Sprintf("%d(PC)", a.Offset)
}
case D_EXTERN:
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
case D_STATIC:
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
case D_AUTO:
if a.Sym != nil {
str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset)
} else {
str = fmt.Sprintf("%d(SP)", a.Offset)
}
case D_PARAM:
if a.Sym != nil {
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset)
} else {
str = fmt.Sprintf("%d(FP)", a.Offset)
}
case D_CONST:
str = fmt.Sprintf("$%d", a.Offset)
case D_CONST2:
if !(flag&fmtLong != 0 /*untyped*/) {
// D_CONST2 outside of ATEXT should not happen
str = fmt.Sprintf("!!$%d-%d", a.Offset, a.Offset2)
}
case D_FCONST:
str = fmt.Sprintf("$(%.17g)", a.U.Dval)
case D_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
case D_ADDR:
a.Type_ = int16(a.Index)
a.Index = D_NONE
str = fmt.Sprintf("$%v", Dconv(p, 0, a))
a.Index = uint8(a.Type_)
a.Type_ = D_ADDR
goto conv
}
brk:
if a.Index != D_NONE {
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
str += s
}
conv:
fp += str
return fp
}
var regstr = []string{
"AL", /* [D_AL] */
"CL",
"DL",
"BL",
"AH",
"CH",
"DH",
"BH",
"AX", /* [D_AX] */
"CX",
"DX",
"BX",
"SP",
"BP",
"SI",
"DI",
"F0", /* [D_F0] */
"F1",
"F2",
"F3",
"F4",
"F5",
"F6",
"F7",
"CS", /* [D_CS] */
"SS",
"DS",
"ES",
"FS",
"GS",
"GDTR", /* [D_GDTR] */
"IDTR", /* [D_IDTR] */
"LDTR", /* [D_LDTR] */
"MSW", /* [D_MSW] */
"TASK", /* [D_TASK] */
"CR0", /* [D_CR] */
"CR1",
"CR2",
"CR3",
"CR4",
"CR5",
"CR6",
"CR7",
"DR0", /* [D_DR] */
"DR1",
"DR2",
"DR3",
"DR4",
"DR5",
"DR6",
"DR7",
"TR0", /* [D_TR] */
"TR1",
"TR2",
"TR3",
"TR4",
"TR5",
"TR6",
"TR7",
"X0", /* [D_X0] */
"X1",
"X2",
"X3",
"X4",
"X5",
"X6",
"X7",
"TLS", /* [D_TLS] */
"NONE", /* [D_NONE] */
}
func Rconv(r int) string {
var str string
var fp string
if r >= D_AL && r <= D_NONE {
str = fmt.Sprintf("%s", regstr[r-D_AL])
} else {
str = fmt.Sprintf("gok(%d)", r)
}
fp += str
return fp
}

View file

@ -0,0 +1,999 @@
// Inferno utils/8l/pass.c
// http://code.google.com/p/inferno-os/source/browse/utils/8l/pass.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package i386
import (
"cmd/internal/obj"
"encoding/binary"
"fmt"
"log"
"math"
)
var zprg = obj.Prog{
Back: 2,
As: AGOK,
From: obj.Addr{
Type_: D_NONE,
Index: D_NONE,
Scale: 1,
},
To: obj.Addr{
Type_: D_NONE,
Index: D_NONE,
Scale: 1,
},
}
func symtype(a *obj.Addr) int {
var t int
t = int(a.Type_)
if t == D_ADDR {
t = int(a.Index)
}
return t
}
func isdata(p *obj.Prog) bool {
return p.As == ADATA || p.As == AGLOBL
}
func iscall(p *obj.Prog) bool {
return p.As == ACALL
}
func datasize(p *obj.Prog) int {
return int(p.From.Scale)
}
func textflag(p *obj.Prog) int {
return int(p.From.Scale)
}
func settextflag(p *obj.Prog, f int) {
p.From.Scale = int8(f)
}
func canuselocaltls(ctxt *obj.Link) int {
switch ctxt.Headtype {
case obj.Hlinux,
obj.Hnacl,
obj.Hplan9,
obj.Hwindows:
return 0
}
return 1
}
func progedit(ctxt *obj.Link, p *obj.Prog) {
var literal string
var s *obj.LSym
var q *obj.Prog
// See obj6.c for discussion of TLS.
if canuselocaltls(ctxt) != 0 {
// Reduce TLS initial exec model to TLS local exec model.
// Sequences like
// MOVL TLS, BX
// ... off(BX)(TLS*1) ...
// become
// NOP
// ... off(TLS) ...
if p.As == AMOVL && p.From.Type_ == D_TLS && D_AX <= p.To.Type_ && p.To.Type_ <= D_DI {
p.As = ANOP
p.From.Type_ = D_NONE
p.To.Type_ = D_NONE
}
if p.From.Index == D_TLS && D_INDIR+D_AX <= p.From.Type_ && p.From.Type_ <= D_INDIR+D_DI {
p.From.Type_ = D_INDIR + D_TLS
p.From.Scale = 0
p.From.Index = D_NONE
}
if p.To.Index == D_TLS && D_INDIR+D_AX <= p.To.Type_ && p.To.Type_ <= D_INDIR+D_DI {
p.To.Type_ = D_INDIR + D_TLS
p.To.Scale = 0
p.To.Index = D_NONE
}
} else {
// As a courtesy to the C compilers, rewrite TLS local exec load as TLS initial exec load.
// The instruction
// MOVL off(TLS), BX
// becomes the sequence
// MOVL TLS, BX
// MOVL off(BX)(TLS*1), BX
// This allows the C compilers to emit references to m and g using the direct off(TLS) form.
if p.As == AMOVL && p.From.Type_ == D_INDIR+D_TLS && D_AX <= p.To.Type_ && p.To.Type_ <= D_DI {
q = obj.Appendp(ctxt, p)
q.As = p.As
q.From = p.From
q.From.Type_ = D_INDIR + p.To.Type_
q.From.Index = D_TLS
q.From.Scale = 2 // TODO: use 1
q.To = p.To
p.From.Type_ = D_TLS
p.From.Index = D_NONE
p.From.Offset = 0
}
}
// TODO: Remove.
if ctxt.Headtype == obj.Hplan9 {
if p.From.Scale == 1 && p.From.Index == D_TLS {
p.From.Scale = 2
}
if p.To.Scale == 1 && p.To.Index == D_TLS {
p.To.Scale = 2
}
}
// Rewrite CALL/JMP/RET to symbol as D_BRANCH.
switch p.As {
case ACALL,
AJMP,
ARET:
if (p.To.Type_ == D_EXTERN || p.To.Type_ == D_STATIC) && p.To.Sym != nil {
p.To.Type_ = D_BRANCH
}
break
}
// Rewrite float constants to values stored in memory.
switch p.As {
// Convert AMOVSS $(0), Xx to AXORPS Xx, Xx
case AMOVSS:
if p.From.Type_ == D_FCONST {
if p.From.U.Dval == 0 {
if p.To.Type_ >= D_X0 {
if p.To.Type_ <= D_X7 {
p.As = AXORPS
p.From.Type_ = p.To.Type_
p.From.Index = p.To.Index
break
}
}
}
}
fallthrough
// fallthrough
case AFMOVF,
AFADDF,
AFSUBF,
AFSUBRF,
AFMULF,
AFDIVF,
AFDIVRF,
AFCOMF,
AFCOMFP,
AADDSS,
ASUBSS,
AMULSS,
ADIVSS,
ACOMISS,
AUCOMISS:
if p.From.Type_ == D_FCONST {
var i32 uint32
var f32 float32
f32 = float32(p.From.U.Dval)
i32 = math.Float32bits(f32)
literal = fmt.Sprintf("$f32.%08x", i32)
s = obj.Linklookup(ctxt, literal, 0)
if s.Type_ == 0 {
s.Type_ = obj.SRODATA
obj.Adduint32(ctxt, s, i32)
s.Reachable = 0
}
p.From.Type_ = D_EXTERN
p.From.Sym = s
p.From.Offset = 0
}
// Convert AMOVSD $(0), Xx to AXORPS Xx, Xx
case AMOVSD:
if p.From.Type_ == D_FCONST {
if p.From.U.Dval == 0 {
if p.To.Type_ >= D_X0 {
if p.To.Type_ <= D_X7 {
p.As = AXORPS
p.From.Type_ = p.To.Type_
p.From.Index = p.To.Index
break
}
}
}
}
fallthrough
// fallthrough
case AFMOVD,
AFADDD,
AFSUBD,
AFSUBRD,
AFMULD,
AFDIVD,
AFDIVRD,
AFCOMD,
AFCOMDP,
AADDSD,
ASUBSD,
AMULSD,
ADIVSD,
ACOMISD,
AUCOMISD:
if p.From.Type_ == D_FCONST {
var i64 uint64
i64 = math.Float64bits(p.From.U.Dval)
literal = fmt.Sprintf("$f64.%016x", i64)
s = obj.Linklookup(ctxt, literal, 0)
if s.Type_ == 0 {
s.Type_ = obj.SRODATA
obj.Adduint64(ctxt, s, i64)
s.Reachable = 0
}
p.From.Type_ = D_EXTERN
p.From.Sym = s
p.From.Offset = 0
}
break
}
}
func prg() *obj.Prog {
var p *obj.Prog
p = new(obj.Prog)
*p = zprg
return p
}
func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
var p *obj.Prog
var q *obj.Prog
var p1 *obj.Prog
var p2 *obj.Prog
var autoffset int32
var deltasp int32
var a int
if ctxt.Symmorestack[0] == nil {
ctxt.Symmorestack[0] = obj.Linklookup(ctxt, "runtime.morestack", 0)
ctxt.Symmorestack[1] = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0)
}
if ctxt.Headtype == obj.Hplan9 && ctxt.Plan9privates == nil {
ctxt.Plan9privates = obj.Linklookup(ctxt, "_privates", 0)
}
ctxt.Cursym = cursym
if cursym.Text == nil || cursym.Text.Link == nil {
return
}
p = cursym.Text
autoffset = int32(p.To.Offset)
if autoffset < 0 {
autoffset = 0
}
cursym.Locals = autoffset
cursym.Args = p.To.Offset2
q = nil
if !(p.From.Scale&obj.NOSPLIT != 0) || (p.From.Scale&obj.WRAPPER != 0) {
p = obj.Appendp(ctxt, p)
p = load_g_cx(ctxt, p) // load g into CX
}
if !(cursym.Text.From.Scale&obj.NOSPLIT != 0) {
p = stacksplit(ctxt, p, autoffset, bool2int(!(cursym.Text.From.Scale&obj.NEEDCTXT != 0)), &q) // emit split check
}
if autoffset != 0 {
p = obj.Appendp(ctxt, p)
p.As = AADJSP
p.From.Type_ = D_CONST
p.From.Offset = int64(autoffset)
p.Spadj = autoffset
} else {
// zero-byte stack adjustment.
// Insert a fake non-zero adjustment so that stkcheck can
// recognize the end of the stack-splitting prolog.
p = obj.Appendp(ctxt, p)
p.As = ANOP
p.Spadj = int32(-ctxt.Arch.Ptrsize)
p = obj.Appendp(ctxt, p)
p.As = ANOP
p.Spadj = int32(ctxt.Arch.Ptrsize)
}
if q != nil {
q.Pcond = p
}
deltasp = autoffset
if cursym.Text.From.Scale&obj.WRAPPER != 0 {
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
//
// MOVL g_panic(CX), BX
// TESTL BX, BX
// JEQ end
// LEAL (autoffset+4)(SP), DI
// CMPL panic_argp(BX), DI
// JNE end
// MOVL SP, panic_argp(BX)
// end:
// NOP
//
// The NOP is needed to give the jumps somewhere to land.
// It is a liblink NOP, not an x86 NOP: it encodes to 0 instruction bytes.
p = obj.Appendp(ctxt, p)
p.As = AMOVL
p.From.Type_ = D_INDIR + D_CX
p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
p.To.Type_ = D_BX
p = obj.Appendp(ctxt, p)
p.As = ATESTL
p.From.Type_ = D_BX
p.To.Type_ = D_BX
p = obj.Appendp(ctxt, p)
p.As = AJEQ
p.To.Type_ = D_BRANCH
p1 = p
p = obj.Appendp(ctxt, p)
p.As = ALEAL
p.From.Type_ = D_INDIR + D_SP
p.From.Offset = int64(autoffset) + 4
p.To.Type_ = D_DI
p = obj.Appendp(ctxt, p)
p.As = ACMPL
p.From.Type_ = D_INDIR + D_BX
p.From.Offset = 0 // Panic.argp
p.To.Type_ = D_DI
p = obj.Appendp(ctxt, p)
p.As = AJNE
p.To.Type_ = D_BRANCH
p2 = p
p = obj.Appendp(ctxt, p)
p.As = AMOVL
p.From.Type_ = D_SP
p.To.Type_ = D_INDIR + D_BX
p.To.Offset = 0 // Panic.argp
p = obj.Appendp(ctxt, p)
p.As = ANOP
p1.Pcond = p
p2.Pcond = p
}
if ctxt.Debugzerostack != 0 && autoffset != 0 && !(cursym.Text.From.Scale&obj.NOSPLIT != 0) {
// 8l -Z means zero the stack frame on entry.
// This slows down function calls but can help avoid
// false positives in garbage collection.
p = obj.Appendp(ctxt, p)
p.As = AMOVL
p.From.Type_ = D_SP
p.To.Type_ = D_DI
p = obj.Appendp(ctxt, p)
p.As = AMOVL
p.From.Type_ = D_CONST
p.From.Offset = int64(autoffset) / 4
p.To.Type_ = D_CX
p = obj.Appendp(ctxt, p)
p.As = AMOVL
p.From.Type_ = D_CONST
p.From.Offset = 0
p.To.Type_ = D_AX
p = obj.Appendp(ctxt, p)
p.As = AREP
p = obj.Appendp(ctxt, p)
p.As = ASTOSL
}
for ; p != nil; p = p.Link {
a = int(p.From.Type_)
if a == D_AUTO {
p.From.Offset += int64(deltasp)
}
if a == D_PARAM {
p.From.Offset += int64(deltasp) + 4
}
a = int(p.To.Type_)
if a == D_AUTO {
p.To.Offset += int64(deltasp)
}
if a == D_PARAM {
p.To.Offset += int64(deltasp) + 4
}
switch p.As {
default:
continue
case APUSHL,
APUSHFL:
deltasp += 4
p.Spadj = 4
continue
case APUSHW,
APUSHFW:
deltasp += 2
p.Spadj = 2
continue
case APOPL,
APOPFL:
deltasp -= 4
p.Spadj = -4
continue
case APOPW,
APOPFW:
deltasp -= 2
p.Spadj = -2
continue
case ARET:
break
}
if autoffset != deltasp {
ctxt.Diag("unbalanced PUSH/POP")
}
if autoffset != 0 {
p.As = AADJSP
p.From.Type_ = D_CONST
p.From.Offset = int64(-autoffset)
p.Spadj = -autoffset
p = obj.Appendp(ctxt, p)
p.As = ARET
// If there are instructions following
// this ARET, they come from a branch
// with the same stackframe, so undo
// the cleanup.
p.Spadj = +autoffset
}
if p.To.Sym != nil { // retjmp
p.As = AJMP
}
}
}
// Append code to p to load g into cx.
// Overwrites p with the first instruction (no first appendp).
// Overwriting p is unusual but it lets use this in both the
// prologue (caller must call appendp first) and in the epilogue.
// Returns last new instruction.
func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
var next *obj.Prog
p.As = AMOVL
p.From.Type_ = D_INDIR + D_TLS
p.From.Offset = 0
p.To.Type_ = D_CX
next = p.Link
progedit(ctxt, p)
for p.Link != next {
p = p.Link
}
if p.From.Index == D_TLS {
p.From.Scale = 2
}
return p
}
// Append code to p to check for stack split.
// Appends to (does not overwrite) p.
// Assumes g is in CX.
// Returns last new instruction.
// On return, *jmpok is the instruction that should jump
// to the stack frame allocation if no split is needed.
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok **obj.Prog) *obj.Prog {
var q *obj.Prog
var q1 *obj.Prog
if ctxt.Debugstack != 0 {
// 8l -K means check not only for stack
// overflow but stack underflow.
// On underflow, INT 3 (breakpoint).
// Underflow itself is rare but this also
// catches out-of-sync stack guard info.
p = obj.Appendp(ctxt, p)
p.As = ACMPL
p.From.Type_ = D_INDIR + D_CX
p.From.Offset = 4
p.To.Type_ = D_SP
p = obj.Appendp(ctxt, p)
p.As = AJCC
p.To.Type_ = D_BRANCH
p.To.Offset = 4
q1 = p
p = obj.Appendp(ctxt, p)
p.As = AINT
p.From.Type_ = D_CONST
p.From.Offset = 3
p = obj.Appendp(ctxt, p)
p.As = ANOP
q1.Pcond = p
}
q1 = nil
if framesize <= obj.StackSmall {
// small stack: SP <= stackguard
// CMPL SP, stackguard
p = obj.Appendp(ctxt, p)
p.As = ACMPL
p.From.Type_ = D_SP
p.To.Type_ = D_INDIR + D_CX
p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
if ctxt.Cursym.Cfunc != 0 {
p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
}
} else if framesize <= obj.StackBig {
// large stack: SP-framesize <= stackguard-StackSmall
// LEAL -(framesize-StackSmall)(SP), AX
// CMPL AX, stackguard
p = obj.Appendp(ctxt, p)
p.As = ALEAL
p.From.Type_ = D_INDIR + D_SP
p.From.Offset = -(int64(framesize) - obj.StackSmall)
p.To.Type_ = D_AX
p = obj.Appendp(ctxt, p)
p.As = ACMPL
p.From.Type_ = D_AX
p.To.Type_ = D_INDIR + D_CX
p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
if ctxt.Cursym.Cfunc != 0 {
p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
}
} else {
// Such a large stack we need to protect against wraparound
// if SP is close to zero.
// SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
// The +StackGuard on both sides is required to keep the left side positive:
// SP is allowed to be slightly below stackguard. See stack.h.
//
// Preemption sets stackguard to StackPreempt, a very large value.
// That breaks the math above, so we have to check for that explicitly.
// MOVL stackguard, CX
// CMPL CX, $StackPreempt
// JEQ label-of-call-to-morestack
// LEAL StackGuard(SP), AX
// SUBL stackguard, AX
// CMPL AX, $(framesize+(StackGuard-StackSmall))
p = obj.Appendp(ctxt, p)
p.As = AMOVL
p.From.Type_ = D_INDIR + D_CX
p.From.Offset = 0
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
if ctxt.Cursym.Cfunc != 0 {
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
}
p.To.Type_ = D_SI
p = obj.Appendp(ctxt, p)
p.As = ACMPL
p.From.Type_ = D_SI
p.To.Type_ = D_CONST
p.To.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1)))
p = obj.Appendp(ctxt, p)
p.As = AJEQ
p.To.Type_ = D_BRANCH
q1 = p
p = obj.Appendp(ctxt, p)
p.As = ALEAL
p.From.Type_ = D_INDIR + D_SP
p.From.Offset = obj.StackGuard
p.To.Type_ = D_AX
p = obj.Appendp(ctxt, p)
p.As = ASUBL
p.From.Type_ = D_SI
p.From.Offset = 0
p.To.Type_ = D_AX
p = obj.Appendp(ctxt, p)
p.As = ACMPL
p.From.Type_ = D_AX
p.To.Type_ = D_CONST
p.To.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall)
}
// common
p = obj.Appendp(ctxt, p)
p.As = AJHI
p.To.Type_ = D_BRANCH
p.To.Offset = 4
q = p
p = obj.Appendp(ctxt, p)
p.As = ACALL
p.To.Type_ = D_BRANCH
if ctxt.Cursym.Cfunc != 0 {
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
} else {
p.To.Sym = ctxt.Symmorestack[noctxt]
}
p = obj.Appendp(ctxt, p)
p.As = AJMP
p.To.Type_ = D_BRANCH
p.Pcond = ctxt.Cursym.Text.Link
if q != nil {
q.Pcond = p.Link
}
if q1 != nil {
q1.Pcond = q.Link
}
*jmpok = q
return p
}
func follow(ctxt *obj.Link, s *obj.LSym) {
var firstp *obj.Prog
var lastp *obj.Prog
ctxt.Cursym = s
firstp = ctxt.Arch.Prg()
lastp = firstp
xfol(ctxt, s.Text, &lastp)
lastp.Link = nil
s.Text = firstp.Link
}
func nofollow(a int) int {
switch a {
case AJMP,
ARET,
AIRETL,
AIRETW,
AUNDEF:
return 1
}
return 0
}
func pushpop(a int) int {
switch a {
case APUSHL,
APUSHFL,
APUSHW,
APUSHFW,
APOPL,
APOPFL,
APOPW,
APOPFW:
return 1
}
return 0
}
func relinv(a int) int {
switch a {
case AJEQ:
return AJNE
case AJNE:
return AJEQ
case AJLE:
return AJGT
case AJLS:
return AJHI
case AJLT:
return AJGE
case AJMI:
return AJPL
case AJGE:
return AJLT
case AJPL:
return AJMI
case AJGT:
return AJLE
case AJHI:
return AJLS
case AJCS:
return AJCC
case AJCC:
return AJCS
case AJPS:
return AJPC
case AJPC:
return AJPS
case AJOS:
return AJOC
case AJOC:
return AJOS
}
log.Fatalf("unknown relation: %s", anames8[a])
return 0
}
func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) {
var q *obj.Prog
var i int
var a int
loop:
if p == nil {
return
}
if p.As == AJMP {
q = p.Pcond
if q != nil && q.As != ATEXT {
/* mark instruction as done and continue layout at target of jump */
p.Mark = 1
p = q
if p.Mark == 0 {
goto loop
}
}
}
if p.Mark != 0 {
/*
* p goes here, but already used it elsewhere.
* copy up to 4 instructions or else branch to other copy.
*/
i = 0
q = p
for ; i < 4; (func() { i++; q = q.Link })() {
if q == nil {
break
}
if q == *last {
break
}
a = int(q.As)
if a == ANOP {
i--
continue
}
if nofollow(a) != 0 || pushpop(a) != 0 {
break // NOTE(rsc): arm does goto copy
}
if q.Pcond == nil || q.Pcond.Mark != 0 {
continue
}
if a == ACALL || a == ALOOP {
continue
}
for {
if p.As == ANOP {
p = p.Link
continue
}
q = obj.Copyp(ctxt, p)
p = p.Link
q.Mark = 1
(*last).Link = q
*last = q
if int(q.As) != a || q.Pcond == nil || q.Pcond.Mark != 0 {
continue
}
q.As = int16(relinv(int(q.As)))
p = q.Pcond
q.Pcond = q.Link
q.Link = p
xfol(ctxt, q.Link, last)
p = q.Link
if p.Mark != 0 {
return
}
goto loop
/* */
}
}
q = ctxt.Arch.Prg()
q.As = AJMP
q.Lineno = p.Lineno
q.To.Type_ = D_BRANCH
q.To.Offset = p.Pc
q.Pcond = p
p = q
}
/* emit p */
p.Mark = 1
(*last).Link = p
*last = p
a = int(p.As)
/* continue loop with what comes after p */
if nofollow(a) != 0 {
return
}
if p.Pcond != nil && a != ACALL {
/*
* some kind of conditional branch.
* recurse to follow one path.
* continue loop on the other.
*/
q = obj.Brchain(ctxt, p.Pcond)
if q != nil {
p.Pcond = q
}
q = obj.Brchain(ctxt, p.Link)
if q != nil {
p.Link = q
}
if p.From.Type_ == D_CONST {
if p.From.Offset == 1 {
/*
* expect conditional jump to be taken.
* rewrite so that's the fall-through case.
*/
p.As = int16(relinv(a))
q = p.Link
p.Link = p.Pcond
p.Pcond = q
}
} else {
q = p.Link
if q.Mark != 0 {
if a != ALOOP {
p.As = int16(relinv(a))
p.Link = p.Pcond
p.Pcond = q
}
}
}
xfol(ctxt, p.Link, last)
if p.Pcond.Mark != 0 {
return
}
p = p.Pcond
goto loop
}
p = p.Link
goto loop
}
var Link386 = obj.LinkArch{
ByteOrder: binary.LittleEndian,
Pconv: Pconv,
Name: "386",
Thechar: '8',
Endian: obj.LittleEndian,
Addstacksplit: addstacksplit,
Assemble: span8,
Datasize: datasize,
Follow: follow,
Iscall: iscall,
Isdata: isdata,
Prg: prg,
Progedit: progedit,
Settextflag: settextflag,
Symtype: symtype,
Textflag: textflag,
Minlc: 1,
Ptrsize: 4,
Regsize: 4,
D_ADDR: D_ADDR,
D_AUTO: D_AUTO,
D_BRANCH: D_BRANCH,
D_CONST: D_CONST,
D_EXTERN: D_EXTERN,
D_FCONST: D_FCONST,
D_NONE: D_NONE,
D_PARAM: D_PARAM,
D_SCONST: D_SCONST,
D_STATIC: D_STATIC,
ACALL: ACALL,
ADATA: ADATA,
AEND: AEND,
AFUNCDATA: AFUNCDATA,
AGLOBL: AGLOBL,
AJMP: AJMP,
ANOP: ANOP,
APCDATA: APCDATA,
ARET: ARET,
ATEXT: ATEXT,
ATYPE: ATYPE,
AUSEFIELD: AUSEFIELD,
}

View file

@ -0,0 +1,16 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package i386
const (
fmtLong = 1 << iota
)
func bool2int(b bool) int {
if b {
return 1
}
return 0
}

161
src/cmd/internal/obj/ld.go Normal file
View file

@ -0,0 +1,161 @@
// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
// http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.c
// http://code.google.com/p/inferno-os/source/browse/utils/6l/span.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package obj
import (
"fmt"
"os"
"path"
"strings"
)
func addlib(ctxt *Link, src, obj, pathname string) {
name := path.Clean(pathname)
// runtime.a -> runtime
short := strings.TrimSuffix(name, ".a")
// already loaded?
for i := range ctxt.Library {
if ctxt.Library[i].Pkg == short {
return
}
}
var pname string
// runtime -> runtime.a for search
if (!(ctxt.Windows != 0) && name[0] == '/') || (ctxt.Windows != 0 && name[1] == ':') {
pname = name
} else {
// try dot, -L "libdir", and then goroot.
for _, dir := range ctxt.Libdir {
pname = dir + "/" + name
if _, err := os.Stat(pname); !os.IsNotExist(err) {
break
}
}
}
pname = path.Clean(pname)
// runtime.a -> runtime
pname = strings.TrimSuffix(pname, ".a")
if ctxt.Debugvlog > 1 && ctxt.Bso != nil {
fmt.Fprintf(ctxt.Bso, "%5.2f addlib: %s %s pulls in %s\n", Cputime(), obj, src, pname)
}
addlibpath(ctxt, src, obj, pname, name)
}
/*
* add library to library list.
* srcref: src file referring to package
* objref: object file referring to package
* file: object file, e.g., /home/rsc/go/pkg/container/vector.a
* pkg: package import path, e.g. container/vector
*/
func addlibpath(ctxt *Link, srcref, objref, file, pkg string) {
for _, lib := range ctxt.Library {
if lib.File == file {
return
}
}
if ctxt.Debugvlog > 1 && ctxt.Bso != nil {
fmt.Fprintf(ctxt.Bso, "%5.2f addlibpath: srcref: %s objref: %s file: %s pkg: %s\n", Cputime(), srcref, objref, file, pkg)
}
ctxt.Library = append(ctxt.Library, Library{
Objref: objref,
Srcref: srcref,
File: file,
Pkg: pkg,
})
}
const (
LOG = 5
)
func mkfwd(sym *LSym) {
var p *Prog
var i int
var dwn [LOG]int32
var cnt [LOG]int32
var lst [LOG]*Prog
for i = 0; i < LOG; i++ {
if i == 0 {
cnt[i] = 1
} else {
cnt[i] = LOG * cnt[i-1]
}
dwn[i] = 1
lst[i] = nil
}
i = 0
for p = sym.Text; p != nil && p.Link != nil; p = p.Link {
i--
if i < 0 {
i = LOG - 1
}
p.Forwd = nil
dwn[i]--
if dwn[i] <= 0 {
dwn[i] = cnt[i]
if lst[i] != nil {
lst[i].Forwd = p
}
lst[i] = p
}
}
}
func Copyp(ctxt *Link, q *Prog) *Prog {
var p *Prog
p = ctxt.Arch.Prg()
*p = *q
return p
}
func Appendp(ctxt *Link, q *Prog) *Prog {
var p *Prog
p = ctxt.Arch.Prg()
p.Link = q.Link
q.Link = p
p.Lineno = q.Lineno
p.Mode = q.Mode
return p
}

View file

@ -0,0 +1,463 @@
// Derived from Inferno utils/6l/l.h and related files.
// http://code.google.com/p/inferno-os/source/browse/utils/6l/l.h
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package obj
import "encoding/binary"
type Addr struct {
Offset int64
U struct {
Sval string
Dval float64
Branch *Prog
}
Sym *LSym
Gotype *LSym
Type_ int16
Index uint8
Scale int8
Reg int8
Name int8
Class int8
Etype uint8
Offset2 int32
Node *struct{}
Width int64
}
type Prog struct {
Ctxt *Link
Pc int64
Lineno int32
Link *Prog
As int16
Scond uint8
From Addr
Reg uint8
From3 Addr
To Addr
Opt interface{}
Forwd *Prog
Pcond *Prog
Comefrom *Prog
Pcrel *Prog
Spadj int32
Mark uint16
Optab uint16
Back uint8
Ft uint8
Tt uint8
Isize uint8
Printed uint8
Width int8
Mode int8
TEXTFLAG uint8
}
type LSym struct {
Name string
Extname string
Type_ int16
Version int16
Dupok uint8
Cfunc uint8
External uint8
Nosplit uint8
Reachable uint8
Cgoexport uint8
Special uint8
Stkcheck uint8
Hide uint8
Leaf uint8
Fnptr uint8
Localentry uint8
Seenglobl uint8
Onlist uint8
Printed uint8
Symid int16
Dynid int32
Sig int32
Plt int32
Got int32
Align int32
Elfsym int32
Args int32
Locals int32
Value int64
Size int64
Hash *LSym
Allsym *LSym
Next *LSym
Sub *LSym
Outer *LSym
Gotype *LSym
Reachparent *LSym
Queue *LSym
File string
Dynimplib string
Dynimpvers string
Sect *struct{}
Autom *Auto
Text *Prog
Etext *Prog
Pcln *Pcln
P []byte
R []Reloc
}
type Reloc struct {
Off int32
Siz uint8
Done uint8
Type_ int32
Variant int32
Add int64
Xadd int64
Sym *LSym
Xsym *LSym
}
type Auto struct {
Asym *LSym
Link *Auto
Aoffset int32
Type_ int16
Gotype *LSym
}
type Hist struct {
Link *Hist
Name string
Line int32
Offset int32
Printed uint8
}
type Link struct {
Thechar int32
Thestring string
Goarm int32
Headtype int
Arch *LinkArch
Ignore func(string) int32
Debugasm int32
Debugline int32
Debughist int32
Debugread int32
Debugvlog int32
Debugstack int32
Debugzerostack int32
Debugdivmod int32
Debugfloat int32
Debugpcln int32
Flag_shared int32
Iself int32
Bso *Biobuf
Pathname string
Windows int32
Trimpath string
Goroot string
Goroot_final string
Enforce_data_order int32
Hash [LINKHASH]*LSym
Allsym *LSym
Nsymbol int32
Hist *Hist
Ehist *Hist
Plist *Plist
Plast *Plist
Sym_div *LSym
Sym_divu *LSym
Sym_mod *LSym
Sym_modu *LSym
Symmorestack [2]*LSym
Tlsg *LSym
Plan9privates *LSym
Curp *Prog
Printp *Prog
Blitrl *Prog
Elitrl *Prog
Rexflag int
Rep int
Repn int
Lock int
Asmode int
Andptr []byte
And [100]uint8
Instoffset int64
Autosize int32
Armsize int32
Pc int64
Libdir []string
Library []Library
Tlsoffset int
Diag func(string, ...interface{})
Mode int
Curauto *Auto
Curhist *Auto
Cursym *LSym
Version int
Textp *LSym
Etextp *LSym
Histdepth int32
Nhistfile int32
Filesyms *LSym
}
type Plist struct {
Name *LSym
Firstpc *Prog
Recur int
Link *Plist
}
type LinkArch struct {
Pconv func(*Prog) string
Name string
Thechar int
Endian int32
ByteOrder binary.ByteOrder
Addstacksplit func(*Link, *LSym)
Assemble func(*Link, *LSym)
Datasize func(*Prog) int
Follow func(*Link, *LSym)
Iscall func(*Prog) bool
Isdata func(*Prog) bool
Prg func() *Prog
Progedit func(*Link, *Prog)
Settextflag func(*Prog, int)
Symtype func(*Addr) int
Textflag func(*Prog) int
Minlc int
Ptrsize int
Regsize int
D_ADDR int
D_AUTO int
D_BRANCH int
D_CONST int
D_EXTERN int
D_FCONST int
D_NONE int
D_PARAM int
D_SCONST int
D_STATIC int
D_OREG int
ACALL int
ADATA int
AEND int
AFUNCDATA int
AGLOBL int
AJMP int
ANOP int
APCDATA int
ARET int
ATEXT int
ATYPE int
AUSEFIELD int
}
type Library struct {
Objref string
Srcref string
File string
Pkg string
}
type Pcln struct {
Pcsp Pcdata
Pcfile Pcdata
Pcline Pcdata
Pcdata []Pcdata
Funcdata []*LSym
Funcdataoff []int64
File []*LSym
Lastfile *LSym
Lastindex int
}
type Pcdata struct {
P []byte
}
type Pciter struct {
d Pcdata
p []byte
pc uint32
nextpc uint32
pcscale uint32
value int32
start int
done int
}
// prevent incompatible type signatures between liblink and 8l on Plan 9
// prevent incompatible type signatures between liblink and 8l on Plan 9
// LSym.type
const (
Sxxx = iota
STEXT
SELFRXSECT
STYPE
SSTRING
SGOSTRING
SGOFUNC
SRODATA
SFUNCTAB
STYPELINK
SSYMTAB
SPCLNTAB
SELFROSECT
SMACHOPLT
SELFSECT
SMACHO
SMACHOGOT
SWINDOWS
SELFGOT
SNOPTRDATA
SINITARR
SDATA
SBSS
SNOPTRBSS
STLSBSS
SXREF
SMACHOSYMSTR
SMACHOSYMTAB
SMACHOINDIRECTPLT
SMACHOINDIRECTGOT
SFILE
SFILEPATH
SCONST
SDYNIMPORT
SHOSTOBJ
SSUB = 1 << 8
SMASK = SSUB - 1
SHIDDEN = 1 << 9
)
// Reloc.type
const (
R_ADDR = 1 + iota
R_ADDRPOWER
R_SIZE
R_CALL
R_CALLARM
R_CALLIND
R_CALLPOWER
R_CONST
R_PCREL
R_TLS
R_TLS_LE
R_TLS_IE
R_GOTOFF
R_PLT0
R_PLT1
R_PLT2
R_USEFIELD
R_POWER_TOC
)
// Reloc.variant
const (
RV_NONE = iota
RV_POWER_LO
RV_POWER_HI
RV_POWER_HA
RV_POWER_DS
RV_CHECK_OVERFLOW = 1 << 8
RV_TYPE_MASK = RV_CHECK_OVERFLOW - 1
)
// Auto.type
const (
A_AUTO = 1 + iota
A_PARAM
)
const (
LINKHASH = 100003
)
// Pcdata iterator.
// for(pciterinit(ctxt, &it, &pcd); !it.done; pciternext(&it)) { it.value holds in [it.pc, it.nextpc) }
// symbol version, incremented each time a file is loaded.
// version==1 is reserved for savehist.
const (
HistVersion = 1
)
// Link holds the context for writing object code from a compiler
// to be linker input or for reading that input into the linker.
const (
LittleEndian = 0x04030201
BigEndian = 0x01020304
)
// LinkArch is the definition of a single architecture.
/* executable header types */
const (
Hunknown = 0 + iota
Hdarwin
Hdragonfly
Helf
Hfreebsd
Hlinux
Hnacl
Hnetbsd
Hopenbsd
Hplan9
Hsolaris
Hwindows
)
const (
LinkAuto = 0 + iota
LinkInternal
LinkExternal
)
// asm5.c
// asm6.c
// asm8.c
// asm9.c
// data.c
// go.c
// ld.c

314
src/cmd/internal/obj/obj.go Normal file
View file

@ -0,0 +1,314 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package obj
import (
"fmt"
"path/filepath"
"strings"
)
const (
HISTSZ = 10
NSYM = 50
)
func linklinefmt(ctxt *Link, lno0 int, showAll, showFullPath bool) string {
var a [HISTSZ]struct {
incl *Hist
idel int32
line *Hist
ldel int32
}
lno := int32(lno0)
lno1 := lno
var d int32
var i int
var n int
var h *Hist
n = 0
var fp string
for h = ctxt.Hist; h != nil; h = h.Link {
if h.Offset < 0 {
continue
}
if lno < h.Line {
break
}
if h.Name != "<no name>" {
if h.Offset > 0 {
// #line directive
if n > 0 && n < int(HISTSZ) {
a[n-1].line = h
a[n-1].ldel = h.Line - h.Offset + 1
}
} else {
// beginning of file
if n < int(HISTSZ) {
a[n].incl = h
a[n].idel = h.Line
a[n].line = nil
}
n++
}
continue
}
n--
if n > 0 && n < int(HISTSZ) {
d = h.Line - a[n].incl.Line
a[n-1].ldel += d
a[n-1].idel += d
}
}
if n > int(HISTSZ) {
n = int(HISTSZ)
}
for i = n - 1; i >= 0; i-- {
if i != n-1 {
if !showAll {
break
}
fp += " "
}
if ctxt.Debugline != 0 || showFullPath {
fp += fmt.Sprintf("%s/", ctxt.Pathname)
}
if a[i].line != nil {
fp += fmt.Sprintf("%s:%d[%s:%d]", a[i].line.Name, lno-a[i].ldel+1, a[i].incl.Name, lno-a[i].idel+1)
} else {
fp += fmt.Sprintf("%s:%d", a[i].incl.Name, lno-a[i].idel+1)
}
lno = a[i].incl.Line - 1 // now print out start of this file
}
if n == 0 {
fp += fmt.Sprintf("<unknown line number %d %d %d %s>", lno1, ctxt.Hist.Offset, ctxt.Hist.Line, ctxt.Hist.Name)
}
return fp
}
// Does s have t as a path prefix?
// That is, does s == t or does s begin with t followed by a slash?
// For portability, we allow ASCII case folding, so that haspathprefix("a/b/c", "A/B") is true.
// Similarly, we allow slash folding, so that haspathprefix("a/b/c", "a\\b") is true.
func haspathprefix(s string, t string) bool {
var i int
var cs int
var ct int
if len(t) > len(s) {
return false
}
for i = 0; i < len(t); i++ {
cs = int(s[i])
ct = int(t[i])
if 'A' <= cs && cs <= 'Z' {
cs += 'a' - 'A'
}
if 'A' <= ct && ct <= 'Z' {
ct += 'a' - 'A'
}
if cs == '\\' {
cs = '/'
}
if ct == '\\' {
ct = '/'
}
if cs != ct {
return false
}
}
return i >= len(s) || s[i] == '/' || s[i] == '\\'
}
// This is a simplified copy of linklinefmt above.
// It doesn't allow printing the full stack, and it returns the file name and line number separately.
// TODO: Unify with linklinefmt somehow.
func linkgetline(ctxt *Link, line int32, f **LSym, l *int32) {
var a [HISTSZ]struct {
incl *Hist
idel int32
line *Hist
ldel int32
}
var lno int32
var d int32
var dlno int32
var n int
var h *Hist
var buf string
var buf1 string
var file string
lno = int32(line)
n = 0
for h = ctxt.Hist; h != nil; h = h.Link {
if h.Offset < 0 {
continue
}
if lno < h.Line {
break
}
if h.Name != "<no name>" {
if h.Offset > 0 {
// #line directive
if n > 0 && n < HISTSZ {
a[n-1].line = h
a[n-1].ldel = h.Line - h.Offset + 1
}
} else {
// beginning of file
if n < HISTSZ {
a[n].incl = h
a[n].idel = h.Line
a[n].line = nil
}
n++
}
continue
}
n--
if n > 0 && n < HISTSZ {
d = h.Line - a[n].incl.Line
a[n-1].ldel += d
a[n-1].idel += d
}
}
if n > HISTSZ {
n = HISTSZ
}
if n <= 0 {
*f = Linklookup(ctxt, "??", HistVersion)
*l = 0
return
}
n--
if a[n].line != nil {
file = a[n].line.Name
dlno = a[n].ldel - 1
} else {
file = a[n].incl.Name
dlno = a[n].idel - 1
}
if filepath.IsAbs(file) || strings.HasPrefix(file, "<") {
buf = fmt.Sprintf("%s", file)
} else {
buf = fmt.Sprintf("%s/%s", ctxt.Pathname, file)
}
// Remove leading ctxt->trimpath, or else rewrite $GOROOT to $GOROOT_FINAL.
if ctxt.Trimpath != "" && haspathprefix(buf, ctxt.Trimpath) {
if len(buf) == len(ctxt.Trimpath) {
buf = "??"
} else {
buf1 = fmt.Sprintf("%s", buf[len(ctxt.Trimpath)+1:])
if buf1[0] == '\x00' {
buf1 = "??"
}
buf = buf1
}
} else if ctxt.Goroot_final != "" && haspathprefix(buf, ctxt.Goroot) {
buf1 = fmt.Sprintf("%s%s", ctxt.Goroot_final, buf[len(ctxt.Goroot):])
buf = buf1
}
lno -= dlno
*f = Linklookup(ctxt, buf, HistVersion)
*l = lno
}
func linklinehist(ctxt *Link, lineno int, f string, offset int) {
var h *Hist
if false { // debug['f']
if f != "" {
if offset != 0 {
fmt.Printf("%4d: %s (#line %d)\n", lineno, f, offset)
} else {
fmt.Printf("%4d: %s\n", lineno, f)
}
} else {
fmt.Printf("%4d: <pop>\n", lineno)
}
}
h = new(Hist)
*h = Hist{}
h.Name = f
h.Line = int32(lineno)
h.Offset = int32(offset)
h.Link = nil
if ctxt.Ehist == nil {
ctxt.Hist = h
ctxt.Ehist = h
return
}
ctxt.Ehist.Link = h
ctxt.Ehist = h
}
func linkprfile(ctxt *Link, line int) {
l := int32(line)
var i int
var n int
var a [HISTSZ]Hist
var h *Hist
var d int32
n = 0
for h = ctxt.Hist; h != nil; h = h.Link {
if l < h.Line {
break
}
if h.Name != "<no name>" {
if h.Offset == 0 {
if n >= 0 && n < HISTSZ {
a[n] = *h
}
n++
continue
}
if n > 0 && n < HISTSZ {
if a[n-1].Offset == 0 {
a[n] = *h
n++
} else {
a[n-1] = *h
}
}
continue
}
n--
if n >= 0 && n < HISTSZ {
d = h.Line - a[n].Line
for i = 0; i < n; i++ {
a[i].Line += d
}
}
}
if n > HISTSZ {
n = HISTSZ
}
for i = 0; i < n; i++ {
fmt.Printf("%s:%d ", a[i].Name, int(l-a[i].Line+a[i].Offset+1))
}
}
/*
* start a new Prog list.
*/
func linknewplist(ctxt *Link) *Plist {
var pl *Plist
pl = new(Plist)
*pl = Plist{}
if ctxt.Plist == nil {
ctxt.Plist = pl
} else {
ctxt.Plast.Link = pl
}
ctxt.Plast = pl
return pl
}

View file

@ -0,0 +1,457 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package obj
import (
"fmt"
"log"
"path/filepath"
"strings"
)
var outfile string
// The Go and C compilers, and the assembler, call writeobj to write
// out a Go object file. The linker does not call this; the linker
// does not write out object files.
func Writeobjdirect(ctxt *Link, b *Biobuf) {
var flag int
var found int
var h *Hist
var s *LSym
var text *LSym
var etext *LSym
var curtext *LSym
var data *LSym
var edata *LSym
var pl *Plist
var p *Prog
var plink *Prog
var a *Auto
// Build list of symbols, and assign instructions to lists.
// Ignore ctxt->plist boundaries. There are no guarantees there,
// and the C compilers and assemblers just use one big list.
text = nil
curtext = nil
data = nil
etext = nil
edata = nil
for pl = ctxt.Plist; pl != nil; pl = pl.Link {
for p = pl.Firstpc; p != nil; p = plink {
if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 {
fmt.Printf("obj: %p %v\n", p, p)
}
plink = p.Link
p.Link = nil
if int(p.As) == ctxt.Arch.AEND {
continue
}
if int(p.As) == ctxt.Arch.ATYPE {
// Assume each TYPE instruction describes
// a different local variable or parameter,
// so no dedup.
// Using only the TYPE instructions means
// that we discard location information about local variables
// in C and assembly functions; that information is inferred
// from ordinary references, because there are no TYPE
// instructions there. Without the type information, gdb can't
// use the locations, so we don't bother to save them.
// If something else could use them, we could arrange to
// preserve them.
if curtext == nil {
continue
}
a = new(Auto)
a.Asym = p.From.Sym
a.Aoffset = int32(p.From.Offset)
a.Type_ = int16(ctxt.Arch.Symtype(&p.From))
a.Gotype = p.From.Gotype
a.Link = curtext.Autom
curtext.Autom = a
continue
}
if int(p.As) == ctxt.Arch.AGLOBL {
s = p.From.Sym
tmp6 := s.Seenglobl
s.Seenglobl++
if tmp6 != 0 {
fmt.Printf("duplicate %v\n", p)
}
if s.Onlist != 0 {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
s.Onlist = 1
if data == nil {
data = s
} else {
edata.Next = s
}
s.Next = nil
s.Size = p.To.Offset
if s.Type_ == 0 || s.Type_ == SXREF {
s.Type_ = SBSS
}
flag = ctxt.Arch.Textflag(p)
if flag&DUPOK != 0 {
s.Dupok = 1
}
if flag&RODATA != 0 {
s.Type_ = SRODATA
} else if flag&NOPTR != 0 {
s.Type_ = SNOPTRBSS
}
edata = s
continue
}
if int(p.As) == ctxt.Arch.ADATA {
savedata(ctxt, p.From.Sym, p, "<input>")
continue
}
if int(p.As) == ctxt.Arch.ATEXT {
s = p.From.Sym
if s == nil {
// func _() { }
curtext = nil
continue
}
if s.Text != nil {
log.Fatalf("duplicate TEXT for %s", s.Name)
}
if s.Onlist != 0 {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
s.Onlist = 1
if text == nil {
text = s
} else {
etext.Next = s
}
etext = s
flag = ctxt.Arch.Textflag(p)
if flag&DUPOK != 0 {
s.Dupok = 1
}
if flag&NOSPLIT != 0 {
s.Nosplit = 1
}
s.Next = nil
s.Type_ = STEXT
s.Text = p
s.Etext = p
curtext = s
continue
}
if int(p.As) == ctxt.Arch.AFUNCDATA {
// Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information.
if curtext == nil { // func _() {}
continue
}
if p.To.Sym.Name == "go_args_stackmap" {
if int(p.From.Type_) != ctxt.Arch.D_CONST || p.From.Offset != FUNCDATA_ArgsPointerMaps {
ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps")
}
p.To.Sym = Linklookup(ctxt, string(fmt.Sprintf("%s.args_stackmap", curtext.Name)), int(curtext.Version))
}
}
if curtext == nil {
continue
}
s = curtext
s.Etext.Link = p
s.Etext = p
}
}
// Add reference to Go arguments for C or assembly functions without them.
for s = text; s != nil; s = s.Next {
if !strings.HasPrefix(s.Name, "\"\".") {
continue
}
found = 0
for p = s.Text; p != nil; p = p.Link {
if int(p.As) == ctxt.Arch.AFUNCDATA && int(p.From.Type_) == ctxt.Arch.D_CONST && p.From.Offset == FUNCDATA_ArgsPointerMaps {
found = 1
break
}
}
if !(found != 0) {
p = Appendp(ctxt, s.Text)
p.As = int16(ctxt.Arch.AFUNCDATA)
p.From.Type_ = int16(ctxt.Arch.D_CONST)
p.From.Offset = FUNCDATA_ArgsPointerMaps
if ctxt.Arch.Thechar == '6' || ctxt.Arch.Thechar == '8' {
p.To.Type_ = int16(ctxt.Arch.D_EXTERN)
} else {
p.To.Type_ = int16(ctxt.Arch.D_OREG)
p.To.Name = int8(ctxt.Arch.D_EXTERN)
}
p.To.Sym = Linklookup(ctxt, string(fmt.Sprintf("%s.args_stackmap", s.Name)), int(s.Version))
}
}
// Turn functions into machine code images.
for s = text; s != nil; s = s.Next {
mkfwd(s)
linkpatch(ctxt, s)
ctxt.Arch.Follow(ctxt, s)
ctxt.Arch.Addstacksplit(ctxt, s)
ctxt.Arch.Assemble(ctxt, s)
linkpcln(ctxt, s)
}
// Emit header.
Bputc(b, 0)
Bputc(b, 0)
fmt.Fprintf(b, "go13ld")
Bputc(b, 1) // version
// Emit autolib.
for h = ctxt.Hist; h != nil; h = h.Link {
if h.Offset < 0 {
wrstring(b, h.Name)
}
}
wrstring(b, "")
// Emit symbols.
for s = text; s != nil; s = s.Next {
writesym(ctxt, b, s)
}
for s = data; s != nil; s = s.Next {
writesym(ctxt, b, s)
}
// Emit footer.
Bputc(b, 0xff)
Bputc(b, 0xff)
fmt.Fprintf(b, "go13ld")
}
func writesym(ctxt *Link, b *Biobuf, s *LSym) {
var r *Reloc
var i int
var j int
var c int
var n int
var pc *Pcln
var p *Prog
var a *Auto
var name string
if ctxt.Debugasm != 0 {
fmt.Fprintf(ctxt.Bso, "%s ", s.Name)
if s.Version != 0 {
fmt.Fprintf(ctxt.Bso, "v=%d ", s.Version)
}
if s.Type_ != 0 {
fmt.Fprintf(ctxt.Bso, "t=%d ", s.Type_)
}
if s.Dupok != 0 {
fmt.Fprintf(ctxt.Bso, "dupok ")
}
if s.Cfunc != 0 {
fmt.Fprintf(ctxt.Bso, "cfunc ")
}
if s.Nosplit != 0 {
fmt.Fprintf(ctxt.Bso, "nosplit ")
}
fmt.Fprintf(ctxt.Bso, "size=%d value=%d", int64(s.Size), int64(s.Value))
if s.Type_ == STEXT {
fmt.Fprintf(ctxt.Bso, " args=%#x locals=%#x", uint64(s.Args), uint64(s.Locals))
if s.Leaf != 0 {
fmt.Fprintf(ctxt.Bso, " leaf")
}
}
fmt.Fprintf(ctxt.Bso, "\n")
for p = s.Text; p != nil; p = p.Link {
fmt.Fprintf(ctxt.Bso, "\t%#04x %v\n", uint(int(p.Pc)), p)
}
for i = 0; i < len(s.P); {
fmt.Fprintf(ctxt.Bso, "\t%#04x", uint(i))
for j = i; j < i+16 && j < len(s.P); j++ {
fmt.Fprintf(ctxt.Bso, " %02x", s.P[j])
}
for ; j < i+16; j++ {
fmt.Fprintf(ctxt.Bso, " ")
}
fmt.Fprintf(ctxt.Bso, " ")
for j = i; j < i+16 && j < len(s.P); j++ {
c = int(s.P[j])
if ' ' <= c && c <= 0x7e {
fmt.Fprintf(ctxt.Bso, "%c", c)
} else {
fmt.Fprintf(ctxt.Bso, ".")
}
}
fmt.Fprintf(ctxt.Bso, "\n")
i += 16
}
for i = 0; i < len(s.R); i++ {
r = &s.R[i]
name = ""
if r.Sym != nil {
name = r.Sym.Name
}
if ctxt.Arch.Thechar == '5' || ctxt.Arch.Thechar == '9' {
fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%x\n", int(r.Off), r.Siz, r.Type_, name, uint64(int64(r.Add)))
} else {
fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type_, name, int64(r.Add))
}
}
}
Bputc(b, 0xfe)
wrint(b, int64(s.Type_))
wrstring(b, s.Name)
wrint(b, int64(s.Version))
wrint(b, int64(s.Dupok))
wrint(b, s.Size)
wrsym(b, s.Gotype)
wrdata(b, s.P)
wrint(b, int64(len(s.R)))
for i = 0; i < len(s.R); i++ {
r = &s.R[i]
wrint(b, int64(r.Off))
wrint(b, int64(r.Siz))
wrint(b, int64(r.Type_))
wrint(b, r.Add)
wrint(b, r.Xadd)
wrsym(b, r.Sym)
wrsym(b, r.Xsym)
}
if s.Type_ == STEXT {
wrint(b, int64(s.Args))
wrint(b, int64(s.Locals))
wrint(b, int64(s.Nosplit))
wrint(b, int64(s.Leaf)|int64(s.Cfunc)<<1)
n = 0
for a = s.Autom; a != nil; a = a.Link {
n++
}
wrint(b, int64(n))
for a = s.Autom; a != nil; a = a.Link {
wrsym(b, a.Asym)
wrint(b, int64(a.Aoffset))
if int(a.Type_) == ctxt.Arch.D_AUTO {
wrint(b, A_AUTO)
} else if int(a.Type_) == ctxt.Arch.D_PARAM {
wrint(b, A_PARAM)
} else {
log.Fatalf("%s: invalid local variable type %d", s.Name, a.Type_)
}
wrsym(b, a.Gotype)
}
pc = s.Pcln
wrdata(b, pc.Pcsp.P)
wrdata(b, pc.Pcfile.P)
wrdata(b, pc.Pcline.P)
wrint(b, int64(len(pc.Pcdata)))
for i = 0; i < len(pc.Pcdata); i++ {
wrdata(b, pc.Pcdata[i].P)
}
wrint(b, int64(len(pc.Funcdataoff)))
for i = 0; i < len(pc.Funcdataoff); i++ {
wrsym(b, pc.Funcdata[i])
}
for i = 0; i < len(pc.Funcdataoff); i++ {
wrint(b, pc.Funcdataoff[i])
}
wrint(b, int64(len(pc.File)))
for i = 0; i < len(pc.File); i++ {
wrpathsym(ctxt, b, pc.File[i])
}
}
}
func wrint(b *Biobuf, sval int64) {
var uv uint64
var v uint64
var buf [10]uint8
var p []uint8
uv = (uint64(sval) << 1) ^ uint64(int64(sval>>63))
p = buf[:]
for v = uv; v >= 0x80; v >>= 7 {
p[0] = uint8(v | 0x80)
p = p[1:]
}
p[0] = uint8(v)
p = p[1:]
Bwrite(b, buf[:len(buf)-len(p)])
}
func wrstring(b *Biobuf, s string) {
wrint(b, int64(len(s)))
b.w.WriteString(s)
}
// wrpath writes a path just like a string, but on windows, it
// translates '\\' to '/' in the process.
func wrpath(ctxt *Link, b *Biobuf, p string) {
wrstring(b, filepath.ToSlash(p))
}
func wrdata(b *Biobuf, v []byte) {
wrint(b, int64(len(v)))
Bwrite(b, v)
}
func wrpathsym(ctxt *Link, b *Biobuf, s *LSym) {
if s == nil {
wrint(b, 0)
wrint(b, 0)
return
}
wrpath(ctxt, b, s.Name)
wrint(b, int64(s.Version))
}
func wrsym(b *Biobuf, s *LSym) {
if s == nil {
wrint(b, 0)
wrint(b, 0)
return
}
wrstring(b, s.Name)
wrint(b, int64(s.Version))
}
var startmagic string = "\x00\x00go13ld"
var endmagic string = "\xff\xffgo13ld"

View file

@ -0,0 +1,129 @@
// Inferno utils/6l/pass.c
// http://code.google.com/p/inferno-os/source/browse/utils/6l/pass.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package obj
// Code and data passes.
func Brchain(ctxt *Link, p *Prog) *Prog {
var i int
for i = 0; i < 20; i++ {
if p == nil || int(p.As) != ctxt.Arch.AJMP || p.Pcond == nil {
return p
}
p = p.Pcond
}
return nil
}
func brloop(ctxt *Link, p *Prog) *Prog {
var c int
var q *Prog
c = 0
for q = p; q != nil; q = q.Pcond {
if int(q.As) != ctxt.Arch.AJMP || q.Pcond == nil {
break
}
c++
if c >= 5000 {
return nil
}
}
return q
}
func linkpatch(ctxt *Link, sym *LSym) {
var c int32
var name string
var p *Prog
var q *Prog
ctxt.Cursym = sym
for p = sym.Text; p != nil; p = p.Link {
if ctxt.Arch.Progedit != nil {
ctxt.Arch.Progedit(ctxt, p)
}
if int(p.To.Type_) != ctxt.Arch.D_BRANCH {
continue
}
if p.To.U.Branch != nil {
// TODO: Remove to.u.branch in favor of p->pcond.
p.Pcond = p.To.U.Branch
continue
}
if p.To.Sym != nil {
continue
}
c = int32(p.To.Offset)
for q = sym.Text; q != nil; {
if int64(c) == q.Pc {
break
}
if q.Forwd != nil && int64(c) >= q.Forwd.Pc {
q = q.Forwd
} else {
q = q.Link
}
}
if q == nil {
name = "<nil>"
if p.To.Sym != nil {
name = p.To.Sym.Name
}
ctxt.Diag("branch out of range (%#x)\n%v [%s]", uint32(c), p, name)
p.To.Type_ = int16(ctxt.Arch.D_NONE)
}
p.To.U.Branch = q
p.Pcond = q
}
for p = sym.Text; p != nil; p = p.Link {
p.Mark = 0 /* initialization for follow */
if p.Pcond != nil {
p.Pcond = brloop(ctxt, p.Pcond)
if p.Pcond != nil {
if int(p.To.Type_) == ctxt.Arch.D_BRANCH {
p.To.Offset = p.Pcond.Pc
}
}
}
}
}

View file

@ -0,0 +1,370 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package obj
import (
"fmt"
"log"
)
func addvarint(ctxt *Link, d *Pcdata, val uint32) {
var v uint32
for v = val; v >= 0x80; v >>= 7 {
d.P = append(d.P, uint8(v|0x80))
}
d.P = append(d.P, uint8(v))
}
// funcpctab writes to dst a pc-value table mapping the code in func to the values
// returned by valfunc parameterized by arg. The invocation of valfunc to update the
// current value is, for each p,
//
// val = valfunc(func, val, p, 0, arg);
// record val as value at p->pc;
// val = valfunc(func, val, p, 1, arg);
//
// where func is the function, val is the current value, p is the instruction being
// considered, and arg can be used to further parameterize valfunc.
func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*Link, *LSym, int32, *Prog, int32, interface{}) int32, arg interface{}) {
var dbg int
var i int
var oldval int32
var val int32
var started int32
var delta uint32
var pc int64
var p *Prog
// To debug a specific function, uncomment second line and change name.
dbg = 0
//dbg = strcmp(func->name, "main.main") == 0;
//dbg = strcmp(desc, "pctofile") == 0;
ctxt.Debugpcln += int32(dbg)
dst.P = dst.P[:0]
if ctxt.Debugpcln != 0 {
fmt.Fprintf(ctxt.Bso, "funcpctab %s [valfunc=%s]\n", func_.Name, desc)
}
val = -1
oldval = val
if func_.Text == nil {
ctxt.Debugpcln -= int32(dbg)
return
}
pc = func_.Text.Pc
if ctxt.Debugpcln != 0 {
fmt.Fprintf(ctxt.Bso, "%6x %6d %v\n", uint64(pc), val, func_.Text)
}
started = 0
for p = func_.Text; p != nil; p = p.Link {
// Update val. If it's not changing, keep going.
val = valfunc(ctxt, func_, val, p, 0, arg)
if val == oldval && started != 0 {
val = valfunc(ctxt, func_, val, p, 1, arg)
if ctxt.Debugpcln != 0 {
fmt.Fprintf(ctxt.Bso, "%6x %6s %v\n", uint64(int64(p.Pc)), "", p)
}
continue
}
// If the pc of the next instruction is the same as the
// pc of this instruction, this instruction is not a real
// instruction. Keep going, so that we only emit a delta
// for a true instruction boundary in the program.
if p.Link != nil && p.Link.Pc == p.Pc {
val = valfunc(ctxt, func_, val, p, 1, arg)
if ctxt.Debugpcln != 0 {
fmt.Fprintf(ctxt.Bso, "%6x %6s %v\n", uint64(int64(p.Pc)), "", p)
}
continue
}
// The table is a sequence of (value, pc) pairs, where each
// pair states that the given value is in effect from the current position
// up to the given pc, which becomes the new current position.
// To generate the table as we scan over the program instructions,
// we emit a "(value" when pc == func->value, and then
// each time we observe a change in value we emit ", pc) (value".
// When the scan is over, we emit the closing ", pc)".
//
// The table is delta-encoded. The value deltas are signed and
// transmitted in zig-zag form, where a complement bit is placed in bit 0,
// and the pc deltas are unsigned. Both kinds of deltas are sent
// as variable-length little-endian base-128 integers,
// where the 0x80 bit indicates that the integer continues.
if ctxt.Debugpcln != 0 {
fmt.Fprintf(ctxt.Bso, "%6x %6d %v\n", uint64(int64(p.Pc)), val, p)
}
if started != 0 {
addvarint(ctxt, dst, uint32((p.Pc-pc)/int64(ctxt.Arch.Minlc)))
pc = p.Pc
}
delta = uint32(val) - uint32(oldval)
if delta>>31 != 0 {
delta = 1 | ^(delta << 1)
} else {
delta <<= 1
}
addvarint(ctxt, dst, delta)
oldval = val
started = 1
val = valfunc(ctxt, func_, val, p, 1, arg)
}
if started != 0 {
if ctxt.Debugpcln != 0 {
fmt.Fprintf(ctxt.Bso, "%6x done\n", uint64(int64(func_.Text.Pc)+func_.Size))
}
addvarint(ctxt, dst, uint32((func_.Value+func_.Size-pc)/int64(ctxt.Arch.Minlc)))
addvarint(ctxt, dst, 0) // terminator
}
if ctxt.Debugpcln != 0 {
fmt.Fprintf(ctxt.Bso, "wrote %d bytes to %p\n", len(dst.P), dst)
for i = 0; i < len(dst.P); i++ {
fmt.Fprintf(ctxt.Bso, " %02x", dst.P[i])
}
fmt.Fprintf(ctxt.Bso, "\n")
}
ctxt.Debugpcln -= int32(dbg)
}
// pctofileline computes either the file number (arg == 0)
// or the line number (arg == 1) to use at p.
// Because p->lineno applies to p, phase == 0 (before p)
// takes care of the update.
func pctofileline(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
var i int32
var l int32
var f *LSym
var pcln *Pcln
if int(p.As) == ctxt.Arch.ATEXT || int(p.As) == ctxt.Arch.ANOP || int(p.As) == ctxt.Arch.AUSEFIELD || p.Lineno == 0 || phase == 1 {
return oldval
}
linkgetline(ctxt, p.Lineno, &f, &l)
if f == nil {
// print("getline failed for %s %P\n", ctxt->cursym->name, p);
return oldval
}
if arg == nil {
return l
}
pcln = arg.(*Pcln)
if f == pcln.Lastfile {
return int32(pcln.Lastindex)
}
for i = 0; i < int32(len(pcln.File)); i++ {
file := pcln.File[i]
if file == f {
pcln.Lastfile = f
pcln.Lastindex = int(i)
return int32(i)
}
}
pcln.File = append(pcln.File, f)
pcln.Lastfile = f
pcln.Lastindex = int(i)
return i
}
// pctospadj computes the sp adjustment in effect.
// It is oldval plus any adjustment made by p itself.
// The adjustment by p takes effect only after p, so we
// apply the change during phase == 1.
func pctospadj(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
if oldval == -1 { // starting
oldval = 0
}
if phase == 0 {
return oldval
}
if oldval+p.Spadj < -10000 || oldval+p.Spadj > 1100000000 {
ctxt.Diag("overflow in spadj: %d + %d = %d", oldval, p.Spadj, oldval+p.Spadj)
log.Fatalf("bad code")
}
return oldval + p.Spadj
}
// pctopcdata computes the pcdata value in effect at p.
// A PCDATA instruction sets the value in effect at future
// non-PCDATA instructions.
// Since PCDATA instructions have no width in the final code,
// it does not matter which phase we use for the update.
func pctopcdata(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
if phase == 0 || int(p.As) != ctxt.Arch.APCDATA || p.From.Offset != int64(arg.(uint32)) {
return oldval
}
if int64(int32(p.To.Offset)) != p.To.Offset {
ctxt.Diag("overflow in PCDATA instruction: %v", p)
log.Fatalf("bad code")
}
return int32(p.To.Offset)
}
func linkpcln(ctxt *Link, cursym *LSym) {
var p *Prog
var pcln *Pcln
var i int
var npcdata int
var nfuncdata int
ctxt.Cursym = cursym
pcln = new(Pcln)
cursym.Pcln = pcln
npcdata = 0
nfuncdata = 0
for p = cursym.Text; p != nil; p = p.Link {
if int(p.As) == ctxt.Arch.APCDATA && p.From.Offset >= int64(npcdata) {
npcdata = int(p.From.Offset + 1)
}
if int(p.As) == ctxt.Arch.AFUNCDATA && p.From.Offset >= int64(nfuncdata) {
nfuncdata = int(p.From.Offset + 1)
}
}
pcln.Pcdata = make([]Pcdata, npcdata)
pcln.Pcdata = pcln.Pcdata[:npcdata]
pcln.Funcdata = make([]*LSym, nfuncdata)
pcln.Funcdataoff = make([]int64, nfuncdata)
pcln.Funcdataoff = pcln.Funcdataoff[:nfuncdata]
funcpctab(ctxt, &pcln.Pcsp, cursym, "pctospadj", pctospadj, nil)
funcpctab(ctxt, &pcln.Pcfile, cursym, "pctofile", pctofileline, pcln)
funcpctab(ctxt, &pcln.Pcline, cursym, "pctoline", pctofileline, nil)
// tabulate which pc and func data we have.
havepc := make([]uint32, (npcdata+31)/32)
havefunc := make([]uint32, (nfuncdata+31)/32)
for p = cursym.Text; p != nil; p = p.Link {
if int(p.As) == ctxt.Arch.AFUNCDATA {
if (havefunc[p.From.Offset/32]>>uint64(p.From.Offset%32))&1 != 0 {
ctxt.Diag("multiple definitions for FUNCDATA $%d", p.From.Offset)
}
havefunc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32)
}
if int(p.As) == ctxt.Arch.APCDATA {
havepc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32)
}
}
// pcdata.
for i = 0; i < npcdata; i++ {
if (havepc[i/32]>>uint(i%32))&1 == 0 {
continue
}
funcpctab(ctxt, &pcln.Pcdata[i], cursym, "pctopcdata", pctopcdata, interface{}(uint32(i)))
}
// funcdata
if nfuncdata > 0 {
for p = cursym.Text; p != nil; p = p.Link {
if int(p.As) == ctxt.Arch.AFUNCDATA {
i = int(p.From.Offset)
pcln.Funcdataoff[i] = p.To.Offset
if int(p.To.Type_) != ctxt.Arch.D_CONST {
// TODO: Dedup.
//funcdata_bytes += p->to.sym->size;
pcln.Funcdata[i] = p.To.Sym
}
}
}
}
}
// iteration over encoded pcdata tables.
func getvarint(pp *[]byte) uint32 {
var p []byte
var shift int
var v uint32
v = 0
p = *pp
for shift = 0; ; shift += 7 {
v |= uint32(p[0]&0x7F) << uint(shift)
tmp7 := p
p = p[1:]
if !(tmp7[0]&0x80 != 0) {
break
}
}
*pp = p
return v
}
func pciternext(it *Pciter) {
var v uint32
var dv int32
it.pc = it.nextpc
if it.done != 0 {
return
}
if -cap(it.p) >= -cap(it.d.P[len(it.d.P):]) {
it.done = 1
return
}
// value delta
v = getvarint(&it.p)
if v == 0 && !(it.start != 0) {
it.done = 1
return
}
it.start = 0
dv = int32(v>>1) ^ (int32(v<<31) >> 31)
it.value += dv
// pc delta
v = getvarint(&it.p)
it.nextpc = it.pc + v*it.pcscale
}
func pciterinit(ctxt *Link, it *Pciter, d *Pcdata) {
it.d = *d
it.p = it.d.P
it.pc = 0
it.nextpc = 0
it.value = -1
it.start = 1
it.done = 0
it.pcscale = uint32(ctxt.Arch.Minlc)
pciternext(it)
}

View file

@ -0,0 +1,485 @@
// cmd/9c/9.out.h from Vita Nuova.
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package ppc64
// auto generated by go tool dist
/*
* powerpc 64
*/
const (
NSNAME = 8
NSYM = 50
NREG = 32
NFREG = 32
)
const (
REGZERO = 0
REGSP = 1
REGSB = 2
REGRET = 3
REGARG = -1
REGRT1 = 3
REGRT2 = 4
REGMIN = 7
REGENV = 11
REGTLS = 13
REGMAX = 27
REGEXT = 30
REGG = 30
REGTMP = 31
FREGRET = 0
FREGMIN = 17
FREGMAX = 26
FREGEXT = 26
FREGCVI = 27
FREGZERO = 28
FREGHALF = 29
FREGONE = 30
FREGTWO = 31
)
/*
* GENERAL:
*
* compiler allocates R3 up as temps
* compiler allocates register variables R7-R27
* compiler allocates external registers R30 down
*
* compiler allocates register variables F17-F26
* compiler allocates external registers F26 down
*/
const (
BIG = 32768 - 8
)
const (
LABEL = 1 << 0
LEAF = 1 << 1
FLOAT = 1 << 2
BRANCH = 1 << 3
LOAD = 1 << 4
FCMP = 1 << 5
SYNC = 1 << 6
LIST = 1 << 7
FOLL = 1 << 8
NOSCHED = 1 << 9
)
const (
C_NONE = iota
C_REG
C_FREG
C_CREG
C_SPR
C_ZCON
C_SCON
C_UCON
C_ADDCON
C_ANDCON
C_LCON
C_DCON
C_SACON
C_SECON
C_LACON
C_LECON
C_DACON
C_SBRA
C_LBRA
C_SAUTO
C_LAUTO
C_SEXT
C_LEXT
C_ZOREG
C_SOREG
C_LOREG
C_FPSCR
C_MSR
C_XER
C_LR
C_CTR
C_ANY
C_GOK
C_ADDR
C_NCLASS
)
const (
AXXX = iota
AADD
AADDCC
AADDV
AADDVCC
AADDC
AADDCCC
AADDCV
AADDCVCC
AADDME
AADDMECC
AADDMEVCC
AADDMEV
AADDE
AADDECC
AADDEVCC
AADDEV
AADDZE
AADDZECC
AADDZEVCC
AADDZEV
AAND
AANDCC
AANDN
AANDNCC
ABC
ABCL
ABEQ
ABGE
ABGT
ABL
ABLE
ABLT
ABNE
ABR
ABVC
ABVS
ACMP
ACMPU
ACNTLZW
ACNTLZWCC
ACRAND
ACRANDN
ACREQV
ACRNAND
ACRNOR
ACROR
ACRORN
ACRXOR
ADIVW
ADIVWCC
ADIVWVCC
ADIVWV
ADIVWU
ADIVWUCC
ADIVWUVCC
ADIVWUV
AEQV
AEQVCC
AEXTSB
AEXTSBCC
AEXTSH
AEXTSHCC
AFABS
AFABSCC
AFADD
AFADDCC
AFADDS
AFADDSCC
AFCMPO
AFCMPU
AFCTIW
AFCTIWCC
AFCTIWZ
AFCTIWZCC
AFDIV
AFDIVCC
AFDIVS
AFDIVSCC
AFMADD
AFMADDCC
AFMADDS
AFMADDSCC
AFMOVD
AFMOVDCC
AFMOVDU
AFMOVS
AFMOVSU
AFMSUB
AFMSUBCC
AFMSUBS
AFMSUBSCC
AFMUL
AFMULCC
AFMULS
AFMULSCC
AFNABS
AFNABSCC
AFNEG
AFNEGCC
AFNMADD
AFNMADDCC
AFNMADDS
AFNMADDSCC
AFNMSUB
AFNMSUBCC
AFNMSUBS
AFNMSUBSCC
AFRSP
AFRSPCC
AFSUB
AFSUBCC
AFSUBS
AFSUBSCC
AMOVMW
ALSW
ALWAR
AMOVWBR
AMOVB
AMOVBU
AMOVBZ
AMOVBZU
AMOVH
AMOVHBR
AMOVHU
AMOVHZ
AMOVHZU
AMOVW
AMOVWU
AMOVFL
AMOVCRFS
AMTFSB0
AMTFSB0CC
AMTFSB1
AMTFSB1CC
AMULHW
AMULHWCC
AMULHWU
AMULHWUCC
AMULLW
AMULLWCC
AMULLWVCC
AMULLWV
ANAND
ANANDCC
ANEG
ANEGCC
ANEGVCC
ANEGV
ANOR
ANORCC
AOR
AORCC
AORN
AORNCC
AREM
AREMCC
AREMV
AREMVCC
AREMU
AREMUCC
AREMUV
AREMUVCC
ARFI
ARLWMI
ARLWMICC
ARLWNM
ARLWNMCC
ASLW
ASLWCC
ASRW
ASRAW
ASRAWCC
ASRWCC
ASTSW
ASTWCCC
ASUB
ASUBCC
ASUBVCC
ASUBC
ASUBCCC
ASUBCV
ASUBCVCC
ASUBME
ASUBMECC
ASUBMEVCC
ASUBMEV
ASUBV
ASUBE
ASUBECC
ASUBEV
ASUBEVCC
ASUBZE
ASUBZECC
ASUBZEVCC
ASUBZEV
ASYNC
AXOR
AXORCC
ADCBF
ADCBI
ADCBST
ADCBT
ADCBTST
ADCBZ
AECIWX
AECOWX
AEIEIO
AICBI
AISYNC
APTESYNC
ATLBIE
ATLBIEL
ATLBSYNC
ATW
ASYSCALL
ADATA
AGLOBL
AGOK
AHISTORY
ANAME
ANOP
ARETURN
ATEXT
AWORD
AEND
ADYNT
AINIT
ASIGNAME
ARFCI
AFRES
AFRESCC
AFRSQRTE
AFRSQRTECC
AFSEL
AFSELCC
AFSQRT
AFSQRTCC
AFSQRTS
AFSQRTSCC
ACNTLZD
ACNTLZDCC
ACMPW
ACMPWU
ADIVD
ADIVDCC
ADIVDVCC
ADIVDV
ADIVDU
ADIVDUCC
ADIVDUVCC
ADIVDUV
AEXTSW
AEXTSWCC
AFCFID
AFCFIDCC
AFCTID
AFCTIDCC
AFCTIDZ
AFCTIDZCC
ALDAR
AMOVD
AMOVDU
AMOVWZ
AMOVWZU
AMULHD
AMULHDCC
AMULHDU
AMULHDUCC
AMULLD
AMULLDCC
AMULLDVCC
AMULLDV
ARFID
ARLDMI
ARLDMICC
ARLDC
ARLDCCC
ARLDCR
ARLDCRCC
ARLDCL
ARLDCLCC
ASLBIA
ASLBIE
ASLBMFEE
ASLBMFEV
ASLBMTE
ASLD
ASLDCC
ASRD
ASRAD
ASRADCC
ASRDCC
ASTDCCC
ATD
ADWORD
AREMD
AREMDCC
AREMDV
AREMDVCC
AREMDU
AREMDUCC
AREMDUV
AREMDUVCC
AHRFID
AUNDEF
AUSEFIELD
ATYPE
AFUNCDATA
APCDATA
ACHECKNIL
AVARDEF
AVARKILL
ADUFFCOPY
ADUFFZERO
ALAST
)
/* type/name */
const (
D_GOK = 0 + iota
D_NONE
D_EXTERN
D_STATIC
D_AUTO
D_PARAM
D_BRANCH
D_OREG
D_CONST
D_FCONST
D_SCONST
D_REG
D_FPSCR
D_MSR
D_FREG
D_CREG
D_SPR
D_OPT
D_FILE
D_FILE1
D_DCR
D_DCONST
D_ADDR
D_LAST
D_R0 = 0
D_F0 = D_R0 + NREG
D_XER = 1
D_LR = 8
D_CTR = 9
)

View file

@ -0,0 +1,389 @@
package ppc64
/* and many supervisor level registers */
/*
* this is the ranlib header
*/
var anames9 = []string{
"XXX",
"ADD",
"ADDCC",
"ADDV",
"ADDVCC",
"ADDC",
"ADDCCC",
"ADDCV",
"ADDCVCC",
"ADDME",
"ADDMECC",
"ADDMEVCC",
"ADDMEV",
"ADDE",
"ADDECC",
"ADDEVCC",
"ADDEV",
"ADDZE",
"ADDZECC",
"ADDZEVCC",
"ADDZEV",
"AND",
"ANDCC",
"ANDN",
"ANDNCC",
"BC",
"BCL",
"BEQ",
"BGE",
"BGT",
"BL",
"BLE",
"BLT",
"BNE",
"BR",
"BVC",
"BVS",
"CMP",
"CMPU",
"CNTLZW",
"CNTLZWCC",
"CRAND",
"CRANDN",
"CREQV",
"CRNAND",
"CRNOR",
"CROR",
"CRORN",
"CRXOR",
"DIVW",
"DIVWCC",
"DIVWVCC",
"DIVWV",
"DIVWU",
"DIVWUCC",
"DIVWUVCC",
"DIVWUV",
"EQV",
"EQVCC",
"EXTSB",
"EXTSBCC",
"EXTSH",
"EXTSHCC",
"FABS",
"FABSCC",
"FADD",
"FADDCC",
"FADDS",
"FADDSCC",
"FCMPO",
"FCMPU",
"FCTIW",
"FCTIWCC",
"FCTIWZ",
"FCTIWZCC",
"FDIV",
"FDIVCC",
"FDIVS",
"FDIVSCC",
"FMADD",
"FMADDCC",
"FMADDS",
"FMADDSCC",
"FMOVD",
"FMOVDCC",
"FMOVDU",
"FMOVS",
"FMOVSU",
"FMSUB",
"FMSUBCC",
"FMSUBS",
"FMSUBSCC",
"FMUL",
"FMULCC",
"FMULS",
"FMULSCC",
"FNABS",
"FNABSCC",
"FNEG",
"FNEGCC",
"FNMADD",
"FNMADDCC",
"FNMADDS",
"FNMADDSCC",
"FNMSUB",
"FNMSUBCC",
"FNMSUBS",
"FNMSUBSCC",
"FRSP",
"FRSPCC",
"FSUB",
"FSUBCC",
"FSUBS",
"FSUBSCC",
"MOVMW",
"LSW",
"LWAR",
"MOVWBR",
"MOVB",
"MOVBU",
"MOVBZ",
"MOVBZU",
"MOVH",
"MOVHBR",
"MOVHU",
"MOVHZ",
"MOVHZU",
"MOVW",
"MOVWU",
"MOVFL",
"MOVCRFS",
"MTFSB0",
"MTFSB0CC",
"MTFSB1",
"MTFSB1CC",
"MULHW",
"MULHWCC",
"MULHWU",
"MULHWUCC",
"MULLW",
"MULLWCC",
"MULLWVCC",
"MULLWV",
"NAND",
"NANDCC",
"NEG",
"NEGCC",
"NEGVCC",
"NEGV",
"NOR",
"NORCC",
"OR",
"ORCC",
"ORN",
"ORNCC",
"REM",
"REMCC",
"REMV",
"REMVCC",
"REMU",
"REMUCC",
"REMUV",
"REMUVCC",
"RFI",
"RLWMI",
"RLWMICC",
"RLWNM",
"RLWNMCC",
"SLW",
"SLWCC",
"SRW",
"SRAW",
"SRAWCC",
"SRWCC",
"STSW",
"STWCCC",
"SUB",
"SUBCC",
"SUBVCC",
"SUBC",
"SUBCCC",
"SUBCV",
"SUBCVCC",
"SUBME",
"SUBMECC",
"SUBMEVCC",
"SUBMEV",
"SUBV",
"SUBE",
"SUBECC",
"SUBEV",
"SUBEVCC",
"SUBZE",
"SUBZECC",
"SUBZEVCC",
"SUBZEV",
"SYNC",
"XOR",
"XORCC",
"DCBF",
"DCBI",
"DCBST",
"DCBT",
"DCBTST",
"DCBZ",
"ECIWX",
"ECOWX",
"EIEIO",
"ICBI",
"ISYNC",
"PTESYNC",
"TLBIE",
"TLBIEL",
"TLBSYNC",
"TW",
"SYSCALL",
"DATA",
"GLOBL",
"GOK",
"HISTORY",
"NAME",
"NOP",
"RETURN",
"TEXT",
"WORD",
"END",
"DYNT",
"INIT",
"SIGNAME",
"RFCI",
"FRES",
"FRESCC",
"FRSQRTE",
"FRSQRTECC",
"FSEL",
"FSELCC",
"FSQRT",
"FSQRTCC",
"FSQRTS",
"FSQRTSCC",
"CNTLZD",
"CNTLZDCC",
"CMPW",
"CMPWU",
"DIVD",
"DIVDCC",
"DIVDVCC",
"DIVDV",
"DIVDU",
"DIVDUCC",
"DIVDUVCC",
"DIVDUV",
"EXTSW",
"EXTSWCC",
"FCFID",
"FCFIDCC",
"FCTID",
"FCTIDCC",
"FCTIDZ",
"FCTIDZCC",
"LDAR",
"MOVD",
"MOVDU",
"MOVWZ",
"MOVWZU",
"MULHD",
"MULHDCC",
"MULHDU",
"MULHDUCC",
"MULLD",
"MULLDCC",
"MULLDVCC",
"MULLDV",
"RFID",
"RLDMI",
"RLDMICC",
"RLDC",
"RLDCCC",
"RLDCR",
"RLDCRCC",
"RLDCL",
"RLDCLCC",
"SLBIA",
"SLBIE",
"SLBMFEE",
"SLBMFEV",
"SLBMTE",
"SLD",
"SLDCC",
"SRD",
"SRAD",
"SRADCC",
"SRDCC",
"STDCCC",
"TD",
"DWORD",
"REMD",
"REMDCC",
"REMDV",
"REMDVCC",
"REMDU",
"REMDUCC",
"REMDUV",
"REMDUVCC",
"HRFID",
"UNDEF",
"USEFIELD",
"TYPE",
"FUNCDATA",
"PCDATA",
"CHECKNIL",
"VARDEF",
"VARKILL",
"DUFFCOPY",
"DUFFZERO",
"LAST",
}
var cnames9 = []string{
"NONE",
"REG",
"FREG",
"CREG",
"SPR",
"ZCON",
"SCON",
"UCON",
"ADDCON",
"ANDCON",
"LCON",
"DCON",
"SACON",
"SECON",
"LACON",
"LECON",
"DACON",
"SBRA",
"LBRA",
"SAUTO",
"LAUTO",
"SEXT",
"LEXT",
"ZOREG",
"SOREG",
"LOREG",
"FPSCR",
"MSR",
"XER",
"LR",
"CTR",
"ANY",
"GOK",
"ADDR",
"NCLASS",
}
var dnames9 = []string{
D_GOK: "GOK/R0",
D_NONE: "NONE/XER",
D_EXTERN: "EXTERN",
D_STATIC: "STATIC",
D_AUTO: "AUTO",
D_PARAM: "PARAM",
D_BRANCH: "BRANCH",
D_OREG: "OREG",
D_CONST: "CONST/LR",
D_FCONST: "FCONST/CTR",
D_SCONST: "SCONST",
D_REG: "REG",
D_FPSCR: "FPSCR",
D_MSR: "MSR",
D_FREG: "FREG",
D_CREG: "CREG",
D_SPR: "SPR",
D_OPT: "OPT",
D_FILE: "FILE",
D_FILE1: "FILE1",
D_DCR: "DCR",
D_DCONST: "DCONST",
D_ADDR: "ADDR",
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,372 @@
// cmd/9l/list.c from Vita Nuova.
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package ppc64
import (
"cmd/internal/obj"
"fmt"
)
const (
STRINGSZ = 1000
)
//
// Format conversions
// %A int Opcodes (instruction mnemonics)
//
// %D Addr* Addresses (instruction operands)
// Flags: "%lD": seperate the high and low words of a constant by "-"
//
// %P Prog* Instructions
//
// %R int Registers
//
// %$ char* String constant addresses (for internal use only)
// %^ int C_* classes (for liblink internal use)
var bigP *obj.Prog
func Pconv(p *obj.Prog) string {
var str string
var fp string
var a int
var ch int
a = int(p.As)
if a == ADATA || a == AINIT || a == ADYNT {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
} else if a == ATEXT {
if p.Reg != 0 {
str = fmt.Sprintf("%.5d (%v) %v %v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, fmtLong, &p.To))
} else {
str = fmt.Sprintf("%.5d (%v) %v %v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, fmtLong, &p.To))
}
} else if a == AGLOBL {
if p.Reg != 0 {
str = fmt.Sprintf("%.5d (%v) %v %v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
} else {
str = fmt.Sprintf("%.5d (%v) %v %v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
}
} else {
if p.Mark&NOSCHED != 0 {
str += fmt.Sprintf("*")
}
if p.Reg == NREG && p.From3.Type_ == D_NONE {
str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
} else if a != ATEXT && p.From.Type_ == D_OREG {
str += fmt.Sprintf("%.5d (%v)\t%v\t%d(R%d+R%d),%v", p.Pc, p.Line(), Aconv(a), p.From.Offset, p.From.Reg, p.Reg, Dconv(p, 0, &p.To))
} else if p.To.Type_ == D_OREG {
str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%d(R%d+R%d)", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.To.Offset, p.To.Reg, p.Reg)
} else {
str += fmt.Sprintf("%.5d (%v)\t%v\t%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From))
if p.Reg != NREG {
ch = 'R'
if p.From.Type_ == D_FREG {
ch = 'F'
}
str += fmt.Sprintf(",%c%d", ch, p.Reg)
}
if p.From3.Type_ != D_NONE {
str += fmt.Sprintf(",%v", Dconv(p, 0, &p.From3))
}
str += fmt.Sprintf(",%v", Dconv(p, 0, &p.To))
}
if p.Spadj != 0 {
fp += fmt.Sprintf("%s # spadj=%d", str, p.Spadj)
return fp
}
}
fp += str
return fp
}
func Aconv(a int) string {
var s string
var fp string
s = "???"
if a >= AXXX && a < ALAST {
s = anames9[a]
}
fp += s
return fp
}
func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
var str string
var fp string
var v int32
if flag&fmtLong != 0 /*untyped*/ {
if a.Type_ == D_CONST {
str = fmt.Sprintf("$%d-%d", int32(a.Offset), int32(a.Offset>>32))
} else {
// ATEXT dst is not constant
str = fmt.Sprintf("!!%v", Dconv(p, 0, a))
}
goto ret
}
switch a.Type_ {
default:
str = fmt.Sprintf("GOK-type(%d)", a.Type_)
case D_NONE:
str = ""
if a.Name != D_NONE || a.Reg != NREG || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(NONE)", Mconv(a), a.Reg)
}
case D_CONST,
D_DCONST:
if a.Reg != NREG {
str = fmt.Sprintf("$%v(R%d)", Mconv(a), a.Reg)
} else {
str = fmt.Sprintf("$%v", Mconv(a))
}
case D_OREG:
if a.Reg != NREG {
str = fmt.Sprintf("%v(R%d)", Mconv(a), a.Reg)
} else {
str = fmt.Sprintf("%v", Mconv(a))
}
case D_REG:
str = fmt.Sprintf("R%d", a.Reg)
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(REG)", Mconv(a), a.Reg)
}
case D_FREG:
str = fmt.Sprintf("F%d", a.Reg)
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(F%d)(REG)", Mconv(a), a.Reg)
}
case D_CREG:
if a.Reg == NREG {
str = "CR"
} else {
str = fmt.Sprintf("CR%d", a.Reg)
}
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(C%d)(REG)", Mconv(a), a.Reg)
}
case D_SPR:
if a.Name == D_NONE && a.Sym == nil {
switch uint32(a.Offset) {
case D_XER:
str = fmt.Sprintf("XER")
case D_LR:
str = fmt.Sprintf("LR")
case D_CTR:
str = fmt.Sprintf("CTR")
default:
str = fmt.Sprintf("SPR(%d)", a.Offset)
break
}
break
}
str = fmt.Sprintf("SPR-GOK(%d)", a.Reg)
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(SPR-GOK%d)(REG)", Mconv(a), a.Reg)
}
case D_DCR:
if a.Name == D_NONE && a.Sym == nil {
str = fmt.Sprintf("DCR(%d)", a.Offset)
break
}
str = fmt.Sprintf("DCR-GOK(%d)", a.Reg)
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(DCR-GOK%d)(REG)", Mconv(a), a.Reg)
}
case D_OPT:
str = fmt.Sprintf("OPT(%d)", a.Reg)
case D_FPSCR:
if a.Reg == NREG {
str = "FPSCR"
} else {
str = fmt.Sprintf("FPSCR(%d)", a.Reg)
}
case D_MSR:
str = fmt.Sprintf("MSR")
case D_BRANCH:
if p.Pcond != nil {
v = int32(p.Pcond.Pc)
//if(v >= INITTEXT)
// v -= INITTEXT-HEADR;
if a.Sym != nil {
str = fmt.Sprintf("%s+%.5x(BRANCH)", a.Sym.Name, uint32(v))
} else {
str = fmt.Sprintf("%.5x(BRANCH)", uint32(v))
}
} else if a.U.Branch != nil {
str = fmt.Sprintf("%d", a.U.Branch.Pc)
} else if a.Sym != nil {
str = fmt.Sprintf("%s+%d(APC)", a.Sym.Name, a.Offset)
} else {
str = fmt.Sprintf("%d(APC)", a.Offset)
}
//sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
case D_FCONST:
str = fmt.Sprintf("$%.17g", a.U.Dval)
case D_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
break
}
ret:
fp += str
return fp
}
func Mconv(a *obj.Addr) string {
var str string
var fp string
var s *obj.LSym
var l int32
s = a.Sym
//if(s == nil) {
// l = a->offset;
// if((vlong)l != a->offset)
// sprint(str, "0x%llux", a->offset);
// else
// sprint(str, "%lld", a->offset);
// goto out;
//}
switch a.Name {
default:
str = fmt.Sprintf("GOK-name(%d)", a.Name)
case D_NONE:
l = int32(a.Offset)
if int64(l) != a.Offset {
str = fmt.Sprintf("0x%x", uint64(a.Offset))
} else {
str = fmt.Sprintf("%d", a.Offset)
}
case D_EXTERN:
if a.Offset != 0 {
str = fmt.Sprintf("%s+%d(SB)", s.Name, a.Offset)
} else {
str = fmt.Sprintf("%s(SB)", s.Name)
}
case D_STATIC:
str = fmt.Sprintf("%s<>+%d(SB)", s.Name, a.Offset)
case D_AUTO:
if s == nil {
str = fmt.Sprintf("%d(SP)", -a.Offset)
} else {
str = fmt.Sprintf("%s-%d(SP)", s.Name, -a.Offset)
}
case D_PARAM:
if s == nil {
str = fmt.Sprintf("%d(FP)", a.Offset)
} else {
str = fmt.Sprintf("%s+%d(FP)", s.Name, a.Offset)
}
break
}
//out:
fp += str
return fp
}
func Rconv(r int) string {
var str string
var fp string
if r < NREG {
str = fmt.Sprintf("r%d", r)
} else {
str = fmt.Sprintf("f%d", r-NREG)
}
fp += str
return fp
}
func DRconv(a int) string {
var s string
var fp string
s = "C_??"
if a >= C_NONE && a <= C_NCLASS {
s = cnames9[a]
}
fp += s
return fp
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,16 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ppc64
const (
fmtLong = 1 << iota
)
func bool2int(b bool) int {
if b {
return 1
}
return 0
}

View file

@ -0,0 +1,52 @@
// Inferno utils/5l/span.c
// http://code.google.com/p/inferno-os/source/browse/utils/5l/span.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package obj
// Instruction layout.
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// For the linkers. Must match Go definitions.
// TODO(rsc): Share Go definitions with linkers directly.
const (
StackSystem = 0
StackBig = 4096
StackGuard = 640 + StackSystem
StackSmall = 128
StackLimit = StackGuard - StackSystem - StackSmall
)
const (
StackPreempt = -1314 // 0xfff...fade
)

286
src/cmd/internal/obj/sym.go Normal file
View file

@ -0,0 +1,286 @@
// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
// http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.c
// http://code.google.com/p/inferno-os/source/browse/utils/6l/span.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package obj
import (
"fmt"
"log"
"os"
"path/filepath"
)
func yy_isalpha(c int) bool {
return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
}
var headers = []struct {
name string
val int
}{
struct {
name string
val int
}{"android", Hlinux},
struct {
name string
val int
}{"darwin", Hdarwin},
struct {
name string
val int
}{"dragonfly", Hdragonfly},
struct {
name string
val int
}{"elf", Helf},
struct {
name string
val int
}{"freebsd", Hfreebsd},
struct {
name string
val int
}{"linux", Hlinux},
struct {
name string
val int
}{"nacl", Hnacl},
struct {
name string
val int
}{"netbsd", Hnetbsd},
struct {
name string
val int
}{"openbsd", Hopenbsd},
struct {
name string
val int
}{"plan9", Hplan9},
struct {
name string
val int
}{"solaris", Hsolaris},
struct {
name string
val int
}{"windows", Hwindows},
struct {
name string
val int
}{"windowsgui", Hwindows},
}
func headtype(name string) int {
var i int
for i = 0; i < len(headers); i++ {
if name == headers[i].name {
return headers[i].val
}
}
return -1
}
func Headstr(v int) string {
var buf string
var i int
for i = 0; i < len(headers); i++ {
if v == headers[i].val {
return headers[i].name
}
}
buf = fmt.Sprintf("%d", v)
return buf
}
func Linknew(arch *LinkArch) *Link {
var ctxt *Link
var p string
var buf string
ctxt = new(Link)
ctxt.Arch = arch
ctxt.Version = HistVersion
ctxt.Goroot = Getgoroot()
ctxt.Goroot_final = os.Getenv("GOROOT_FINAL")
buf, _ = os.Getwd()
if buf == "" {
buf = "/???"
}
buf = filepath.ToSlash(buf)
ctxt.Pathname = buf
ctxt.Headtype = headtype(Getgoos())
if ctxt.Headtype < 0 {
log.Fatalf("unknown goos %s", Getgoos())
}
// Record thread-local storage offset.
// TODO(rsc): Move tlsoffset back into the linker.
switch ctxt.Headtype {
default:
log.Fatalf("unknown thread-local storage offset for %s", Headstr(ctxt.Headtype))
case Hplan9,
Hwindows:
break
/*
* ELF uses TLS offset negative from FS.
* Translate 0(FS) and 8(FS) into -16(FS) and -8(FS).
* Known to low-level assembly in package runtime and runtime/cgo.
*/
case Hlinux,
Hfreebsd,
Hnetbsd,
Hopenbsd,
Hdragonfly,
Hsolaris:
ctxt.Tlsoffset = -2 * ctxt.Arch.Ptrsize
case Hnacl:
switch ctxt.Arch.Thechar {
default:
log.Fatalf("unknown thread-local storage offset for nacl/%s", ctxt.Arch.Name)
case '6':
ctxt.Tlsoffset = 0
case '8':
ctxt.Tlsoffset = -8
case '5':
ctxt.Tlsoffset = 0
break
}
/*
* OS X system constants - offset from 0(GS) to our TLS.
* Explained in ../../runtime/cgo/gcc_darwin_*.c.
*/
case Hdarwin:
switch ctxt.Arch.Thechar {
default:
log.Fatalf("unknown thread-local storage offset for darwin/%s", ctxt.Arch.Name)
case '6':
ctxt.Tlsoffset = 0x8a0
case '8':
ctxt.Tlsoffset = 0x468
break
}
break
}
// On arm, record goarm.
if ctxt.Arch.Thechar == '5' {
p = Getgoarm()
if p != "" {
ctxt.Goarm = int32(Atoi(p))
} else {
ctxt.Goarm = 6
}
}
return ctxt
}
func linknewsym(ctxt *Link, symb string, v int) *LSym {
var s *LSym
s = new(LSym)
*s = LSym{}
s.Dynid = -1
s.Plt = -1
s.Got = -1
s.Name = symb
s.Type_ = 0
s.Version = int16(v)
s.Value = 0
s.Sig = 0
s.Size = 0
ctxt.Nsymbol++
s.Allsym = ctxt.Allsym
ctxt.Allsym = s
return s
}
func _lookup(ctxt *Link, symb string, v int, creat int) *LSym {
var s *LSym
var h uint32
h = uint32(v)
for i := 0; i < len(symb); i++ {
c := int(symb[i])
h = h + h + h + uint32(c)
}
h &= 0xffffff
h %= LINKHASH
for s = ctxt.Hash[h]; s != nil; s = s.Hash {
if int(s.Version) == v && s.Name == symb {
return s
}
}
if !(creat != 0) {
return nil
}
s = linknewsym(ctxt, symb, v)
s.Extname = s.Name
s.Hash = ctxt.Hash[h]
ctxt.Hash[h] = s
return s
}
func Linklookup(ctxt *Link, name string, v int) *LSym {
return _lookup(ctxt, name, v, 1)
}
// read-only lookup
func linkrlookup(ctxt *Link, name string, v int) *LSym {
return _lookup(ctxt, name, v, 0)
}

View file

@ -0,0 +1,33 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file defines flags attached to various functions
// and data objects. The compilers, assemblers, and linker must
// all agree on these values.
package obj
const (
// Don't profile the marked routine. This flag is deprecated.
NOPROF = 1
// It is ok for the linker to get multiple of these symbols. It will
// pick one of the duplicates to use.
DUPOK = 2
// Don't insert stack check preamble.
NOSPLIT = 4
// Put this data in a read-only section.
RODATA = 8
// This data contains no pointers.
NOPTR = 16
// This is a wrapper function and should not count as disabling 'recover'.
WRAPPER = 32
// This function uses its incoming context register.
NEEDCTXT = 64
)

View file

@ -0,0 +1,113 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package obj
import (
"bufio"
"fmt"
"go/build"
"io"
"os"
"strconv"
"time"
)
var start time.Time
func Cputime() float64 {
if start.IsZero() {
start = time.Now()
}
return time.Since(start).Seconds()
}
type Biobuf struct {
unget int
haveUnget bool
r *bufio.Reader
w *bufio.Writer
}
func Binitw(w io.Writer) *Biobuf {
return &Biobuf{w: bufio.NewWriter(w)}
}
func (b *Biobuf) Write(p []byte) (int, error) {
return b.w.Write(p)
}
func (b *Biobuf) Flush() error {
return b.w.Flush()
}
func Bwrite(b *Biobuf, p []byte) (int, error) {
return b.w.Write(p)
}
func Bputc(b *Biobuf, c byte) {
b.w.WriteByte(c)
}
func Bgetc(b *Biobuf) int {
if b.haveUnget {
b.haveUnget = false
return int(b.unget)
}
c, err := b.r.ReadByte()
if err != nil {
b.unget = -1
return -1
}
b.unget = int(c)
return int(c)
}
func Bungetc(b *Biobuf) {
b.haveUnget = true
}
func Boffset(b *Biobuf) int64 {
panic("Boffset")
}
func Bflush(b *Biobuf) error {
return b.w.Flush()
}
func Getgoroot() string {
return build.Default.GOROOT
}
func Getgoarch() string {
return build.Default.GOARCH
}
func Getgoos() string {
return build.Default.GOOS
}
func Atoi(s string) int {
i, _ := strconv.Atoi(s)
return i
}
func Getgoarm() string {
env := os.Getenv("GOARM")
if env != "" {
return env
}
return "5"
}
func (p *Prog) Line() string {
return linklinefmt(p.Ctxt, int(p.Lineno), false, false)
}
func (p *Prog) String() string {
if p.Ctxt == nil {
return fmt.Sprintf("<Prog without ctxt>")
}
return p.Ctxt.Arch.Pconv(p)
}

View file

@ -0,0 +1,836 @@
// Inferno utils/6c/6.out.h
// http://code.google.com/p/inferno-os/source/browse/utils/6c/6.out.h
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package x86
/*
* amd64
*/
const (
AXXX = iota
AAAA
AAAD
AAAM
AAAS
AADCB
AADCL
AADCW
AADDB
AADDL
AADDW
AADJSP
AANDB
AANDL
AANDW
AARPL
ABOUNDL
ABOUNDW
ABSFL
ABSFW
ABSRL
ABSRW
ABTL
ABTW
ABTCL
ABTCW
ABTRL
ABTRW
ABTSL
ABTSW
ABYTE
ACALL
ACLC
ACLD
ACLI
ACLTS
ACMC
ACMPB
ACMPL
ACMPW
ACMPSB
ACMPSL
ACMPSW
ADAA
ADAS
ADATA
ADECB
ADECL
ADECQ
ADECW
ADIVB
ADIVL
ADIVW
AENTER
AGLOBL
AGOK
AHISTORY
AHLT
AIDIVB
AIDIVL
AIDIVW
AIMULB
AIMULL
AIMULW
AINB
AINL
AINW
AINCB
AINCL
AINCQ
AINCW
AINSB
AINSL
AINSW
AINT
AINTO
AIRETL
AIRETW
AJCC
AJCS
AJCXZL
AJEQ
AJGE
AJGT
AJHI
AJLE
AJLS
AJLT
AJMI
AJMP
AJNE
AJOC
AJOS
AJPC
AJPL
AJPS
ALAHF
ALARL
ALARW
ALEAL
ALEAW
ALEAVEL
ALEAVEW
ALOCK
ALODSB
ALODSL
ALODSW
ALONG
ALOOP
ALOOPEQ
ALOOPNE
ALSLL
ALSLW
AMOVB
AMOVL
AMOVW
AMOVBLSX
AMOVBLZX
AMOVBQSX
AMOVBQZX
AMOVBWSX
AMOVBWZX
AMOVWLSX
AMOVWLZX
AMOVWQSX
AMOVWQZX
AMOVSB
AMOVSL
AMOVSW
AMULB
AMULL
AMULW
ANAME
ANEGB
ANEGL
ANEGW
ANOP
ANOTB
ANOTL
ANOTW
AORB
AORL
AORW
AOUTB
AOUTL
AOUTW
AOUTSB
AOUTSL
AOUTSW
APAUSE
APOPAL
APOPAW
APOPFL
APOPFW
APOPL
APOPW
APUSHAL
APUSHAW
APUSHFL
APUSHFW
APUSHL
APUSHW
ARCLB
ARCLL
ARCLW
ARCRB
ARCRL
ARCRW
AREP
AREPN
ARET
AROLB
AROLL
AROLW
ARORB
ARORL
ARORW
ASAHF
ASALB
ASALL
ASALW
ASARB
ASARL
ASARW
ASBBB
ASBBL
ASBBW
ASCASB
ASCASL
ASCASW
ASETCC
ASETCS
ASETEQ
ASETGE
ASETGT
ASETHI
ASETLE
ASETLS
ASETLT
ASETMI
ASETNE
ASETOC
ASETOS
ASETPC
ASETPL
ASETPS
ACDQ
ACWD
ASHLB
ASHLL
ASHLW
ASHRB
ASHRL
ASHRW
ASTC
ASTD
ASTI
ASTOSB
ASTOSL
ASTOSW
ASUBB
ASUBL
ASUBW
ASYSCALL
ATESTB
ATESTL
ATESTW
ATEXT
AVERR
AVERW
AWAIT
AWORD
AXCHGB
AXCHGL
AXCHGW
AXLAT
AXORB
AXORL
AXORW
AFMOVB
AFMOVBP
AFMOVD
AFMOVDP
AFMOVF
AFMOVFP
AFMOVL
AFMOVLP
AFMOVV
AFMOVVP
AFMOVW
AFMOVWP
AFMOVX
AFMOVXP
AFCOMB
AFCOMBP
AFCOMD
AFCOMDP
AFCOMDPP
AFCOMF
AFCOMFP
AFCOML
AFCOMLP
AFCOMW
AFCOMWP
AFUCOM
AFUCOMP
AFUCOMPP
AFADDDP
AFADDW
AFADDL
AFADDF
AFADDD
AFMULDP
AFMULW
AFMULL
AFMULF
AFMULD
AFSUBDP
AFSUBW
AFSUBL
AFSUBF
AFSUBD
AFSUBRDP
AFSUBRW
AFSUBRL
AFSUBRF
AFSUBRD
AFDIVDP
AFDIVW
AFDIVL
AFDIVF
AFDIVD
AFDIVRDP
AFDIVRW
AFDIVRL
AFDIVRF
AFDIVRD
AFXCHD
AFFREE
AFLDCW
AFLDENV
AFRSTOR
AFSAVE
AFSTCW
AFSTENV
AFSTSW
AF2XM1
AFABS
AFCHS
AFCLEX
AFCOS
AFDECSTP
AFINCSTP
AFINIT
AFLD1
AFLDL2E
AFLDL2T
AFLDLG2
AFLDLN2
AFLDPI
AFLDZ
AFNOP
AFPATAN
AFPREM
AFPREM1
AFPTAN
AFRNDINT
AFSCALE
AFSIN
AFSINCOS
AFSQRT
AFTST
AFXAM
AFXTRACT
AFYL2X
AFYL2XP1
AEND
ADYNT_
AINIT_
ASIGNAME
ACMPXCHGB
ACMPXCHGL
ACMPXCHGW
ACMPXCHG8B
ACPUID
AINVD
AINVLPG
ALFENCE
AMFENCE
AMOVNTIL
ARDMSR
ARDPMC
ARDTSC
ARSM
ASFENCE
ASYSRET
AWBINVD
AWRMSR
AXADDB
AXADDL
AXADDW
ACMOVLCC
ACMOVLCS
ACMOVLEQ
ACMOVLGE
ACMOVLGT
ACMOVLHI
ACMOVLLE
ACMOVLLS
ACMOVLLT
ACMOVLMI
ACMOVLNE
ACMOVLOC
ACMOVLOS
ACMOVLPC
ACMOVLPL
ACMOVLPS
ACMOVQCC
ACMOVQCS
ACMOVQEQ
ACMOVQGE
ACMOVQGT
ACMOVQHI
ACMOVQLE
ACMOVQLS
ACMOVQLT
ACMOVQMI
ACMOVQNE
ACMOVQOC
ACMOVQOS
ACMOVQPC
ACMOVQPL
ACMOVQPS
ACMOVWCC
ACMOVWCS
ACMOVWEQ
ACMOVWGE
ACMOVWGT
ACMOVWHI
ACMOVWLE
ACMOVWLS
ACMOVWLT
ACMOVWMI
ACMOVWNE
ACMOVWOC
ACMOVWOS
ACMOVWPC
ACMOVWPL
ACMOVWPS
AADCQ
AADDQ
AANDQ
ABSFQ
ABSRQ
ABTCQ
ABTQ
ABTRQ
ABTSQ
ACMPQ
ACMPSQ
ACMPXCHGQ
ACQO
ADIVQ
AIDIVQ
AIMULQ
AIRETQ
AJCXZQ
ALEAQ
ALEAVEQ
ALODSQ
AMOVQ
AMOVLQSX
AMOVLQZX
AMOVNTIQ
AMOVSQ
AMULQ
ANEGQ
ANOTQ
AORQ
APOPFQ
APOPQ
APUSHFQ
APUSHQ
ARCLQ
ARCRQ
AROLQ
ARORQ
AQUAD
ASALQ
ASARQ
ASBBQ
ASCASQ
ASHLQ
ASHRQ
ASTOSQ
ASUBQ
ATESTQ
AXADDQ
AXCHGQ
AXORQ
AADDPD
AADDPS
AADDSD
AADDSS
AANDNPD
AANDNPS
AANDPD
AANDPS
ACMPPD
ACMPPS
ACMPSD
ACMPSS
ACOMISD
ACOMISS
ACVTPD2PL
ACVTPD2PS
ACVTPL2PD
ACVTPL2PS
ACVTPS2PD
ACVTPS2PL
ACVTSD2SL
ACVTSD2SQ
ACVTSD2SS
ACVTSL2SD
ACVTSL2SS
ACVTSQ2SD
ACVTSQ2SS
ACVTSS2SD
ACVTSS2SL
ACVTSS2SQ
ACVTTPD2PL
ACVTTPS2PL
ACVTTSD2SL
ACVTTSD2SQ
ACVTTSS2SL
ACVTTSS2SQ
ADIVPD
ADIVPS
ADIVSD
ADIVSS
AEMMS
AFXRSTOR
AFXRSTOR64
AFXSAVE
AFXSAVE64
ALDMXCSR
AMASKMOVOU
AMASKMOVQ
AMAXPD
AMAXPS
AMAXSD
AMAXSS
AMINPD
AMINPS
AMINSD
AMINSS
AMOVAPD
AMOVAPS
AMOVOU
AMOVHLPS
AMOVHPD
AMOVHPS
AMOVLHPS
AMOVLPD
AMOVLPS
AMOVMSKPD
AMOVMSKPS
AMOVNTO
AMOVNTPD
AMOVNTPS
AMOVNTQ
AMOVO
AMOVQOZX
AMOVSD
AMOVSS
AMOVUPD
AMOVUPS
AMULPD
AMULPS
AMULSD
AMULSS
AORPD
AORPS
APACKSSLW
APACKSSWB
APACKUSWB
APADDB
APADDL
APADDQ
APADDSB
APADDSW
APADDUSB
APADDUSW
APADDW
APANDB
APANDL
APANDSB
APANDSW
APANDUSB
APANDUSW
APANDW
APAND
APANDN
APAVGB
APAVGW
APCMPEQB
APCMPEQL
APCMPEQW
APCMPGTB
APCMPGTL
APCMPGTW
APEXTRW
APFACC
APFADD
APFCMPEQ
APFCMPGE
APFCMPGT
APFMAX
APFMIN
APFMUL
APFNACC
APFPNACC
APFRCP
APFRCPIT1
APFRCPI2T
APFRSQIT1
APFRSQRT
APFSUB
APFSUBR
APINSRW
APINSRD
APINSRQ
APMADDWL
APMAXSW
APMAXUB
APMINSW
APMINUB
APMOVMSKB
APMULHRW
APMULHUW
APMULHW
APMULLW
APMULULQ
APOR
APSADBW
APSHUFHW
APSHUFL
APSHUFLW
APSHUFW
APSHUFB
APSLLO
APSLLL
APSLLQ
APSLLW
APSRAL
APSRAW
APSRLO
APSRLL
APSRLQ
APSRLW
APSUBB
APSUBL
APSUBQ
APSUBSB
APSUBSW
APSUBUSB
APSUBUSW
APSUBW
APSWAPL
APUNPCKHBW
APUNPCKHLQ
APUNPCKHQDQ
APUNPCKHWL
APUNPCKLBW
APUNPCKLLQ
APUNPCKLQDQ
APUNPCKLWL
APXOR
ARCPPS
ARCPSS
ARSQRTPS
ARSQRTSS
ASHUFPD
ASHUFPS
ASQRTPD
ASQRTPS
ASQRTSD
ASQRTSS
ASTMXCSR
ASUBPD
ASUBPS
ASUBSD
ASUBSS
AUCOMISD
AUCOMISS
AUNPCKHPD
AUNPCKHPS
AUNPCKLPD
AUNPCKLPS
AXORPD
AXORPS
APF2IW
APF2IL
API2FW
API2FL
ARETFW
ARETFL
ARETFQ
ASWAPGS
AMODE
ACRC32B
ACRC32Q
AIMUL3Q
APREFETCHT0
APREFETCHT1
APREFETCHT2
APREFETCHNTA
AMOVQL
ABSWAPL
ABSWAPQ
AUNDEF
AAESENC
AAESENCLAST
AAESDEC
AAESDECLAST
AAESIMC
AAESKEYGENASSIST
APSHUFD
APCLMULQDQ
AUSEFIELD
ATYPE
AFUNCDATA
APCDATA
ACHECKNIL
AVARDEF
AVARKILL
ADUFFCOPY
ADUFFZERO
ALAST
)
const (
D_AL = 0 + iota
D_CL
D_DL
D_BL
D_SPB
D_BPB
D_SIB
D_DIB
D_R8B
D_R9B
D_R10B
D_R11B
D_R12B
D_R13B
D_R14B
D_R15B
D_AX = 16 + iota - 16
D_CX
D_DX
D_BX
D_SP
D_BP
D_SI
D_DI
D_R8
D_R9
D_R10
D_R11
D_R12
D_R13
D_R14
D_R15
D_AH = 32 + iota - 32
D_CH
D_DH
D_BH
D_F0 = 36
D_M0 = 44
D_X0 = 52 + iota - 38
D_X1
D_X2
D_X3
D_X4
D_X5
D_X6
D_X7
D_X8
D_X9
D_X10
D_X11
D_X12
D_X13
D_X14
D_X15
D_CS = 68 + iota - 54
D_SS
D_DS
D_ES
D_FS
D_GS
D_GDTR
D_IDTR
D_LDTR
D_MSW
D_TASK
D_CR = 79
D_DR = 95
D_TR = 103
D_TLS = 111
D_NONE = 112
D_BRANCH = 113
D_EXTERN = 114
D_STATIC = 115
D_AUTO = 116
D_PARAM = 117
D_CONST = 118
D_FCONST = 119
D_SCONST = 120
D_ADDR = 121 + iota - 78
D_INDIR
D_LAST
T_TYPE = 1 << 0
T_INDEX = 1 << 1
T_OFFSET = 1 << 2
T_FCONST = 1 << 3
T_SYM = 1 << 4
T_SCONST = 1 << 5
T_64 = 1 << 6
T_GOTYPE = 1 << 7
REGARG = -1
REGRET = D_AX
FREGRET = D_X0
REGSP = D_SP
REGTMP = D_DI
REGEXT = D_R15
FREGMIN = D_X0 + 5
FREGEXT = D_X0 + 15
)

View file

@ -0,0 +1,789 @@
package x86
/*
* this is the ranlib header
*/
var anames6 = []string{
"XXX",
"AAA",
"AAD",
"AAM",
"AAS",
"ADCB",
"ADCL",
"ADCW",
"ADDB",
"ADDL",
"ADDW",
"ADJSP",
"ANDB",
"ANDL",
"ANDW",
"ARPL",
"BOUNDL",
"BOUNDW",
"BSFL",
"BSFW",
"BSRL",
"BSRW",
"BTL",
"BTW",
"BTCL",
"BTCW",
"BTRL",
"BTRW",
"BTSL",
"BTSW",
"BYTE",
"CALL",
"CLC",
"CLD",
"CLI",
"CLTS",
"CMC",
"CMPB",
"CMPL",
"CMPW",
"CMPSB",
"CMPSL",
"CMPSW",
"DAA",
"DAS",
"DATA",
"DECB",
"DECL",
"DECQ",
"DECW",
"DIVB",
"DIVL",
"DIVW",
"ENTER",
"GLOBL",
"GOK",
"HISTORY",
"HLT",
"IDIVB",
"IDIVL",
"IDIVW",
"IMULB",
"IMULL",
"IMULW",
"INB",
"INL",
"INW",
"INCB",
"INCL",
"INCQ",
"INCW",
"INSB",
"INSL",
"INSW",
"INT",
"INTO",
"IRETL",
"IRETW",
"JCC",
"JCS",
"JCXZL",
"JEQ",
"JGE",
"JGT",
"JHI",
"JLE",
"JLS",
"JLT",
"JMI",
"JMP",
"JNE",
"JOC",
"JOS",
"JPC",
"JPL",
"JPS",
"LAHF",
"LARL",
"LARW",
"LEAL",
"LEAW",
"LEAVEL",
"LEAVEW",
"LOCK",
"LODSB",
"LODSL",
"LODSW",
"LONG",
"LOOP",
"LOOPEQ",
"LOOPNE",
"LSLL",
"LSLW",
"MOVB",
"MOVL",
"MOVW",
"MOVBLSX",
"MOVBLZX",
"MOVBQSX",
"MOVBQZX",
"MOVBWSX",
"MOVBWZX",
"MOVWLSX",
"MOVWLZX",
"MOVWQSX",
"MOVWQZX",
"MOVSB",
"MOVSL",
"MOVSW",
"MULB",
"MULL",
"MULW",
"NAME",
"NEGB",
"NEGL",
"NEGW",
"NOP",
"NOTB",
"NOTL",
"NOTW",
"ORB",
"ORL",
"ORW",
"OUTB",
"OUTL",
"OUTW",
"OUTSB",
"OUTSL",
"OUTSW",
"PAUSE",
"POPAL",
"POPAW",
"POPFL",
"POPFW",
"POPL",
"POPW",
"PUSHAL",
"PUSHAW",
"PUSHFL",
"PUSHFW",
"PUSHL",
"PUSHW",
"RCLB",
"RCLL",
"RCLW",
"RCRB",
"RCRL",
"RCRW",
"REP",
"REPN",
"RET",
"ROLB",
"ROLL",
"ROLW",
"RORB",
"RORL",
"RORW",
"SAHF",
"SALB",
"SALL",
"SALW",
"SARB",
"SARL",
"SARW",
"SBBB",
"SBBL",
"SBBW",
"SCASB",
"SCASL",
"SCASW",
"SETCC",
"SETCS",
"SETEQ",
"SETGE",
"SETGT",
"SETHI",
"SETLE",
"SETLS",
"SETLT",
"SETMI",
"SETNE",
"SETOC",
"SETOS",
"SETPC",
"SETPL",
"SETPS",
"CDQ",
"CWD",
"SHLB",
"SHLL",
"SHLW",
"SHRB",
"SHRL",
"SHRW",
"STC",
"STD",
"STI",
"STOSB",
"STOSL",
"STOSW",
"SUBB",
"SUBL",
"SUBW",
"SYSCALL",
"TESTB",
"TESTL",
"TESTW",
"TEXT",
"VERR",
"VERW",
"WAIT",
"WORD",
"XCHGB",
"XCHGL",
"XCHGW",
"XLAT",
"XORB",
"XORL",
"XORW",
"FMOVB",
"FMOVBP",
"FMOVD",
"FMOVDP",
"FMOVF",
"FMOVFP",
"FMOVL",
"FMOVLP",
"FMOVV",
"FMOVVP",
"FMOVW",
"FMOVWP",
"FMOVX",
"FMOVXP",
"FCOMB",
"FCOMBP",
"FCOMD",
"FCOMDP",
"FCOMDPP",
"FCOMF",
"FCOMFP",
"FCOML",
"FCOMLP",
"FCOMW",
"FCOMWP",
"FUCOM",
"FUCOMP",
"FUCOMPP",
"FADDDP",
"FADDW",
"FADDL",
"FADDF",
"FADDD",
"FMULDP",
"FMULW",
"FMULL",
"FMULF",
"FMULD",
"FSUBDP",
"FSUBW",
"FSUBL",
"FSUBF",
"FSUBD",
"FSUBRDP",
"FSUBRW",
"FSUBRL",
"FSUBRF",
"FSUBRD",
"FDIVDP",
"FDIVW",
"FDIVL",
"FDIVF",
"FDIVD",
"FDIVRDP",
"FDIVRW",
"FDIVRL",
"FDIVRF",
"FDIVRD",
"FXCHD",
"FFREE",
"FLDCW",
"FLDENV",
"FRSTOR",
"FSAVE",
"FSTCW",
"FSTENV",
"FSTSW",
"F2XM1",
"FABS",
"FCHS",
"FCLEX",
"FCOS",
"FDECSTP",
"FINCSTP",
"FINIT",
"FLD1",
"FLDL2E",
"FLDL2T",
"FLDLG2",
"FLDLN2",
"FLDPI",
"FLDZ",
"FNOP",
"FPATAN",
"FPREM",
"FPREM1",
"FPTAN",
"FRNDINT",
"FSCALE",
"FSIN",
"FSINCOS",
"FSQRT",
"FTST",
"FXAM",
"FXTRACT",
"FYL2X",
"FYL2XP1",
"END",
"DYNT_",
"INIT_",
"SIGNAME",
"CMPXCHGB",
"CMPXCHGL",
"CMPXCHGW",
"CMPXCHG8B",
"CPUID",
"INVD",
"INVLPG",
"LFENCE",
"MFENCE",
"MOVNTIL",
"RDMSR",
"RDPMC",
"RDTSC",
"RSM",
"SFENCE",
"SYSRET",
"WBINVD",
"WRMSR",
"XADDB",
"XADDL",
"XADDW",
"CMOVLCC",
"CMOVLCS",
"CMOVLEQ",
"CMOVLGE",
"CMOVLGT",
"CMOVLHI",
"CMOVLLE",
"CMOVLLS",
"CMOVLLT",
"CMOVLMI",
"CMOVLNE",
"CMOVLOC",
"CMOVLOS",
"CMOVLPC",
"CMOVLPL",
"CMOVLPS",
"CMOVQCC",
"CMOVQCS",
"CMOVQEQ",
"CMOVQGE",
"CMOVQGT",
"CMOVQHI",
"CMOVQLE",
"CMOVQLS",
"CMOVQLT",
"CMOVQMI",
"CMOVQNE",
"CMOVQOC",
"CMOVQOS",
"CMOVQPC",
"CMOVQPL",
"CMOVQPS",
"CMOVWCC",
"CMOVWCS",
"CMOVWEQ",
"CMOVWGE",
"CMOVWGT",
"CMOVWHI",
"CMOVWLE",
"CMOVWLS",
"CMOVWLT",
"CMOVWMI",
"CMOVWNE",
"CMOVWOC",
"CMOVWOS",
"CMOVWPC",
"CMOVWPL",
"CMOVWPS",
"ADCQ",
"ADDQ",
"ANDQ",
"BSFQ",
"BSRQ",
"BTCQ",
"BTQ",
"BTRQ",
"BTSQ",
"CMPQ",
"CMPSQ",
"CMPXCHGQ",
"CQO",
"DIVQ",
"IDIVQ",
"IMULQ",
"IRETQ",
"JCXZQ",
"LEAQ",
"LEAVEQ",
"LODSQ",
"MOVQ",
"MOVLQSX",
"MOVLQZX",
"MOVNTIQ",
"MOVSQ",
"MULQ",
"NEGQ",
"NOTQ",
"ORQ",
"POPFQ",
"POPQ",
"PUSHFQ",
"PUSHQ",
"RCLQ",
"RCRQ",
"ROLQ",
"RORQ",
"QUAD",
"SALQ",
"SARQ",
"SBBQ",
"SCASQ",
"SHLQ",
"SHRQ",
"STOSQ",
"SUBQ",
"TESTQ",
"XADDQ",
"XCHGQ",
"XORQ",
"ADDPD",
"ADDPS",
"ADDSD",
"ADDSS",
"ANDNPD",
"ANDNPS",
"ANDPD",
"ANDPS",
"CMPPD",
"CMPPS",
"CMPSD",
"CMPSS",
"COMISD",
"COMISS",
"CVTPD2PL",
"CVTPD2PS",
"CVTPL2PD",
"CVTPL2PS",
"CVTPS2PD",
"CVTPS2PL",
"CVTSD2SL",
"CVTSD2SQ",
"CVTSD2SS",
"CVTSL2SD",
"CVTSL2SS",
"CVTSQ2SD",
"CVTSQ2SS",
"CVTSS2SD",
"CVTSS2SL",
"CVTSS2SQ",
"CVTTPD2PL",
"CVTTPS2PL",
"CVTTSD2SL",
"CVTTSD2SQ",
"CVTTSS2SL",
"CVTTSS2SQ",
"DIVPD",
"DIVPS",
"DIVSD",
"DIVSS",
"EMMS",
"FXRSTOR",
"FXRSTOR64",
"FXSAVE",
"FXSAVE64",
"LDMXCSR",
"MASKMOVOU",
"MASKMOVQ",
"MAXPD",
"MAXPS",
"MAXSD",
"MAXSS",
"MINPD",
"MINPS",
"MINSD",
"MINSS",
"MOVAPD",
"MOVAPS",
"MOVOU",
"MOVHLPS",
"MOVHPD",
"MOVHPS",
"MOVLHPS",
"MOVLPD",
"MOVLPS",
"MOVMSKPD",
"MOVMSKPS",
"MOVNTO",
"MOVNTPD",
"MOVNTPS",
"MOVNTQ",
"MOVO",
"MOVQOZX",
"MOVSD",
"MOVSS",
"MOVUPD",
"MOVUPS",
"MULPD",
"MULPS",
"MULSD",
"MULSS",
"ORPD",
"ORPS",
"PACKSSLW",
"PACKSSWB",
"PACKUSWB",
"PADDB",
"PADDL",
"PADDQ",
"PADDSB",
"PADDSW",
"PADDUSB",
"PADDUSW",
"PADDW",
"PANDB",
"PANDL",
"PANDSB",
"PANDSW",
"PANDUSB",
"PANDUSW",
"PANDW",
"PAND",
"PANDN",
"PAVGB",
"PAVGW",
"PCMPEQB",
"PCMPEQL",
"PCMPEQW",
"PCMPGTB",
"PCMPGTL",
"PCMPGTW",
"PEXTRW",
"PFACC",
"PFADD",
"PFCMPEQ",
"PFCMPGE",
"PFCMPGT",
"PFMAX",
"PFMIN",
"PFMUL",
"PFNACC",
"PFPNACC",
"PFRCP",
"PFRCPIT1",
"PFRCPI2T",
"PFRSQIT1",
"PFRSQRT",
"PFSUB",
"PFSUBR",
"PINSRW",
"PINSRD",
"PINSRQ",
"PMADDWL",
"PMAXSW",
"PMAXUB",
"PMINSW",
"PMINUB",
"PMOVMSKB",
"PMULHRW",
"PMULHUW",
"PMULHW",
"PMULLW",
"PMULULQ",
"POR",
"PSADBW",
"PSHUFHW",
"PSHUFL",
"PSHUFLW",
"PSHUFW",
"PSHUFB",
"PSLLO",
"PSLLL",
"PSLLQ",
"PSLLW",
"PSRAL",
"PSRAW",
"PSRLO",
"PSRLL",
"PSRLQ",
"PSRLW",
"PSUBB",
"PSUBL",
"PSUBQ",
"PSUBSB",
"PSUBSW",
"PSUBUSB",
"PSUBUSW",
"PSUBW",
"PSWAPL",
"PUNPCKHBW",
"PUNPCKHLQ",
"PUNPCKHQDQ",
"PUNPCKHWL",
"PUNPCKLBW",
"PUNPCKLLQ",
"PUNPCKLQDQ",
"PUNPCKLWL",
"PXOR",
"RCPPS",
"RCPSS",
"RSQRTPS",
"RSQRTSS",
"SHUFPD",
"SHUFPS",
"SQRTPD",
"SQRTPS",
"SQRTSD",
"SQRTSS",
"STMXCSR",
"SUBPD",
"SUBPS",
"SUBSD",
"SUBSS",
"UCOMISD",
"UCOMISS",
"UNPCKHPD",
"UNPCKHPS",
"UNPCKLPD",
"UNPCKLPS",
"XORPD",
"XORPS",
"PF2IW",
"PF2IL",
"PI2FW",
"PI2FL",
"RETFW",
"RETFL",
"RETFQ",
"SWAPGS",
"MODE",
"CRC32B",
"CRC32Q",
"IMUL3Q",
"PREFETCHT0",
"PREFETCHT1",
"PREFETCHT2",
"PREFETCHNTA",
"MOVQL",
"BSWAPL",
"BSWAPQ",
"UNDEF",
"AESENC",
"AESENCLAST",
"AESDEC",
"AESDECLAST",
"AESIMC",
"AESKEYGENASSIST",
"PSHUFD",
"PCLMULQDQ",
"USEFIELD",
"TYPE",
"FUNCDATA",
"PCDATA",
"CHECKNIL",
"VARDEF",
"VARKILL",
"DUFFCOPY",
"DUFFZERO",
"LAST",
}
var dnames6 = []string{
D_AL: "AL",
D_CL: "CL",
D_DL: "DL",
D_BL: "BL",
D_SPB: "SPB",
D_BPB: "BPB",
D_SIB: "SIB",
D_DIB: "DIB",
D_R8B: "R8B",
D_R9B: "R9B",
D_R10B: "R10B",
D_R11B: "R11B",
D_R12B: "R12B",
D_R13B: "R13B",
D_R14B: "R14B",
D_R15B: "R15B",
D_AX: "AX",
D_CX: "CX",
D_DX: "DX",
D_BX: "BX",
D_SP: "SP",
D_BP: "BP",
D_SI: "SI",
D_DI: "DI",
D_R8: "R8",
D_R9: "R9",
D_R10: "R10",
D_R11: "R11",
D_R12: "R12",
D_R13: "R13",
D_R14: "R14",
D_R15: "R15",
D_AH: "AH",
D_CH: "CH",
D_DH: "DH",
D_BH: "BH",
D_F0: "F0",
D_M0: "M0",
D_X0: "X0",
D_X1: "X1",
D_X2: "X2",
D_X3: "X3",
D_X4: "X4",
D_X5: "X5",
D_X6: "X6",
D_X7: "X7",
D_X8: "X8",
D_X9: "X9",
D_X10: "X10",
D_X11: "X11",
D_X12: "X12",
D_X13: "X13",
D_X14: "X14",
D_X15: "X15",
D_CS: "CS",
D_SS: "SS",
D_DS: "DS",
D_ES: "ES",
D_FS: "FS",
D_GS: "GS",
D_GDTR: "GDTR",
D_IDTR: "IDTR",
D_LDTR: "LDTR",
D_MSW: "MSW",
D_TASK: "TASK",
D_CR: "CR",
D_DR: "DR",
D_TR: "TR",
D_TLS: "TLS",
D_NONE: "NONE",
D_BRANCH: "BRANCH",
D_EXTERN: "EXTERN",
D_STATIC: "STATIC",
D_AUTO: "AUTO",
D_PARAM: "PARAM",
D_CONST: "CONST",
D_FCONST: "FCONST",
D_SCONST: "SCONST",
D_ADDR: "ADDR",
D_INDIR: "INDIR",
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,324 @@
// Inferno utils/6c/list.c
// http://code.google.com/p/inferno-os/source/browse/utils/6c/list.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package x86
import (
"cmd/internal/obj"
"fmt"
)
//
// Format conversions
// %A int Opcodes (instruction mnemonics)
//
// %D Addr* Addresses (instruction operands)
// Flags: "%lD": seperate the high and low words of a constant by "-"
//
// %P Prog* Instructions
//
// %R int Registers
//
// %$ char* String constant addresses (for internal use only)
const (
STRINGSZ = 1000
)
var bigP *obj.Prog
func Pconv(p *obj.Prog) string {
var str string
var fp string
switch p.As {
case ADATA:
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, 0, &p.To))
case ATEXT:
if p.From.Scale != 0 {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, fmtLong, &p.To))
break
}
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, fmtLong, &p.To))
default:
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
break
}
fp += str
return fp
}
func Aconv(i int) string {
var fp string
fp += anames6[i]
return fp
}
func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
var str string
var s string
var fp string
var i int
i = int(a.Type_)
if flag&fmtLong != 0 /*untyped*/ {
if i == D_CONST {
str = fmt.Sprintf("$%d-%d", a.Offset&0xffffffff, a.Offset>>32)
} else {
// ATEXT dst is not constant
str = fmt.Sprintf("!!%v", Dconv(p, 0, a))
}
goto brk
}
if i >= D_INDIR {
if a.Offset != 0 {
str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(i-D_INDIR))
} else {
str = fmt.Sprintf("(%v)", Rconv(i-D_INDIR))
}
goto brk
}
switch i {
default:
if a.Offset != 0 {
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(i))
} else {
str = fmt.Sprintf("%v", Rconv(i))
}
case D_NONE:
str = ""
case D_BRANCH:
if a.Sym != nil {
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
} else if p != nil && p.Pcond != nil {
str = fmt.Sprintf("%d", p.Pcond.Pc)
} else if a.U.Branch != nil {
str = fmt.Sprintf("%d", a.U.Branch.Pc)
} else {
str = fmt.Sprintf("%d(PC)", a.Offset)
}
case D_EXTERN:
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
case D_STATIC:
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
case D_AUTO:
if a.Sym != nil {
str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset)
} else {
str = fmt.Sprintf("%d(SP)", a.Offset)
}
case D_PARAM:
if a.Sym != nil {
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset)
} else {
str = fmt.Sprintf("%d(FP)", a.Offset)
}
case D_CONST:
str = fmt.Sprintf("$%d", a.Offset)
case D_FCONST:
str = fmt.Sprintf("$(%.17g)", a.U.Dval)
case D_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
case D_ADDR:
a.Type_ = int16(a.Index)
a.Index = D_NONE
str = fmt.Sprintf("$%v", Dconv(p, 0, a))
a.Index = uint8(a.Type_)
a.Type_ = D_ADDR
goto conv
}
brk:
if a.Index != D_NONE {
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
str += s
}
conv:
fp += str
return fp
}
var regstr = []string{
"AL", /* [D_AL] */
"CL",
"DL",
"BL",
"SPB",
"BPB",
"SIB",
"DIB",
"R8B",
"R9B",
"R10B",
"R11B",
"R12B",
"R13B",
"R14B",
"R15B",
"AX", /* [D_AX] */
"CX",
"DX",
"BX",
"SP",
"BP",
"SI",
"DI",
"R8",
"R9",
"R10",
"R11",
"R12",
"R13",
"R14",
"R15",
"AH",
"CH",
"DH",
"BH",
"F0", /* [D_F0] */
"F1",
"F2",
"F3",
"F4",
"F5",
"F6",
"F7",
"M0",
"M1",
"M2",
"M3",
"M4",
"M5",
"M6",
"M7",
"X0",
"X1",
"X2",
"X3",
"X4",
"X5",
"X6",
"X7",
"X8",
"X9",
"X10",
"X11",
"X12",
"X13",
"X14",
"X15",
"CS", /* [D_CS] */
"SS",
"DS",
"ES",
"FS",
"GS",
"GDTR", /* [D_GDTR] */
"IDTR", /* [D_IDTR] */
"LDTR", /* [D_LDTR] */
"MSW", /* [D_MSW] */
"TASK", /* [D_TASK] */
"CR0", /* [D_CR] */
"CR1",
"CR2",
"CR3",
"CR4",
"CR5",
"CR6",
"CR7",
"CR8",
"CR9",
"CR10",
"CR11",
"CR12",
"CR13",
"CR14",
"CR15",
"DR0", /* [D_DR] */
"DR1",
"DR2",
"DR3",
"DR4",
"DR5",
"DR6",
"DR7",
"TR0", /* [D_TR] */
"TR1",
"TR2",
"TR3",
"TR4",
"TR5",
"TR6",
"TR7",
"TLS", /* [D_TLS] */
"NONE", /* [D_NONE] */
}
func Rconv(r int) string {
var str string
var fp string
if r >= D_AL && r <= D_NONE {
str = fmt.Sprintf("%s", regstr[r-D_AL])
} else {
str = fmt.Sprintf("gok(%d)", r)
}
fp += str
return fp
}

File diff suppressed because it is too large Load diff

View file

@ -2,8 +2,15 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Dummy placeholder for the real obj package.
package x86
var Exported bool
const (
fmtLong = 1 << iota
)
func bool2int(b bool) int {
if b {
return 1
}
return 0
}