Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Nov 2018 08:48:45 -0800
From:      Mark Millard <marklmi@yahoo.com>
To:        FreeBSD Toolchain <freebsd-toolchain@freebsd.org>
Cc:        Jan Beich <jbeich@FreeBSD.org>, ports-list freebsd <freebsd-ports@freebsd.org>
Subject:   Re: ports head -r487783: on armv7 x11/pixman fails to build:  /usr/bin/ld: error: can't create dynamic relocation R_ARM_V4BX against local  symbol in readonly segment; recompile object files with -fPIC [lld/trunk has afix]
Message-ID:  <872CB297-10D5-4A1C-B01F-B00A9256E9D2@yahoo.com>
In-Reply-To: <4BEBC4A6-D9F2-4838-8DAB-4B494D4E0B0D@yahoo.com>
References:  <A76D7D49-E36E-4665-AA4B-D083CCF7D57B@yahoo.com> <a7m8-loy5-wny@FreeBSD.org> <03FFE5BB-777D-40D3-9AA3-C8C359BE1F2B@yahoo.com> <908FD96A-9F8F-4477-8E2F-2C97D49AF35E@yahoo.com> <F744DFE3-DB37-4A95-8C8E-DC1A5507D402@yahoo.com> <4BEBC4A6-D9F2-4838-8DAB-4B494D4E0B0D@yahoo.com>

next in thread | previous in thread | raw e-mail | index | archive | help
[The update to lld/trunk/ELF/Arch/ARM.cpp will not fix
what we have run into.]

On 2018-Nov-16, at 19:35, Mark Millard <marklmi at yahoo.com> wrote:

> Such timing: https://reviews.llvm.org/D53444 indicates
> commits to lld/trunk/ELF/Arch/ARM.cpp today (2018-Nov-16)
> to support R_ARM_V4BX in lld.
>=20
> (No update text below. The above just did not fit well.)
>=20
> On 2018-Nov-16, at 18:49, Mark Millard <marklmi at yahoo.com> wrote:
>=20
>=20
>> On 2018-Nov-16, at 18:15, Mark Millard <marklmi at yahoo.com> wrote:
>>=20
>>>=20
>>> I finally figured out parts of the issue, I think.
>>> At least how the V_ARM_V4BX use is getting there
>>> despite lld's status for handling it . . .
>>>=20
>>> On armv7:
>>>=20
>>> # more test_bx_lr.S
>>>      .text
>>>      .arch armv6
>>>      .object_arch armv4
>>>      .arm
>>>      .altmacro
>>>      .p2align 2
>>>      .func fname
>>>      .global fname
>>>      .hidden fname
>>>      .type fname, %function
>>>      fname:
>>>      bx      lr
>>>=20
>>> (I got those lines from the failing port's .S files,
>>> including includes. Note the .object_arch armv4 use
>>> and the forced armv6, not armv7.)
>>=20
>> For reference relative to the use of .object_arch armv4 :
>>=20
>> # grep -r object_arch =
/wrkdirs/usr/ports/x11/pixman/work/pixman-0.34.0/pixman/ | more
>> =
/wrkdirs/usr/ports/x11/pixman/work/pixman-0.34.0/pixman/pixman-arm-neon-as=
m.S:    .object_arch armv4
>> =
/wrkdirs/usr/ports/x11/pixman/work/pixman-0.34.0/pixman/pixman-arm-simd-as=
m-scaled.S:   .object_arch armv4
>> =
/wrkdirs/usr/ports/x11/pixman/work/pixman-0.34.0/pixman/pixman-arm-neon-as=
m-bilinear.S:.object_arch armv4
>> =
/wrkdirs/usr/ports/x11/pixman/work/pixman-0.34.0/pixman/pixman-arm-simd-as=
m.S:  .object_arch armv4
>>=20
>> Without .object_arch armv4 the assembler involved does not output
>> the V_ARM_V4BX *ABS* relocation records (adjusted the small example):
>>=20
>> # objdump -x test_bx_lr.o | more
>>=20
>> test_bx_lr.o:     file format elf32-littlearm
>> test_bx_lr.o
>> architecture: arm, flags 0x00000010:
>> HAS_SYMS
>> start address 0x00000000
>> private flags =3D 5000000: [Version5 EABI]
>>=20
>> Sections:
>> Idx Name          Size      VMA       LMA       File off  Algn
>> 0 .text         00000004  00000000  00000000  00000034  2**2
>>                 CONTENTS, ALLOC, LOAD, READONLY, CODE
>> 1 .data         00000000  00000000  00000000  00000038  2**0
>>                 CONTENTS, ALLOC, LOAD, DATA
>> 2 .bss          00000000  00000000  00000000  00000038  2**0
>>                 ALLOC
>> 3 .ARM.attributes 0000001b  00000000  00000000  00000038  2**0
>>                 CONTENTS, READONLY
>> SYMBOL TABLE:
>> 00000000 l    d  .text  00000000 .text
>> 00000000 l    d  .data  00000000 .data
>> 00000000 l    d  .bss   00000000 .bss
>> 00000000 l    d  .ARM.attributes        00000000 .ARM.attributes
>> 00000000 g     F .text  00000000 .hidden fname
>>=20
>>=20
>>=20
>>> # clang -target armv7-unknown-freebsd13.0-gnueabihf -O -pipe =
-no-integrated-as  -MT test_bx_lr.lo -MD -MP -MF test_bx_lr.Tpo -c =
test_bx_lr.S -fPIC -DPIC -o test_bx_lr.o
>>>=20
>>> (The -target is not necessary. I just choose to be explicit.)
>>>=20
>>> # objdump -x test_bx_lr.o | more
>>>=20
>>> test_bx_lr.o:     file format elf32-littlearm
>>> test_bx_lr.o
>>> architecture: armv4, flags 0x00000011:
>>> HAS_RELOC, HAS_SYMS
>>> start address 0x00000000
>>> private flags =3D 5000000: [Version5 EABI]
>>>=20
>>> Sections:
>>> Idx Name          Size      VMA       LMA       File off  Algn
>>> 0 .text         00000004  00000000  00000000  00000034  2**2
>>>                CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
>>> 1 .data         00000000  00000000  00000000  00000038  2**0
>>>                CONTENTS, ALLOC, LOAD, DATA
>>> 2 .bss          00000000  00000000  00000000  00000038  2**0
>>>                ALLOC
>>> 3 .ARM.attributes 0000001b  00000000  00000000  00000038  2**0
>>>                CONTENTS, READONLY
>>> SYMBOL TABLE:
>>> 00000000 l    d  .text  00000000 .text
>>> 00000000 l    d  .data  00000000 .data
>>> 00000000 l    d  .bss   00000000 .bss
>>> 00000000 l    d  .ARM.attributes        00000000 .ARM.attributes
>>> 00000000 g     F .text  00000000 .hidden fname
>>>=20
>>>=20
>>> RELOCATION RECORDS FOR [.text]:
>>> OFFSET   TYPE              VALUE=20
>>> 00000000 R_ARM_V4BX        *ABS*
>>>=20
>>>=20
>>> truss for that cc command reports looking in many
>>> places for as, finally finding /usr/local/bin/as :
>>>=20
>>> access("/usr/bin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>> access("/usr/bin/as",X_OK|R_OK)			 ERR#2 'No such =
file or directory'
>>>=20
>>> (Note: based on WITHOUT_BINUTILS=3D for buildworld the above would =
normally
>>> not be found. But for WITH_BINUTILS=3D the host as would be found.)
>>>=20
>>> access("/sbin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>> access("/bin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>> access("/usr/sbin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>> access("/usr/bin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>> =
access("/usr/local/sbin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|R_OK)=
 ERR#2 'No such file or directory'
>>> =
access("/usr/local/bin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>> =
access("/usr/home/markmi/bin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|=
R_OK) ERR#2 'No such file or directory'
>>> access("/sbin/as",X_OK|R_OK)			 ERR#2 'No such =
file or directory'
>>> access("/bin/as",X_OK|R_OK)			 ERR#2 'No such file or =
directory'
>>> access("/usr/sbin/as",X_OK|R_OK)		 ERR#2 'No such file or =
directory'
>>> access("/usr/bin/as",X_OK|R_OK)			 ERR#2 'No such =
file or directory'
>>> access("/usr/local/sbin/as",X_OK|R_OK)		 ERR#2 'No such =
file or directory'
>>> access("/usr/local/bin/as",X_OK|R_OK)		 =3D 0 (0x0)
>>>=20
>>> (Note the =
/usr/home/markmi/bin/armv7-unknown-freebsd13.0-gnueabihf-as attempt
>>> before the one actually found and used. I would not have guessed the
>>> need to worry about such a place.)
>>>=20
>>> Then follows:
>>>=20
>>> fstatat(AT_FDCWD,"/usr/local/bin/as",{ mode=3D-r-xr-xr-x =
,inode=3D80287,size=3D21817416,blksize=3D32768 },0x0) =3D 0 (0x0)
>>> __sysctl(0xbfbfe020,0x2,0xbfbfe018,0xbfbfe01c,0xe,0x236c9140) =3D 0 =
(0x0)
>>> access("/usr/bin/clang",F_OK)			 =3D 0 (0x0)
>>> vfork()						 =3D 61461 =
(0xf015)
>>> wait4(61461,{ EXITED,val=3D0 },0x0,0x0)		 =3D 61461 =
(0xf015)
>>> access("/usr/local/bin/as",F_OK)		 =3D 0 (0x0)
>>> vfork()						 =3D 61462 =
(0xf016)
>>> wait4(61462,{ EXITED,val=3D0 },0x0,0x0)		 =3D 61462 =
(0xf016)
>>> access("/tmp/test_bx_lr-0c7bf8.s",W_OK)		 =3D 0 (0x0)
>>> fstatat(AT_FDCWD,"/tmp/test_bx_lr-0c7bf8.s",{ mode=3D-rw-r--r-- =
,inode=3D802647,size=3D210,blksize=3D32768 },0x0) =3D 0 (0x0)
>>> fstatat(AT_FDCWD,"/tmp/test_bx_lr-0c7bf8.s",{ mode=3D-rw-r--r-- =
,inode=3D802647,size=3D210,blksize=3D32768 },AT_SYMLINK_NOFOLLOW) =3D 0 =
(0x0)
>>> fstatat(AT_FDCWD,"/tmp/test_bx_lr-0c7bf8.s",{ mode=3D-rw-r--r-- =
,inode=3D802647,size=3D210,blksize=3D32768 },AT_SYMLINK_NOFOLLOW) =3D 0 =
(0x0)
>>> unlink("/tmp/test_bx_lr-0c7bf8.s")		 =3D 0 (0x0)
>>>=20
>>> llvm/clang is not providing the assembler used for -no-integrated-as =
.
>>> This would appear to imply that a system without ports or other such
>>> can not use -no-integrated-as with clang for buildworld buildkernel.
>>>=20
>>> In my normal armv7 command line context the above ends up using:
>>>=20
>>> # /usr/local/bin/as -v
>>> GNU assembler version 2.30 (armv7-portbld-freebsd13.0) using BFD =
version (GNU Binutils) 2.30
>>>=20
>>> So a GNU toolchain's as is actually in control of what goes in
>>> the .o file in many contexts. It is not clear that all the
>>> alternatives are equivalent for R_ARM_V4BX being generated
>>> or not.
>>>=20
>>>=20
>>> Simplifying the command (but still showing target):
>>>=20
>>> # clang -target armv7-unknown-freebsd13.0-gnueabihf -pipe =
-no-integrated-as -c test_bx_lr.S -o test_bx_lr.o
>>>=20
>>> # objdump -x test_bx_lr.o | more
>>>=20
>>> test_bx_lr.o:     file format elf32-littlearm
>>> test_bx_lr.o
>>> architecture: armv4, flags 0x00000011:
>>> HAS_RELOC, HAS_SYMS
>>> start address 0x00000000
>>> private flags =3D 5000000: [Version5 EABI]
>>>=20
>>> Sections:
>>> Idx Name          Size      VMA       LMA       File off  Algn
>>> 0 .text         00000004  00000000  00000000  00000034  2**2
>>>                CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
>>> 1 .data         00000000  00000000  00000000  00000038  2**0
>>>                CONTENTS, ALLOC, LOAD, DATA
>>> 2 .bss          00000000  00000000  00000000  00000038  2**0
>>>                ALLOC
>>> 3 .ARM.attributes 0000001b  00000000  00000000  00000038  2**0
>>>                CONTENTS, READONLY
>>> SYMBOL TABLE:
>>> 00000000 l    d  .text  00000000 .text
>>> 00000000 l    d  .data  00000000 .data
>>> 00000000 l    d  .bss   00000000 .bss
>>> 00000000 l    d  .ARM.attributes        00000000 .ARM.attributes
>>> 00000000 g     F .text  00000000 .hidden fname
>>>=20
>>>=20
>>> RELOCATION RECORDS FOR [.text]:
>>> OFFSET   TYPE              VALUE=20
>>> 00000000 R_ARM_V4BX        *ABS*
>>>=20
>>>=20
>>> Without the -no-integrated-as the notation in the file is rejected,
>>> with "unknown directive" for .func .
>>>=20
>>>=20
>>>=20
>>> Using poudriere bulk with -i and installing binutils in the
>>> session, I see the same inside my amd64->armv7 cross build
>>> environment. So there still is the question of how R_ARM_V4BX
>>> is handled by various lld's in various contexts. (Or whatever
>>> linker is being used if it is not lld.)
>>>=20
>>> Back to amd64 land . . .
>>>=20
>>> Renaming the existing as files so we can see all the places
>>> searched before not-found is declared (on amd64 with -target
>>> specified):
>>>=20
>>> access("/usr/bin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>> access("/usr/bin/as",X_OK|R_OK)			 ERR#2 'No such =
file or directory'
>>> access("/usr/bin/x86_64-unknown-freebsd13.0-as",X_OK|R_OK) ERR#2 'No =
such file or directory'
>>> access("/sbin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>> access("/bin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>> access("/usr/sbin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>> access("/usr/bin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>> =
access("/usr/local/sbin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|R_OK)=
 ERR#2 'No such file or directory'
>>> =
access("/usr/local/bin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>> =
access("/usr/home/markmi/bin/armv7-unknown-freebsd13.0-gnueabihf-as",X_OK|=
R_OK) ERR#2 'No such file or directory'
>>> access("/sbin/as",X_OK|R_OK)			 ERR#2 'No such =
file or directory'
>>> access("/bin/as",X_OK|R_OK)			 ERR#2 'No such file or =
directory'
>>> access("/usr/sbin/as",X_OK|R_OK)		 ERR#2 'No such file or =
directory'
>>> access("/usr/bin/as",X_OK|R_OK)			 ERR#2 'No such =
file or directory'
>>> access("/usr/local/sbin/as",X_OK|R_OK)		 ERR#2 'No such =
file or directory'
>>> access("/usr/local/bin/as",X_OK|R_OK)		 ERR#2 'No such =
file or directory'
>>> access("/usr/home/markmi/bin/as",X_OK|R_OK)	 ERR#2 'No such file or =
directory'
>>> access("/sbin/x86_64-unknown-freebsd13.0-as",X_OK|R_OK) ERR#2 'No =
such file or directory'
>>> access("/bin/x86_64-unknown-freebsd13.0-as",X_OK|R_OK) ERR#2 'No =
such file or directory'
>>> access("/usr/sbin/x86_64-unknown-freebsd13.0-as",X_OK|R_OK) ERR#2 =
'No such file or directory'
>>> access("/usr/bin/x86_64-unknown-freebsd13.0-as",X_OK|R_OK) ERR#2 'No =
such file or directory'
>>> access("/usr/local/sbin/x86_64-unknown-freebsd13.0-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>> access("/usr/local/bin/x86_64-unknown-freebsd13.0-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>> =
access("/usr/home/markmi/bin/x86_64-unknown-freebsd13.0-as",X_OK|R_OK) =
ERR#2 'No such file or directory'
>>>=20
>>> (Note: It actually explicitly tries to use the x86_64 assembler if =
it
>>> does not find an armv7 or a generically pathed one. The generically
>>> pathed ones would normally also be x86_64 ones.)
>>>=20
>>>=20
>>> Another thing of note (using aarch64 as an example):
>>>=20
>>> /usr/local/aarch64-unknown-freebsd13.0/bin/as
>>>=20
>>> does not appear to be someplace that clang would find as
>>> but is a place devel/aarch64-binutils puts one.


The change is (leading whitespace possibly not preserved):
(lines 517-522 with only one line number on the line are
new)

373		void ARM::relocateOne(uint8_t *Loc, RelType Type, =
uint64_t Val) const {
. . .
516	516		    break;
	517		  case R_ARM_V4BX:
	518		    // V4BX is just a marker to indicate there's =
a "bx rN" instruction at the
	519		    // given address. It can be used to =
implement a special linker mode which
	520		    // rewrites ARMv4T inputs to ARMv4. Since we =
support only ARMv4 input and
	521		    // not ARMv4 output, we can just ignore it.
	522		    break;
517	523		  default:
518	524		    error(getErrorLocation(Loc) + "unrecognized =
reloc " + Twine(Type));
519	525		  }
520	526

But we have not gotten the unrecognized reloc message. Our
examples did not go through  ARM::relocateOne with a
R_ARM_V4BX .

The native poudriere build reached different code in a different
routine with a different error message. The "can't create dynamic
relocation" message is from lld/ELF/Relocations.cpp and its
static RelExpr adjustExpr template.

The amd64->armv7 cross-builds have not gotten any messages.
(No direct evidence of part of its specific code path, but
clearly not either of the message paths noted above.)

So there are at last 3 distinct code flow paths for R_ARM_V4BX
*ABS* handling in actual operation across the clang/llvm/lld
variants tried, including some where the same lld source
was used to build lld but different results happened.

It leaves me wondering if something(s) uninitialized is(are)
controlling what code ends up trying to handle the R_ARM_V4BX
*ABS* .



=3D=3D=3D
Mark Millard
marklmi at yahoo.com
( dsl-only.net went
away in early 2018-Mar)




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?872CB297-10D5-4A1C-B01F-B00A9256E9D2>