Problems with building ia64 big endian code on FreeBSD

Dietmar Hahn dietmar.hahn@fujitsu-siemens.com
Fri Jul 9 09:49:00 GMT 2004


Hi,
I tried to build a big endian object on a itanium2 (ia64) machine with 
FreeBSD. I used binutils-2.15 with: 
./configure --target=ia64-freebsd5.0 --enable-64-bit-bfd
I compiled the source with:
cc -ansi -Wall -O -Wa,-mlp64 -mbig-endian -Wa,-mbe -c tst.c

tst.c:
typedef void FUNC();

extern FUNC func_1;
extern FUNC func_2;

FUNC    *const func_vector[] =
        {
                func_1, func_2
        };

The generated relocations seem to be in little endian:
objdump -r tst.o:

tst.o:     file format elf64-ia64-big

RELOCATION RECORDS FOR [.data]:
OFFSET           TYPE              VALUE 
0000000000000000 FPTR64LSB         func_1
0000000000000008 FPTR64LSB         func_2

The problem is the type FPTR64LSB - I think it has to be FPTR64MSB.
After that I built the binutils again with:
./configure --target=ia64-hp-hpux --enable-64-bit-bfd

Now I got the following output of objdump -r:

tst.o:     file format elf64-ia64-big

RELOCATION RECORDS FOR [.data]:
OFFSET           TYPE              VALUE 
0000000000000000 FPTR64MSB         func_1
0000000000000008 FPTR64MSB         func_2

Now I used the second as to build the objects. Later in linking (with the ld 
build with target=ia64-freebsd5.0) to the final object without relocations 
the linker built buggy code.
I extracted the problem to the following example:

tst.s:

.global func_1; .align 16; .proc func_1; func_1:; .regstk 0, 0, 0, 0

        movl r20=1f
        ;;
1:
        br.ret.sptk.few rp
        ;;
.endp func_1


.global func_2; .align 16; .proc func_2; func_2:; .regstk 0, 0, 0, 0

        alloc loc0 = ar.pfs,0,2,0,0
        mov loc1=rp
        ;;
        br.call.sptk.many rp = func_1
        ;;

        mov ar.pfs = loc0
        mov rp=loc1
        ;;
        br.ret.sptk.many rp

.endp func_2

I built an object with:
as-hpux -mlp64 -mbe -o tst.o tst.s
objdump -d tst.o:

tst.o:     file format elf64-ia64-big

Disassembly of section .text:

0000000000000000 <func_1>:
   0:   05 00 00 00 01 00       [MLX]       nop.m 0x0
   6:   00 00 00 00 00 80                   movl r20=0x0;;
   c:   02 00 00 60 
  10:   1d 00 00 00 01 00       [MFB]       nop.m 0x0
  16:   00 00 00 02 00 80                   nop.f 0x0
  1c:   00 00 84 00                         br.ret.sptk.few b0;;

0000000000000020 <func_2>:
  20:   02 00 09 04 80 05       [MII]       alloc r32=ar.pfs,2,2,0
  26:   10 02 00 62 00 00                   mov r33=b0;;
  2c:   00 00 04 00                         nop.i 0x0
  30:   1d 00 00 00 01 00       [MFB]       nop.m 0x0
  36:   00 00 00 02 00 00                   nop.f 0x0
  3c:   08 00 00 50                         br.call.sptk.many b0=30 
<func_2+0x10>;;
  40:   01 00 00 00 01 00       [MII]       nop.m 0x0
  46:   00 00 01 55 00 00                   mov.i ar.pfs=r32
  4c:   10 0a 00 07                         mov b0=r33;;
  50:   1d 00 00 00 01 00       [MFB]       nop.m 0x0
  56:   00 00 00 02 00 80                   nop.f 0x0
  5c:   08 00 84 00                         br.ret.sptk.many b0;;

This looked fine.
Then I did: ld -EB -o t.o tst.o
objdump -d t.o:
.o:     file format elf64-ia64-big

Disassembly of section .text:

