#1540 sdcc --no-std-crt0 place _GSFINAL in _DATA

open
nobody
linker (61)
5
2014-01-03
2009-06-06
dfulab
No

I am trying to make my own crt0 startup code for an embedded Z182 processor and I ran into some nasty issues.

SDCC Win32 release installed from sdcc-2.9.0-setup.exe
I used the precompiled crt0.o that comes with SDCC under SDCC\lib\z80 and the following c code for testing:

blink.c:
#include <stdio.h>

static char a[]="abc";
main(void)
{
while(1)
;
}

ROM is at 0x0000 to 0x8000
RAM is at 0xE000 to 0xFFFF

Using the command line for automatically linking in the startup code:
sdcc -mz80 -portmode=z180 --code-loc 0x112 --data-loc 0xe000 blink.c

This produces the expected behaviour in blink.map file:
Value Global
-------- --------------------------------
0000 l__BSS
0000 l__CABS
0000 l__HEAP
0000 l__HOME
0000 l__OVERLAY
0000 s__HEADER
0001 l__GSFINAL
0004 l__DATA
000C l__CODE
0015 l__GSINIT
010C l__HEADER
0112 s__CODE
011E s__GSINIT <--- this is within CODE segment
011E s__HOME
0133 s__GSFINAL <--- this is within CODE segment
E000 s__DATA
E004 s__BSS
E004 s__CABS
E004 s__HEAP
E004 s__OVERLAY

I have very different results from using --no-std-crt0
sdcc -mz80 --no-std-crt0 -portmode=z180 --code-loc 0x112 --data-loc 0xe000 blink.c crt0.o

Value Global
-------- --------------------------------
0000 l__BSS
0000 l__CABS
0000 l__HEAP
0000 l__HOME
0000 l__OVERLAY
0000 s__HEADER
0001 l__GSFINAL
0004 l__DATA
000C l__CODE
0015 l__GSINIT
010C l__HEADER
0112 s__CODE
E000 s__DATA
E004 s__GSINIT <--- this is within DATA segment !!!!
E004 s__HOME
E004 s__OVERLAY
E019 s__GSFINAL <--- this is within DATA segment !!!!
E01A s__BSS
E01A s__CABS
E01A s__HEAP

Discussion

  • dfulab
    dfulab
    2009-06-06

    Blink.lst file

     
    Attachments
  • Maarten Brock
    Maarten Brock
    2014-01-03

    Without your modified crt0 startup code it is hard to reproduce this.

    However it seems this is a result of SDCC using a very different method for adding the crt0 for z80 from the mcs51. For z80 to enforce the correct order of areas a list of them is in crt0.s. SDCC then tries to find crt0.o outside the (sdar) libraries and when found adds a hard link to it at the top of the linker script to make sure it's the first one the linker sees. And to override this behavior you need --no-std-crt0.

    For the mcs51 OTOH it just references a global symbol (__sdcc_gsinit_startup) that is defined in crtstart.asm. This will link in the required object from the libraries. To make sure the areas are linked in the correct order SDCC generates a list of areas (see _mcs51_genExtraAreas() in src/mcs51/main.c) in every generated asm file.

    Now since the generated z80 blink.asm doesn't have the ordered area list and your crt0.o is not the first to be linked the areas can get mixed up. A good work-around is to compile all source files first and then link them in a separate command with your crt0 first.

    Maarten