Commit 1fc330d8 authored by Russ Cox's avatar Russ Cox

[dev.cc] cmd/internal/obj: reconvert from liblink

cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.

- Brings in new, more regular Prog, Addr definitions

- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).

- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
  They need to be updated for the changes.

- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.

All architectures build successfully again.

Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963Reviewed-by: default avatarRob Pike <r@golang.org>
parent 8db173b8
// +build ignore
// 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.
......
// +build ignore
// 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.
......
// +build ignore
// Copyright 2014 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.
......
// +build ignore
// 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.
......
// +build ignore
// 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.
......
// +build ignore
// Copyright 2014 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.
......
......@@ -1678,7 +1678,7 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool,
// verifyAsm specifies whether to check the assemblers written in Go
// against the assemblers written in C. If set, asm will run both (say) 6a and new6a
// and fail if the two produce different output files.
const verifyAsm = false
const verifyAsm = true
func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
......@@ -1691,8 +1691,8 @@ func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
if verifyAsm {
newArgs := make([]interface{}, len(args))
copy(newArgs, args)
newArgs[0] = tool("new" + archChar + "a")
newArgs[2] = ofile + ".new" // x.6 becomes x.6.new
newArgs[1] = tool("new" + archChar + "a")
newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
return err
}
......@@ -1705,7 +1705,7 @@ func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
return err
}
if !bytes.Equal(data1, data2) {
return fmt.Errorf("%sa and n%sa produced different output files:\n%s\n%s", archChar, archChar, strings.Join(stringList(args...), " "), strings.Join(stringList(newArgs...), " "))
return fmt.Errorf("%sa and new%sa produced different output files:\n%s\n%s", archChar, archChar, strings.Join(stringList(args...), " "), strings.Join(stringList(newArgs...), " "))
}
}
return nil
......
......@@ -30,17 +30,7 @@
package arm
// list[5689].c
// obj.c
// objfile.c
// pass.c
// pcln.c
// sym.c
import "cmd/internal/obj"
// TODO(ality): remove this workaround.
// It's here because Pconv in liblink/list?.c references %L.
......@@ -57,18 +47,54 @@ const (
)
const (
REGRET = 0
REGEXT = 10
REG_R0 = 32 + iota
REG_R1
REG_R2
REG_R3
REG_R4
REG_R5
REG_R6
REG_R7
REG_R8
REG_R9
REG_R10
REG_R11
REG_R12
REG_R13
REG_R14
REG_R15
REG_F0
REG_F1
REG_F2
REG_F3
REG_F4
REG_F5
REG_F6
REG_F7
REG_F8
REG_F9
REG_F10
REG_F11
REG_F12
REG_F13
REG_F14
REG_F15
REG_FPSR
REG_FPCR
REG_CPSR
REG_SPSR
REGRET = REG_R0
REGEXT = REG_R10
REGG = REGEXT - 0
REGM = REGEXT - 1
REGTMP = 11
REGSP = 13
REGLINK = 14
REGPC = 15
REGTMP = REG_R11
REGSP = REG_R13
REGLINK = REG_R14
REGPC = REG_R15
NFREG = 16
FREGRET = 0
FREGEXT = 7
FREGTMP = 15
FREGRET = REG_F0
FREGEXT = REG_F7
FREGTMP = REG_F15
)
/* compiler allocates register variables F0 up */
......@@ -110,13 +136,13 @@ const (
C_SP
C_HREG
C_ADDR
C_TEXTSIZE
C_GOK
C_NCLASS
)
const (
AXXX = iota
AAND
AAND = obj.A_ARCHSPECIFIC + iota
AEOR
ASUB
ARSB
......@@ -131,8 +157,6 @@ const (
AORR
ABIC
AMVN
AB
ABL
ABEQ
ABNE
ABCS
......@@ -190,23 +214,12 @@ const (
AMOVM
ASWPBU
ASWPW
ANOP
ARFE
ASWI
AMULA
ADATA
AGLOBL
AGOK
AHISTORY
ANAME
ARET
ATEXT
AWORD
ADYNT_
AINIT_
ABCASE
ACASE
AEND
AMULL
AMULAL
AMULLU
......@@ -214,31 +227,22 @@ const (
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
AB = obj.AJMP
ABL = obj.ACALL
)
/* scond byte */
......@@ -249,56 +253,29 @@ const (
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
C_SCOND_XOR = 14
C_SCOND_EQ = 0 ^ C_SCOND_XOR
C_SCOND_NE = 1 ^ C_SCOND_XOR
C_SCOND_HS = 2 ^ C_SCOND_XOR
C_SCOND_LO = 3 ^ C_SCOND_XOR
C_SCOND_MI = 4 ^ C_SCOND_XOR
C_SCOND_PL = 5 ^ C_SCOND_XOR
C_SCOND_VS = 6 ^ C_SCOND_XOR
C_SCOND_VC = 7 ^ C_SCOND_XOR
C_SCOND_HI = 8 ^ C_SCOND_XOR
C_SCOND_LS = 9 ^ C_SCOND_XOR
C_SCOND_GE = 10 ^ C_SCOND_XOR
C_SCOND_LT = 11 ^ C_SCOND_XOR
C_SCOND_GT = 12 ^ C_SCOND_XOR
C_SCOND_LE = 13 ^ C_SCOND_XOR
C_SCOND_NONE = 14 ^ C_SCOND_XOR
C_SCOND_NV = 15 ^ C_SCOND_XOR
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
*/
......
package arm
var Anames = []string{
"XXX",
"AND",
"XXX ",
"CALL",
"CHECKNIL",
"DATA",
"DUFFCOPY",
"DUFFZERO",
"END",
"FUNCDATA",
"GLOBL",
"JMP",
"NOP",
"PCDATA",
"RET",
"TEXT",
"TYPE",
"UNDEF",
"USEFIELD",
"VARDEF",
"VARKILL",
"AND ",
"EOR",
"SUB",
"RSB",
......@@ -17,8 +35,6 @@ var Anames = []string{
"ORR",
"BIC",
"MVN",
"B",
"BL",
"BEQ",
"BNE",
"BCS",
......@@ -76,23 +92,12 @@ var Anames = []string{
"MOVM",
"SWPBU",
"SWPW",
"NOP",
"RFE",
"SWI",
"MULA",
"DATA",
"GLOBL",
"GOK",
"HISTORY",
"NAME",
"RET",
"TEXT",
"WORD",
"DYNT_",
"INIT_",
"BCASE",
"CASE",
"END",
"MULL",
"MULAL",
"MULLU",
......@@ -100,27 +105,16 @@ var Anames = []string{
"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",
......@@ -164,6 +158,7 @@ var cnames5 = []string{
"SP",
"HREG",
"ADDR",
"TEXTSIZE",
"GOK",
"NCLASS",
"SCOND = (1<<4)-1",
......@@ -172,25 +167,21 @@ var cnames5 = []string{
"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",
"SCOND_XOR = 14",
"SCOND_EQ = 0 ^ C_SCOND_XOR",
"SCOND_NE = 1 ^ C_SCOND_XOR",
"SCOND_HS = 2 ^ C_SCOND_XOR",
"SCOND_LO = 3 ^ C_SCOND_XOR",
"SCOND_MI = 4 ^ C_SCOND_XOR",
"SCOND_PL = 5 ^ C_SCOND_XOR",
"SCOND_VS = 6 ^ C_SCOND_XOR",
"SCOND_VC = 7 ^ C_SCOND_XOR",
"SCOND_HI = 8 ^ C_SCOND_XOR",
"SCOND_LS = 9 ^ C_SCOND_XOR",
"SCOND_GE = 10 ^ C_SCOND_XOR",
"SCOND_LT = 11 ^ C_SCOND_XOR",
"SCOND_GT = 12 ^ C_SCOND_XOR",
"SCOND_LE = 13 ^ C_SCOND_XOR",
"SCOND_NONE = 14 ^ C_SCOND_XOR",
"SCOND_NV = 15 ^ C_SCOND_XOR",
}
This diff is collapsed.
......@@ -70,7 +70,7 @@ func Pconv(p *obj.Prog) string {
a = int(p.As)
s = int(p.Scond)
sc = extra[s&C_SCOND]
sc = extra[(s&C_SCOND)^C_SCOND_XOR]
if s&C_SBIT != 0 {
sc += ".S"
}
......@@ -84,25 +84,21 @@ func Pconv(p *obj.Prog) string {
sc += ".U"
}
if a == AMOVM {
if p.From.Type == D_CONST {
if p.From.Type == obj.TYPE_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 {
} else if p.To.Type == obj.TYPE_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 {
} else if a == obj.ADATA {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
} else if p.As == obj.ATEXT {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
} else if p.Reg == 0 {
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))
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Rconv(int(p.Reg)), Dconv(p, 0, &p.To))
}
fp += str
......@@ -114,7 +110,7 @@ func Aconv(a int) string {
var fp string
s = "???"
if a >= AXXX && a < ALAST {
if a >= obj.AXXX && a < ALAST {
s = Anames[a]
}
fp += s
......@@ -132,63 +128,53 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
default:
str = fmt.Sprintf("GOK-type(%d)", a.Type)
case D_NONE:
case obj.TYPE_NONE:
str = ""
if a.Name != D_NONE || a.Reg != NREG || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(NONE)", Mconv(a), a.Reg)
if a.Name != obj.TYPE_NONE || a.Reg != 0 || a.Sym != nil {
str = fmt.Sprintf("%v(%v)(NONE)", Mconv(a), Rconv(int(a.Reg)))
}
case D_CONST:
if a.Reg != NREG {
str = fmt.Sprintf("$%v(R%d)", Mconv(a), a.Reg)
case obj.TYPE_CONST,
obj.TYPE_ADDR:
if a.Reg != 0 {
str = fmt.Sprintf("$%v(%v)", Mconv(a), Rconv(int(a.Reg)))
} else {
str = fmt.Sprintf("$%v", Mconv(a))
}
case D_CONST2:
str = fmt.Sprintf("$%d-%d", a.Offset, a.Offset2)
case obj.TYPE_TEXTSIZE:
if a.U.Argsize == obj.ArgsSizeUnknown {
str = fmt.Sprintf("$%d", a.Offset)
} else {
str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize)
}
case D_SHIFT:
case obj.TYPE_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)
if a.Reg != 0 {
str += fmt.Sprintf("(%v)", Rconv(int(a.Reg)))
}
case D_OREG:
if a.Reg != NREG {
str = fmt.Sprintf("%v(R%d)", Mconv(a), a.Reg)
case obj.TYPE_MEM:
if a.Reg != 0 {
str = fmt.Sprintf("%v(%v)", Mconv(a), Rconv(int(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 obj.TYPE_REG:
str = fmt.Sprintf("%v", Rconv(int(a.Reg)))
if a.Name != obj.TYPE_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(%v)(REG)", Mconv(a), Rconv(int(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:
case obj.TYPE_BRANCH:
if a.Sym != nil {
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
} else if p != nil && p.Pcond != nil {
......@@ -196,14 +182,13 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
} 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:
case obj.TYPE_FCONST:
str = fmt.Sprintf("$%.17g", a.U.Dval)
case D_SCONST:
case obj.TYPE_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
break
}
......@@ -221,9 +206,8 @@ func RAconv(a *obj.Addr) string {
str = fmt.Sprintf("GOK-reglist")
switch a.Type {
case D_CONST,
D_CONST2:
if a.Reg != NREG {
case obj.TYPE_CONST:
if a.Reg != 0 {
break
}
if a.Sym != nil {
......@@ -233,10 +217,9 @@ func RAconv(a *obj.Addr) string {
str = ""
for i = 0; i < NREG; i++ {
if v&(1<<uint(i)) != 0 {
if str[0] == 0 {
if str == "" {
str += "[R"
} else {
str += ",R"
}
str += fmt.Sprintf("%d", i)
......@@ -253,10 +236,38 @@ func RAconv(a *obj.Addr) string {
func Rconv(r int) string {
var fp string
var str string
if r == 0 {
fp += "NONE"
return fp
}
if REG_R0 <= r && r <= REG_R15 {
fp += fmt.Sprintf("R%d", r-REG_R0)
return fp
}
if REG_F0 <= r && r <= REG_F15 {
fp += fmt.Sprintf("F%d", r-REG_F0)
return fp
}
str = fmt.Sprintf("R%d", r)
fp += str
switch r {
case REG_FPSR:
fp += "FPSR"
return fp
case REG_FPCR:
fp += "FPCR"
return fp
case REG_CPSR:
fp += "CPSR"
return fp
case REG_SPSR:
fp += "SPSR"
return fp
}
fp += fmt.Sprintf("badreg(%d)", r)
return fp
}
......@@ -288,19 +299,19 @@ func Mconv(a *obj.Addr) string {
default:
str = fmt.Sprintf("GOK-name(%d)", a.Name)
case D_NONE:
case obj.NAME_NONE:
str = fmt.Sprintf("%d", a.Offset)
case D_EXTERN:
case obj.NAME_EXTERN:
str = fmt.Sprintf("%s+%d(SB)", s.Name, int(a.Offset))
case D_STATIC:
case obj.NAME_STATIC:
str = fmt.Sprintf("%s<>+%d(SB)", s.Name, int(a.Offset))
case D_AUTO:
case obj.NAME_AUTO:
str = fmt.Sprintf("%s-%d(SP)", s.Name, int(-a.Offset))
case D_PARAM:
case obj.NAME_PARAM:
str = fmt.Sprintf("%s+%d(FP)", s.Name, int(a.Offset))
break
}
......
This diff is collapsed.
......@@ -37,7 +37,6 @@ import (
)
func mangle(file string) {
log.Fatalf("%s: mangled input file", file)
}
......@@ -58,7 +57,7 @@ func Symgrow(ctxt *Link, s *LSym, lsiz int64) {
func savedata(ctxt *Link, s *LSym, p *Prog, pn string) {
off := int32(p.From.Offset)
siz := int32(ctxt.Arch.Datasize(p))
siz := int32(p.From3.Offset)
if off < 0 || siz < 0 || off >= 1<<30 || siz >= 100 {
mangle(pn)
}
......@@ -71,7 +70,7 @@ func savedata(ctxt *Link, s *LSym, p *Prog, pn string) {
default:
ctxt.Diag("bad data: %P", p)
case ctxt.Arch.D_FCONST:
case TYPE_FCONST:
switch siz {
default:
ctxt.Diag("unexpected %d-byte floating point constant", siz)
......@@ -85,11 +84,11 @@ func savedata(ctxt *Link, s *LSym, p *Prog, pn string) {
ctxt.Arch.ByteOrder.PutUint64(s.P[off:], flt)
}
case ctxt.Arch.D_SCONST:
case TYPE_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 {
case TYPE_CONST, TYPE_ADDR:
if p.To.Sym != nil || int(p.To.Type) == TYPE_ADDR {
r := Addrel(s)
r.Off = off
r.Siz = uint8(siz)
......@@ -119,7 +118,7 @@ func Addrel(s *LSym) *Reloc {
return &s.R[len(s.R)-1]
}
func setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 {
func Setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 {
if s.Type == 0 {
s.Type = SDATA
}
......@@ -147,7 +146,7 @@ func adduintxx(ctxt *Link, s *LSym, v uint64, wid int) int64 {
var off int64
off = s.Size
setuintxx(ctxt, s, off, v, int64(wid))
Setuintxx(ctxt, s, off, v, int64(wid))
return off
}
......@@ -168,19 +167,19 @@ func Adduint64(ctxt *Link, s *LSym, v uint64) int64 {
}
func setuint8(ctxt *Link, s *LSym, r int64, v uint8) int64 {
return setuintxx(ctxt, s, r, uint64(v), 1)
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)
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)
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)
return Setuintxx(ctxt, s, r, v, 8)
}
func addaddrplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
......
// cmd/9l/noop.c, cmd/9l/pass.c, cmd/9l/span.c from Vita Nuova.
// 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-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
// 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-2008 Lucent Technologies Inc. and others
// 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
......@@ -74,5 +75,5 @@ const (
FUNCDATA_ArgsPointerMaps = 0
FUNCDATA_LocalsPointerMaps = 1
FUNCDATA_DeadValueMaps = 2
ArgsSizeUnknown = 0x80000000
ArgsSizeUnknown = -0x80000000
)
......@@ -5,12 +5,75 @@
package obj
import (
"fmt"
"math"
"os"
"strings"
)
// go-specific code shared across loaders (5l, 6l, 8l).
var Framepointer_enabled int
var fieldtrack_enabled int
var Zprog Prog
// Toolchain experiments.
// These are controlled by the GOEXPERIMENT environment
// variable recorded when the toolchain is built.
// This list is also known to cmd/gc.
var exper = []struct {
name string
val *int
}{
struct {
name string
val *int
}{"fieldtrack", &fieldtrack_enabled},
struct {
name string
val *int
}{"framepointer", &Framepointer_enabled},
}
func addexp(s string) {
var i int
for i = 0; i < len(exper); i++ {
if exper[i].name == s {
if exper[i].val != nil {
*exper[i].val = 1
}
return
}
}
fmt.Printf("unknown experiment %s\n", s)
os.Exit(2)
}
func linksetexp() {
for _, f := range strings.Split(goexperiment, ",") {
if f != "" {
addexp(f)
}
}
}
func expstring() string {
buf := "X"
for i := range exper {
if *exper[i].val != 0 {
buf += "," + exper[i].name
}
}
if buf == "X" {
buf += ",none"
}
return "X:" + buf[2:]
}
// replace all "". with pkg.
func expandpkg(t0 string, pkg string) string {
return strings.Replace(t0, `"".`, pkg+".", -1)
......
......@@ -30,9 +30,10 @@
package i386
import "cmd/internal/obj"
const (
AXXX = iota
AAAA
AAAA = obj.A_ARCHSPECIFIC + iota
AAAD
AAAM
AAAS
......@@ -62,7 +63,6 @@ const (
ABTSL
ABTSW
ABYTE
ACALL
ACLC
ACLD
ACLI
......@@ -76,7 +76,6 @@ const (
ACMPSW
ADAA
ADAS
ADATA
ADECB
ADECL
ADECW
......@@ -84,9 +83,6 @@ const (
ADIVL
ADIVW
AENTER
AGLOBL
AGOK
AHISTORY
AHLT
AIDIVB
AIDIVL
......@@ -119,7 +115,6 @@ const (
AJLS
AJLT
AJMI
AJMP
AJNE
AJOC
AJOS
......@@ -159,11 +154,9 @@ const (
AMULB
AMULL
AMULW
ANAME
ANEGB
ANEGL
ANEGW
ANOP
ANOTB
ANOTL
ANOTW
......@@ -197,7 +190,6 @@ const (
ARCRW
AREP
AREPN
ARET
AROLB
AROLL
AROLW
......@@ -254,7 +246,6 @@ const (
ATESTB
ATESTL
ATESTW
ATEXT
AVERR
AVERW
AWAIT
......@@ -367,10 +358,6 @@ const (
AFXTRACT
AFYL2X
AFYL2XP1
AEND
ADYNT_
AINIT_
ASIGNAME
ACMPXCHGB
ACMPXCHGL
ACMPXCHGW
......@@ -429,7 +416,6 @@ const (
APREFETCHT2
APREFETCHNTA
ABSWAPL
AUNDEF
AADDPD
AADDPS
AADDSD
......@@ -544,73 +530,53 @@ const (
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
REG_NONE = 0
REG_AL = 0 + 16 + iota - 1
REG_CL
REG_DL
REG_BL
REG_AH = 4 + 16 + iota - 5
REG_CH
REG_DH
REG_BH
REG_AX = 8 + 16 + iota - 9
REG_CX
REG_DX
REG_BX
REG_SP
REG_BP
REG_SI
REG_DI
REG_F0 = 16 + 16
REG_F7 = REG_F0 + 7 + 16
REG_CS = 24 + 16 + iota - 19
REG_SS
REG_DS
REG_ES
REG_FS
REG_GS
REG_GDTR
REG_IDTR
REG_LDTR
REG_MSW
REG_TASK
REG_CR = 35 + 16
REG_DR = 43 + 16
REG_TR = 51 + 16
REG_X0 = 59 + 16 + iota - 33
REG_X1
REG_X2
REG_X3
REG_X4
REG_X5
REG_X6
REG_X7
REG_TLS = 67 + 16
MAXREG = 68 + 16
T_TYPE = 1 << 0
T_INDEX = 1 << 1
T_OFFSET = 1 << 2
......@@ -620,8 +586,8 @@ const (
T_OFFSET2 = 1 << 6
T_GOTYPE = 1 << 7
REGARG = -1
REGRET = D_AX
FREGRET = D_F0
REGSP = D_SP
REGTMP = D_DI
REGRET = REG_AX
FREGRET = REG_F0
REGSP = REG_SP
REGTMP = REG_DI
)
......@@ -4,8 +4,26 @@ package i386
* this is the ranlib header
*/
var Anames = []string{
"XXX",
"AAA",
"XXX ",
"CALL",
"CHECKNIL",
"DATA",
"DUFFCOPY",
"DUFFZERO",
"END",
"FUNCDATA",
"GLOBL",
"JMP",
"NOP",
"PCDATA",
"RET",
"TEXT",
"TYPE",
"UNDEF",
"USEFIELD",
"VARDEF",
"VARKILL",
"AAA ",
"AAD",
"AAM",
"AAS",
......@@ -35,7 +53,6 @@ var Anames = []string{
"BTSL",
"BTSW",
"BYTE",
"CALL",
"CLC",
"CLD",
"CLI",
......@@ -49,7 +66,6 @@ var Anames = []string{
"CMPSW",
"DAA",
"DAS",
"DATA",
"DECB",
"DECL",
"DECW",
......@@ -57,9 +73,6 @@ var Anames = []string{
"DIVL",
"DIVW",
"ENTER",
"GLOBL",
"GOK",
"HISTORY",
"HLT",
"IDIVB",
"IDIVL",
......@@ -92,7 +105,6 @@ var Anames = []string{
"JLS",
"JLT",
"JMI",
"JMP",
"JNE",
"JOC",
"JOS",
......@@ -132,11 +144,9 @@ var Anames = []string{
"MULB",
"MULL",
"MULW",
"NAME",
"NEGB",
"NEGL",
"NEGW",
"NOP",
"NOTB",
"NOTL",
"NOTW",
......@@ -170,7 +180,6 @@ var Anames = []string{
"RCRW",
"REP",
"REPN",
"RET",
"ROLB",
"ROLL",
"ROLW",
......@@ -227,7 +236,6 @@ var Anames = []string{
"TESTB",
"TESTL",
"TESTW",
"TEXT",
"VERR",
"VERW",
"WAIT",
......@@ -340,10 +348,6 @@ var Anames = []string{
"FXTRACT",
"FYL2X",
"FYL2XP1",
"END",
"DYNT_",
"INIT_",
"SIGNAME",
"CMPXCHGB",
"CMPXCHGL",
"CMPXCHGW",
......@@ -402,7 +406,6 @@ var Anames = []string{
"PREFETCHT2",
"PREFETCHNTA",
"BSWAPL",
"UNDEF",
"ADDPD",
"ADDPS",
"ADDSD",
......@@ -517,68 +520,5 @@ var Anames = []string{
"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",
}
This diff is collapsed.
......@@ -46,16 +46,16 @@ func Pconv(p *obj.Prog) 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 obj.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.From3.Offset, 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))
case obj.ATEXT:
if p.From3.Offset != 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.From3.Offset, Dconv(p, 0, &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))
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))
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))
......@@ -78,45 +78,34 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) 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))
}
switch a.Type {
default:
str = fmt.Sprintf("type=%d", a.Type)
goto brk
}
case obj.TYPE_NONE:
str = ""
if i >= D_INDIR {
// TODO(rsc): This special case is for instructions like
// PINSRQ CX,$1,X6
// where the $1 is included in the p->to Addr.
// Move into a new field.
case obj.TYPE_REG:
if a.Offset != 0 {
str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(i-D_INDIR))
} else {
str = fmt.Sprintf("(%v)", Rconv(i-D_INDIR))
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(int(a.Reg)))
break
}
goto brk
}
switch i {
default:
if a.Offset != 0 {
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(i))
} else {
str = fmt.Sprintf("%v", Rconv(int(a.Reg)))
str = fmt.Sprintf("%v", Rconv(i))
// TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
// SHRQ $32(DX*0), AX
// Remove.
if a.Index != REG_NONE {
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
str += s
}
case D_NONE:
str = ""
case D_BRANCH:
case obj.TYPE_BRANCH:
if a.Sym != nil {
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
} else if p != nil && p.Pcond != nil {
......@@ -124,69 +113,85 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
} 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 obj.TYPE_MEM:
switch a.Name {
default:
str = fmt.Sprintf("name=%d", a.Name)
case obj.NAME_NONE:
if a.Offset != 0 {
str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(int(a.Reg)))
} else {
str = fmt.Sprintf("(%v)", Rconv(int(a.Reg)))
}
case obj.NAME_EXTERN:
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
case obj.NAME_STATIC:
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
case obj.NAME_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 obj.NAME_PARAM:
if a.Sym != nil {
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset)
} else {
str = fmt.Sprintf("%d(FP)", a.Offset)
}
break
}
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)
if a.Index != REG_NONE {
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
str += s
}
case D_CONST:
case obj.TYPE_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)
// TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
// SHRQ $32(DX*0), AX
// Remove.
if a.Index != REG_NONE {
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
str += s
}
case D_FCONST:
case obj.TYPE_TEXTSIZE:
if a.U.Argsize == obj.ArgsSizeUnknown {
str = fmt.Sprintf("$%d", a.Offset)
} else {
str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize)
}
case obj.TYPE_FCONST:
str = fmt.Sprintf("$(%.17g)", a.U.Dval)
case D_SCONST:
case obj.TYPE_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
case D_ADDR:
a.Type = int16(a.Index)
a.Index = D_NONE
case obj.TYPE_ADDR:
a.Type = obj.TYPE_MEM
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
a.Type = obj.TYPE_ADDR
break
}
conv:
fp += str
return fp
}
var Register = []string{
"AL", /* [D_AL] */
"AL", /* [REG_AL] */
"CL",
"DL",
"BL",
......@@ -194,7 +199,7 @@ var Register = []string{
"CH",
"DH",
"BH",
"AX", /* [D_AX] */
"AX", /* [REG_AX] */
"CX",
"DX",
"BX",
......@@ -202,7 +207,7 @@ var Register = []string{
"BP",
"SI",
"DI",
"F0", /* [D_F0] */
"F0", /* [REG_F0] */
"F1",
"F2",
"F3",
......@@ -210,18 +215,18 @@ var Register = []string{
"F5",
"F6",
"F7",
"CS", /* [D_CS] */
"CS", /* [REG_CS] */
"SS",
"DS",
"ES",
"FS",
"GS",
"GDTR", /* [D_GDTR] */
"IDTR", /* [D_IDTR] */
"LDTR", /* [D_LDTR] */
"MSW", /* [D_MSW] */
"TASK", /* [D_TASK] */
"CR0", /* [D_CR] */
"GDTR", /* [REG_GDTR] */
"IDTR", /* [REG_IDTR] */
"LDTR", /* [REG_LDTR] */
"MSW", /* [REG_MSW] */
"TASK", /* [REG_TASK] */
"CR0", /* [REG_CR] */
"CR1",
"CR2",
"CR3",
......@@ -229,7 +234,7 @@ var Register = []string{
"CR5",
"CR6",
"CR7",
"DR0", /* [D_DR] */
"DR0", /* [REG_DR] */
"DR1",
"DR2",
"DR3",
......@@ -237,7 +242,7 @@ var Register = []string{
"DR5",
"DR6",
"DR7",
"TR0", /* [D_TR] */
"TR0", /* [REG_TR] */
"TR1",
"TR2",
"TR3",
......@@ -245,7 +250,7 @@ var Register = []string{
"TR5",
"TR6",
"TR7",
"X0", /* [D_X0] */
"X0", /* [REG_X0] */
"X1",
"X2",
"X3",
......@@ -253,18 +258,21 @@ var Register = []string{
"X5",
"X6",
"X7",
"TLS", /* [D_TLS] */
"NONE", /* [D_NONE] */
"TLS", /* [REG_TLS] */
"MAXREG", /* [MAXREG] */
}
func Rconv(r int) string {
var str string
var fp string
if r >= D_AL && r <= D_NONE {
str = fmt.Sprintf("%s", Register[r-D_AL])
if r == REG_NONE {
fp += "NONE"
return fp
}
if r >= REG_AL && r-REG_AL < len(Register) {
str = fmt.Sprintf("%s", Register[r-REG_AL])
} else {
str = fmt.Sprintf("gok(%d)", r)
}
......
This diff is collapsed.
......@@ -116,7 +116,6 @@ func mkfwd(sym *LSym) {
if i == 0 {
cnt[i] = 1
} else {
cnt[i] = LOG * cnt[i-1]
}
dwn[i] = 1
......
This diff is collapsed.
......@@ -15,7 +15,7 @@ const (
NSYM = 50
)
func linklinefmt(ctxt *Link, lno0 int, showAll, showFullPath bool) string {
func Linklinefmt(ctxt *Link, lno0 int, showAll, showFullPath bool) string {
var a [HISTSZ]struct {
incl *Hist
idel int32
......@@ -222,11 +222,9 @@ func Linklinehist(ctxt *Link, lineno int, f string, offset int) {
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)
}
}
......@@ -297,7 +295,6 @@ func Linkprfile(ctxt *Link, line int) {
* start a new Prog list.
*/
func Linknewplist(ctxt *Link) *Plist {
var pl *Plist
pl = new(Plist)
......@@ -305,7 +302,6 @@ func Linknewplist(ctxt *Link) *Plist {
if ctxt.Plist == nil {
ctxt.Plist = pl
} else {
ctxt.Plast.Link = pl
}
ctxt.Plast = pl
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment