Building 32-bit FreeBSD mips using LLD as the linker reports several failures across two components due to "unsupported non-zero ri_gp_value".
LLD shows this error when an object file with non-zero ri_gp_value value in the .reginfo or .MIPS.options section is used to build a relocatable object (-r). Is it a regular object file or something "specific" like crt*.o? BTW you can check .reginfo or .MIPS.options content by the following command: llvm-readobj -mips-options -mips-reginfo *.o
The build uses -r only in a few special cases, although I see many objects with non-zero GP. One example object that is used with -r, from the rescue tools (built as described in https://svnweb.freebsd.org/base/head/usr.sbin/crunch/crunchide/crunchide.c?revision=308734&view=markup#l28): File: ./rescue/librescue/sysctl.o Format: ELF32-mips Arch: mips AddressSize: 32bit LoadName: MIPS RegInfo { GP: 0x4000 General Mask: 0xB23F03FC Co-Proc Mask0: 0x0 Co-Proc Mask1: 0x0 Co-Proc Mask2: 0x0 Co-Proc Mask3: 0x0 } There is no .MIPS.options section in the file. The other case comes from statically-linked libpam: File: ./lib/libpam/static_libpam/openpam_static_modules.o Format: ELF32-mips Arch: mips AddressSize: 32bit LoadName: MIPS RegInfo { GP: 0x7FF0 General Mask: 0xF2FF0FFC Co-Proc Mask0: 0x0 Co-Proc Mask1: 0x0 Co-Proc Mask2: 0x0 Co-Proc Mask3: 0x0 } There is no .MIPS.options section in the file.
Created attachment 17644 [details] reproducer for FreeBSD/mips linking error --- openpam_static_modules.o --- ld -o openpam_static_modules.o -r --whole-archive openpam_static.o ../modules/pam_chroot/libpam_chroot.a ../modules/pam_deny/libpam_deny.a ../modules/pam_echo/libpam_echo.a ../modules/pam_exec/libpam_exec.a ../modules/pam_ftpusers/libpam_ftpusers.a ../modules/pam_group/libpam_group.a ../modules/pam_guest/libpam_guest.a ../modules/pam_krb5/libpam_krb5.a ../modules/pam_ksu/libpam_ksu.a ../modules/pam_lastlog/libpam_lastlog.a ../modules/pam_login_access/libpam_login_access.a ../modules/pam_nologin/libpam_nologin.a ../modules/pam_opie/libpam_opie.a ../modules/pam_opieaccess/libpam_opieaccess.a ../modules/pam_passwdqc/libpam_passwdqc.a ../modules/pam_permit/libpam_permit.a ../modules/pam_radius/libpam_radius.a ../modules/pam_rhosts/libpam_rhosts.a ../modules/pam_rootok/libpam_rootok.a ../modules/pam_securetty/libpam_securetty.a ../modules/pam_self/libpam_self.a ../modules/pam_ssh/libpam_ssh.a ../modules/pam_tacplus/libpam_tacplus.a ../modules/pam_unix/libpam_unix.a ld: error: ../modules/pam_echo/libpam_echo.a(pam_echo.o): unsupported non-zero ri_gp_value ld: error: ../modules/pam_tacplus/libpam_tacplus.a(pam_tacplus.o): unsupported non-zero ri_gp_value *** [openpam_static_modules.o] Error code 1 (ignored)
LLD does not perform any relocation calculation when generate a relocatable output. If all input files have the same ri_gp_value value, we can just copy this value to the output file and do not touch the relocations at all. But usually ri_gp_value differ from each other. So to fix the bug we have to teach LLD to calculate relocations in "-r" mode. At the first glance the task does not look easy.
How do you build pam_echo.o or sysctl.o or any other object files with non-zero ri_gp_value? Are they in turn result of linking some other object files using -r option or just plain compiler output?
It looks like pam_echo is built like so: --- pam_echo.o --- cc -isystem /tank/emaste/obj/mips.mips/tank/emaste/src/freebsd-xlld/tmp/usr/include -L/tank/emaste/obj/mips.mips/tank/emaste/src/freebsd-xlld/tmp/usr/lib -B/tank/emaste/obj/mips.mips/tank/emaste/src/freebsd-xlld/tmp/usr/lib --sysroot=/tank/emaste/obj/mips.mips/tank/emaste/src/freebsd-xlld/tmp -B/tank/emaste/obj/mips.mips/tank/emaste/src/freebsd-xlld/tmp/usr/bin -DOPENPAM_STATIC_MODULES -O -pipe -G0 -EB -msoft-float -I/tank/emaste/src/freebsd-xlld/lib/libpam/modules/pam_echo/../../../../contrib/openpam/include -I/tank/emaste/src/freebsd-xlld/lib/libpam/modules/pam_echo/../../libpam -DOPENPAM_DEBUG -MD -MF.depend.pam_echo.o -MTpam_echo.o -std=gnu99 -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls -Wold-style-definition -Wno-pointer-sign -c /tank/emaste/src/freebsd-xlld/lib/libpam/modules/pam_echo/pam_echo.c -o pam_echo.o --- libpam_echo.a --- building static pam_echo library ar -crD libpam_echo.a `NM='nm' NMFLAGS='' lorder pam_echo.o | tsort -q` ranlib -D libpam_echo.a --- openpam_static_modules.o --- ld -o openpam_static_modules.o -r --whole-archive openpam_static.o ../modules/pam_chroot/libpam_chroot.a ../modules/pam_deny/libpam_deny.a ../modules/pam_echo/libpam_echo.a ../modules/pam_exec/libpam_exec.a ../modules/pam_ftpusers/libpam_ftpusers.a ../modules/pam_group/libpam_group.a ../modules/pam_guest/libpam_guest.a ../modules/pam_krb5/libpam_krb5.a ../modules/pam_ksu/libpam_ksu.a ../modules/pam_lastlog/libpam_lastlog.a ../modules/pam_login_access/libpam_login_access.a ../modules/pam_nologin/libpam_nologin.a ../modules/pam_opie/libpam_opie.a ../modules/pam_opieaccess/libpam_opieaccess.a ../modules/pam_passwdqc/libpam_passwdqc.a ../modules/pam_permit/libpam_permit.a ../modules/pam_radius/libpam_radius.a ../modules/pam_rhosts/libpam_rhosts.a ../modules/pam_rootok/libpam_rootok.a ../modules/pam_securetty/libpam_securetty.a ../modules/pam_self/libpam_self.a ../modules/pam_ssh/libpam_ssh.a ../modules/pam_tacplus/libpam_tacplus.a ../modules/pam_unix/libpam_unix.a ld: error: ../modules/pam_echo/libpam_echo.a(pam_echo.o): unsupported non-zero ri_gp_value ld: error: ../modules/pam_tacplus/libpam_tacplus.a(pam_tacplus.o): unsupported non-zero ri_gp_value *** [openpam_static_modules.o] Error code 1 (ignored)
(In reply to emaste from comment #6) > It looks like pam_echo is built like so: > > --- pam_echo.o --- > > cc -isystem > /tank/emaste/obj/mips.mips/tank/emaste/src/freebsd-xlld/tmp/usr/include > -L/tank/emaste/obj/mips.mips/tank/emaste/src/freebsd-xlld/tmp/usr/lib > -B/tank/emaste/obj/mips.mips/tank/emaste/src/freebsd-xlld/tmp/usr/lib > --sysroot=/tank/emaste/obj/mips.mips/tank/emaste/src/freebsd-xlld/tmp > -B/tank/emaste/obj/mips.mips/tank/emaste/src/freebsd-xlld/tmp/usr/bin > -DOPENPAM_STATIC_MODULES -O -pipe -G0 -EB -msoft-float > -I/tank/emaste/src/freebsd-xlld/lib/libpam/modules/pam_echo/../../../../ > contrib/openpam/include > -I/tank/emaste/src/freebsd-xlld/lib/libpam/modules/pam_echo/../../libpam > -DOPENPAM_DEBUG -MD -MF.depend.pam_echo.o -MTpam_echo.o -std=gnu99 > -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wno-unused-parameter > -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type > -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wunused-parameter > -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls > -Wold-style-definition -Wno-pointer-sign -c > /tank/emaste/src/freebsd-xlld/lib/libpam/modules/pam_echo/pam_echo.c -o > pam_echo.o I'm surprised that compiler generates an object file with non-zero ri_gp_value, so a few more questions: 1. What is "cc": gcc or Clang? 2. Does pam_echo.o has non-zero ri_gp_value right after compilation? 3. If answer on the second question is "yes", could you please make a preprocessed output from pam_echo.c and send it to me? I will try to reproduce generating of non-zero ri_gp_value by compiler.
Created attachment 18982 [details] preprocessed pam_echo .i and .s, along with .o obtained via % make TARGET_ARCH=mips buildenv Entering world for mips:mips For ZSH you must run: export CPUTYPE= % unset CPUTYPE % which cc /usr/obj/mips.mips/usr/home/emaste/src/freebsd-mips-lld/tmp/usr/bin/cc % cd lib/libpam/modules/pam_echo % make objlink % rm obj/* zsh: sure you want to delete all 10 files in /usr/home/emaste/src/freebsd-mips-lld/lib/libpam/modules/pam_echo/obj [yn]? y % % CFLAGS=--save-temps make pam_echo.o cc -isystem /usr/obj/mips.mips/usr/home/emaste/src/freebsd-mips-lld/tmp/usr/include -L/usr/obj/mips.mips/usr/home/emaste/src/freebsd-mips-lld/tmp/usr/lib -B/usr/obj/mips.mips/usr/home/emaste/src/freebsd-mips-lld/tmp/usr/lib --sysroot=/usr/obj/mips.mips/usr/home/emaste/src/freebsd-mips-lld/tmp -B/usr/obj/mips.mips/usr/home/emaste/src/freebsd-mips-lld/tmp/usr/bin -DOPENPAM_STATIC_MODULES --save-temps -G0 -mxgot -EB -mabi=32 -msoft-float -I/usr/home/emaste/src/freebsd-mips-lld/contrib/openpam/include -I/usr/home/emaste/src/freebsd-mips-lld/lib/libpam -DOPENPAM_DEBUG -MD -MF.depend.pam_echo.o -MTpam_echo.o -std=gnu99 -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls -Wold-style-definition -Wno-pointer-sign -c /usr/home/emaste/src/freebsd-mips-lld/lib/libpam/modules/pam_echo/pam_echo.c -o pam_echo.o % tar -cvJ -f pam_echo.txz obj/*
Coming back to this after some time, so I checked current FreeBSD with current LLD. Error still is: ld: error: ../modules/pam_echo/libpam_echo.a(pam_echo.o): unsupported non-zero ri_gp_value ld: error: ../modules/pam_tacplus/libpam_tacplus.a(pam_tacplus.o): unsupported non-zero ri_gp_value 1. this is compiled with (old) gcc: % readelf --string-dump=.comment modules/pam_echo/pam_echo.o String dump of section '.comment': [ 1] $FreeBSD$ [ b] GCC: (GNU) 4.2.1 20070831 patched [FreeBSD] 2. Yes, the transformations leading up to the error are in full: cc -isystem /usr/obj/mips.mips/usr/home/emaste/src/freebsd-mips-lld/tmp/usr/include -L/usr/obj/mips.mips/usr/home/emaste/src/freebsd-mips-lld/tmp/usr/lib -B/usr/obj/mips.mips/usr/home/emaste/src/freebsd-mips-lld/tmp/usr/lib --sysroot=/usr/obj/mips.mips/usr/home/emaste/src/freebsd-mips-lld/tmp -B/usr/obj/mips.mips/usr/home/emaste/src/freebsd-mips-lld/tmp/usr/bin -DOPENPAM_STATIC_MODULES -O -pipe -G0 -mxgot -EB -mabi=32 -msoft-float -I/usr/home/emaste/src/freebsd-mips-lld/contrib/openpam/include -I/usr/home/emaste/src/freebsd-mips-lld/lib/libpam -DOPENPAM_DEBUG -MD -MF.depend.pam_echo.o -MTpam_echo.o -std=gnu99 -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls -Wold-style-definition -Wno-pointer-sign -c /usr/home/emaste/src/freebsd-mips-lld/lib/libpam/modules/pam_echo/pam_echo.c -o pam_echo.o ar -crD libpam_echo.a `NM='nm' NMFLAGS='' lorder pam_echo.o | tsort -q` ranlib -D libpam_echo.a So pam_echo.o is as output by gcc 4.2.1, and it's just ar+ranlib for libpam_echo.a as lld input. nuc% readelf -A modules/pam_echo/pam_echo.o Section '.reginfo' contains 1 entries: REGINFO ri_gprmask: 0xf2ff00fc ri_cprmask[0]: 0x00000000 ri_cprmask[1]: 0x00000000 ri_cprmask[2]: 0x00000000 ri_cprmask[3]: 0x00000000 ri_gp_value: 0x4000 3. Preprocessed pam_echo attached
Created attachment 20034 [details] Patch for LLD to implement handling of non-zero ri_gp_value
Ed, could you try the ri_gp_value.patch attached to this bug report? I hope it fixes the problem.
(In reply to Simon Atanasyan from comment #11) > Ed, could you try the ri_gp_value.patch attached to this bug report? I hope > it fixes the problem. I massaged the patch slightly to apply it to the lld in my FreeBSD working branch (6.0 + Multi-GOT) and will let it build tonight.
With the patch I'm able to build rescue, one of the components that previously failed. (I have not yet been able to test the result.)
(In reply to emaste from comment #13) > With the patch I'm able to build rescue, one of the components that > previously failed. (I have not yet been able to test the result.) Do you plan to test the result? If so, when do you plan to do that? I ask to just schedule me future tasks.
I hope r331772 fixes the bug.