Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

as_300(1)

ld(1)

nm_300(1)

strip(1)

crt0(3)

end(3C)

a.out_800(4)

magic(4)

a.out_300(4)  —  Series 300/400 Implementation

NAME

a.out − assembler and link editor output

Remarks:

This manual entry describes the a.out file format for Series 300/400 computers.  Refer to other a.out∗(4) manual entries for descriptions of other implementations.

DESCRIPTION

The a.out file is the output file of the link editor ld (see ld(1). The linker makes a.out executable if there were no linking errors and no unresolved external references.  The assembler as (or ld with the -r option) produces non-executable files with the same basic structure. 

File a.out has eight defined sections: a header, the program text and data segments, a Pascal interface section, a symbol table, a supplementary symbol table, and text and data relocation information (in that order).  Pascal interface text will only be present in those Pascal code segments that have not been linked.  The symbol table may be missing if the program was linked with the ld -s option, or if the symbol table and debug information were removed by strip (see strip(1)). The supplementary symbol table is present only in files containing position-independent code, or in files that were produced with the Pascal compiler or the +s option to the assembler.  Also note that relocation information is not normally present in executable files. 

In addition to these sections, there may be one or more extensions.  Each extension is preceded by a header consisting of an extension-independent part and an extension-dependent part.  Currently defined extensions include one for dynamic loading support and one for debugger support.  The dynamic loader extension is actually placed within the text segment of shared library files (created with the -b option to ld) and executables that use shared libraries.  The debugger extension is placed after the relocation sections.  HP-UX compilers create this information under control of the -g option. 

When an a.out file is loaded into memory for execution, three logical segments are set up: the text segment, the data segment (initialized data followed by uninitialized, the latter actually being initialized to all 0’s), and a stack.  The text segment begins at location 0x0 in the core image; the header is not loaded.  If the magic number (the first field in the header) is EXEC_MAGIC, it indicates that the text segment is not to be write-protected or shared, so the data segment will be contiguous with the text segment.  If the magic number is SHARE_MAGIC or DEMAND_MAGIC, the data segment begins at the first 0 mod 0x1000 byte boundary following the text segment, and the text segment is not writable by the program; if other processes are executing the same a.out file, they will share a single text segment.  If the magic number is DEMAND_MAGIC, the text and data segments are not read in from the file until they are referenced by the program. 

The stack will occupy the highest possible locations in the core image and grow downward (the stack is automatically extended as required).  The data segment is only extended as requested by the brk() system call (see brk(2)).

Shared libraries, indicated by the magic number SHL_MAGIC, are similar to demand-loaded executables, except that they are loaded by the dynamic loader /lib/dld.sl (see dld.sl(5)) at some point during startup, rather than by exec(), and that the load address is arbitrary.  No stack segment is set up for shared libraries; they share the stack used by the executable.  The data and bss segments of a shared library are shared on a page by page basis by all processes using the library.  Whenever a process writes to a shared library data or bss segment, a modified copy of that page is made for the process.  Dynamic load libraries, indicated by the magic number DL_MAGIC, are analagous to shared libraries except that the text segment is also made copy on write in order to support dynamic relocation. 

The start of the text segment in the a.out file is given by the macro TEXT_OFFSET(hdr), where hdr is a copy of the file header.  The macro DATA_OFFSET(hdr) provides the starting location of the data segment. 

The value of a word in the text or data portions that is not a reference to an undefined external symbol is exactly the value that will appear in memory when the file is executed.  If a word in the text or data portion involves a reference to an undefined external symbol, as indicated by the relocation information (discussed below) for that word, then the value of the word as stored in the file is an offset from the associated external symbol.  When the file is processed by the link editor and the external symbol becomes defined, the value of the symbol will be added to the word in the file. 

Header

The format of the a.out header for the MC68000 is as follows (segment sizes are in bytes):

struct exec {
    MAGIC   a_magic;        /* magic number */
    short   a_stamp;        /* version id */
    short   a_highwater;    /* shlib highwater mark */
    long    a_miscinfo;     /* miscellaneous info */
    long    a_text;         /* size of text segment */
    long    a_data;         /* size of data segment */
    long    a_bss;          /* size of bss segment */
    long    a_trsize;       /* text relocation size */
    long    a_drsize;       /* data relocation size */
    long    a_pasint;       /* Pascal interface size */
    long    a_lesyms;       /* symbol table size */
    long    a_spared;
    long    a_entry;        /* entry point */
    long    a_spares;
    long    a_supsym;       /* supplementary symtab size */
    long    a_drelocs;      /* nonpic relocations */
    long    a_extension;    /* file offset of extension */
};

Pascal Interface Section

The Pascal interface section consists of the ASCII representation of the interface text for that Pascal module. 

The start of the Pascal interface section is given by the macro MODCAL_OFFSET(hdr). 

Symbol Table

The symbol table consists of entries of the form:

struct nlist {
    long            n_value;
    unsigned charn_type;
    unsigned charn_length;
    short           n_almod;
    int             n_dlt:1;
    int             n_plt:1;
    int             n_dreloc:1;
    int             n_list:1;
    int             n_unused:12;
};

This structure is followed by n_length ASCII characters which compose the symbol name. 

The n_type field indicates the type of the symbol; the following values are possible:

UNDEF undefined symbol

ABS absolute symbol

TEXT text segment symbol

DATA data segment symbol

BSS bss segment symbol

One of these values OR ed with 040 indicates an external symbol.  One of these values OR ed with 020 indicates an aligned symbol.  One of these values OR ed with 0100 indicates a secondary definition. 

The bit fields are used by the linker for the relocation of position-independent code (generated with the +z option to the compilers) when creating a shared library. 

The start of the symbol table is given by the macro LESYM_OFFSET(hdr). 

In object files that were compiled as position-independent code, generated by the Pascal compiler, or assembled with the as +s option, a supplementary symbol table follows the standard symbol table.  This table is a simple array of eight-byte structures which stand in one-to-one correspondence with the symbol table entries.  The fields of this structure are used by the linker when creating a shared library. 

Relocation

If relocation information is present, it amounts to eight bytes per relocatable datum. 

The format of the relocation data is:

struct r_info{
    longr_address;
    short  r_symbolnum;
    char   r_segment;
    char   r_length;
};

The r_address field indicates the position of the relocation within the segment. 

The r_segment field indicates the segment referred to by the text or data word associated with the relocation word:

RTEXT indicates the reference is to the text segment;

RDATA indicates the reference is to initialized data;

RBSS indicates the reference is to bss (uninitialized data);

REXT indicates the reference is to an undefined external symbol;

RPC indicates the reference is PC relative;

RDLT indicates the reference is to an offset from the base of the data linkage table;

RPLT indicates the reference is to an entry within the procedure linkage table. 

The latter three relocation types are found primarily in position-independent code. 

The r_symbolnum field contains a symbol number in the case of external references, and is unused otherwise.  The first symbol is numbered 0, the second 1, etc. 

The r_length field indicates the length of the datum to be relocated. 

RBYTE indicates it is a byte

RWORD indicates it is a short

RLONG indicates it is a long

RALIGN indicates it is a special align symbol

The start of the text relocation section is provided by the macro RTEXT_OFFSET(hdr).

The start of the data relocation section is provided by the macro RDATA_OFFSET(hdr). 

Extensions

The a_extension field of the header gives the file offset of the first extension, and each extension header gives the file offset of the next.  The dynamic loader extension, if present, will be the first extension present, and the debugger extension, if present, will be next.  Additional extensions can be defined by certain languages or tools.  When present, they are placed after the dynamic loader and debugger extensions. 

The extension header is of the form

struct header_extension
{
    union
    {
        long spare1[13];
        struct _dl_header dl_header;
        struct _debug_header debug_header;
    } e_spec;
    short e_header;
    short e_version;
    long e_size;
    long e_extension;
};

The union allows for extension specific information to be included in the header.  The e_header field contains a constant which identifies the extension type.  Currently defined values include DL_HEADER and DEBUG_HEADER.  The e_version field can be used to identify different versions of an extension.  The e_size field gives the collective size for the extension; e_extension gives the file offset of the next extension. 

For more information about the dynamic loader extension and the debug extension, consult the files /usr/include/shl.h and /usr/include/debug.h, respectively. 

SEE ALSO

as_300(1), ld(1), nm_300(1), strip(1), crt0(3), end(3C), a.out_800(4), magic(4). 

Hewlett-Packard Company  —  HP-UX Release 9.0: August 1992

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026