cgo on dragonfly

269 views
Skip to first unread message

Joel Sing

unread,
Aug 23, 2013, 1:49:41 PM8/23/13
to golang-dev
I had a quick look at enabling cgo support on dragonfly, however hit a
snag. The errno on dragonfly is specified in errno.h as:

extern __thread int errno;

This means that the resulting object files have:

SYMBOL TABLE:
...
0000000000000000 *UND* 0000000000000000 errno
...
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000000000000015 R_X86_64_TLSGD errno+0xfffffffffffffffc
...

And the gc linker does not know how to handle R_X86_64_TLSGD.

I've modified cmd/ld/ldelf.c so that it recognises ElfSymTypeTLS and
R_X86_64_TLSGD, however my linker foo is probably not strong enough to
quickly figure out the associated change to cmd/6l/asm.c.

Is anyone able to provide a pointer re how this needs to be handled,
or suggest a suitable work around?

Ian Lance Taylor

unread,
Aug 23, 2013, 3:26:56 PM8/23/13
to Joel Sing, golang-dev
I'm sure I'm missing something obvious, but why isn't 6l kicking out
to the external linker in this case?

Ian

Varialus

unread,
Aug 25, 2013, 2:47:56 AM8/25/13
to golan...@googlegroups.com
Setting the following environment variable was quite useful to me while working on getting cgo to work.

export GO_LDFLAGS="-linkmode external"

Would you try setting it before running all.bash and let me know whether it made a difference?

Thanks,
Varialus

Varialus

unread,
Aug 25, 2013, 5:58:10 PM8/25/13
to golan...@googlegroups.com
Joel,

Could I have access to your cgo branch or just a diff file of where your at? I'd like to start from where you left off. Also it might be good to give dho a copy. He helped me to get past a bit assembly that I had been stuck on.

I've updated my project page with current cgo enabling effort. When I tried to figure out where an error was occurring, I tracked it down to a particular spot in the build process where a function was getting called on DragonFly but not on FreeBSD, but I couldn't figure out why. When I enabled external linking, I still had problems, but the build at least progressed into the testing phase, which was rewarding after having been stuck on a single error the whole day.

Thanks,
Varialus


On Friday, August 23, 2013 11:49:41 AM UTC-6, Joel Sing wrote:

Varialus

unread,
Aug 25, 2013, 7:28:51 PM8/25/13
to golan...@googlegroups.com
I just built from HEAD plus the dragonflydynld set to "/usr/libexec/ld-elf.so.2" in src/cmd/6l/asm.c and cgo enabled in src/cmd/api/goapi.go, and it built and passed all tests. So uh, does that mean that cgo works?

Varialus

Ian Lance Taylor

unread,
Aug 25, 2013, 7:30:53 PM8/25/13
to Varialus, golang-dev
On Sun, Aug 25, 2013 at 4:28 PM, Varialus <vari...@gmail.com> wrote:
> I just built from HEAD plus the dragonflydynld set to
> "/usr/libexec/ld-elf.so.2" in src/cmd/6l/asm.c and cgo enabled in
> src/cmd/api/goapi.go, and it built and passed all tests. So uh, does that
> mean that cgo works?

If the tests in misc/cgo were run and passed--you should be able to
see that in the all.bash output--then cgo works.

Ian
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "golang-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-dev+...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Varialus

unread,
Aug 25, 2013, 7:35:46 PM8/25/13
to golan...@googlegroups.com, Varialus
Sorry for the false alarm. I forgot that there's also a place to enable it in src/pkg/go/build/build.go. Sigh... Back to work.

Joel Sing

unread,
Aug 26, 2013, 10:55:32 AM8/26/13
to Varialus, golang-dev
The following enables cgo and with a slight linkmode hack it passes all tests:

https://codereview.appspot.com/13213043/

I'll attempt follow up in more detail tomorrow...

Joel Sing

unread,
Aug 26, 2013, 11:00:18 AM8/26/13
to Ian Lance Taylor, golang-dev
Ugh... that is a good question and I'm not sure. The specific error
that occurs during go_bootstrap is:

cmd/go
# cmd/go
/home/joel/src/go2/pkg/dragonfly_amd64/net.a(_all.o): malformed elf
file: net(.text)#0: reloc of invalid sym #17 errno shndx=0 type=6

I'm yet to dig into the details re when linkmode should switch to
external, however it would seem that it fails to realise that it
cannot link against net.a with linkmode == internal.

Running make.bash with GO_LDFLAGS="-linkmode external" allows the
build to complete, however still fails tests. Hacking 6l/obj.c and
forcing linkmode = LinkExternal on dragonfly allows it to build and
pass all tests.

Is there any specific debug or symbol info that would be useful?

Ian Lance Taylor

unread,
Aug 26, 2013, 11:37:24 AM8/26/13
to Joel Sing, golang-dev
Part of what is happening here is that the linker does not force
external linking mode because the net package uses cgo; see ldhostobj
in cmd/ld/lib.c. So that is why we are using the internal linker.

Another part is that the C implementation of getaddrinfo does refer to
errno. At least, it does on a GNU/Linux system, and it would not be
surprising if DragonFly is the same. This reference gets compiled
into an ELF object file that is part of the net package, and gets
passed to the linker. (Normally linking against an ELF file would
cause the external linker to be invoked, but as noted above the net
package is an exception.)

