[Bug 269455] Using LTO on powerpc64 generates broken binaries

From: <bugzilla-noreply_at_freebsd.org>
Date: Fri, 10 Feb 2023 09:23:29 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=269455

            Bug ID: 269455
           Summary: Using LTO on powerpc64 generates broken binaries
           Product: Base System
           Version: CURRENT
          Hardware: powerpc
                OS: Any
            Status: New
          Severity: Affects Many People
          Priority: ---
         Component: bin
          Assignee: bugs@FreeBSD.org
          Reporter: pkubaj@FreeBSD.org

This is a repost of https://github.com/llvm/llvm-project/issues/46697.
I'm creating a PR here, because it turns out that LTO itself works fine when
using lld from ports, but is broken with the base lld (lld 15 is also
affected). It looks like it has affected powerpc64 ever since the GCC -> LLVM
switch (so LLVM 9), but I never tried linking with ports lld until now.

I have a simple test program:
int main()
{
return 0;
}

and do:
root@talos-powerpc64:~ # clang -fuse-ld=/usr/local/bin/ld.lld15 -flto test.c
root@talos-powerpc64:~ # ./a.out
root@talos-powerpc64:~ # clang -flto test.c
root@talos-powerpc64:~ # ./a.out
Segmentation fault (core dumped)

I also deassembled both binaries and did a diff:
--- baselld.S   2023-02-09 23:53:53.171611000 +0100
+++ portslld.S  2023-02-09 23:53:58.827662000 +0100
@@ -1,5 +1,5 @@

-a.out2:        file format elf64-powerpc
+a.out: file format elf64-powerpc

 Disassembly of section .text:

@@ -20,7 +20,7 @@
 10010558: fb df 00 60          std 30, 96(31)
 1001055c: 7c be 2b 78          mr      30, 5
 ;      if (environ == NULL)
-10010560: e8 a4 80 70          ld 5, -32656(4)
+10010560: e8 a4 80 58          ld 5, -32680(4)
 10010564: fb 9f 00 50          std 28, 80(31)
 10010568: 28 25 00 00          cmpldi  5, 0
 1001056c: 7c 7c 1b 78          mr      28, 3
@@ -33,7 +33,7 @@
 ;      if (environ == NULL)
 10010588: 40 82 00 0c          bf      2, 0x10010594 <_start+0x68>
 ;              environ = env;
-1001058c: 38 64 80 70          addi 3, 4, -32656
+1001058c: 38 64 80 58          addi 3, 4, -32680
 10010590: fb c3 00 00          std 30, 0(3)
 ;      if (argc > 0 && argv[0] != NULL) {
 10010594: 2c 1c 00 01          cmpwi   28, 1
@@ -65,7 +65,7 @@
 100105e0: 41 82 00 10          bt      2, 0x100105f0 <_start+0xc4>
 ;              __ps_strings = ps_strings;
 100105e4: 3c 62 00 01          addis 3, 2, 1
-100105e8: 38 63 80 68          addi 3, 3, -32664
+100105e8: 38 63 80 50          addi 3, 3, -32688
 100105ec: f9 03 00 00          std 8, 0(3)
 ;      if (&_DYNAMIC != NULL)
 100105f0: 3c 62 ff ff          addis 3, 2, -1
@@ -95,8 +95,8 @@
 10010640: 3f 42 00 01          addis 26, 2, 1
 ;      for (;  aux->a_type != AT_NULL; aux++) {
 10010644: 7c 63 f2 14          add 3, 3, 30
-10010648: 38 9b 80 78          addi 4, 27, -32648
-1001064c: 38 ba 80 7c          addi 5, 26, -32644
+10010648: 38 9b 80 60          addi 4, 27, -32672
+1001064c: 38 ba 80 64          addi 5, 26, -32668
 10010650: 38 63 ff f8          addi 3, 3, -8
 10010654: 48 00 00 10          b 0x10010664 <_start+0x138>
 10010658: 7c a7 2b 78          mr      7, 5
@@ -144,9 +144,9 @@
 ;              target = ((ifunc_resolver_t)ptr)(cpu_features, cpu_features2,
 100106e0: 7d 89 03 a6          mtctr 12
 100106e4: 39 20 00 00          li 9, 0
-100106e8: 80 7b 80 78          lwz 3, -32648(27)
+100106e8: 80 7b 80 60          lwz 3, -32672(27)
 100106ec: 39 40 00 00          li 10, 0
-100106f0: 80 9a 80 7c          lwz 4, -32644(26)
+100106f0: 80 9a 80 64          lwz 4, -32668(26)
 100106f4: 4e 80 04 21          bctrl
 100106f8: e8 41 00 18          ld 2, 24(1)
 ;              *where = target;
@@ -169,10 +169,10 @@
 10010734: 4e 80 04 21          bctrl
 10010738: e8 41 00 18          ld 2, 24(1)
 ;      exit(main(argc, argv, env));
-1001073c: 3c 62 00 01          addis 3, 2, 1
+1001073c: 3c 62 ff fe          addis 3, 2, -2
 10010740: 7f a4 eb 78          mr      4, 29
 10010744: 7f c5 f3 78          mr      5, 30
-10010748: 39 83 80 50          addi 12, 3, -32688
+10010748: 39 83 7e 30          addi 12, 3, 32304
 1001074c: 7f 83 e3 78          mr      3, 28
 10010750: 7d 89 03 a6          mtctr 12
 10010754: 4e 80 04 21          bctrl
@@ -452,6 +452,8 @@
 10010b04: eb e1 ff f8          ld 31, -8(1)
 10010b08: 4e 80 00 20          blr
                ...
+
+0000000010010b18 <main>:
 10010b18: 38 60 00 00          li 3, 0
 10010b1c: 90 61 ff f4          stw 3, -12(1)
 10010b20: 38 60 00 00          li 3, 0



For some reason, main function is missing when linked with the base lld.
Since this issue is non-existent with lld from ports, it must be because of how
we built LLVM. It only affects powerpc64. powerpc and powerpc64le are not
affected.

If it's necessary to have access to some powerpc64 system for debugging, I can
arrange it.

-- 
You are receiving this mail because:
You are the assignee for the bug.