#399 sdcc shouldn't presume _CODE/_DATA addresses with custom crt0

open
nobody
None
5
2014-04-17
2013-08-19
Brian Ruthven
No

When using sdcc to link objects using --no-std-crt0, _CODE = 0x0200 and _DATA = 0x8000 are still passed to the linker. e.g.

$ sdcc -mz80 --no-std-crt0 mycrt0.rel file1.rel file2.rel file3.rel

With --no-std-crt0, does it make sense to still pass these when linking this way?

I've logged this as a feature request, because I'm not sure it's a bug. When I'm linking, I have to arrange for symbols in my crt0 file, then pass these to the link line:

$ sdcc -mz80 --no-std-crt0 --out-fmt-ihx \
    -Wl "-b _CODE = _crt_code_start"    \
    -Wl "-b _DATA = _crt_data_start"    \
    -o kernel.ihx           \
    ../ml/crt-kernel.rel version.rel ../disp/kernel_disp.lib ... etc ...

The crt contains (amongst other things):

        .area   _HEADER (ABS)
...
_crt_code_start::
        .area   _CODE

        .area   _CODE_END
_crt_data_start::

        .area   _INITIALIZED

Thus the whole lot flows on from one section to another.

Incidentally, I stopped using an explicit linker file, as it became awkward to maintain across sdcc updates with changes to sdldz80 flags, linker filename changes, coding in knowledge of sdcc's installation directory (to link in z80.lib), etc...

Currently I'm using sdcc #8787.

Discussion

  • Why not use --code-loc and --data-loc?

    Philipp

     
  • Brian Ruthven
    Brian Ruthven
    2014-04-17

    I want the code and data to flow on from one another, so I don't know at compile/link time what that address will be.

    To work around this, I use the two labels as described above.

    Using --code-loc with a symbol like this complains about a non-integer value:

    $ /sw/bin/sdcc              \
        -mz80 --no-std-crt0 --out-fmt-ihx           \
        --code-loc = _crt_code_start    \
        --data-loc = _crt_data_start    \
        -o kernel.ihx           \
        ../ml/crt-kernel.rel version.rel ../disp/kernel_disp.lib ../dos/kernel_dos.lib ../drv/kernel_drv.lib ../io/kernel_io.lib ../mem/kernel_mem.lib ../ml/kernel_ml.lib ../syscall/kernel_syscall.lib ./kernel_os.lib
    at 1: error 194: Bad integer argument for option --code-loc
    *** Error code 1
    make: Fatal error: Command failed for target `kernel.ihx'
    

    Unless I'm missing something and there is another way of doing this, I can't use --code-loc and --data-loc. So I must pass this directly to the linker. The kernel.lk file I end up with is:

    -mjwx
    -i kernel.ihx
    -b _CODE = 0x0200
    -b _DATA = 0x8000
    -b _CODE = _crt_code_start
    -b _DATA = _crt_data_start
    -k /sw/bin/../share/sdcc/lib/z80
    -k /sw/share/sdcc/lib/z80
    -l ../disp/kernel_disp.lib
    -l ../dos/kernel_dos.lib
    -l ../drv/kernel_drv.lib
    -l ../io/kernel_io.lib
    -l ../mem/kernel_mem.lib
    -l ../ml/kernel_ml.lib
    -l ../syscall/kernel_syscall.lib
    -l ./kernel_os.lib
    -l z80
    ../ml/crt-kernel.rel
    version.rel
    
    -e
    

    and thankfully the lines auto-inserted by SDCC appear before my own definitions, and sdld appears to take the most recent one. However, I'm relying on an implementation detail of how sdld appears to work.

    Taking all the _CODE and _DATA lines out of the above .lk file doesn't produce correct results, so I would still need to specify the linker lines as I do today. However, if sdcc omitted the default lines with --no-std-crt0 (or provided an additional switch to do so), then I could continue using the values I provide, and would not be relying on how sdld handled duplicate definitions in the .lk file.

     
    Last edit: Brian Ruthven 2014-04-17