x86: use symname also for IP-relative arguments

Change-Id: Ic291e8b284290f29dd586415a873fbf90bafcac9
Reviewed-on: https://go-review.googlesource.com/45099
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/x86/x86asm/format_test.go b/x86/x86asm/format_test.go
index 2750a28..9f110f8 100644
--- a/x86/x86asm/format_test.go
+++ b/x86/x86asm/format_test.go
@@ -13,6 +13,8 @@
 	switch addr {
 	case 0x424080:
 		return "runtime.printint", 0x424080
+	case 0x4c8068:
+		return "main.A", 0x4c8068
 	}
 	return "", 0
 }
@@ -33,9 +35,9 @@
 			"mov rax, qword ptr [rsp+0x8]",
 			"mov 0x8(%rsp),%rax"},
 		{0x450678, "488b05e9790700",
-			"MOVQ 0x779e9(IP), AX",
-			"mov rax, qword ptr [rip+0x779e9]",
-			"mov 0x779e9(%rip),%rax"},
+			"MOVQ main.A(SB), AX",
+			"mov rax, qword ptr [main.A]",
+			"mov main.A,%rax"},
 		{0x450664, "e8173afdff",
 			"CALL runtime.printint(SB)",
 			"call runtime.printint",
diff --git a/x86/x86asm/gnu.go b/x86/x86asm/gnu.go
index 5bb54df..75cff72 100644
--- a/x86/x86asm/gnu.go
+++ b/x86/x86asm/gnu.go
@@ -539,6 +539,13 @@
 		}
 		return gccRegName[x]
 	case Mem:
+		if s, disp := memArgToSymbol(x, pc, inst.Len, symname); s != "" {
+			suffix := ""
+			if disp != 0 {
+				suffix = fmt.Sprintf("%+d", disp)
+			}
+			return fmt.Sprintf("%s%s", s, suffix)
+		}
 		seg := ""
 		var haveCS, haveDS, haveES, haveFS, haveGS, haveSS bool
 		switch x.Segment {
diff --git a/x86/x86asm/intel.go b/x86/x86asm/intel.go
index 4c32d9d..472eabd 100644
--- a/x86/x86asm/intel.go
+++ b/x86/x86asm/intel.go
@@ -428,6 +428,13 @@
 		}
 
 		prefix += "ptr "
+		if s, disp := memArgToSymbol(a, pc, inst.Len, symname); s != "" {
+			suffix := ""
+			if disp != 0 {
+				suffix = fmt.Sprintf("%+d", disp)
+			}
+			return prefix + fmt.Sprintf("[%s%s]", s, suffix)
+		}
 		if a.Segment != 0 {
 			prefix += strings.ToLower(a.Segment.String()) + ":"
 		}
diff --git a/x86/x86asm/plan9x.go b/x86/x86asm/plan9x.go
index d5cf614..a93bffd 100644
--- a/x86/x86asm/plan9x.go
+++ b/x86/x86asm/plan9x.go
@@ -121,14 +121,12 @@
 		}
 		return fmt.Sprintf("$%#x", uint64(a))
 	case Mem:
-		if a.Segment == 0 && a.Disp != 0 && a.Base == 0 && (a.Index == 0 || a.Scale == 0) {
-			if s, base := symname(uint64(a.Disp)); s != "" {
-				suffix := ""
-				if uint64(a.Disp) != base {
-					suffix = fmt.Sprintf("%+d", uint64(a.Disp)-base)
-				}
-				return fmt.Sprintf("%s%s(SB)", s, suffix)
+		if s, disp := memArgToSymbol(a, pc, inst.Len, symname); s != "" {
+			suffix := ""
+			if disp != 0 {
+				suffix = fmt.Sprintf("%+d", disp)
 			}
+			return fmt.Sprintf("%s%s(SB)", s, suffix)
 		}
 		s := ""
 		if a.Segment != 0 {
@@ -150,6 +148,25 @@
 	return arg.String()
 }
 
+func memArgToSymbol(a Mem, pc uint64, instrLen int, symname SymLookup) (string, int64) {
+	if a.Segment != 0 || a.Disp == 0 || a.Index != 0 || a.Scale != 0 {
+		return "", 0
+	}
+
+	var disp uint64
+	switch a.Base {
+	case IP, EIP, RIP:
+		disp = uint64(a.Disp + int64(pc) + int64(instrLen))
+	case 0:
+		disp = uint64(a.Disp)
+	default:
+		return "", 0
+	}
+
+	s, base := symname(disp)
+	return s, int64(disp) - int64(base)
+}
+
 var plan9Suffix = [maxOp + 1]bool{
 	ADC:       true,
 	ADD:       true,