Difference between OUTPUT_ARCH(arm) and OUTPUT_ARCH(armv4) in linker script

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.

c
gcc
arm
embedded
ld
asked on Stack Overflow Oct 17, 2016 by yurko • edited Oct 21, 2016 by yurko

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0