Skip to content
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/cgo: stdcall import names are not undecorated and conflict with symbol versioning #4607

Closed
james4k opened this issue Jan 2, 2013 · 7 comments
Milestone

Comments

@james4k
Copy link
Contributor

james4k commented Jan 2, 2013

Windows, MinGW. go1 and tip.

When using cgo to call a __stdcall decorated function that is dynamically imported,
cmd/ld gives a "funcname(0): not defined" message. This happens because the
import name is decorated with the argument size (funcname@0).

So the dynimport looks like:
#pragma dynimport funcname@0 funcname@0 libname.dll

The first issue is that it, from my understanding, it should look like:
#pragma dynimport funcname funcname@0 libname.dll

The second issue is that cgo uses the @ character here for symbol versioning in ELF, and
the decorator gets stripped from the symbol.

I have attached a .zip file with a minimal library and a .go file to reproduce this.
Just extract somewhere in $GOPATH/src and run make.bat, as long as you have MinGW setup.

I do believe a probable fix would be simple. The symbol version delimiter would be
changed to a '#' or another character, and the decorator for imported symbols in pe
objects for the first dynimport argument would be stripped. I will put together a CL for
review sometime soon. Initial testing of this seems to be promising, but my
understanding of how cgo, ld, etc. works is limited so I could definitely be doing this
wrong.

Discussion: https://groups.google.com/d/topic/golang-dev/Lf1H_3jbQgw/discussion

Attachments:

  1. cgostdcall.zip (1316 bytes)
@james4k
Copy link
Contributor Author

james4k commented Jan 3, 2013

Comment 1:

I guess the real question is: is this actually an issue, or am I just 'doing it wrong'?
:)

@minux
Copy link
Member

minux commented Jan 3, 2013

Comment 2:

IMO, we can't change symbol version delimiter to a '#', because it will
break ELF based systems.
just fixing cmd/cgo to emit
#pragma dynimport funcname funcname@0 libname.dll
on windows seems correct to me.

Labels changed: added priority-later, removed priority-triage.

Status changed to Accepted.

@james4k
Copy link
Contributor Author

james4k commented Jan 3, 2013

Comment 3:

I don't think it will break on ELF based systems, because the delimiter is handled
purely by cmd/cgo and cmd/ld. Just changing cmd/cgo is not enough, because the version
is parsed and stripped from dynimports for everyone including PE. Perhaps there would be
a way to only do this for ELF, though.

@james4k
Copy link
Contributor Author

james4k commented Jan 3, 2013

Comment 4:

See here, where the delimiter is handled from cgo's dynimport output:
http://code.google.com/p/go/source/browse/src/cmd/ld/go.c#509

@james4k
Copy link
Contributor Author

james4k commented Jan 3, 2013

Comment 5:

https://golang.org/cl/7047043/

@minux
Copy link
Member

minux commented Jan 3, 2013

Comment 6:

sure. you can mail that CL out.

Status changed to Started.

@rsc
Copy link
Contributor

rsc commented Jan 30, 2013

Comment 7:

This issue was closed by revision dab268f.

Status changed to Fixed.

@rsc rsc added this to the Go1.1 milestone Apr 14, 2015
@rsc rsc removed the go1.1 label Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants