3

Among other things I am trying to understand the difference between OUTPUT_ARCH(arm) and OUTPUT_ARCH(armv4).

Assume we have next files (I have used linker script example from here as a basis):

main.c:

int main(void)
{
    test_1();
    test_2();
    return 0;
}


main.lds:

OUTPUT_ARCH(arm)
SECTIONS
{
    . = 0x10000;
    .text : { *(.text) }
    . = 0x8000000;
    .data : { *(.data) }
    .bss : { *(.bss) }
}


test_1.c:

void test_1(void)
{
    return;
}


test_2.c:

void test_2(void)
{
    return;
}

If we compile it and dump its content we have next:

c:\SysGCC\arm-elf\bin>arm-elf-gcc.exe test_1.c -c

c:\SysGCC\arm-elf\bin>arm-elf-gcc.exe test_2.c -c

c:\SysGCC\arm-elf\bin>arm-elf-objdump.exe -x test_1.o

test_1.o:     file format elf32-littlearm
test_1.o
architecture: arm, flags 0x00000010:
HAS_SYMS
start address 0x00000000
private flags = 200: [APCS-32] [FPA float format] [software FP]

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000014  00000000  00000000  00000034  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00000000  00000000  00000048  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000048  2**0
                  ALLOC
  3 .comment      00000012  00000000  00000000  00000048  2**0
                  CONTENTS, READONLY
  4 .ARM.attributes 00000010  00000000  00000000  0000005a  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
00000000 l    df *ABS*  00000000 test_1.c
00000000 l    d  .text  00000000 .text
00000000 l    d  .data  00000000 .data
00000000 l    d  .bss   00000000 .bss
00000000 l    d  .comment       00000000 .comment
00000000 l    d  .ARM.attributes        00000000 .ARM.attributes
00000000 g     F .text  00000014 test_1

c:\SysGCC\arm-elf\bin>arm-elf-gcc.exe -static -nostartfiles -T main.lds -o main.elf test_1.o test_2.o

c:\SysGCC\arm-elf\bin>arm-elf-objdump.exe -x main.elf

main.elf:     file format elf32-littlearm
main.elf
architecture: arm, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00010000

Program Header:
    LOAD off    0x00008000 vaddr 0x00010000 paddr 0x00010000 align 2**15
         filesz 0x00000028 memsz 0x00000028 flags r-x
private flags = 200: [APCS-32] [FPA float format] [software FP]

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000028  00010000  00010000  00008000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .comment      00000011  00000000  00000000  00008028  2**0
                  CONTENTS, READONLY
  2 .ARM.attributes 00000010  00000000  00000000  00008039  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
00010000 l    d  .text  00000000 .text
00000000 l    d  .comment       00000000 .comment
00000000 l    d  .ARM.attributes        00000000 .ARM.attributes
00000000 l    df *ABS*  00000000 test_1.c
00000000 l    df *ABS*  00000000 test_2.c
00010014 g     F .text  00000014 test_2
00010000 g     F .text  00000014 test_1

But if I change OUTPUT_ARCH(arm) to OUTPUT_ARCH(armv4), I get an error from linker:

c:\SysGCC\arm-elf\bin>arm-elf-gcc.exe -static -nostartfiles -T main.lds -o main.elf test_1.o test_2.o
c:/sysgcc/arm-elf/bin/../lib/gcc/arm-elf/4.6.3/../../../../arm-elf/bin/ld.exe: error: test_1.o uses software FP, whereas main.elf uses hardware FP
c:/sysgcc/arm-elf/bin/../lib/gcc/arm-elf/4.6.3/../../../../arm-elf/bin/ld.exe: failed to merge target specific data of file test_1.o
c:/sysgcc/arm-elf/bin/../lib/gcc/arm-elf/4.6.3/../../../../arm-elf/bin/ld.exe: error: test_2.o uses software FP, whereas main.elf uses hardware FP
c:/sysgcc/arm-elf/bin/../lib/gcc/arm-elf/4.6.3/../../../../arm-elf/bin/ld.exe: failed to merge target specific data of file test_2.o
collect2: ld returned 1 exit status

It can be fixed by specifying -mfloat-abi=hard option. In this case there is a difference in private flags comparing with previous output:

c:\SysGCC\arm-elf\bin>arm-elf-gcc.exe -mfloat-abi=hard test_1.c -c

c:\SysGCC\arm-elf\bin>arm-elf-gcc.exe -mfloat-abi=hard test_2.c -c

c:\SysGCC\arm-elf\bin>arm-elf-objdump.exe -x test_1.o

test_1.o:     file format elf32-littlearm
test_1.o
architecture: arm, flags 0x00000010:
HAS_SYMS
start address 0x00000000
private flags = 0: [APCS-32] [FPA float format]

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000014  00000000  00000000  00000034  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00000000  00000000  00000048  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000048  2**0
                  ALLOC
  3 .comment      00000012  00000000  00000000  00000048  2**0
                  CONTENTS, READONLY
  4 .ARM.attributes 00000010  00000000  00000000  0000005a  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
00000000 l    df *ABS*  00000000 test_1.c
00000000 l    d  .text  00000000 .text
00000000 l    d  .data  00000000 .data
00000000 l    d  .bss   00000000 .bss
00000000 l    d  .comment       00000000 .comment
00000000 l    d  .ARM.attributes        00000000 .ARM.attributes
00000000 g     F .text  00000014 test_1



c:\SysGCC\arm-elf\bin>arm-elf-gcc.exe -static -nostartfiles -T main.lds -o main.elf test_1.o test_2.o

c:\SysGCC\arm-elf\bin>arm-elf-objdump.exe -x main.elf

main.elf:     file format elf32-littlearm
main.elf
architecture: arm, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00010000

Program Header:
    LOAD off    0x00008000 vaddr 0x00010000 paddr 0x00010000 align 2**15
         filesz 0x00000028 memsz 0x00000028 flags r-x
private flags = 0: [APCS-32] [FPA float format]

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000028  00010000  00010000  00008000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .comment      00000011  00000000  00000000  00008028  2**0
                  CONTENTS, READONLY
  2 .ARM.attributes 00000010  00000000  00000000  00008039  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
00010000 l    d  .text  00000000 .text
00000000 l    d  .comment       00000000 .comment
00000000 l    d  .ARM.attributes        00000000 .ARM.attributes
00000000 l    df *ABS*  00000000 test_1.c
00000000 l    df *ABS*  00000000 test_2.c
00010014 g     F .text  00000014 test_2
00010000 g     F .text  00000014 test_1

Does it mean that OUTPUT_ARCH(armv4) causes linker to generate output solely for hard float?

In general, what is the difference between OUTPUT_ARCH(arm) and OUTPUT_ARCH(armv4)?

According to ld manual OUTPUT_ARCH() specifies a particular output machine architecture.

The argument is one of the names used by the BFD library.

But I have found no clear information about BFD library except general information.

I use arm-elf toolchain from here (Binutils 2.22, GCC 4.6.3, Newlib 1.2.0, GDB 7.4).

Thank you in advance for help.

UPDATE 1:

This update is a reply for the comment below.

Compiler -v output from old toolchain we use now:

Using built-in specs.
Target: arm-elf
Configured with: ../gcc-4.4.1/configure --target=arm-elf --host=i686-pc-mingw32 --with-cpu=xscale --without-stabs -nfp --prefix=/c/cross-gcc/4.4.1 --disable-nls --disable-shared --disable-__cxa_atexit
 --enable-threads --with-gnu-gcc --with-gnu-ld --with-gnu-as --with-dwarf2 --enable-languages=c,c++ --enable-interwork --disable-multilib --with-gmp=/c/cross-gcc/4.4.1 --with-mpfr=/c/cross-gcc/4.4.1 -
-with-newlib --with-headers=../../newlib-1.17.0/newlib-1.17.0/newlib/libc/include --disable-libssp --disable-libstdcxx-pch --disable-libmudflap --disable-libgomp -v
Thread model: single
gcc version 4.4.1 (GCC)

