New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/objdump: symbolization of global variable doesn't work for shared objects #24712

Open
cherrymui opened this Issue Apr 5, 2018 · 4 comments

Comments

Projects
None yet
4 participants
@cherrymui
Contributor

cherrymui commented Apr 5, 2018

What operating system and processor architecture are you using (go env)?

darwin/amd64

What did you do?

package main

var X int

//go:noinline
func F() { X = 5 }

func main() { F() }
$ go build p
$ go tool objdump -s "\.F$" p 
TEXT main.F(SB) /tmp/p2/src/p/p.go
  p.go:6		0x104b3a0		48c7050553070005000000	MOVQ $0x5, main.X(SB)	
  p.go:6		0x104b3ab		c3			RET			
  :-1			0x104b3ac		cc			INT $0x3		
  :-1			0x104b3ad		cc			INT $0x3		
  :-1			0x104b3ae		cc			INT $0x3		
  :-1			0x104b3af		cc			INT $0x3

The address of global variable is symbolized (main.X(SB)), which is nice.

But this is not correct for shared objects, e.g. plugin:

$ go build -buildmode=plugin p
$ go tool objdump -s "\.F$" p.so 
TEXT _p.F(SB) /tmp/p2/src/p/p.go
  p.go:6		0x44670			4c8b3dc1090000		MOVQ __cgo_yield+200(SB), R15	
  p.go:6		0x44677			49c70705000000		MOVQ $0x5, 0(R15)		
  p.go:6		0x4467e			c3			RET				
  :-1			0x4467f			cc			INT $0x3

Note the __cgo_yield+200(SB), which should actually be X in the GOT, like what compile -S prints

	0x0000 00000 (/tmp/p2/src/p/p.go:6)	MOVQ	"".X@GOT(SB), R15
	0x0007 00007 (/tmp/p2/src/p/p.go:6)	MOVQ	$5, (R15)

cc @aarzilli

@bcmills bcmills added this to the Go1.11 milestone Apr 6, 2018

@aarzilli

This comment has been minimized.

Contributor

aarzilli commented Apr 13, 2018

On linux the issue looks slightly different:

$ go tool objdump -s "\.F$" ./plugintest.so
TEXT plugin/unnamed-4036773a44b691436565e34d67d3eba243fd5a0e.F(SB) 
  :0			0xa01a0			4c8b3d69982500		MOVQ 0x259869(IP), R15	
  :0			0xa01a7			49c70705000000		MOVQ $0x5, 0(R15)	
  :0			0xa01ae			c3			RET			

TEXT local.plugin/unnamed-4036773a44b691436565e34d67d3eba243fd5a0e.F(SB) 
  :0			0xa01a0			4c8b3d69982500		MOVQ 0x259869(IP), R15	
  :0			0xa01a7			49c70705000000		MOVQ $0x5, 0(R15)	
  :0			0xa01ae			c3			RET			

I don't know what's going on on darwin, but on linux the address isn't identified as the GLOBAL_OFFSET_TABLE because the size of the GLOBAL_OFFSET_TABLE symbol is zero. Also I don't know if there is a way to recover the original name of a GOT slot.

@cherrymui

This comment has been minimized.

Contributor

cherrymui commented Apr 13, 2018

Thanks for looking into it.

I haven't looked into the detail about the names in GOT, but apparently Mac otool can tell the name:

_p.F:
0000000000044710        movq    0x921(%rip), %r15 ## literal pool symbol address: _p.X
0000000000044717        movq    $0x5, (%r15)
000000000004471e        retq
000000000004471f        int3

Linux objdump also kind of knows, with an offset which I don't yet understand:

00000000000a1b30 <p.F>:
   a1b30:       4c 8b 3d 79 c1 25 00    mov    0x25c179(%rip),%r15        # 2fdcb0 <p.X@@Base-0x1ec80>
   a1b37:       49 c7 07 05 00 00 00    movq   $0x5,(%r15)
   a1b3e:       c3                      retq   
   a1b3f:       cc                      int3   

So I guess there is a way to tell (but I haven't looked into it).

@aarzilli

This comment has been minimized.

Contributor

aarzilli commented Apr 13, 2018

Linux objdump also kind of knows, with an offset which I don't yet understand:

Weird, that's not what it prints for me...

@ianlancetaylor ianlancetaylor modified the milestones: Go1.11, Go1.12 Jun 14, 2018

@ianlancetaylor

This comment has been minimized.

Contributor

ianlancetaylor commented Dec 10, 2018

Likely related to #17883.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment