func nacladdr(ctxt *liblink.Link, p *liblink.Prog, a *liblink.Addr) { if p.As == ALEAL || p.As == ALEAQ { return } if a.Typ == D_BP || a.Typ == D_INDIR+D_BP { ctxt.Diag("invalid address: %P", p) return } if a.Typ == D_INDIR+D_TLS { a.Typ = D_INDIR + D_BP } else if a.Typ == D_TLS { a.Typ = D_BP } if D_INDIR <= a.Typ && a.Typ <= D_INDIR+D_INDIR { switch a.Typ { // all ok case D_INDIR + D_BP, D_INDIR + D_SP, D_INDIR + D_R15: break default: if a.Index != D_NONE { ctxt.Diag("invalid address %P", p) } a.Index = a.Typ - D_INDIR if a.Index != D_NONE { a.Scale = 1 } a.Typ = D_INDIR + D_R15 break } } }
func Dconv(p *liblink.Prog, flag int, a *liblink.Addr) string { var str string var s string var fp string var i int i = a.Typ 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.Typ = a.Index a.Index = D_NONE str = fmt.Sprintf("$%v", Dconv(p, 0, a)) a.Index = a.Typ a.Typ = 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 }
func readaddr(b *bufio.Reader, a *liblink.Addr) { if rdstring(b) != "addr" { log.Fatal("out of sync") } a.Offset = rdint(b) a.U.Dval = rdfloat(b) buf := make([]byte, 8) for i := 0; i < 8; i++ { buf[i] = byte(rdint(b)) } a.U.Sval = string(buf) a.U.Branch = rdprog(b) a.Sym = rdsym(b) a.Gotype = rdsym(b) a.Typ = int(rdint(b)) a.Index = int(rdint(b)) a.Scale = int8(rdint(b)) a.Reg = int(rdint(b)) a.Name = int(rdint(b)) a.Class = int(rdint(b)) a.Etype = uint8(rdint(b)) a.Offset2 = int(rdint(b)) a.Width = rdint(b) }