     START-INFO-DIR-ENTRY
     * Ld-Internals: (ldint).	The GNU linker internals.
     END-INFO-DIR-ENTRY

This file documents the internals of the GNU linker ld.

Copyright (C) 1992 Free Software Foundation, Inc. Contributed by Cygnus Support.

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy or distribute modified versions of this manual under the terms of the GPL (for which purpose this text may be regarded as a program in the language TeX).

Copyright © 1992 Free Software Foundation, Inc.

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

This file documents the internals of the GNU linker ld.  It is a collection of miscellaneous information with little form at this point. Mostly, it is a repository into which you can put information about GNU ld as you discover it (or as you design changes to ld).

The README File
***************

Check the README file; it often has useful information that does not appear anywhere else in the directory.

How linker emulations are generated
***********************************

The linker is controlled by linker scripts written in a linker control language.  A linker emulation gives the personality of the linker, and is mainly defined by certain linker scripts. If you want to understand how these scripts are generated, the main file to look at is the genscripts.sh shell script, which is invoked by the Makefile for each ``emulation'' to generate a set of 5 linker scripts.

For example, for the sun3 emulation used by ld68k, genscripts.sh sources the file emulparams/sun3.sh, which sets the emulation parameters, and specifies that the format is a.out, and to use scripttempl/aout.sc to generate the linker scripts.

genscripts.sh generates 5 different linker scripts, one for each of the ld options -z (default), -n, -N, -r and -Ur, where each script is slightly different and is generated using the template in scripttempl/aout.sc (for the sun3).

Porting the linker
******************

Before porting ld itself, you will need to port the BFD library; see ../bfd/PORTING.

The host is the system a tool runs on. The target is the system a tool runs for; i.e., a tool can read and write the binaries of the target. Most often, host==target, but ld supports cross-linking (and to some extent the same ld binary can be used a linker for multiple target architectures).

Porting to a new host
=====================

Pick a name for your host. Call that HOST-TYPE. You need to create the file config/HOST-TYPE.mh.

Porting to a new target
=======================

Pick a name for your target. Call that TARGET. You need to create at least config/TARGET.mt. It should contain

     EMUL=EMULATION

An emulation controls the ``personality'' of ld, such as the default linker script.  Usually, the EMULATION will have the same name as the TARGET, and you will need to create a new EMULATION (see below).

You also need to edit Makefile.in and possibly configure.in. To see how to do that, search for existing examples (e.g., sun3, sun4, hp300bsd).

Porting to a new emulation target
=================================

Pick a name for your target. Call that EMULATION. Usually, EMULATION and TARGET are the same. You need to create at least emulparams/EMULATION.sh. You also need to edit Makefile.in. To see how to do that, search for existing examples.

The file emulparams/EMULATION.sh defines a set of parameters that are used to generate the emulation.  Its syntax is that of a Bourne shell script.  It is ``sourced'' by genscripts.sh.

Writing EMULATION.sh
====================

Usually, EMULATION.sh contains:

     EMULATION_NAME=EMULATION
     SCRIPT_NAME=SCRIPT
     OUTPUT_FORMAT="TARGET-NAME"
     TEXT_START_ADDR=TEXT-START-ADDR
     PAGE_SIZE=PAGE-SIZE
     SEGMENT_SIZE=SEGMENT-SIZE  # If different from PAGE_SIZE.
     ARCH=ARCH

Here:

TARGET-NAME
     Matches the filename field of the bfd_target you want to use.  (This is a string, and currently the first field.) For an a.out target, TARGET-NAME matches the TARGETNAME defined in ../bfd/TARGET.c.

ARCH
     The architecture: e.g., m68k, sparc, ....

SCRIPT
     The file scripttempl/SCRIPT.sc is a shell script which, when evaluated (by genscripts.sh), writes a linker script file to standard output.  You may need to write a new script.  If you use the a.out format or something similar, you can probably set

          SCRIPT_NAME=aout

TEXT-START-ADDR
PAGE-SIZE
SEGMENT-SIZE
     These set the shell variables TEXT_START_ADDR, PAGE_SIZE, and SEGMENT_SIZE for use by scripttempl/SCRIPT.sc. If your script doesn't use these variables, you don't have to define the variables, For emulations using a.out files, you can get these values from ../bfd/TARGET.c.

In some cases, you may need more more definitions. For example, if you can't use emultempl/generic.em, you may need to add:

     TEMPLATE_NAME=EMULATION

and write your own emultempl/EMULATION.em file.

Writing a new linker script scripttempl/SCRIPT.sc
=================================================

You may need to write a new script file for your emulation.

Your script can use the shell variable LD_FLAG, which has the value:

LD_FLAG=
     when building a script to be used by default

LD_FLAG=n
     when building a script to be used for ld -n

LD_FLAG=N
     when building a script to be used for ld -N

LD_FLAG=r
     when building a script to be used for ld -r

LD_FLAG=u
     when building a script to be used for ld -Ur

The variable RELOCATING is only set if relocation is happening (i.e., unless the linker is invoked with -r). Thus your script should has an action ACTION that should only be done when relocating, express that as:

     ${RELOCATING+ ACTION}

This is the case for most assignments, which should look like:

     ${RELOCATING+ _end = .}

Also, you should assign absolute addresses to sections only when relocating, so:

     .text ${RELOCATING+ ${TEXT_START_ADDR}}:

The form:

     	 .section { ... } > section

should be:

     	 .section { ... } > ${RELOCATING+ section}

RELOCATING is set except when LD_FLAG=r or LD_FLAG=u. CONSTRUCTING is set except when LD_FLAG=u.

Alignment of the data segments is controlled by the variables DATA_ALIGNMENT_ (note trailing underscore), DATA_ALIGNMENT_n, DATA_ALIGNMENT_N, DATA_ALIGNMENT_r, or DATA_ALIGNMENT_u depending on the value of LD_FLAGS.  Normally, the default value works (this is "ALIGN(${SEGMENT_SIZE})" for the _n, and __ (default) variants; "." for the _N, variant; and "" for the _r and _u variants).

Handling -n and -N style binaries in your linker script
=======================================================

The -n linker option requests the linker to create a binary with a write-protected text segment, but not demand-pagable (NMAGIC). SunOS starts the text segment for demand-paged binaries at 0x2020 and other binaries at 0x2000, since the exec header (0x20 bytes) is paged in with the text.  Some other Unix variants do the same.

In that case, the emulparams/EMULATION.sh should define:

NONPAGED_TEXT_START_ADDR
     The text start address to use when linking with -n or -N options.

For example, on a sun4:

     TEXT_START_ADDR=0x2020
     NONPAGED_TEXT_START_ADDR=0x2000

The -N linker option creates a binary with a non-write-protected text segment (NMAGIC).  This is like -n, except that the data segment needs not be page-aligned.