40000000000000b0 <func_1>:
40000000000000b0:       00 00 00 00 01 00       [MII]       nop.m 0x0
40000000000000b6:       00 00 00 04 04 00                   data8 0x1010000000
40000000000000bc:       02 40 00 00                         break.i 0x20010
40000000000000c0:       1d 00 00 00 01 00       [MFB]       nop.m 0x0
40000000000000c6:       00 00 00 02 00 80                   nop.f 0x0
40000000000000cc:       00 00 84 00                         br.ret.sptk.few 
b0;;

40000000000000d0 <func_2>:
40000000000000d0:       02 00 09 04 80 05       [MII]       alloc 
r32=ar.pfs,2,2,0
40000000000000d6:       10 02 00 62 00 00                   mov r33=b0;;
40000000000000dc:       00 00 04 00                         nop.i 0x0
40000000000000e0:       1d 00 00 00 01 00       [MFB]       nop.m 0x0
40000000000000e6:       00 00 08 ff ff d0                   data8 
0x1fffc200000
40000000000000ec:       08 00 00 50                   (p33) br.call.sptk.many 
b6=40000000000000e0 <func_2+0x10>;;
40000000000000f0:       01 00 00 00 01 00       [MII]       nop.m 0x0
40000000000000f6:       00 00 01 55 00 00                   mov.i ar.pfs=r32
40000000000000fc:       10 0a 00 07                         mov b0=r33;;
4000000000000100:       1d 00 00 00 01 00       [MFB]       nop.m 0x0
4000000000000106:       00 00 00 02 00 80                   nop.f 0x0
400000000000010c:       08 00 84 00                         br.ret.sptk.many 
b0;;

Here I saw the buggy code. Because both the br.call... and the movl r20=... 
were wrong.
With try and error I looked through  the sources in the bfd directory and 
found the function elf64_ia64_install_value() in the file elf64-ia64.c
I saw that for bfd_get_64() and bfd_put_64() the functions bfd_getb64() and 
bfd_putb64() were used. I changed this to bfd_getl64() and bfd_putl64() only 
for the instruction relocations and after new compiling ld I got the right 
code.

objdump -d t.o:
t.o:     file format elf64-ia64-big

Disassembly of section .text:

20000000000000b0 <func_1>:
20000000000000b0:       05 00 00 00 01 00       [MLX]       nop.m 0x0
20000000000000b6:       00 00 00 00 20 80                   movl 
r20=0x20000000000000c0;;
20000000000000bc:       02 04 04 60 
20000000000000c0:       1d 00 00 00 01 00       [MFB]       nop.m 0x0
20000000000000c6:       00 00 00 02 00 80                   nop.f 0x0
20000000000000cc:       00 00 84 00                         br.ret.sptk.few 
b0;;

20000000000000d0 <func_2>:
20000000000000d0:       02 00 09 04 80 05       [MII]       alloc 
r32=ar.pfs,2,2,0
20000000000000d6:       10 02 00 62 00 00                   mov r33=b0;;
20000000000000dc:       00 00 04 00                         nop.i 0x0
20000000000000e0:       1d 00 00 00 01 00       [MFB]       nop.m 0x0
20000000000000e6:       00 00 00 02 00 00                   nop.f 0x0
20000000000000ec:       d8 ff ff 58                         br.call.sptk.many 
b0=20000000000000b0 <func_1>;;
20000000000000f0:       01 00 00 00 01 00       [MII]       nop.m 0x0
20000000000000f6:       00 00 01 55 00 00                   mov.i ar.pfs=r32
20000000000000fc:       10 0a 00 07                         mov b0=r33;;
2000000000000100:       1d 00 00 00 01 00       [MFB]       nop.m 0x0
2000000000000106:       00 00 00 02 00 80                   nop.f 0x0
200000000000010c:       08 00 84 00                         br.ret.sptk.many 
b0;;


My question is, what is the current state of the binutils for my use - build 
ia64 big endian code on a running ia64-freebsd. May my fixes to bfd lead to 
other problems ? Is anybody working on this stuff ?

Many thanks.

Dietmar




More information about the Binutils mailing list