0

When using the gnu toolchain particularly arm-none-eabi is there any reason why when using the command line linker option it resorts to what seems an incorrect address to the start of 'main'. However, when 'main' is anything else the correct starting address and stack is initialized. For example,

.thumb
.syntax unified

.globl _start
_start:
.word 0x20001000
.word reset

reset:
        bl main
        b .




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


arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-as start.s -o start.o
arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-ld -Ttext=0x08000000 start.o main.o -o main.elf
arm-none-eabi-objdump -d main.elf

main.elf:     file format elf32-littlearm


Disassembly of section .text:

08000000 <main>:
  8000000:      2000            movs    r0, #0
  8000002:      4770            bx      lr

08000004 <_start>:
  8000004:      20001000        .word   0x20001000
  8000008:      0800000c        .word   0x0800000c

0800000c <reset>:
  800000c:      f7ff fff8       bl      8000000 <main>
  8000010:      e7fe            b.n     8000010 <reset+0x4>

in the disassembly the output above doesn't initialize the stack 0x20001000 and start of rom 0x08000000 correctly from what I notice, but..

.thumb
.syntax unified

.globl _start
_start:
.word 0x20001000
.word reset

reset:
        bl notmain
        b .




int notmain ( void )
{
        return(0);
}


arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-as start.s -o start.o
arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-ld -Ttext=0x08000000 start.o main.o -o main.elf
arm-none-eabi-objdump -d main.elf

main.elf:     file format elf32-littlearm


Disassembly of section .text:

08000000 <_start>:
  8000000:      20001000        .word   0x20001000
  8000004:      08000008        .word   0x08000008

08000008 <reset>:
  8000008:      f000 f802       bl      8000010 <xmain>
  800000c:      e7fe            b.n     800000c <reset+0x4>
        ...

08000010 <notmain>:
  8000010:      2000            movs    r0, #0
  8000012:      4770            bx      lr

I tried looking through the toolchain in my files to find any other reference to main pertaining to linker scripts and got some other help along the way, but there doesnt seem to be a clear solution as to why this is. Of course, if you create your own linker or a generated one you wont run into this problem, but I was just curious as I am trying to learn the tool a bit more.

odnal
  • 23
  • 4

1 Answers1

0

..but I was just curious as I am trying to learn the tool a bit more

The arm-eabi-none is meant to be used with (as a guess because you have not stated otherwise). This can process elf format files and it is a 'library', but there is no OS. If newlib mechanics want main() to be first, the tool will set things up like this. You don't want an elf file, but a binary. If you want a binary (ihex, srec, etc), then use a linker script! This is what it is meant for.


Use ld --verbose to see the default linker script. You are complaining about the order of emitted .text, but you have done nothing to define the ordering. The linker script may need main to be first so that some other library feature may work. You have a reset vector and a CPU which initializes the stack and 'reset vector' or initial code.

This is still emitted in the 'bad case', but it is not placed correctly. You need to have a custom linker script and position this a the first thing in the binary. Relying on the linker to place it correctly is error prone. An upgrade of tools can definitely change the order.

See: Can _start be a thumb function, were you have options like, -nostartfiles -static -nostdlib and use a custom linker script as an elf binary is unlikely to be understood and you need to flash/burn a binary to whatever boot device (or CPU built-in) is going to read the reset vectors.

artless noise
  • 21,212
  • 6
  • 68
  • 105
  • the gnu tools in this case output elf files and from there you can use other tools to make ihex, srec, etc. None of which is relevant to newlib because the arm-linux-...produce the same result. The default linker scripts assuming those are used (have an ENTRY(_start) in them implying that the label _start is somehow magic and required) with command line specifications instead of a linker script do not show anything with respect to main, nor is a crt0 being used here. – old_timer Jan 04 '21 at 03:50
  • Normally ld uses the objects in command line order unless an object or something in it is called out in the linker script. There is a gap here why are they being reordered? – old_timer Jan 04 '21 at 03:52
  • nostartfiles, etc dont affect this issue, why dont the command line options work? Yes of course using the tool differently (a linker script) fixes this. I dont think that is the question. – old_timer Jan 04 '21 at 03:57
  • making _start a thumb function doesnt appear to affect this either. – old_timer Jan 04 '21 at 03:58
  • Hmm, the linker scripts I thought were being used are not...so where is the ld magic then...hardcoded? Has to be I dont see any other hits in an install directory so it must be in the code somewhere. – old_timer Jan 04 '21 at 04:01
  • arm tools on an arm linux system (as, gcc, ld) also demonstrate the problem. – old_timer Jan 04 '21 at 04:08
  • The *thumb function* link was meant to be a reference to a setup that would solve the issue, even with ARM. Ie, use a linker script, `-nostartfiles`, `-static`, etc. If you don't use a linker script, things maybe organized how ever the tool chain wants. It is especially obvious if you look at `-lto` and gold. – artless noise Jan 21 '21 at 17:15