ldscript

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
sigflup
Very interested
Posts: 111
Joined: Mon Sep 06, 2010 12:05 pm
Contact:

ldscript

Post by sigflup » Fri Jan 31, 2014 7:36 pm

I've got my ldscript down to:

Code: Select all

SECTIONS
{
  .text 0x00000000:
  {
    *(.text)
    . = ALIGN(0x4);
    *(.rodata)
  } 

  .data :
  {
   . = ALIGN(0x4);
    *(.data)
  } 

  .bss 0xff0000 : {
    *(.bss)
  }

}
Does anyone else have anything smaller? Basically I don't initialize data on declaration- a minor inconvenience

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

Post by Chilly Willy » Fri Jan 31, 2014 8:51 pm

That's about as small as you can get, but it won't work for gcc. You need a pretty decent linker script for modern gcc. Look at the ones I use as an example...

Code: Select all

OUTPUT_ARCH(m68k)
EXTERN (_start)
ENTRY (_start)
__DYNAMIC  =  0;

/*
 * The memory map look like this:
 * +--------------------+ <- 0x00000000
 * | .text              |
 * |                    |
 * |          _text_end |
 * +--------------------+
 * .                    .
 * .                    .
 * .                    .
 * +--------------------+ <- 0x00FF0000
 * | .data              | initialized data goes here
 * |                    |
 * |          _data_end |
 * +--------------------+
 * | .bss               |
 * |         _bss_start | start of bss, cleared by crt0
 * |                    |
 * |          _bss__end | start of heap, used by sbrk()
 * +--------------------+
 * .                    .
 * .                    .
 * .                    .
 * |             _stack | top of stack
 * +--------------------+ <- 0x01000000
 */

MEMORY
{
    rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00400000
    ram (wx) : ORIGIN = 0x00FF0000, LENGTH = 0x00010000
}

/*
 * Allocate the stack to be at the top of memory, since the stack
 * grows down
 */

PROVIDE (__stack = 0x01000000);

SECTIONS
{
  .text 0x00000000 :
  {
    __text_start = .;
    *(.text)
    *(.text.*)
    *(.gnu.linkonce.t.*)

    . = ALIGN(16);
    __INIT_SECTION__ = .;
    KEEP (*(.init))
    SHORT (0x4E75)	/* rts */
    . = ALIGN(16);
    __FINI_SECTION__ = .;
    KEEP (*(.fini))
    SHORT (0x4E75)	/* rts */

    *(.eh_frame_hdr)
    KEEP (*(.eh_frame))
    *(.gcc_except_table)
    KEEP (*(.jcr))

    . = ALIGN(16);
     __CTOR_LIST__ = .;
    ___CTOR_LIST__ = .;
    LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
    LONG(0)
    __CTOR_END__ = .;

    . = ALIGN(16);
    __DTOR_LIST__ = .;
    ___DTOR_LIST__ = .;
    LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
     LONG(0)
    __DTOR_END__ = .;

    *(.rdata)
    *(.rodata)
    *(.rodata.*)
    *(.gnu.linkonce.r.*)
    . = ALIGN(16);
    __text_end = .;
  } > rom
  __text_size = __text_end - __text_start;

  .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;

}
That will handle C++ programs made by any recent version gcc. Yours won't.

sigflup
Very interested
Posts: 111
Joined: Mon Sep 06, 2010 12:05 pm
Contact:

Post by sigflup » Fri Jan 31, 2014 10:12 pm

Works on 4.2.1, which i use. It's just for me,.i don't really care too for c++. my OS lags gcc so I'm not going to get the newest for a while. When that happens, I'll fix it when it breaks

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

Post by Stef » Sat Feb 01, 2014 10:49 am

Why to do you want the smallest LD script ? i don't think it can really help in term of compilation time.

sigflup
Very interested
Posts: 111
Joined: Mon Sep 06, 2010 12:05 pm
Contact:

Post by sigflup » Sat Feb 01, 2014 4:42 pm

just for fun. I like having minimal source code, it's an aesthetic thing

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

Post by Stef » Sat Feb 01, 2014 8:02 pm

haha ok :) well i don't think you can get it much lower then ;)

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

Post by Chilly Willy » Sat Feb 01, 2014 11:44 pm

Yeah, there's always something to be said about doing things like making the smallest whatever. That lead to what can comprise the smallest MegaDrive game that works on real hardware - you need the start address at 0x4, "SEGA" at 0x100, and storing "SEGA" to 0xA14000. Nothing else is REQUIRED, and the last two are only required for TMSS. Obviously, if you use the interrupts, the vectors will need to be set, but a lot can be done without any ints at all.

That said, a full ldscript makes making C and C++ apps easier and more full-featured. You can use things like read-only strings in the rom section, initializers/constructors, etc. The more features of gcc you take advantage of, the more you need the full script and a proper init code block that copies the initialized data and clears the bss and calls the initializers.

Post Reply