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/link: PPC ELF symbol tables incorrectly report function prologue when not using -shared #20290

ianlancetaylor opened this issue May 9, 2017 · 2 comments


Copy link

@ianlancetaylor ianlancetaylor commented May 9, 2017

In cmd/link/internal/ld/symtab.go we see this code:

	if (Buildmode == BuildmodeCArchive || Buildmode == BuildmodePIE || ctxt.DynlinkingGo()) && SysArch.Family == sys.PPC64 && typ == STT_FUNC && x.Name != "runtime.duffzero" && x.Name != "runtime.duffcopy" {
		// On ppc64 the top three bits of the st_other field indicate how
		// many instructions separate the global and local entry points. In
		// our case it is two instructions, indicated by the value 3.
		other |= 3 << 5

This is correct provided that we do in fact separate the global and local entry points by two instructions. Those two instructions are added at compilation time by code in the function preprocess in cmd/internal/obj/ppc64/obj9.go, under these conditions:

	if c.ctxt.Flag_shared && c.cursym.Name != "runtime.duffzero" && c.cursym.Name != "runtime.duffcopy" {

So everything should work out provided that whenever we link with -buildmode=c-archive we compile all the input files with -shared. If we compile the input files without -shared, and then put the results into an archive with -buildmode=c-archive, the symbol table will report that there is a two instruction prologue when, in fact, there is not. Of course the resulting code will not work if put into a shared library, but that is expected since it was compiled without -shared.

When using the go tool, this does not happen, as using -buildmode=c-archive implies passing -shared to the compiler (see BuildModeInit in cmd/go/internal/work/build.go). But when building Go in some other way this actually can come up. In particular it can come up when building with Bazel (, or, at least, it can once Bazel start properly supporting building Go archives.

If we want to preserve the distinction between compiling in shared mode and not, which at least for the moment I think we do for efficiency reasons, then we need to fix the linker to put the correct number in the symbol table st_other field when describing a symbol compiled without -shared.

CC @mwhudson

@ianlancetaylor ianlancetaylor added this to the Go1.9Maybe milestone May 9, 2017
@ianlancetaylor ianlancetaylor self-assigned this May 9, 2017
Copy link

@gopherbot gopherbot commented May 9, 2017

CL mentions this issue.

gopherbot pushed a commit that referenced this issue May 9, 2017
This permits the user to override the code generation flag when they
know better. This is always a good policy for all flags automatically
inserted by the build system.

Doing this now so that I can write a test for #20290.

Update #20290

Change-Id: I5c6708a277238d571b8d037993a5a59e2a442e98
Run-TryBot: Ian Lance Taylor <>
Reviewed-by: Brad Fitzpatrick <>
TryBot-Result: Gobot Gobot <>
Copy link

@gopherbot gopherbot commented May 9, 2017

CL mentions this issue.

@gopherbot gopherbot closed this in 5331e7e May 9, 2017
@golang golang locked and limited conversation to collaborators May 9, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants