A missing byte from initialized vars?

SGDK only sub forum

Moderator: Stef

Post Reply
User avatar
Miquel
Very interested
Posts: 319
Joined: Sat Jul 30, 2016 12:33 am

A missing byte from initialized vars?

Post by Miquel » Sun Apr 22, 2018 5:58 pm

I think that if the initialized variables are odd in size one last byte is not copied.
And yes, I checked it and _sdata could be odd.

That's the current code:

Code: Select all

* copy initialized variables from ROM to Work RAM
        lea     _stext,%a0
        lea     0xFF0000,%a1
        move.l  #_sdata,%d0
        lsr.l   #1,%d0
        beq     NoCopy

        subq.w  #1,%d0
CopyVar:
        move.w  (%a0)+,(%a1)+
        dbra    %d0,CopyVar
And that's how I'm trying to solve it:

Code: Select all

* Copy initialized C variables from ROM to Work RAM
	lea		_stext, %a0
	lea		0xFF0000, %a1
	move.l	#_sdata, %d1
	move.l	%d1, %d0
	lsr.l	#2, %d0
	jeq		2f
	subq.w	#1, %d0
4:
	move.l	(%a0)+, (%a1)+
	dbra		%d0, 4b
2:
	btst		#1, %d1
	jeq		1f
	move.w	(%a0)+, (%a1)+
1:
	btst		#0, %d1
	jeq		0f
	move.b	(%a0), (%a1)
0:
I tried to by faster by coping longs.

edit: even=>odd
Last edited by Miquel on Mon Apr 23, 2018 1:31 am, edited 2 times in total.

User avatar
Sik
Very interested
Posts: 705
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: A missing byte from initialized vars?

Post by Sik » Sun Apr 22, 2018 7:10 pm

You mean when it's odd, not even. I don't think the toolchain will ever allow the sections to be unaligned though (padding will end up getting added somewhere if really needed), so the issue should never show up in practice anyway.
Sik is pronounced as "seek", not as "sick".

User avatar
Miquel
Very interested
Posts: 319
Joined: Sat Jul 30, 2016 12:33 am

Re: A missing byte from initialized vars?

Post by Miquel » Sun Apr 22, 2018 10:13 pm

Yes, sorry I meant when is odd.

Sik, for example when the program is:

Code: Select all

char var = 7;
main(){}
_sdata is 1, and then no data is initialized. Tested.

Similarly with this program:

Code: Select all

long v = 44;
short f = 22;
char var = 7;
main(){}
Last byte (7) isn't copied. Tested.

If you want to use padding, perhaps you need to check if it's odd and then increment the size (d0), right?

User avatar
Sik
Very interested
Posts: 705
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: A missing byte from initialized vars?

Post by Sik » Mon Apr 23, 2018 3:39 am

...OK, that seems pretty broken.
Miquel wrote:
Sun Apr 22, 2018 10:13 pm
If you want to use padding, perhaps you need to check if it's odd and then increment the size (d0), right?
I was thinking something more like adding 1 to d0 before the bit shift. If the size was even then this does nothing, but if it wasn't then it bumps it up by one word (so the same effect as you suggest but easier to do, albeit somewhat less intuitive). This trick in general is pretty good to get bit shifts to round up instead of down (often needed for calculating allocations and such).

I doubt that copying one too many bytes will be a problem, but if it's a problem then you'll indeed need to copy the extra byte manually as in the first post.
Sik is pronounced as "seek", not as "sick".

User avatar
Stef
Very interested
Posts: 2773
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: A missing byte from initialized vars?

Post by Stef » Mon Apr 23, 2018 8:46 pm

I'm a bit surprised by this issue, as Sik pointed i though the segment size was always word aligned...
I will fix that, thanks for reporting :)

Chilly Willy
Very interested
Posts: 2586
Joined: Fri Aug 17, 2007 9:33 pm

Re: A missing byte from initialized vars?

Post by Chilly Willy » Mon Apr 23, 2018 9:00 pm

If you look at the linker file, none of the segments are aligned, other than the explicit alignment from setting the start address for the segment.

Code: Select all

  .data 0xFF0000 :
  AT ( ADDR (.text) + SIZEOF (.text) )
  {
    *(.got.plt) *(.got)
    *(.shdata)
    *(.data .data.*)
    _edata = .;
  } > ram
  _sdata = SIZEOF (.data);

  .bss 0xFF0000 + SIZEOF (.data) :
  {
    _start = . ;
    *(.shbss)
    *(.bss .bss.*)
    *(COMMON)
    _bend = . ;
  } > ram
  
As you can see, neither data segment is aligned, and .data is only aligned because it starts at 0xFF0000, and .bss isn't aligned, period.

My toolchain aligns them like this

Code: Select all

  .data 0x00FF0000 :
  AT ( LOADADDR (.text) + SIZEOF (.text) )
  {
    __data_start = .;
    *(.data)
    *(.data.*)
    *(.gnu.linkonce.d.*)
    CONSTRUCTORS

    *(.lit8)
    *(.lit4)
    *(.sdata)
    *(.sdata.*)
    *(.gnu.linkonce.s.*)
    . = ALIGN(8);
    __data_end = .;
  } > ram
  __data_size = __data_end - __data_start;

  .bss :
  {
    __bss_start = .;
    *(.bss)
    *(.bss.*)
    *(.gnu.linkonce.b.*)
    *(.sbss)
    *(.sbss.*)
    *(.gnu.linkonce.sb.*)
    *(.scommon)
    *(COMMON)
    . = ALIGN(8);
    end = .;
    _end = end;
    __end = _end;
    __bss_end = .;
  } > ram
  __bss_size = __bss_end - __bss_start;
I use an alignment of 8 because I allow using the standard memory allocator routines, which assume everything is at least 8 byte aligned.

User avatar
Stef
Very interested
Posts: 2773
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: A missing byte from initialized vars?

Post by Stef » Mon Apr 23, 2018 9:17 pm

yep, just realized that :p
I fixed the var initialization routine, should be fine :) my memory allocation routine take care of unaligned segment anyway.

User avatar
Miquel
Very interested
Posts: 319
Joined: Sat Jul 30, 2016 12:33 am

Re: A missing byte from initialized vars?

Post by Miquel » Mon Apr 23, 2018 11:36 pm

Alignment is not the core problem of this issue.

The thing is: size don't include the padding bytes coming from alignment at the end; you can align an array of 3 bytes all you want, but it's size is still 3.

User avatar
Stef
Very interested
Posts: 2773
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: A missing byte from initialized vars?

Post by Stef » Tue Apr 24, 2018 7:35 am

Yeah indeed... but that was what i meant by speaking about "size alignment", i mean having a padding byte when needed to compute segment size so it's always word based. We can use different method for that, using ALIGN(2) and label difference instead of the SIZEOF(..) operator as Chilly Willy made ;)

Chilly Willy
Very interested
Posts: 2586
Joined: Fri Aug 17, 2007 9:33 pm

Re: A missing byte from initialized vars?

Post by Chilly Willy » Tue Apr 24, 2018 1:32 pm

I didn't just align the start of a segment, but also it's end, which means that naturally the size is also aligned. That also made moving data for .data and clearing .bss faster as I could assume that both the start and length are 8 byte multiples.

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests