Next: , Previous: , Up: Libraries   [Contents]


3.2 Linker scripts for memory management

The linker script sets up the memory map of an application. It also sets up default values for variables used elsewhere by sbrk() and the crt0. These default variables are typically called _bss_start and _end.

For G++, the constructor and destructor tables must also be setup here. The actual section names vary depending on the object file format. For a.out and coff, the three main sections are .text, .data, and .bss.

Now that you have an image, you can test to make sure it got the memory map right. You can do this by having the linker create a memory map (by using the -Map option), or afterwards by using nm to check a few critical addresses like start, bss_end, and _etext.

Here’s a breakdown of a linker script for a m68k based target board. See the file libgloss/m68k/idp.ld, or go to the appendixes in the end of the manual. Example Linker Script.

STARTUP(crt0.o)
OUTPUT_ARCH(m68k)
INPUT(idp.o)
SEARCH_DIR(.)
__DYNAMIC  =  0;

The STARTUP command loads the file specified so that it’s first. In this case it also doubles to load the file as well, because the m68k-coff configuration defaults to not linking in the crt0.o by default. It assumes that the developer probably has their own crt0.o. This behavior is controlled in the config file for each architecture. It’s a macro called STARTFILE_SPEC, and if it’s set to null, then when gcc formats it’s command line, it doesn’t add crto.o. Any file name can be specified here, but the default is always crt0.o.

Course if you only use ld to link, then the control of whether or not to link in crt0.o is done on the command line. If you have multiple crto files, then you can leave this out all together, and link in the crt0.o in the makefile, or by having different linker scripts. Sometimes this is done for initializing floating point optionally, or to add device support.

The OUTPUT_ARCH sets architecture the output file is for.

INPUT loads in the file specified. In this case, it’s a relocated library that contains the definitions for the low-level functions need by libc.a. This could have also been specified on the command line, but as it’s always needed, it might as well be here as a default. SEARCH_DIR specifies the path to look for files, and _DYNAMIC means in this case there are no shared libraries.

/*
 * Setup the memory map of the MC68ec0x0 Board (IDP)
 * stack grows up towards high memory. This works for
 * both the rom68k and the mon68k monitors.
 */
MEMORY
{
  ram     : ORIGIN = 0x10000, LENGTH = 2M
}

This specifies a name for a section that can be referred to later in the script. In this case, it’s only a pointer to the beginning of free RAM space, with an upper limit at 2M. If the output file exceeds the upper limit, it will produce an error message.

/*
 * stick everything in ram (of course)
 */
SECTIONS
{
  .text :
  {
    CREATE_OBJECT_SYMBOLS
    *(.text)
     etext  =  .;
     __CTOR_LIST__ = .;
     LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
    *(.ctors)
     LONG(0)
     __CTOR_END__ = .;
     __DTOR_LIST__ = .;
     LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
    *(.dtors)
     LONG(0)
     __DTOR_END__ = .;
    *(.lit)
    *(.shdata)
  }  > ram
  .shbss SIZEOF(.text) + ADDR(.text) :	{
    *(.shbss)
  }

Set up the .text section. In a COFF file, .text is where all the actual instructions are. This also sets up the CONTRUCTOR and the DESTRUCTOR tables for G++. Notice that the section description redirects itself to the ram variable setup earlier.

  .talias :	 { }  > ram
  .data  : {
    *(.data)
    CONSTRUCTORS
    _edata  =  .;
  } > ram

Setup the .data section. In a coff file, this is where all he initialized data goes. CONSTRUCTORS is a special command used by ld.

  .bss SIZEOF(.data) + ADDR(.data) :
  {
   __bss_start = ALIGN(0x8);
   *(.bss)
   *(COMMON)
      end = ALIGN(0x8);
      _end = ALIGN(0x8);
      __end = ALIGN(0x8);
  }
  .mstack  : { }  > ram
  .rstack  : { }  > ram
  .stab  . (NOLOAD) : 
  {
    [ .stab ]
  }
  .stabstr  . (NOLOAD) :
  {
    [ .stabstr ]
  }
}

Setup the .bss section. In a COFF file, this is where unitialized data goes. The symbols _bss_start and _end are setup here for use by the crt0.o when it zero’s the .bss section.


Next: , Previous: , Up: Libraries   [Contents]