4ad/go

cmd/link/internal/ld/elf: does not write dynamically imported syms correctly

binarycrusader opened this issue · 4 comments

Even on x86, Go's internal linker does not write .dynsym / .symtab entries as expected.

In particular, functions imported from libraries such as libc.so (e.g. via loadcgo) when written to .dynsym / .symtab are listed as OBJT (STT_OBJECT) instead of as FUNC (STT_FUNC).

Unknown what effect this is having at this time.

At it's simplest, this is because Elfadddynsym() has this logic:

                if s.Attr.CgoExport() && s.Type&obj.SMASK == obj.STEXT {
                        t |= STT_FUNC
                } else {
                        t |= STT_OBJECT
                }

It assumes that only dynamic symbols of type STEXT and that are marked with CgoExport() should be listed as a function, which doesn't make any sense to me.

This may be because Go considers the import of a C symbol to be unique within every package, but then I would assume this logic should be limited to Buildmode != BuildmodeExe.

Note that this expectation is not unique to Solaris; a "readelf -a" of various executables on a Linux system shows the same expectation.

4ad commented

I remember that this is intentional, although I do not remember the reason.

The explanation I found (but can't find again at this moment), was roughly that since Go considers C symbols that are imported to be unique to each package, they don't want them "exported" in a way that affects linking.

However, that would only make sense when Buildmode != BuildmodeExe. I'm just leaving this open so that I can investigate at a later point or if I discover it to be causing other problems.