Page 1 of 1

ldscript

Posted: Fri Jan 31, 2014 7:36 pm
by sigflup
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

Posted: Fri Jan 31, 2014 8:51 pm
by Chilly Willy
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.

Posted: Fri Jan 31, 2014 10:12 pm
by sigflup
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

Posted: Sat Feb 01, 2014 10:49 am
by Stef
Why to do you want the smallest LD script ? i don't think it can really help in term of compilation time.

Posted: Sat Feb 01, 2014 4:42 pm
by sigflup
just for fun. I like having minimal source code, it's an aesthetic thing

Posted: Sat Feb 01, 2014 8:02 pm
by Stef
haha ok :) well i don't think you can get it much lower then ;)

Posted: Sat Feb 01, 2014 11:44 pm
by Chilly Willy
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.