[Bug middle-end/61577] [4.9.0 Regression] can't compile on hp-ux v3 ia64

peter.bisroev at groundlabs dot com gcc-bugzilla@gcc.gnu.org
Sat Feb 22 00:36:00 GMT 2020


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61577

--- Comment #192 from Peter Bisroev <peter.bisroev at groundlabs dot com> ---
(In reply to dave.anglin from comment #191)
> On 2020-02-19 9:50 p.m., peter.bisroev at groundlabs dot com wrote:
> The problem seems to be that HP ld doesn't handle the PCREL21B relocation
> correctly when it refers
> to a weak function (i.e., it doesn't direct the call through the PLT).  At
> the same time, weak references
> don't seem to work with aCC.
> 
> As far as I can tell, the PCREL21B is generated by gas in
> gas/config/tc-ia64.c at line 5919.  You could try
> changing it to PCREL21BI to see if that helps (run binutils testsuite before
> installing) but the change doesn't
> seem correct.  We might need to generate a 32-bit branch to weak functions
> in gcc.

Hi Dave, thanks for the hint! I have patched by binutils 2.32 as shown in the
diff below.
------------------------------
*** ./gas/config/tc-ia64.c.orig Fri Feb 21 23:52:59 2020
--- ./gas/config/tc-ia64.c      Fri Feb 21 23:54:04 2020
***************
*** 5919,5925 ****
          else if (opnd == IA64_OPND_TGT25b)
            fix->code = BFD_RELOC_IA64_PCREL21M;
          else if (opnd == IA64_OPND_TGT25c)
!           fix->code = BFD_RELOC_IA64_PCREL21B;
          else if (opnd == IA64_OPND_TGT64)
            fix->code = BFD_RELOC_IA64_PCREL60B;
          else
--- 5919,5925 ----
          else if (opnd == IA64_OPND_TGT25b)
            fix->code = BFD_RELOC_IA64_PCREL21M;
          else if (opnd == IA64_OPND_TGT25c)
!           fix->code = BFD_RELOC_IA64_PCREL21BI;
          else if (opnd == IA64_OPND_TGT64)
            fix->code = BFD_RELOC_IA64_PCREL60B;
          else
------------------------------

After recompiling binutils gas failed only two more unit tests than before:
------------------------------
FAIL: ia64 tls
FAIL: ia64 relocations
------------------------------
After looking at both of these I guess it is expected as both of them expect
PCREL21B instead of PCREL21BI.

I have then attempted to recompile gcc 4.7.4 with this patched gas.
Unfortunately that fails during linking when xgcc tries to build
hpux64/libgcc_s.so.0.tmp in 64bit mode during stage 1. An example of an error
is:
------------------------------
ld: Unsatisfied symbol"calloc" in file "emutls_s.o": Expect to be defined in
the load module.
------------------------------

Taking a quick look at emutls_s.o I can see the expected reallocation
------------------------------
$ readelf -r ./ia64-hp-hpux11.31/hpux64/libgcc/emutls_s.o | grep calloc
0000000004d2  002200000079 R_IA64_PCREL21BI  0000000000000000 calloc + 0
------------------------------

But I have not dug dipper as to why the HP linker is unhappy there. Please let
me know if you want me to do so.

> It would be useful to find out why weak doesn't work with aCC.
I wanted to see if there is some offical docs on this from HP.

Going through aCC's programmers guide
(https://support.hpe.com/hpesc/public/docDisplay?docLocale=en_US&docId=emr_na-c05054285)
for my version of aCC ("HP C/aC++ B3910B A.06.29 [Oct 18 2016]", "as: HP
Itanium Assembler B.11.31 (HP-UX/itanium)", "ld: 92453-07 linker ld HP
Itanium(R) B.12.65  IPF/IPF"). I cannot find anything relevant to 'weak' in
section 3, or generally in that reference guide.

"Intel(R) Itanium(R) Architecture Assembly Language Reference Guide"
(https://software.intel.com/sites/default/files/m/d/4/1/d/8/asm_lan.pdf) does
mention weak symbols. This is also the same syntax that HP's as seems to
accept.

However in "HP-UX Linker and Libraries User Guide"
(https://support.hpe.com/hpesc/public/docDisplay?docLocale=en_US&docId=a00055697en_us)
on page 59, for nm, it states:
------------------------------
Distinguish between weak and global symbols by appending * to the key letterof
weak symbols. 
------------------------------

So it looks like HP's as and ld should support weak symbols so I have decided
to test it.

------------------------------
// main.cc

extern "C" {
    void hello() __attribute__ ((weak));
}

int main() {
    hello();
    return 0;
}
------------------------------

------------------------------
// hello.s
//   Adapted from "Hello World" Function Without
//   Unwind Directives from Intel Itanium Architecture
//   Assembly Language Reference Guide.

.section .rdata, "a", "progbits"
.align 8
.STRING1:
stringz "Hello World!!!\n"


.text
.global hello
.proc hello
hello: alloc loc2 = ar.pfs, 0, 4, 1, 0
mov loc3 = sp
mov loc1 = b0
addl out0 = @ltoff(.STRING1), gp
;;
ld8 out0 = [out0]
mov loc0 = gp
br.call.sptk.many b0 = printf
;;
mov gp = loc0
mov ar.pfs = loc2
mov b0 = loc1
mov sp = loc3
br.ret.sptk.many b0
.endp hello

.weak printf
.type printf, @function
------------------------------

------------------------------
$ aCC +w -g0 +O0 +d -c -o main.o main.cc
$ aCC +w -g0 +O0 +d -S -o main.s main.cc
$ as -o hello.o hello.s
$ aCC +w -g0 +O0 +d -o hello main.o hello.o
------------------------------

Now if I dump hello.o I get printf as a weak symbol as expected:
------------------------------
$ readelf -s -r hello.o 

Relocation section '.rela.text' at offset 0xa0 contains 2 entries:
 Offset     Info    Type            Sym.Value  Sym. Name + Addend
00000010  00000232 R_IA64_LTOFF22    00000000   .rdata + 0
00000020  00000449 R_IA64_PCREL21B   00000000   printf + 0

Symbol table '.symtab' contains 5 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS hello.s
     2: 00000000     0 SECTION LOCAL  DEFAULT    1 .rdata
     3: 00000000    80 FUNC    GLOBAL DEFAULT    2 hello
     4: 00000000     0 FUNC    WEAK   DEFAULT  UND printf
------------------------------

Now the same for main.o, but that that shows that 'hello' is a global symbol
instead of weak as expected.
------------------------------
$ readelf -s -r main.o

Relocation section '.rela.IA_64.unwind' at offset 0x40 contains 3 entries:
 Offset     Info    Type            Sym.Value  Sym. Name + Addend
00000000  0000045c R_IA64_SEGREL32MS 00000000   .text + 0
00000004  0000045c R_IA64_SEGREL32MS 00000000   .text + 70
00000008  0000095c R_IA64_SEGREL32MS 00000000   .IA_64.unwind_info + 4

Relocation section '.rela.IA_64.unwind_info' at offset 0x7c contains 1 entry:
 Offset     Info    Type            Sym.Value  Sym. Name + Addend
00000000  00000a5c R_IA64_SEGREL32MS 00000000   .HP.opt_annot + 0

Relocation section '.rela.text' at offset 0x100 contains 1 entry:
 Offset     Info    Type            Sym.Value  Sym. Name + Addend
00000022  00000b49 R_IA64_PCREL21B   00000000   hello + 0

Relocation section '.rela.debug_info' at offset 0x538 contains 6 entries:
 Offset     Info    Type            Sym.Value  Sym. Name + Addend
00000006  00000564 R_IA64_SECREL32MS 00000000   .debug_abbrev + 0
0000000c  00000264 R_IA64_SECREL32MS 00000000   .debug_line + 0
00000010  00000364 R_IA64_SECREL32MS 00000000   .debug_actual + 0
00000014  00000764 R_IA64_SECREL32MS 00000000   .debug_macinfo + 0
0000038d  00000424 R_IA64_DIR32MSB   00000000   .text + 0
00000391  00000424 R_IA64_DIR32MSB   00000000   .text + 70

Relocation section '.rela.debug_procs_info' at offset 0x5d4 contains 5 entries:
 Offset     Info    Type            Sym.Value  Sym. Name + Addend
00000006  00000864 R_IA64_SECREL32MS 00000000   .debug_procs_abbrev + 0
0000000c  00000264 R_IA64_SECREL32MS 00000000   .debug_line + 0
00000010  00000364 R_IA64_SECREL32MS 00000000   .debug_actual + 0
00000049  00000424 R_IA64_DIR32MSB   00000000   .text + 0
0000004d  00000424 R_IA64_DIR32MSB   00000000   .text + 70

Relocation section '.rela.debug_line' at offset 0x680 contains 1 entry:
 Offset     Info    Type            Sym.Value  Sym. Name + Addend
0000002b  00000424 R_IA64_DIR32MSB   00000000   .text + 0

Relocation section '.rela.debug_actual' at offset 0x6c0 contains 1 entry:
 Offset     Info    Type            Sym.Value  Sym. Name + Addend
0000001b  00000424 R_IA64_DIR32MSB   00000000   .text + 0

Symbol table '.symtab' contains 13 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS main.cc
     2: 00000000     0 SECTION LOCAL  DEFAULT   14 .debug_line
     3: 00000000     0 SECTION LOCAL  DEFAULT   16 .debug_actual
     4: 00000000     0 SECTION LOCAL  DEFAULT    5 .text
     5: 00000000     0 SECTION LOCAL  DEFAULT    8 .debug_abbrev
     6: 00000000     0 SECTION LOCAL  DEFAULT   18 .objdebug_file
     7: 00000000     0 SECTION LOCAL  DEFAULT   19 .debug_macinfo
     8: 00000000     0 SECTION LOCAL  DEFAULT   13 .debug_procs_abbrev
     9: 00000000     0 SECTION LOCAL  DEFAULT    3 .IA_64.unwind_info
    10: 00000000     0 SECTION LOCAL  DEFAULT    7 .HP.opt_annot
    11: 00000000     0 FUNC    GLOBAL DEFAULT  UND hello
    12: 00000000   112 FUNC    GLOBAL DEFAULT    5 main
------------------------------

Looking at main.s there is:
------------------------------
...
        .type   hello,@function
        .global hello
...
        br.call.dptk.many rp = hello#
------------------------------
So it looks like even though aCC accepted weak attribute it generated a global
symbol.

Now some interesting dumps from final executable linked by HP's ld:
------------------------------
$ readelf -s hello

Symbol table '.dynsym' contains 32 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
...
    10: 10252e40     0 FUNC    WEAK   DEFAULT  UND printf
    25: 04000970    80 FUNC    GLOBAL DEFAULT   15 hello
...
    45: 10252e40     0 FUNC    WEAK   DEFAULT  UND printf
    60: 04000970    80 FUNC    GLOBAL DEFAULT   15 hello
...

$ objdump --disassemble=main hello
...
Disassembly of section .text:

040008e0 <main>:
 40008e0:       03 08 0d 06 80 05       [MII]       alloc r33=ar.pfs,3,3,0
 40008e6:       00 00 00 02 00 00                   nop.i 0x0;;
 40008ec:       04 08 00 84                         mov r32=r1;;
 40008f0:       01 00 00 00 01 00       [MII]       nop.m 0x0
 40008f6:       20 02 00 62 00 00                   mov r34=b0
 40008fc:       00 00 04 00                         nop.i 0x0;;
 4000900:       19 00 00 00 01 00       [MMB]       nop.m 0x0
 4000906:       00 00 00 02 00 00                   nop.m 0x0
 400090c:       78 00 00 52                         br.call.dptk.many
b0=4000970 <hello>;;
 4000910:       03 08 00 40 00 21       [MII]       mov r1=r32
 4000916:       00 00 00 02 00 20                   nop.i 0x0;;
 400091c:       01 00 00 90                         mov r9=0;;
 4000920:       03 40 00 12 00 21       [MII]       mov r8=r9
 4000926:       00 00 00 02 00 00                   nop.i 0x0;;
 400092c:       20 0a 00 07                         mov b0=r34;;
 4000930:       02 00 00 00 01 00       [MII]       nop.m 0x0
 4000936:       00 08 01 55 00 00                   mov.i ar.pfs=r33;;
 400093c:       00 00 04 00                         nop.i 0x0
 4000940:       19 00 00 00 01 00       [MMB]       nop.m 0x0
 4000946:       00 00 00 02 00 80                   nop.m 0x0
 400094c:       08 00 84 02                         br.ret.dptk.many b0;;

$ objdump --disassemble=hello hello
...
Disassembly of section .text:

04000970 <hello>:
 4000970:       08 10 15 08 80 05       [MMI]       alloc r34=ar.pfs,5,4,0
 4000976:       30 02 30 00 42 20                   mov r35=r12
 400097c:       04 00 c4 00                         mov r33=b0
 4000980:       0a 20 e1 fb ff 27       [MMI]       addl r36=-8,r1;;
 4000986:       40 02 90 30 20 00                   ld8 r36=[r36]
 400098c:       04 08 00 84                         mov r32=r1
 4000990:       17 00 f2 ff 3f 16       [BBB]       br.call.sptk.many
b0=4000950 <.stub>
 4000996:       00 00 00 00 10 00                   nop.b 0x0
 400099c:       00 00 00 20                         nop.b 0x0;;
 40009a0:       00 08 00 40 00 21       [MII]       mov r1=r32
 40009a6:       00 10 01 55 00 00                   mov.i ar.pfs=r34
 40009ac:       10 0a 00 07                         mov b0=r33
 40009b0:       12 60 00 46 00 21       [MBB]       mov r12=r35
 40009b6:       40 04 00 42 00 00                   br.ret.sptk.many b0
 40009bc:       00 00 00 20                         nop.b 0x0

$ objdump --disassemble=.stub hello
...
Disassembly of section .text:

04000950 <.stub>:
 4000950:       0b 78 a0 fb ff 27       [MMI]       addl r15=-24,r1;;
 4000956:       00 41 3c 30 28 c0                   ld8 r16=[r15],8
 400095c:       01 08 00 84                         mov r14=r1;;
 4000960:       11 08 00 1e 18 10       [MIB]       ld8 r1=[r15]
 4000966:       60 80 04 80 03 00                   mov b6=r16
 400096c:       60 00 80 00                         br.few b6;;

$ readelf -r hello

Relocation section '.rela.plt' at offset 0x7e4 contains 1 entry:
 Offset     Info    Type            Sym.Value  Sym. Name + Addend
40010000  00000a80 R_IA64_IPLTMSB    10252e40   printf + 0
------------------------------

And that R_IA64_IPLTMSB relocation seems to be expected since printf is in
shared lib. So I guess we need to figure out how to force aCC to actually
respect __attribute__((weak)).

What do you think?

Thanks!
--peter


More information about the Gcc-bugs mailing list