Menu

#3136 _GSINIT not at right place in crt0.s

open
nobody
None
other
5
2020-10-20
2020-10-18
Mario Smit
No

I've found a bug that I traced back to the crt0.s having .area _GSINIT before gsinit::. This means that any code created in the _GSINIT area will be omitted.

Example code:

#include "stdio.h"
#include "stdint.h"
#include "string.h"

uint8_t query[255];

void dosomething ()
{
  static unsigned char endquery[] = {0,0,1,0,1};  
  memcpy(query, endquery, 5);
}

/*---------------------------------------------------------------------------*/
int main(char *argv[], int argc)
{
  dosomething ();
  printf ("%d,%d,%d,%d,%d",query[0],query[1],query[2],query[3],query[4]);
  return 0;
}

This code emits 255,255,255,255,255 on my system. But it should emit 0,0,1,0,1.

The static unsigned char buffer is not being initialised allthough the compiler does generate code in the _GSINIT section.

Tracked it down here:

    .area   _GSINIT
gsinit::
    ld  bc, #l__INITIALIZER
    ld  a, b
    or  a, c
    jr  Z, gsinit_next
    ld  de, #s__INITIALIZED
    ld  hl, #s__INITIALIZER
    ldir
gsinit_next:

If you change it to:

gsinit::
    .area   _GSINIT
    ld  bc, #l__INITIALIZER
    ld  a, b
    or  a, c
    jr  Z, gsinit_next
    ld  de, #s__INITIALIZED
    ld  hl, #s__INITIALIZER
    ldir
gsinit_next:

The code is generated after the gsinit:: label instead of before it. This way the code behaves as expected.

Discussion

  • Tony Pavlov

    Tony Pavlov - 2020-10-19

    no, that is incorrect. sections are concatenated in the order of appearance to the linker. and your patch will result gsinit point to some random code defined in the same section you put label in. probably that is HEADER.

     
  • Tony Pavlov

    Tony Pavlov - 2020-10-20

    ps: maybe that will work because header is ABS, but anyway, it is not a good idea. you can specify the base addresses for _GSINIT and _GSFINAL via commandline arguments for some reason and everything breaks then.

     

Log in to post a comment.