So we do in fact wind up with a TLS symbol in the internal linker, and
it doesn't know how to deal with that.

The simple fix is going to be forcing the use of the external linker
on DragonFly in ldhostobj even for an internal package, which is
similar to what you are doing in forcing the external linker in all
cases.

The more complex fix would be to teach the internal linker how to
handle a TLS symbol. That is feasible but not simple. The linker
would have to expand the TLS section and it would have to implement
TLS optimizations to convert the reloc references for a static link.

Ian

Varialus

unread,
Aug 30, 2013, 1:19:49 PM8/30/13
to golan...@googlegroups.com, Joel Sing, Devon O'Dell
On Monday, August 26, 2013 9:37:24 AM UTC-6, Ian Lance Taylor wrote:
The simple fix is going to be forcing the use of the external linker
on DragonFly in ldhostobj even for an internal package, which is
similar to what you are doing in forcing the external linker in all
cases.

The more complex fix would be to teach the internal linker how to
handle a TLS symbol.  That is feasible but not simple.  The linker
would have to expand the TLS section and it would have to implement
TLS optimizations to convert the reloc references for a static link.

I have submitted a patch for review, the goal of which was to implement as closely as possible the simple fix described by Ian. I'd like it to get it in before the 1.2 freeze if at all possible. https://codereview.appspot.com/13247046

Also, I have ordered some books on assembly language in order to hopefully learn how to better maintain and contribute to the dfly port and Go in general, but it'll probably be quite a while before that starts to pay off.

Varialus

unread,
Aug 31, 2013, 3:19:39 PM8/31/13
to golan...@googlegroups.com, Joel Sing, Devon O'Dell
As part of the code review for cgo on dfly I have been asked to provide better descriptions of the errors which I'm preventing but I don't know how to satisfactorily describe them. Would someone please describe them suitably for inclusion as inline code comments? Lengthier descriptions such as Ian's previous description are of course welcome, but it's specifically the code comment style description that I'm requesting help with. Thanks and sorry for distracting you from whatever else you would have been doing.

Here's some context for the errors and the errors themselves.


Initial Build State
 - Environment Variables: None Manually Set
 - GOOS: Default dragonfly
 - CGO_ENABLED: Default Enabled
Error State
 - linkmode: auto
 - linkmode: internal
 - Preventative Conditional: strcmp(pkg, "net") == 0 at https://codereview.appspot.com/13247046/diff/45001/src/cmd/ld/lib.c
Cause of Trouble
 - Code: const char *internalpkg[] = { "net" };
Trouble Prevention
 - Code: if( HEADTYPE == Hdragonfly && strcmp(pkg, "net") == 0) { isinternal = 0; }
Error Text
...
text/scanner
# cmd/go
/root/go/pkg/dragonfly_amd64/net.a(_all.o): malformed elf file: net(.text)#0: reloc of invalid sym #17 errno shndx=0 type=6
bash-4.2#


Initial Build State
 - Environment Variables: None Manually Set
 - GOOS: Default dragonfly
 - CGO_ENABLED: Default Enabled
Error State
 - linkmode: auto
 - linkmode: internal
Cause of Trouble
 - Code: const char *internalpkg[] = { "os/user" };
Trouble Prevention
 - Code: if( HEADTYPE == Hdragonfly && strcmp(pkg, "os/user") == 0) { isinternal = 0; }
Error Text
...
ok      os/signal       0.845s
signal: segmentation fault
Aug 31 11:20:06 df1 kernel: pid 35683 (user.test), uid 0: exit on signal 11
ok      path    0.012s
...
?       unsafe  [no test files]
bash-4.2#


Initial Build State
 - Environment Variables: None Manually Set
 - GOOS: Default dragonfly
 - CGO_ENABLED: Default Enabled
Error State
 - linkmode: internal
Cause of Trouble
 - Code: go test -ldflags '-linkmode=internal
Trouble Prevention
 - Code: [ "$GOHOSTOS" = "dragonfly" ] || (go test -ldflags '-linkmode=internal' || exit 1) || exit $?
Error Text
...
ok      _/root/go/misc/cgo/test 1.300s
# testmain
/tmp/go-build113211244/_/root/go/misc/cgo/test/_test/_/root/go/misc/cgo/test.a(_all.o): malformed elf file: _/root/go/misc/cgo/test/(.text)#78: reloc of invalid sym #100 errno shndx=0 type=6
FAIL    _/root/go/misc/cgo/test [build failed]
bash-4.2#

Varialus

unread,
Aug 31, 2013, 4:22:04 PM8/31/13
to golan...@googlegroups.com, Joel Sing, Devon O'Dell
Here's the actual request for the error description which I don't know how to describe.

I would actually like a longer comment here.  As I understand the core
problem is that the DragonFly libc uses "extern __thread int errno;" and
6l/8l don't support __thread variables.  I'd like the comment to explain
that.  The goal should be to say what needs to be fixed in order to
remove this condition.

Also I didn't mean to include the line in the errors which starts with " - Preventative Conditional:". It's just the result of an editing oversight.
Reply all
Reply to author
Forward
0 new messages