Compiler -v output from newer toolchain I used in the examples (SysGCC arm-elf):

Using built-in specs.
COLLECT_GCC=arm-elf-gcc.exe
COLLECT_LTO_WRAPPER=c:/sysgcc/arm-elf/bin/../libexec/gcc/arm-elf/4.6.3/lto-wrapper.exe
Target: arm-elf
Configured with: ../gcc-4.6.3/configure --target arm-elf --enable-win32-registry=SysGCC-arm-elf-4.6.3 --prefix /c/gnu/auto/bu-2.22+gcc-4.6.3+gmp-4.2.4+mpfr-2.4.1+mpc-0.8+newlib-1.20.0-arm-elf/ --enabl
e-languages=c,c++ --disable-nls --with-newlib --with-headers=../newlib-1.20.0/newlib/libc/include --enable-interwork --enable-multilib --with-float=soft
Thread model: single
gcc version 4.6.3 (GCC)

There is no difference between linker output for OUTPUT_ARCH(arm) and OUTPUT_ARCH(armv4) for old compiler. I think I should have checked it before. Seems that it is an answer to this question.

My goal is to use the combination -mfpu=vfpv3 -mfloat-abi=hard, but according to Debian documentation and GCC 4.4.7 manual this combination is not supported by GCC 4.4.

In fact if I try to compile with -mfpu=vfpv3 -mfloat-abi=hard by old compiler, it returns error:

sorry, unimplemented: -mfloat-abi=hard and VFP

Still and all it is possible to use -mfpu=vfpv3 -mfloat-abi=softfp with old compiler, but according to this comparison it gives big overhead for small routines.

yurko
  • 623
  • 1
  • 7
  • 21
  • 1
    What are you trying to do with `OUTPUT_ARCH()`? Generally you **never** use this option. It will not fix any default behaviour. If you are doing something more complex ([for example linking a 'C' file compiled twice with different compiler flags](http://stackoverflow.com/questions/22012960/gcc-to-emit-arm-idiv-instructions-continued/22023026#22023026)) then you might need this option. Each input object has its own *ARCH*; normally they are all equal or you have issues. – artless noise Oct 18 '16 at 13:05
  • @artlessnoise I am just trying to use newer toolchain to build some project and OUTPUT_ARCH(armv4) has been specified there before. While linking the project by newer toolchain I got an issue when toolchain libraries and linker output were not link compatible. Specifying *arm* instead of *armv4* helped. But still, too many things remain unclear. – yurko Oct 19 '16 at 13:48
  • 1
    You might try `gcc -v` with the new and old compilers and post the results. If I understand you are trying to get a large project to work with the new compiler and suspect `OUTPUT_ARCH()` and made a synthetic question to fit the Q/A format of stackoverflow to try and solve your issue? What errors/warnings happen with the original project/compiler if you remove `OUTPUT_ARCH()` from the build? I don't think it is your issue; at least it is hard to contemplate how it could be. – artless noise Oct 19 '16 at 15:22
  • @artlessnoise Sorry for stone age response time. Too many things to do these days. Yes, you are right. I wrote an update in main description above. – yurko Oct 21 '16 at 10:07
  • 1
    Your new compiler is configured with `--with-float=soft`; the *libc* (newlib) of the complier will be in a format that expects soft floating point, yet you want a hard floating point (appropriate for your target, I guess). I suggest [this gcc](https://launchpad.net/gcc-arm-embedded/4.6) although there are many newer versions for you to try (5.0, 6.0, etc) as per https://sourceware.org/ml/newlib/2013/msg00124.html. I think these are true multi-lib with hard/soft FP libraries. Your compiler intrinsic (libgcc) also needs to be correct. There are other ways, but the launchpad compiler is best. – artless noise Oct 21 '16 at 17:06
  • @artlessnoise Thanks a lot for your suggestions. – yurko Oct 23 '16 at 12:21

0 Answers0