[llvm-dev] [lld 11.0.0] ppc64 branch-to-fd

Amol via llvm-dev llvm-dev at lists.llvm.org
Thu Apr 2 07:57:31 PDT 2020


Thank you!

I did not know that lld does not support v1 abi.

Manually setting e_flags to 1, inside the ELF headers of
the object files, now allows lld to show the error:

ld.lld 1.o 2.o
ld.lld: error: 1.o: ABI version 1 is not supported
ld.lld: error: 2.o: ABI version 1 is not supported

-amol

On 02/04/2020, Sean Fertile <sd.fertile at gmail.com> wrote:
> Missed adding the dev-list in the reply so resending.
>
> I believe the bug is that Clang should be setting the e_flags field in the
> ELF header to 1 when producing an object file which uses the
> function-descriptor based ABI. LLD only supports the V2 ELF ABI for
> PowerPC64, which doesn't use function descriptors. LLD will accept object
> files with e_flags equal to 2 (V2 ABI specific) or 0 (unspecified
> nature),and without the correct flags LLD unfortunately can't detect the
> invalid input.
>
> Regards
> Sean
>
>
>
> On Thu, Apr 2, 2020 at 10:04 AM Sean Fertile <sd.fertile at gmail.com> wrote:
>
>> I believe the bug is that Clang should be setting the e_flags field in
>> the
>> ELF header to 1 when producing an object file which uses the
>> function-descriptor based ABI. LLD only supports the V2 ELF ABI for
>> PowerPC64, which doesn't use function descriptors. LLD will accept object
>> files with e_flags equal to 2 (V2 ABI specific) or 0 (unspecified
>> nature),and without the correct flags LLD unfortunately can't detect the
>> invalid input.
>>
>> Regards
>> Sean
>>
>>
>> On Thu, Apr 2, 2020 at 1:34 AM Amol via llvm-dev
>> <llvm-dev at lists.llvm.org>
>> wrote:
>>
>>> Hello,
>>>
>>> [clang/lld version 11.0.0, built on 1Apr20 using source
>>> downloaded from github.]
>>>
>>> When compiling for ppc64 big-endian target, a branch-with-link
>>> targets the function descriptor instead of the function entry.
>>>
>>> Below is a sample:
>>>
>>> /*1.c*/
>>> int main();
>>> int _start(){return main();}
>>>
>>> /*2.c*/
>>> int g_var=20;
>>> int main(){return g_var;}
>>>
>>> /* build */
>>> clang -target ppc64 -O3 -c 1.c
>>> clang -target ppc64 -O3 -c 2.c
>>> ld.lld 1.o 2.o
>>>
>>> The dissassembly shows that _start branches to the
>>> FD(0x...230) instead of to the entry point (0x...1f8):
>>>
>>> 00000000100101c8 <.text>:
>>> . . .
>>> 100101d4: 48 02 00 5d                   bl 0x10030230; <-- bl to FD?
>>> . . .
>>> 100101f8: 3c 62 00 01                   addis 3, 2, 1 <-- main entry pt.
>>> 100101fc: e8 63 80 3a                   lwa 3, -32712(3)
>>> 10010200: 4e 80 00 20                   blr
>>>
>>> SYMBOL TABLE:
>>> 0000000010030230 g     F .opd   0000000000000018 main
>>>
>>> FD of main:
>>> 00000230:  00 00 00 00 10 01 01 f8  00 00 00 00 10 02 82 10
>>> 00000240:  00 00 00 00 00 00 00 00
>>>
>>> The compiler emits a relocation within the object 1.o:
>>> RELOCATION RECORDS FOR [.text]:
>>> OFFSET           TYPE                     VALUE
>>> 000000000000000c R_PPC64_REL24            main
>>>
>>> The relevant code seems to be the function
>>> PPC64::relocate inside lld/ELF/Arch/PPC64.cpp
>>> when it receives R_PPC64_REL24  as rel (with
>>> val 0x2005c in this particular case).
>>>
>>> GNU ld for ppc64 emits a correct bl instruction.
>>>
>>> Is this a bug with lld, or did I simply miss giving
>>> it a switch on its commandline?
>>>
>>> Thank you,
>>> amol
>>> _______________________________________________
>>> LLVM Developers mailing list
>>> llvm-dev at lists.llvm.org
>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>
>>
>


More information about the llvm-dev mailing list