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