https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61577
--- Comment #202 from Peter Bisroev <peter.bisroev at groundlabs dot com> --- (In reply to dave.anglin from comment #201) > On 2020-02-22 4:33 p.m., peter.bisroev at groundlabs dot com wrote: > > They both seem to be ELF32 > Maybe run failing program under gdb to find faulting instruction. Compare > with executable that works. Hi Dave, Well, decoding IA-64 instruction bundles by hand is not fun :) But at least we know what is going on here now. Looking at main.o generated by aCC, the relocation is as expected: ------------------------------ 30: 05 00 00 00 01 00 [MLX] nop.m 0x0 32: PCREL60B hello 36: 00 00 00 00 00 00 brl.call.dptk.many b0=30 <main+0x30>;; 3c: 08 00 00 d2 ------------------------------ Once ld takes care of relocation everything is as expected as well: ------------------------------ 40009b0: 05 00 00 00 01 00 [MLX] nop.m 0x0 40009b6: 00 00 00 00 00 00 brl.call.dptk.many b0=4000a40 <hello>;; 40009bc: 98 00 00 d2 ------------------------------ I've decoded this instruction bundle by hand and verified that immediate value is 0x90 (0x9 << 4) which matches our relative offset of 0x4000a40−0x40009b0 as expected. Now looking at the main.o generated by gcc, the relocation seems to be as expected but the relocation address seems to be off: ------------------------------ 20: 04 00 00 00 01 00 [MLX] nop.m 0x0 21: PCREL60B hello 26: 00 00 00 00 00 00 brl.call.sptk.many b0=20 <main+0x20> 2c: 08 00 00 d0 ------------------------------ As can be seen above, GNU as is telling HP's ld to do the relocation at 0x21, which falls into slot 1 and 0. However the relocation needs to be done at 0x26 to cover slots 2 and 1. Now looking at the linked binary we are getting the following: ------------------------------ 4000950: 04 00 00 00 00 00 [MLX] break.m 0x0 4000956: 00 40 00 00 00 00 brl.call.sptk.many b0=4000950 <_end+0xc3ff0908> 400095c: 08 00 00 d0 ------------------------------ As can be seen above, the slot 0 instruction changed from nop.m to break.m, and this is where we are getting the illegal instruction. In this linked binary, hello() is located at 0x40009d0. So based on this, we expect the offset to be 0x80 (0x40009d0 - 0x4000950). So the expected immediate value for brl.call should be 0x08 (0x80>>4). I decided to double check that HP's ld is doing this relocation properly but at the wrong offset requested by GNU as. Based on our relocation offset of 0x21, I have interpreted slots 1 and 0 by hand as if they were slots 2 and 1. Once we do that, we get the immediate value of 0x08 as expected. The nop.m changes to break.m because ld cleared bits of imm39 (bits 20-58) that form the 60 bit immediate. Based on the above, unless I am mistaken, it looks like a bug in GNU as. Once I get a bit of time this week I will try to look through it to see what is going on there. Just out of curiosity, I have also tried to patch the reloc offset to 0x26 in the object file just to see what happens :). After that, objdump shows expected relocation offset. However HP's linker dies with bus error when I try to link the executable. But I think we are making some progress here. What do you think? Thanks! --peter