Closed apm-opentt closed 3 years ago
Thanks @cherrymui, I tried using -static-libgcc, but unfortunately it did not work.
# go build -v -compiler=gccgo -gccgoflags="-static-libgcc -lpthread" -o awesome.so -buildmode=c-shared awesome.go command-line-arguments # command-line-arguments ld: 0711-224 WARNING: Duplicate symbol: .__divdi3 ld: 0711-224 WARNING: Duplicate symbol: .__moddi3 ld: 0711-224 WARNING: Duplicate symbol: .__divmoddi4 ld: 0711-224 WARNING: Duplicate symbol: .__udivdi3 ld: 0711-224 WARNING: Duplicate symbol: .__umoddi3 ld: 0711-224 WARNING: Duplicate symbol: .__udivmoddi4 ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information. ld: 0711-317 ERROR: Undefined symbol: __gcc_unwind_dbase collect2: error: ld returned 8 exit status
Maybe try adding -gccgoflags=-v to see what flags are passed to ld. What happens if you remove -lpthread ?
@cherrymui here is the -v output:
# go build -v -compiler=gccgo -gccgoflags="-v -static-libgcc -lpthread" -o awesome.so -buildmode=c-shared awesome.go command-line-arguments # command-line-arguments Using built-in specs. COLLECT_GCC=/opt/freeware/bin/gccgo-8 Target: powerpc-ibm-aix7.1.0.0 Configured with: ../gcc-8.5.0/configure --prefix=/opt/freeware --mandir=/opt/freeware/man --infodir=/opt/freeware/info --with-local-prefix=/opt/freeware --with-as=/usr/bin/as --with-ld=/usr/bin/ld --enable-languages=c,c++,fortran,go --enable-version-specific-runtime-libs --disable-nls --disable-libstdcxx-pch --disable-werror --enable-libstdcxx-filesystem-ts --with-gcc-major-version-only --program-suffix=-8 --disable-rpath --host=powerpc-ibm-aix7.1.0.0 Thread model: aix gcc version 8.5.0 (GCC) COLLECT_GCC_OPTIONS='-c' '-g' '-fdebug-prefix-map=/tmp/go-build705049154=/tmp/go-build' '-gno-record-gcc-switches' '-fgo-relative-import-path=_/albert/example' '-o' '/tmp/go-build705049154/b001/_go_.o' '-fPIC' '-I' '/tmp/go-build705049154/b001/_importcfgroot_' '-v' '-static-libgcc' /opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/go1 $WORK/b001/_cgo_gotypes.go $WORK/b001/awesome.cgo1.go -quiet -dumpbase _cgo_gotypes.go -auxbase-strip $WORK/b001/_go_.o -g -gno-record-gcc-switches -version -fdebug-prefix-map=/tmp/go-build705049154=/tmp/go-build -fgo-relative-import-path=_/albert/example -fPIC -I $WORK/b001/_importcfgroot_ -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8 -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/../../.. -o /tmp//cc3jxkXj.s GNU Go (GCC) version 8.5.0 (powerpc-ibm-aix7.1.0.0) compiled by GNU C version 8.5.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version none GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 GNU Go (GCC) version 8.5.0 (powerpc-ibm-aix7.1.0.0) compiled by GNU C version 8.5.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version none GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 COLLECT_GCC_OPTIONS='-c' '-g' '-fdebug-prefix-map=/tmp/go-build705049154=/tmp/go-build' '-gno-record-gcc-switches' '-fgo-relative-import-path=_/albert/example' '-o' '/tmp/go-build705049154/b001/_go_.o' '-fPIC' '-I' '/tmp/go-build705049154/b001/_importcfgroot_' '-v' '-static-libgcc' /usr/bin/as -u -mpwr4 -many -o $WORK/b001/_go_.o /tmp//cc3jxkXj.s COMPILER_PATH=/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/ LIBRARY_PATH=/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-c' '-g' '-fdebug-prefix-map=/tmp/go-build705049154=/tmp/go-build' '-gno-record-gcc-switches' '-fgo-relative-import-path=_/albert/example' '-o' '/tmp/go-build705049154/b001/_go_.o' '-fPIC' '-I' '/tmp/go-build705049154/b001/_importcfgroot_' '-v' '-static-libgcc' # command-line-arguments Using built-in specs. COLLECT_GCC=/opt/freeware/bin/gccgo-8 COLLECT_LTO_WRAPPER=/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/lto-wrapper Target: powerpc-ibm-aix7.1.0.0 Configured with: ../gcc-8.5.0/configure --prefix=/opt/freeware --mandir=/opt/freeware/man --infodir=/opt/freeware/info --with-local-prefix=/opt/freeware --with-as=/usr/bin/as --with-ld=/usr/bin/ld --enable-languages=c,c++,fortran,go --enable-version-specific-runtime-libs --disable-nls --disable-libstdcxx-pch --disable-werror --enable-libstdcxx-filesystem-ts --with-gcc-major-version-only --program-suffix=-8 --disable-rpath --host=powerpc-ibm-aix7.1.0.0 Thread model: aix gcc version 8.5.0 (GCC) COMPILER_PATH=/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/ LIBRARY_PATH=/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-o' '/tmp/go-build705049154/b001/exe/a.out' '-shared' '-nostdlib' '-fPIC' '-v' '-static-libgcc' /opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/collect2 -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8 -L/opt/freeware/lib/gcc/.. -lgo -bpT:0x10000000 -bpD:0x20000000 -btextro -bM:SRE -bnoentry -o $WORK/b001/exe/a.out -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8 -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/../../.. $WORK/b001/_pkg1_.a -lgolibbegin -lgo -lgcc_s -lgcc -lc -lgcc -lpthread ld: 0711-224 WARNING: Duplicate symbol: .__divdi3 ld: 0711-224 WARNING: Duplicate symbol: .__moddi3 ld: 0711-224 WARNING: Duplicate symbol: .__divmoddi4 ld: 0711-224 WARNING: Duplicate symbol: .__udivdi3 ld: 0711-224 WARNING: Duplicate symbol: .__umoddi3 ld: 0711-224 WARNING: Duplicate symbol: .__udivmoddi4 ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information. ld: 0711-317 ERROR: Undefined symbol: __gcc_unwind_dbase collect2: error: ld returned 8 exit status
Are you able to create a shared library that contains just C code?
Hi @ianlancetaylor, I followed the steps in this article to create a shared library using just C code. https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html. The steps worked perfectly on a x86_64 system. However, on the AIX 7.1 env, compiling the shared library worked but linking the shared lib with main.c failed
# gcc -c -Wall -Werror -fpic foo.c # ls foo.c foo.h foo.o main.c # gcc -shared -o libfoo.so foo.o # ls foo.c foo.h foo.o libfoo.so main.c # gcc -v -L`pwd` -Wall -o test main.c -lfoo Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/lto-wrapper Target: powerpc-ibm-aix7.1.0.0 Configured with: ../gcc-8.5.0/configure --prefix=/opt/freeware --mandir=/opt/freeware/man --infodir=/opt/freeware/info --with-local-prefix=/opt/freeware --with-as=/usr/bin/as --with-ld=/usr/bin/ld --enable-languages=c,c++,fortran,go --enable-version-specific-runtime-libs --disable-nls --disable-libstdcxx-pch --disable-werror --enable-libstdcxx-filesystem-ts --with-gcc-major-version-only --program-suffix=-8 --disable-rpath --host=powerpc-ibm-aix7.1.0.0 Thread model: aix gcc version 8.5.0 (GCC) COLLECT_GCC_OPTIONS='-v' '-L/alberttest' '-Wall' '-o' 'test' /opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/cc1 -quiet -v main.c -quiet -dumpbase main.c -auxbase main -Wall -version -o /tmp//cc9qjX4S.s GNU C17 (GCC) version 8.5.0 (powerpc-ibm-aix7.1.0.0) compiled by GNU C version 8.5.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version none GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 ignoring nonexistent directory "/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/../../../../powerpc-ibm-aix7.1.0.0/include" #include "..." search starts here: #include <...> search starts here: /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/include /opt/freeware/include /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/include-fixed /usr/include End of search list. GNU C17 (GCC) version 8.5.0 (powerpc-ibm-aix7.1.0.0) compiled by GNU C version 8.5.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version none GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 67c6592e8f7e62299ec2b7b090ae8741 COLLECT_GCC_OPTIONS='-v' '-L/alberttest' '-Wall' '-o' 'test' /usr/bin/as -u -mpwr4 -many -o /tmp//cc4tcfYD.o /tmp//cc9qjX4S.s COMPILER_PATH=/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/ LIBRARY_PATH=/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-L/alberttest' '-Wall' '-o' 'test' /opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/collect2 -bpT:0x10000000 -bpD:0x20000000 -btextro -o test /lib/crt0.o /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/crtcxa.o /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/crtdbase.o -L/alberttest -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8 -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/../../.. /tmp//cc4tcfYD.o -lfoo /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/libgcc.a /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/libgcc_eh.a -lc -L/opt/freeware/lib /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/libgcc.a /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/libgcc_eh.a ld: 0706-006 Cannot find or open library file: -l foo ld:open(): A file or directory in the path name does not exist. collect2: error: ld returned 255 exit status
Some how ld:open() could not open the file even though it is right there. Is this a gcc install or gcc binary issue?
I'm sorry, I don't know where the issue is. AIX is unlike other Unix systems in several ways.
Hi @apm-opentt,
On AIX, shared libraries must be archives and not standalone shared objects. That's why your C example doesn't work.
The linker when seeing -lfoo
, will search for libfoo.a
and not libfoo.so
.
Thus, you have to add your shared object in an archive first:
# ar -X32_64 q libfoo.a libfoo.so
ar: creating an archive file libfoo.a
For the main subject of this issue, the main problem is that c-shared buildmode isn't fully supported. Thus, it seems that some objects are missing when the linker is called.
With a C shared library, two object files are being added crtdbase.o
and crtcxa_s.o
.
# gcc -shared -o libfoo.so foo.c -fpic -v -maix64
/opt/freeware/libexec/gcc/powerpc-ibm-aix7.2.0.0/8/collect2 ... -b64 -o libfoo.so \
/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/ppc64/crtcxa_s.o \
/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/ppc64/crtdbase.o ...
I have no idea why they aren't added by gccgo when using c-shared. But a workaround for that is to manually add them within gccgoflags.
# go build -v -compiler=gccgo -gccgoflags="-pthread -v -maix64 /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/ppc64/crtcxa_s.o /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/ppc64/crtdbase.o -lpthread" -o awesome.so -buildmode=c-shared awesome.go
This command should work fine.
Note that even if it seems to work without it, you should add -maix64 and -pthread to gccgoflags too.
The reason for -maix64
is that, by default, go
command will want to create 64bit objects while gcc is still 32bit by default.
For -pthread
is just that it should always be passed for a program using threads on AIX. -lpthread
is not enough most of the time (and it should normally be added by -pthread
directly but that's not the case here for an whatever reason...).
Thank you so much @Helflym! I ran your command (I changed 7.2 to 7.1 in the path since I have 7.1). Unfortunately, It still didn't build the .so file. Looks like linking issues with the wrong object mode? I am new to AIX, how can I fix this?
go build -v -compiler=gccgo -gccgoflags="-pthread -v -maix64 /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/ppc64/crtcxa_s.o /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/ppc64/crtdbase.o -lpthread" -o awesome.so -buildmode=c-shared awesome.go command-line-arguments # command-line-arguments Using built-in specs. COLLECT_GCC=/opt/freeware/bin/gccgo-8 Target: powerpc-ibm-aix7.1.0.0 Configured with: ../gcc-8.5.0/configure --prefix=/opt/freeware --mandir=/opt/freeware/man --infodir=/opt/freeware/info --with-local-prefix=/opt/freeware --with-as=/usr/bin/as --with-ld=/usr/bin/ld --enable-languages=c,c++,fortran,go --enable-version-specific-runtime-libs --disable-nls --disable-libstdcxx-pch --disable-werror --enable-libstdcxx-filesystem-ts --with-gcc-major-version-only --program-suffix=-8 --disable-rpath --host=powerpc-ibm-aix7.1.0.0 Thread model: aix gcc version 8.5.0 (GCC) COLLECT_GCC_OPTIONS='-c' '-g' '-fdebug-prefix-map=/tmp/go-build217710626=/tmp/go-build' '-gno-record-gcc-switches' '-fgo-relative-import-path=_/albert/example' '-o' '/tmp/go-build217710626/b001/_go_.o' '-fPIC' '-I' '/tmp/go-build217710626/b001/_importcfgroot_' '-pthread' '-v' '-maix64' '-shared-libgcc' /opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/go1 $WORK/b001/_cgo_gotypes.go $WORK/b001/awesome.cgo1.go -quiet -dumpbase _cgo_gotypes.go -maix64 -auxbase-strip $WORK/b001/_go_.o -g -gno-record-gcc-switches -version -fdebug-prefix-map=/tmp/go-build217710626=/tmp/go-build -fgo-relative-import-path=_/albert/example -fPIC -I $WORK/b001/_importcfgroot_ -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/pthread/ppc64 -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/../../../pthread/ppc64 -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8 -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/../../.. -o /tmp//ccN1LIip.s GNU Go (GCC) version 8.5.0 (powerpc-ibm-aix7.1.0.0) compiled by GNU C version 8.5.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version none GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 GNU Go (GCC) version 8.5.0 (powerpc-ibm-aix7.1.0.0) compiled by GNU C version 8.5.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version none GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 COLLECT_GCC_OPTIONS='-c' '-g' '-fdebug-prefix-map=/tmp/go-build217710626=/tmp/go-build' '-gno-record-gcc-switches' '-fgo-relative-import-path=_/albert/example' '-o' '/tmp/go-build217710626/b001/_go_.o' '-fPIC' '-I' '/tmp/go-build217710626/b001/_importcfgroot_' '-pthread' '-v' '-maix64' '-shared-libgcc' /usr/bin/as -u -a64 -mppc64 -many -o $WORK/b001/_go_.o /tmp//ccN1LIip.s COMPILER_PATH=/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/ LIBRARY_PATH=/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/pthread/ppc64/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/../../../pthread/ppc64/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-c' '-g' '-fdebug-prefix-map=/tmp/go-build217710626=/tmp/go-build' '-gno-record-gcc-switches' '-fgo-relative-import-path=_/albert/example' '-o' '/tmp/go-build217710626/b001/_go_.o' '-fPIC' '-I' '/tmp/go-build217710626/b001/_importcfgroot_' '-pthread' '-v' '-maix64' '-shared-libgcc' gccgo-8: warning: /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/ppc64/crtcxa_s.o: linker input file unused because linking not done gccgo-8: warning: /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/ppc64/crtdbase.o: linker input file unused because linking not done # command-line-arguments ar: 0707-126 $WORK/b001/_go_.o is not valid with the current object file mode. Use the -X option to specify the desired object mode.
I was able to overcome the problem above by setting these environment variables:
export OBJECT_MODE=64
export GOARCH=ppc64
export CGO_ENABLED=1
The awesome.so and awesome.h files were created. I then created the archive .a file
ar -X64 r libawesome.a awesome.so
The next step is to compile the C client that use the shared library. client.c
However, compiling the client.c failed with Undefined symbols for the functions in the awesome.h file. Hi @Helflym any idea how to fix this problem?
gcc -maix64 -L`pwd` -Wall -Werror -o client client.c -Wl,-b64,-bnoobjreorder,-bloadmap:loadmapfile,-bnoquiet (ld): setopt 64 (ld): halt 4 (ld): setopt r/o->w (ld): setfflag 4 (ld): setopt reorder:by_address (ld): savename client (ld): filelist 7 1 (ld): i /lib/crt0_64.o (ld): i /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/ppc64/crtcxa.o (ld): i /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/ppc64/crtdbase.o (ld): i /tmp//cciE7Mbn.o (ld): i /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/ppc64/libgcc.a (ld): i /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/ppc64/libgcc_eh.a (ld): lib /usr/lib/libc.a LIBRARY: Shared object libc.a[shr_64.o]: 3120 symbols imported. LIBRARY: Shared object libc.a[posix_aio_64.o]: 20 symbols imported. LIBRARY: Shared object libc.a[aio_64.o]: 18 symbols imported. LIBRARY: Shared object libc.a[pse_64.o]: 8 symbols imported. LIBRARY: Shared object libc.a[dl_64.o]: 4 symbols imported. LIBRARY: Shared object libc.a[pty_64.o]: 1 symbols imported. LIBRARY: Shared object libc.a[cthread_64.o]: 25 symbols imported. LIBRARY: Shared object libc.a[uchar_64.o]: 4 symbols imported. FILELIST: Number of previously inserted files processed: 7 (ld): resolve RESOLVE: 42 of 4901 symbols were kept. (ld): addgl /usr/lib/glink64.o ADDGL: Glink code added for 6 symbols. (ld): er full ld: 0711-318 ERROR: Undefined symbols were found. The following symbols are in error: Symbol Inpndx TY CL Source-File(Object-File) OR Import-File{Shared-object} RLD: Address Section Rld-type Referencing Symbol ---------------------------------------------------------------------------------------------- .Add [2] ER PR client.c(/tmp//cciE7Mbn.o) 0000002c .text R_RBR [14] .main .Cosine [6] ER PR client.c(/tmp//cciE7Mbn.o) 00000054 .text R_RBR [14] .main .Sort [8] ER PR client.c(/tmp//cciE7Mbn.o) 000000ec .text R_RBR [14] .main .Log [10] ER PR client.c(/tmp//cciE7Mbn.o) 00000160 .text R_RBR [14] .main ER: The return code is 8. ld: 0711-317 ERROR: Undefined symbol: .Add ld: 0711-317 ERROR: Undefined symbol: .Cosine ld: 0711-317 ERROR: Undefined symbol: .Sort ld: 0711-317 ERROR: Undefined symbol: .Log collect2: error: ld returned 8 exit status # gcc -maix64 -L. -Wall -Werror -o client client.c -Wl,-b64,-bnoobjreorder,-bnoquiet (ld): setopt 64 (ld): halt 4 (ld): setopt r/o->w (ld): setfflag 4 (ld): setopt reorder:by_address (ld): savename client (ld): filelist 7 1 (ld): i /lib/crt0_64.o (ld): i /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/ppc64/crtcxa.o (ld): i /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/ppc64/crtdbase.o (ld): i /tmp//cc242zbu.o (ld): i /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/ppc64/libgcc.a (ld): i /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/ppc64/libgcc_eh.a (ld): lib /usr/lib/libc.a LIBRARY: Shared object libc.a[shr_64.o]: 3120 symbols imported. LIBRARY: Shared object libc.a[posix_aio_64.o]: 20 symbols imported. LIBRARY: Shared object libc.a[aio_64.o]: 18 symbols imported. LIBRARY: Shared object libc.a[pse_64.o]: 8 symbols imported. LIBRARY: Shared object libc.a[dl_64.o]: 4 symbols imported. LIBRARY: Shared object libc.a[pty_64.o]: 1 symbols imported. LIBRARY: Shared object libc.a[cthread_64.o]: 25 symbols imported. LIBRARY: Shared object libc.a[uchar_64.o]: 4 symbols imported. FILELIST: Number of previously inserted files processed: 7 (ld): resolve RESOLVE: 42 of 4901 symbols were kept. (ld): addgl /usr/lib/glink64.o ADDGL: Glink code added for 6 symbols. (ld): er full ld: 0711-318 ERROR: Undefined symbols were found. The following symbols are in error: Symbol Inpndx TY CL Source-File(Object-File) OR Import-File{Shared-object} RLD: Address Section Rld-type Referencing Symbol ---------------------------------------------------------------------------------------------- .Add [2] ER PR client.c(/tmp//cc242zbu.o) 0000002c .text R_RBR [14] .main .Cosine [6] ER PR client.c(/tmp//cc242zbu.o) 00000054 .text R_RBR [14] .main .Sort [8] ER PR client.c(/tmp//cc242zbu.o) 000000ec .text R_RBR [14] .main .Log [10] ER PR client.c(/tmp//cc242zbu.o) 00000160 .text R_RBR [14] .main ER: The return code is 8. ld: 0711-317 ERROR: Undefined symbol: .Add ld: 0711-317 ERROR: Undefined symbol: .Cosine ld: 0711-317 ERROR: Undefined symbol: .Sort ld: 0711-317 ERROR: Undefined symbol: .Log collect2: error: ld returned 8 exit status #
I can see the symbols in the awesome.so file with nm command:
nm -X64 awesome.so|grep " T " .Add T 268446464 108 .Cosine T 268446576 92 .Log T 268446896 116 .LogPtr T 268447024 100 .Sort T 268446672 104 .SortPtr T 268446784 104 ._Errno T 268448792
Here is the output of the file command:
file awesome.so awesome.so: 64-bit XCOFF executable or object module not stripped file libawesome.a libawesome.a: archive (big format)
Here is the generated awesome.h file. I don't know why client.c could not compile.
cat awesome.h /* Created by "go tool cgo" - DO NOT EDIT. */ /* package command-line-arguments */ #line 1 "cgo-builtin-prolog" #include/* for ptrdiff_t below */ #ifndef GO_CGO_EXPORT_PROLOGUE_H #define GO_CGO_EXPORT_PROLOGUE_H typedef struct { const char *p; ptrdiff_t n; } _GoString_; #endif /* Start of preamble from import "C" comments. */ /* End of preamble from import "C" comments. */ /* Start of boilerplate cgo prologue. */ #line 1 "cgo-gcc-export-header-prolog" #ifndef GO_CGO_PROLOGUE_H #define GO_CGO_PROLOGUE_H typedef signed char GoInt8; typedef unsigned char GoUint8; typedef short GoInt16; typedef unsigned short GoUint16; typedef int GoInt32; typedef unsigned int GoUint32; typedef long long GoInt64; typedef unsigned long long GoUint64; typedef GoInt64 GoInt; typedef GoUint64 GoUint; typedef __SIZE_TYPE__ GoUintptr; typedef float GoFloat32; typedef double GoFloat64; typedef float _Complex GoComplex64; typedef double _Complex GoComplex128; /* static assertion to make sure the file is being used on architecture at least with matching size of GoInt. */ typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1]; typedef _GoString_ GoString; typedef void *GoMap; typedef void *GoChan; typedef struct { void *t; void *v; } GoInterface; typedef struct { void *data; GoInt len; GoInt cap; } GoSlice; #endif /* End of boilerplate cgo prologue. */ #ifdef __cplusplus extern "C" { #endif extern GoInt Add(GoInt p0, GoInt p1); extern GoFloat64 Cosine(GoFloat64 p0); extern void Sort(GoSlice p0); extern void SortPtr(GoSlice* p0); extern GoInt Log(GoString p0); extern GoInt LogPtr(GoString* p0); #ifdef __cplusplus } #endif #
AIX is really different than Linux regarding shared libraries. One must export symbols he wants to use from this library whereas on Linux everything is exported by default.
Thus, in your case, you need to create an export file:
$ cat > file.exp << EOF
Add
Cosine
Sort
Log
EOF
And tell the linker to use it when creating awesome.so
with -Wl,-bE:file.exp
.
You should normally be able to see them exported, afterward.
$ dump -X64 -Tv awesome.so
...
[112] 0x20000e00 .data EXP DS Ldef [noIMid] Add
[113] 0x20000e18 .data EXP DS Ldef [noIMid] Cosine
[114] 0x20000e30 .data EXP DS Ldef [noIMid] Sort
[115] 0x20000e48 .data EXP DS Ldef [noIMid] Log
However, I've tried to go further. But as I was expecting it, c-shared buildmode isn't supported by gccgo either. libgo.a
is searching for symbols in the main program which aren't being created when this main program comes up from a C file.
You'll end up having this error:
$ ./client
Could not load program client:
Symbol resolution failed for /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/10/ppc64/libgo.a[libgo.so.16] because:
Symbol __go_init_main (number 234) is not exported from dependent
module client.
Symbol main.main (number 235) is not exported from dependent
module client.
Symbol _etext (number 236) is not exported from dependent
module client.
Symbol _edata (number 237) is not exported from dependent
module client.
Examine .loader section symbols with the 'dump -Tv' command.
These symbols are created by Go programs and not C programs. I don't know if it's possible to create stub of these symbols in client.c
to trick libgo.a
thinking they are defined.
Thank you @Helflym for confirming -buildmode=c-shared is not supported on AIX. I will use -buildmode=c-archive method shown in your article Get Started With Go Language on AIX. I used these steps to successfully build the shared library, compile client.c and ran the binary a.out.
go build -compiler gccgo -buildmode=c-archive -o awesome.a -gccgoflags="-lgo -maix64" awesome.go
gcc -maix64 -Wall -Werror client.c awesome.a -pthread -Wl,-bnoobjreorder -DGCCGO -lgo
Hi @Helflym , I tried the steps above on AIX 7.2
with the latest go version go version go1.17.1 aix/ppc64
and with this gcc version:
bash-5.1# gccgo -v Using built-in specs. COLLECT_GCC=gccgo COLLECT_LTO_WRAPPER=/opt/freeware/libexec/gcc/powerpc-ibm-aix7.2.0.0/8/lto-wrapper Target: powerpc-ibm-aix7.2.0.0 Configured with: ../gcc-8.5.0/configure --prefix=/opt/freeware --mandir=/opt/freeware/man --infodir=/opt/freeware/info --with-local-prefix=/opt/freeware --with-as=/usr/bin/as --with-ld=/usr/bin/ld --enable-languages=c,c++,fortran,go --enable-version-specific-runtime-libs --disable-nls --disable-libstdcxx-pch --disable-werror --enable-libstdcxx-filesystem-ts --with-gcc-major-version-only --program-suffix=-8 --disable-rpath --host=powerpc-ibm-aix7.2.0.0 Thread model: aix gcc version 8.5.0 (GCC)
On step 4 of the steps in the previous comment. I got the following link error.
bash-5.1# gcc -maix64 -Wall -Werror client.c awesome.a -pthread -Wl,-bnoobjreorder,-bnoquiet -DGCCGO -lgo -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/opt/freeware/libexec/gcc/powerpc-ibm-aix7.2.0.0/8/lto-wrapper Target: powerpc-ibm-aix7.2.0.0 Configured with: ../gcc-8.5.0/configure --prefix=/opt/freeware --mandir=/opt/freeware/man --infodir=/opt/freeware/info --with-local-prefix=/opt/freeware --with-as=/usr/bin/as --with-ld=/usr/bin/ld --enable-languages=c,c++,fortran,go --enable-version-specific-runtime-libs --disable-nls --disable-libstdcxx-pch --disable-werror --enable-libstdcxx-filesystem-ts --with-gcc-major-version-only --program-suffix=-8 --disable-rpath --host=powerpc-ibm-aix7.2.0.0 Thread model: aix gcc version 8.5.0 (GCC) COLLECT_GCC_OPTIONS='-maix64' '-Wall' '-Werror' '-pthread' '-D' 'GCCGO' '-v' /opt/freeware/libexec/gcc/powerpc-ibm-aix7.2.0.0/8/cc1 -quiet -v -imultilib pthread/ppc64 -D__64BIT__ -D_THREAD_SAFE -D GCCGO client.c -quiet -dumpbase client.c -maix64 -auxbase client -Wall -Werror -version -o /tmp//ccCIUHG0.s GNU C17 (GCC) version 8.5.0 (powerpc-ibm-aix7.2.0.0) compiled by GNU C version 8.5.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version none GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=32768 ignoring nonexistent directory "/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/../../../../powerpc-ibm-aix7.2.0.0/include" #include "..." search starts here: #include <...> search starts here: /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/include /opt/freeware/include /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/include-fixed /usr/include End of search list. GNU C17 (GCC) version 8.5.0 (powerpc-ibm-aix7.2.0.0) compiled by GNU C version 8.5.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version none GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=32768 Compiler executable checksum: 9b08317146c943df0a7a5eedb2533af9 COLLECT_GCC_OPTIONS='-maix64' '-Wall' '-Werror' '-pthread' '-D' 'GCCGO' '-v' /usr/bin/as -u -a64 -mppc64 -many -o /tmp//cckrwujT.o /tmp//ccCIUHG0.s COMPILER_PATH=/opt/freeware/libexec/gcc/powerpc-ibm-aix7.2.0.0/8/:/opt/freeware/libexec/gcc/powerpc-ibm-aix7.2.0.0/8/:/opt/freeware/libexec/gcc/powerpc-ibm-aix7.2.0.0/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/ LIBRARY_PATH=/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/pthread/ppc64/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/../../../pthread/ppc64/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/:/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-maix64' '-Wall' '-Werror' '-pthread' '-D' 'GCCGO' '-v' /opt/freeware/libexec/gcc/powerpc-ibm-aix7.2.0.0/8/collect2 -bpT:0x10000000 -bpD:0x20000000 -btextro -b64 /lib/crt0_64.o /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/pthread/ppc64/crtcxa.o /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/pthread/ppc64/crtdbase.o -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/pthread/ppc64 -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/../../../pthread/ppc64 -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8 -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/../../.. /tmp//cckrwujT.o awesome.a -bnoobjreorder -bnoquiet -lgo /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/pthread/ppc64/libgcc.a /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/pthread/ppc64/libgcc_eh.a -lpthreads -lc -L/opt/freeware/lib /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/pthread/ppc64/libgcc.a /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/pthread/ppc64/libgcc_eh.a (ld): setopt 64 (ld): halt 4 (ld): setopt r/o->w (ld): setfflag 4 (ld): setopt reorder:by_address (ld): savename a.out (ld): filelist 10 1 (ld): i /lib/crt0_64.o (ld): i /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/pthread/ppc64/crtcxa.o (ld): i /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/pthread/ppc64/crtdbase.o (ld): i /tmp//cckrwujT.o (ld): i awesome.a (ld): lib /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/pthread/ppc64/libgo.a (ld): i /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/pthread/ppc64/libgcc.a (ld): i /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/8/pthread/ppc64/libgcc_eh.a (ld): lib /usr/lib/libpthreads.a (ld): lib /usr/lib/libc.a LIBRARY: Shared object libgo.a[libgo.so.13]: 42732 symbols imported. LIBRARY: Shared object libpthreads.a[shr_xpg5_64.o]: 355 symbols imported. LIBRARY: Shared object libc.a[shr_64.o]: 3149 symbols imported. LIBRARY: Shared object libc.a[posix_aio_64.o]: 20 symbols imported. LIBRARY: Shared object libc.a[aio_64.o]: 18 symbols imported. LIBRARY: Shared object libc.a[pse_64.o]: 8 symbols imported. LIBRARY: Shared object libc.a[dl_64.o]: 4 symbols imported. LIBRARY: Shared object libc.a[pty_64.o]: 1 symbols imported. LIBRARY: Shared object libc.a[cthread_64.o]: 25 symbols imported. LIBRARY: Shared object libc.a[uchar_64.o]: 4 symbols imported. FILELIST: Number of previously inserted files processed: 10 (ld): resolve RESOLVE: 278 of 48321 symbols were kept. (ld): addgl /usr/lib/glink64.o ADDGL: Glink code added for 63 symbols. (ld): er full ld: 0711-318 ERROR: Undefined symbols were found. The following symbols are in error: Symbol Inpndx TY CL Source-File(Object-File) OR Import-File{Shared-object} RLD: Address Section Rld-type Referencing Symbol ---------------------------------------------------------------------------------------------- .runtime.setmodinfo [230] ER PR /tmp/go-build2583312005/b001/_cgo_gotypes.go(awesome.a[a.out.a.o]) 10000a10 .text R_RBR [524] .main.main..init0 ER: The return code is 8. ld: 0711-317 ERROR: Undefined symbol: .runtime.setmodinfo collect2: error: ld returned 8 exit status bash-5.1#
Running nm command on awesome.a
bash-5.1# nm -X64 awesome.a|grep setmodinfo .runtime.setmodinfo U -
I saw a similar issue https://github.com/golang/go/issues/42916. Do you know how I can work around ERROR: Undefined symbol: .runtime.setmodinfo
?
The runtime.setmodinfo
issue doesn't have anything to do with this issue.
The workaround for that issue is to use the go tool that comes with gccgo, not the go tool that comes with the default Go compiler.
Hi @ianlancetaylor , I compiled the shared library with gccgo compiler like this on AIX 7.2 go build -compiler gccgo -buildmode=c-archive -o awesome.a -gccgoflags="-lgo -maix64" awesome.go
. If this is wrong, do you mind showing me the correct command? Thank you so much.
That is probably the right command, at least it looks plausible.
What I am saying is that there are two go commands. One that comes with the gc compiler and one that comes with the gccgo compiler. If you use the go command that comes with the gccgo compiler, you will not have the runtime.setmodinfo
problem.
@ianlancetaylor , compiling the go shared library works fine. However, the runtime.setmodinfo
problem comes when trying to build the C client that uses the go shared library.
gcc -maix64 -Wall -Werror client.c awesome.a -pthread -Wl,-bnoobjreorder,-bnoquiet -DGCCGO -lgo -v
See detail output from this comment above.
Turning off go mod seems to worked around it export GO111MODULE=off
I understand that the error is only reported when linking the C program. It remains true that If you use the go command that comes with the gccgo compiler, you will not have the runtime.setmodinfo
problem
Hi @ianlancetaylor , We are already using the latest go and gccgo versions available from bullfreeware for AIX.
golang download
gccgo download
I mean, this is the best we can work with until the community updates the versions for AIX.
If you do the gccgo download but not the golang download, do you get a command named "go"? If so, that is the one you should be using.
On BullFreeware (I'm one of the maintainers behind btw), gcc-go packages providing the go
command as go.gcc
. Golang packages will provide it as go.golang
. Normally, the go
command itself is pointing to the last one you've installed.
About the gcc version, we are currently having gcc-8 by default. But its gccgo is not in a really good shape, thus I generally recommend to move to gcc-9 or higher. Maybe the runtime.setmodinfo
issue comes from the fact that you're using different versions of gcc at the same time.
Note that we should be moving to gcc-10 by default about next week. So it might help you.
Thanks @Helflym . Is this the one we should install? gcc10-go 10.3.0-4?
Yes. Make sur you also download gcc-10. Afterwards, it should work:
$ go.gcc-10 build -buildmode=c-archive -compiler gccgo -gccgoflags="-lgo -maix64" -o awesome_gcc.a awesome.go
$ gcc-10 -maix64 -pthread -o client_gcc awesome_gcc.a client.c -Wl,-bnoobjreorder -I. -DGCCGO -lgo -lm
$ ./client_gcc
Using awesome lib from C:
awesome.Add(12,99) = 111
awesome.Cosine(1) = 0.540302
awesome.Sort(77,12,5,99,28,23): 5,12,23,28,77,99,
Hello from C!
Wonderful. Thank you so much @Helflym!
Hi @Helflym,
I wanted to initialize the go runtime in a bare bone C program for AIX. I will add code later to use dlopen()
to manually load the go shared library.
extern void __go_init(int argc, char **argv, char** env __attribute__ ((unused))); int main(int argc, char **argv, char **env) { __go_init(argc, argv, env); }
I compile it with gcc but I got the following error. Do you know how I can get this to work?
bash-5.1# gcc -maix64 main.c -pthread -lgo ld: 0711-317 ERROR: Undefined symbol: .__go_init ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information. collect2: error: ld returned 8 exit status
Thanks!
That's because __go_init
isn't defined in libgo
itself but in libgolibbegin
which is pulled automatically by -lgo
most of the time.
Here, as you don't have an Go code, AIX linker thinks that -lgo
is useless and thus garbage-collect it.
For initialized Go runtime in a C code without any reference to Go, I guess you have to add -lgolibbegin
manually.
However, I'm wondering why you want to do such things ?
Hi @Helflym,
Here is my scenario: We are using IBM MQ and would like to use MQ Exits mechanism to monitor the use of a queue. The MQ Exits
is basically custom code that gets invoked by MQ. This custom code must be compiled as a shared library so MQ can load it dynamically. In our case, our main logic is written in Go. Our custom MQ exit is written in C and compiled as a .so file for MQ to load dynamically. To control the loading order (load MQ exit first before go share library), we have C glue code to manually load the Go shared library (i.e. dlopen(mygo.so...)). So the flow is MQ -> MQ Exit share library in C-> Glue code in C -> Go shared library. In this flow, I need to initialize the go runtime in the glue code and dlopen() to load the go library. I tried adding --lgolibbegin
manually, it compiled but it could not find another symbol at runtime.
gcc -maix64 mymain.c -pthread -lgo -lgolibbegin bash-5.1# ./a.out exec(): 0509-036 Cannot load program a.out because of the following errors: 0509-130 Symbol resolution failed for /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/10/pthread/ppc64/libgo.a[libgo.so.16] because: 0509-136 Symbol __go_init_main (number 234) is not exported from dependent module a.out. 0509-136 Symbol main.main (number 235) is not exported from dependent module a.out. 0509-192 Examine .loader section symbols with the 'dump -Tv' command.
Do you know why __go_init_main
symbol is not exported and how can I fix it? Thanks!
Indeed, I haven't tried to launch a.out
. My bad..
The solution is to create "fake" functions in C code which lure libgo to think its being loaded by a Go main program.
This is dirty and might have huge side effects. But you can add the below code to your mymain.c
:
void main_init() __asm__ ("__go_init_main");
void main_init() {}
void main_main() __asm__ ("main.main");
void main_main() {}
This will create the symbols wanted by libgo, which are supposed to be created by Go compiler. It seems to be enough in order to launch your testcase. But no idea if it'll be enough for your complex project.
Thanks @Helflym !
Yes, when added the above code in mymain.c
it does launch the go runtime. However, given that mymain.c maps to MQ in my scenario, I had move the code above to my glue code (a shared lib that invoked my mymain.c). It compiled but at runtime it gave me this error:
rtld: 0712-001 Symbol __go_init_main was referenced from module /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/10/pthread/ppc64/libgo.a(libgo.so.16), but a runtime definition of the symbol was not found. rtld: 0712-001 Symbol main.main was referenced from module /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/10/pthread/ppc64/libgo.a(libgo.so.16), but a runtime definition of the symbol was not found.
I tried export LD_LIBRARY_PATH=/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/10/pthread/ppc64
but it didn't help. I got the same error.
I guess the AIX linker have garbage-collected these symbols. As there aren't referenced by any code in your shared library, if you didn't export them manually (or with -bexpall
) they won't be added to the shared object.
If you have an export file, you should add them otherwise you can try to add -Wl,-u__go_init_main -Wl,-umain.main
(I'm not fully sure of the syntax) to the command building your shared object.
Hi @Helflym ,
I tried adding -Wl,-u__go_init_main -Wl,-umain.main
go build -buildmode=c-archive -compiler gccgo '-gccgoflags=-Wl,-u__go_init_main -Wl,-umain.main -lgo -maix64' -o libfoo.a foo.go
xlc_r -q64 -bE:hello.exp -bM:SRE -bnoentry -o shrsub.o hello.o -lfoo -L. -lgo -lgolibbegin -lm -L/opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/10/pthread/ppc64 -lgcc_s /opt/missing_gccgo_object/crtcxa_s.o /opt/missing_gccgo_object/crtdbase.o
For some reason crtcxa_s.o
and crtdbase.o
were missing from gccgo version gcc version 10.3.0
. I temporarily worked around it by using the copies from gcc 8.5. This step gave 2 warnings. By the way,I tried adding -Wl,-u__go_init_main -Wl,-umain.main
in this step too, but it didn't help.
ld: 0711-224 WARNING: Duplicate symbol: .__go_init_main ld: 0711-224 WARNING: Duplicate symbol: .main.main
ar -X64 qv libsub.a shrsub.o
gcc -maix64 -pthread -o main main.c -L. -lsub
. Running ./main returned the same error:
exec(): 0509-036 Cannot load program main because of the following errors: 0509-130 Symbol resolution failed for /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/10/pthread/ppc64/libgo.a[libgo.so.16] because: 0509-136 Symbol __go_init_main (number 234) is not exported from dependent module main. 0509-136 Symbol main.main (number 235) is not exported from dependent module main. 0509-192 Examine .loader section symbols with the 'dump -Tv' command.
I really appreciate your help so far. This is turning into a quite difficult challenge :-(
I'm not sure I completely understand what you're trying to achieve. Can you shared me the code of shrsub.c
and main.c
? I'll try to reproduce it on my VMs.
However, one huge problem I'm seeing right now is that you're trying to use GccGo code with XLC. It might work but it's very unlikely. GCC and XLC aren't fully compatible.
For some reason
crtcxa_s.o
andcrtdbase.o
were missing from gccgo versiongcc version 10.3.0
.
crtcxa_s.o
and crtdbase.o
for version 10 are inside gcc10
RPM not gcc10-go
. But as gcc10-go
have a dependency over gcc10
, they should be available. Otherwise, there is something wrong with your installation which should be fixed before anything else. Especially because there is no guarantee that crtcxa_s.o
and crtdbase.o
are compatible across versions.
Hi @Helflym ,
I apologize, I stated the problem incorrectly. crtcxa_s.o
and crtdbase.o
are not missing in the 10.3.0 version of gcc. Instead the 32 bit version of these files were found in the ppc64
directory. I ran the file
command:
bash-5.1# file /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/10/pthread/ppc64/crtdbase.o /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/10/pthread/ppc64/crtdbase.o: executable (RISC System/6000) or object module not stripped bash-5.1# file /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/10/pthread/ppc64/crtcxa_s.o /opt/freeware/lib/gcc/powerpc-ibm-aix7.2.0.0/10/pthread/ppc64/crtcxa_s.o: executable (RISC System/6000) or object module not stripped
I believe these file should be 64 bits, file command should produce this output:
64-bit XCOFF executable or object module not stripped
The gccgo/gcc was reinstalled but those .o files are still 32 bits files.
To describe the other problems, I am using scenarios
to make it easier for discussion.
Scenario 0.
This is the base scenario from your article. It works with gccgo toolchain. Here are the files scenario0.tar.gz. You can run ./build.sh
to build it. When I use gcc -maix64 main.c wrapper.a -pthread -Wl, -bnoobjreorder
, the main hangs. I suppose this is the expected behavior for gccgo toolchain as go runtime needed to be initialized. Can we install both Golang and gccgo on the my AIX7.2? Will it be a problem if I use Golang toolchain to create the .a file then link this .a or .so file with a gccgo's gcc to compile the client? If yes, is this the version we should install? http://bullfreeware.com/pkg?id=7659
Scenario 1.
In this scenario, I want to simulate scenario where IBM MQ calls MQ Exits (shared lib) calls glue code (shared lib) calls Go library. In the attached files I have MQ.c -> glue.c -> wrapper.go. The wrapper.go is built with -buildmode=c-archive
. MQ.c is the main and it simulates MQ so I can't use it to initialize Go runtime. The initialization is done in glue.c. Here are my files for this scenario. scenario1.tar.gz. When you run ./build.sh
, you will see ld: 0711-317 ERROR: Undefined symbol: _end
Scenario 2.
In this scenario, instead of using -buildmode=c-archive
to build .a Go archive, I am using -buildmode=c-shared
to build Go shared library. This is needed for the glue code to load it manually. In order for -buildmode=c-shared
to work, I had to include the 64 bit crtcxa_s.o
and crtdbase.o
files:
go build -compiler=gccgo -gccgoflags="-lm -pthread -maix64 /opt/missing_gccgo_object/crtcxa_s.o /opt/missing_gccgo_object/crtdbase.o -lpthread" -o libwrapper.so -buildmode=c-shared wrapper.go
Here are files where it builds the .so file then main.c tries to load it manually then invoke the Add function.
scenario2.tar.gz
When you run build.sh
, you will see Function not implemented (Add)
.
Hopefully, you can run these scenarios on your vm to reproduce the errors. Thank you so much.
I apologize, I stated the problem incorrectly. crtcxa_s.o and crtdbase.o are not missing in the 10.3.0 version of gcc. Instead the 32 bit version of these files were found in the ppc64 directory.
That's because 64bit files are now named crtcxa_64_s.o
and crtdbase_64.o
. This is mandatory for the 64bit build of GCC. That's one of the reason one shouldn't add these files himself but let GCC do it. GccGo should be able to do it on its own, but this isn't the case.
Scenario 0.
You shouldn't be able to build the main
without -lgo
. If wrapper.a
is built with gccgo
with c-archive
, then it's a static library. Thus, when it's being linked to main
, libgo.a
must be provided to it.
When I'm doing gcc -maix64 main.c wrapper.a -pthread -Wl, -bnoobjreorder
, I have a lot of symbols missing but that's the correct behavior for me.
Can we install both Golang and gccgo on the my AIX7.2? Will it be a problem if I use Golang toolchain to create the .a file then link this .a or .so file with a gccgo's gcc to compile the client? If yes, is this the version we should install? http://bullfreeware.com/pkg?id=7659
If your question is "can I use a wrapper.a
build with Golang toolchain inside a C file ? The answer is yes. Otherwise, I'm not sure I understand the question.
function go_build() {
echo "Building with Go."
go build -buildmode=c-archive -o wrapper_go.a wrapper.go
if [[ "$?" != 0 ]]; then
echo "Building wrapper_go.a failed."
return
fi
gcc -maix64 main.c wrapper_go.a -pthread -Wl,-bnoobjreorder
if [[ "$?" != 0 ]]; then
echo "Building a.out failed."
return
fi
./a.out
}
This is working fine.
Note that go
command here is the one for Golang toolchain and that I've changed the include in main.c
to be wrapper_go.h
.
Scenario 1.
In this case, we end up in the same situation that I've described previously. Current libgo.a
is looking for symbols in the main
program (__go_init_main
, main.main
, etc) and because of XCOFF format, there is no way to search for these symbols in some loaded library (like libglue
). The only way would be to rebuild libgo.a
which will mean make it support c-shared
buildmode.
Note that there is something wrong in this scenario in all cases. You're using c-archive
buildmode to create code aimed for a shared library. It might work with gccgo toolchain but it's not meant to be. And that's the reason why it doesn't work with Golang toolchain. c-archive
using code and maybe internal functions only meant to be run in the main program. There is no guarantee that gccgo toolchain won't doing the same too.
Scenario 2.
The Function not implemented (Add).
appears because Add
isn't exported by libwrapper.so
. GccGo isn't able to understand by itself which functions should be exported. You'll need to provide these exported symbol in a export file and pass it with -bE:libwrapper.exp
to gccgoflags
.
However, even with that and after adding -lgolibbegin
to the gcc commands in order to find __go_init
, there are still some errors. This time inside Go runtime itself which means the problems is not just some compilations failures...
I'm sorry. But you're trying by different approaches to create a c-shared
Go library which isn't supported. I'm not sure any workarounds are possible on that.
Using Golang toolchain, this is simply impossible: the "shared" version of some code is simply not implemented at all.
Using GccGo toolchain, well as you can see there is a lot of problems even before reaching these "shared" mecanisms which might be able to be bypassed, gcc being able to create shared libraries unlike Go. However, if the runtime isn't supported it it won't be possible anyway.
It would need much further investigations. You can do it if you wish. However, I don't have the time myself for now.
Hi @Helflym , I understand. It looks like this is not a viable path to continue. I will consider other methods, maybe a client/server path. Thank you so much for your help. Merci beaucoup!
What version of Go are you using (
go version
)?http://www.bullfreeware.com/pkg?id=7266
Does this issue reproduce with the latest release?
This is the only version for AIX 7.1
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I want to create a shared object library on AIX 7.1 by following the instructions in this article: https://medium.com/learning-the-go-programming-language/calling-go-functions-from-other-languages-4c7d8bcc69bf I am trying to compile this file into a shared library: https://github.com/vladimirvivien/go-cshared-examples/blob/master/awesome.go Here is the command I used:
What did you expect to see?
I expect the shared library awesome.so created.
What did you see instead?
I got
ERROR: Undefined symbol: __gcc_unwind_dbase
. Here is the full output:I also try use -L, but I got the same error
Hi @Helflym, I read your article https://techchannel.com/IT-Strategy/09/2019/get-started-with-go. Any idea on how I can resolve this issue? Thanks!