Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP
More options
HP.com home
HP-UX Reference > A

a.out(4)

HP-UX 11i Version 3: February 2007
» 

Technical documentation

» Feedback
Content starts here

 » Table of Contents

 » Index

NAME

a.out — assembler and link editor output

SYNOPSIS

#include <elf.h> (for ELF files)

#include <a.out.h> (for SOM files)

DESCRIPTION

ELF a.out

The file name a.out is the default output file name from the link editor, ld(1). The link editor will make an a.out executable if there were no errors in linking. The output file of the assembler, as(1), also follows the format of the a.out file although its default file name is different.

Programs that manipulate ELF files may use the library that elf(3E) describes. An overview of the file format follows. For more complete information, see the references given below.

Linking View Execution View _______________________ _______________________ ELF header ELF header |_____________________| |______________________| |Program header table | | Program header table| | optional | | | |_____________________| | _____________________| | Section 1 | | | |_____________________| | | | . . . | | Segment 1 | | | | | |_____________________| | _____________________| | Section n | | | |_____________________| | | | . . . | | Segment 2 | | | | | |_____________________| | _____________________| | . . . | | . . . | |_____________________| | _____________________| | Section header table| | Section header table| | | | optional | |_____________________| | _____________________|

An ELF header resides at the beginning and holds a ``road map'' describing the file's organization. Sections hold the bulk of object file information for the linking view: instructions, data, symbol table, relocation information, and so on. Segments hold the object file information for the program execution view. As shown, a segment may contain one or more sections.

A program header table, if present, tells the system how to create a process image. Files used to build a process image (execute a program) must have a program header table; relocatable files do not need one. A section header table contains information describing the file's sections. Every section has an entry in the table; each entry gives information such as the section name, the section size, and so on. Files used during linking must have a section header table; other object files may or may not have one.

Although the figure shows the program header table immediately after the ELF header, and the section header table following the sections, actual files may differ. Moreover, sections and segments have no specified order. Only the ELF header has a fixed position in the file.

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 is not writable by the program; if other processes are executing the same a.out file, the processes will share a single text segment.

The data segment starts at the next maximal page boundary past the last text address. (If the system supports more than one page size, the ``maximal page'' is the largest supported size.) When the process image is created, the part of the file holding the end of text and the beginning of data may appear twice. The duplicated chunk of text that appears at the beginning of data is never executed; it is duplicated so that the operating system may bring in pieces of the file in multiples of the actual page size without having to realign the beginning of the data section to a page boundary. Therefore, the first data address is the sum of the next maximal page boundary past the end of text plus the remainder of the last text address divided by the maximal page size. If the last text address is a multiple of the maximal page size, no duplication is necessary. The stack is automatically extended as required. The data segment is extended as requested by the brk(2) system call.

SOM a.out (PA-RISC Only)

The file name a.out is the default file name for the output file from the assembler (see as(1)), compilers, and the linker (see ld(1)). The assembler and compilers create relocatable object files, ready for input to the linker. The linker creates executable object files and shared library files.

An object file consists of a file header, auxiliary headers, space dictionary, subspace dictionary, symbol table, relocation information, compiler records, space string table, symbol string table, and the data for initialized code and data. Not all of these sections are required for all object files. The file must begin with the file header, but the remaining sections do not have to be in any particular order; the file header contains pointers to each of the other sections of the file.

A relocatable object file, created by the assembler or compiler, must contain at least the following sections: file header, space dictionary, subspace dictionary, symbol table, relocation information, space string table, symbol string table, and code and data. It may also contain auxiliary headers and compiler records. Relocatable files generally contain unresolved symbols. The linker combines relocatable files and searches libraries to produce an executable file. The linker can also be used to combine relocatable files and produce a new relocatable file as output, suitable for input to a subsequent linker run.

An executable file, created by the linker, typically contains the following sections: file header, an HP-UX auxiliary header, space dictionary, subspace dictionary, symbol table, space string table, symbol string table, and code and data. The linker also copies any auxiliary headers and compiler records from the input files to the output file. If the file has been stripped (see strip(1)), it will not contain a symbol table, symbol string table, or compiler records. An executable file must not contain any unresolved symbols.

A shared library file, created by the linker, contains the same sections found in an executable file, with additional information added to the code section of the file. This additional information contains a header, export table, import table, and dynamic relocation records to be used by the dynamic loader.

Programs consist of two loadable spaces: a shared, non-writable, code space named $TEXT$; and a private, writable, data space named $PRIVATE$. A program may contain another loadable, private space named $THREAD_SPECIFIC$. A program may contain other unloadable spaces that contain data needed by development tools. For example, symbolic debugging information is contained in a space named $DEBUG$ or $PINFO$. The linker treats loadable and unloadable spaces exactly the same, so the full generality of symbol resolution and relocation is available for the symbolic debugging information.

Spaces have an addressing range of 4,294,967,296 (2^32) bytes. Each loadable space is divided into four 1,073,741,824 (2^30) byte quadrants. The HP-UX operating system places all code in the first quadrant of the $TEXT$ space, all data in the second quadrant of the $PRIVATE$ space, and all shared library code in the third quadrant of shared memory space.

Each space is also divided into logical units called subspaces. When the linker combines relocatable object files, it groups all subspaces from the input files by name, then arranges the groups within the space by a sort key associated with each subspace. Subspaces are not architecturally significant; they merely provide a mechanism for combining individual parts of spaces independently from many input files. Some typical subspaces in a program are shown in the following table:

$SHLIB_INFO$Information needed for dynamic loading
$MILLICODE$Code for millicode routines
$LIT$Sharable literals
$CODE$Code
$UNWIND$Stack unwind information
$GLOBAL$Outer block declarations for Pascal
$DATA$Static initialized data
$COMMON$FORTRAN common
$BSS$Uninitialized data
$TBSS$Thread local storage

Subspaces can be initialized or uninitialized (although typically, only $BSS$ and $TBSS$ are uninitialized). The subspace dictionary entry for an initialized subspace contains a file pointer to the initialization data, while the entry for an uninitialized subspace contains only a 32-bit pattern used to initialize the entire area at load time.

In a relocatable file, initialized code and data often contain references to locations elsewhere in the file, and to unresolved symbols defined in other files. These references are patched at link time using the relocation information. Each entry in the relocation information (a "fixup") specifies a location within the initialized data for a subspace, and an expression that defines the actual value that should be placed at that location, relative to one or two symbols.

The linker summarizes the subspace dictionary in the HP-UX auxiliary header when creating an executable file. HP-UX programs contain only three separate sections: one for the code, one for initialized data, and one for uninitialized data. By convention, this auxiliary header is placed immediately following the file header.

When an a.out file is loaded into memory for execution, three areas of memory are set up: the a.out code is loaded into the first quadrant of a new, sharable space; the data (initialized followed by uninitialized) is loaded into the second quadrant of a new, private space; and a stack is created beginning at a fixed address near the middle of the second quadrant of the data space.

If the a.out file uses shared libraries, then the dynamic loader /usr/lib/dld.sl is loaded into memory and called to map into memory all shared libraries requested by the program. The shared library text is loaded into the third quadrant of the shared memory space, and the shared library data is allocated in the second quadrant of the data space.

The file format described here is a common format for all operating systems designed for HP's Precision Architecture. Therefore, there are some fields and structures that are not used on HP-UX or have been reserved for future use.

File Header

The format of the file header is described by the following structure declaration from <filehdr.h>.

struct header { short int system_id; /* system id */ short int a_magic; /* magic number */ unsigned int version_id; /* a.out format version */ struct sys_clock file_time; /* timestamp */ unsigned int entry_space; /* index of space containing entry point */ unsigned int entry_subspace; /* subspace index of entry */ unsigned int entry_offset; /* offset of entry point */ unsigned int aux_header_location; /* file ptr to aux hdrs */ unsigned int aux_header_size; /* sizeof aux hdrs */ unsigned int som_length; /* length of object module */ unsigned int presumed_dp; /* DP value assumed during compilation */ unsigned int space_location; /* file ptr to space dict */ unsigned int space_total; /* # of spaces */ unsigned int subspace_location; /* file ptr to subsp dict */ unsigned int subspace_total; /* # of subspaces */ unsigned int loader_fixup_location; /* space reference array */ unsigned int loader_fixup_total; /* # of space reference recs */ unsigned int space_strings_location; /* file ptr to sp. strings */ unsigned int space_strings_size; /* sizeof sp. strings */ unsigned int init_array_location; /* location of init pointers */ unsigned int init_array_total; /* # of init pointers */ unsigned int compiler_location; /* file ptr to comp recs */ unsigned int compiler_total; /* # of compiler recs */ unsigned int symbol_location; /* file ptr to sym table */ unsigned int symbol_total; /* # of symbols */ unsigned int fixup_request_location; /* file ptr to fixups */ unsigned int fixup_request_total; /* # of fixups */ unsigned int symbol_strings_location; /* file ptr to sym strings */ unsigned int symbol_strings_size; /* sizeof sym strings */ unsigned int unloadable_sp_location; /* file ptr to debug info */ unsigned int unloadable_sp_size; /* size of debug info */ unsigned int checksum; /* header checksum */ };

The timestamp is a two-word structure as shown below. If unused, both fields are zero.

struct sys_clock { unsigned int secs; unsigned int nanosecs; };

Auxiliary Headers

The auxiliary headers are contained in a single contiguous area in the file, and are located by a pointer in the file header. Auxiliary headers are used for two purposes: to attach users' version and copyright strings to an object file, and to contain the information needed to load an executable program. In an executable program, the HP-UX auxiliary header must precede all other auxiliary headers. The following declarations are found in <aouthdr.h>.

struct aux_id { unsigned int mandatory : 1; /* linker must understand aux hdr info */ unsigned int copy : 1; /* copy aux hdr without modification */ unsigned int append : 1; /* merge multiple entries of same type */ unsigned int ignore : 1; /* ignore aux hdr if type unknown */ unsigned int reserved : 12; /* reserved */ unsigned int type : 16; /* aux hdr type */ unsigned int length; /* sizeof rest of aux hdr */ }; /* Values for the aux_id.type field */ #define HPUX_AUX_ID 4 #define VERSION_AUX_ID 6 #define COPYRIGHT_AUX_ID 9 #define SHLIB_VERSION_AUX_ID 10 struct som_exec_auxhdr { /* HP-UX auxiliary header */ struct aux_id som_auxhdr; /* aux header id */ long exec_tsize; /* text size */ long exec_tmem; /* start address of text */ long exec_tfile; /* file ptr to text */ long exec_dsize; /* data size */ long exec_dmem; /* start address of data */ long exec_dfile; /* file ptr to data */ long exec_bsize; /* bss size */ long exec_entry; /* address of entry point */ long exec_flags; /* loader flags */ long exec_bfill; /* bss initialization value */ }; /* Values for exec_flags */ #define TRAP_NIL_PTRS 01 struct user_string_aux_hdr { /* Version string auxiliary header */ struct aux_id header_id; /* aux header id */ unsigned int string_length; /* strlen(user_string) */ char user_string[1]; /* user-defined string */ }; struct copyright_aux_hdr { /* Copyright string auxiliary header */ struct aux_id header_id; /* aux header id */ unsigned int string_length; /* strlen(user_string) */ char copyright[1]; /* user-defined string */ }; struct shlib_version_aux_hdr { struct aux_id header_id; /* aux header id */ short version; /* version number */ };

Space Dictionary

The space dictionary consists of a sequence of space records, as defined in <spacehdr.h>.

struct space_dictionary_record { union name_pt name; /* index to space name */ unsigned int is_loadable: 1; /* space is loadable */ unsigned int is_defined: 1; /* space is defined within file */ unsigned int is_private: 1; /* space is not sharable */ unsigned int has_intermediate_code: 1; /* contains intermediate code */ unsigned int is_tspecific: 1; /* space is $thread_specific$ */ unsigned int reserved: 11; /* reserved */ unsigned int sort_key: 8; /* sort key for space */ unsigned int reserved2: 8; /* reserved */ int space_number; /* space index */ int subspace_index; /* index to first subspace */ unsigned int subspace_quantity; /* # of subspaces in space */ int loader_fix_index; /* index into loader fixup array */ unsigned int loader_fix_quantity; /* # of loader fixups in space */ int init_pointer_index; /* index into init pointer array */ unsigned int init_pointer_quantity; /* # of init ptrs */ };

The strings for the space names are contained in the space strings table, which is located by a pointer in the file header. Each entry in the space strings table is preceded by a 4-byte integer that defines the length of the string, and is terminated by one to five null characters to pad the string out to a word boundary. Indices to this table are relative to the start of the table, and point to the first byte of the string (not the preceding length word). The union defined below is used for all such string pointers; the character pointer is defined for programs that read the string table into memory and wish to relocate in-memory copies of space records.

union name_pt { char *n_name; unsigned int n_strx; };

Subspace Dictionary

The subspace dictionary consists of a sequence of subspace records, as defined in <scnhdr.h>. Strings for subspace names are contained in the space strings table.

struct subspace_dictionary_record { int space_index; /* index into space dictionary */ unsigned int access_control_bits: 7; /* access and priv levels of subsp */ unsigned int memory_resident: 1; /* lock in memory during exec */ unsigned int dup_common: 1; /* duplicate data symbols allowed */ unsigned int is_common: 1; /* initialized common block */ unsigned int is_loadable: 1; /* subspace is loadable */ unsigned int quadrant: 2; /* quadrant in space subsp should reside in */ unsigned int initially_frozen: 1; /* lock in memory when OS booted */ unsigned int is_first: 1; /* must be first subspace */ unsigned int code_only: 1; /* subspace contains only code */ unsigned int sort_key: 8; /* subspace sort key */ unsigned int replicate_init: 1; /* init values to be replicated to fill subsp len */ unsigned int continuation: 1; /* subspace is a continuation */ unsigned int is_tspecific: 1; /* subspace contains TLS */ unsigned int reserved: 5; /* reserved */ int file_loc_init_value; /* file location or init value */ unsigned int initialization_length; /* length of initialization */ unsigned int subspace_start; /* starting offset */ unsigned int subspace_length; /* total subspace length */ unsigned int reserved2: 16; /* reserved */ unsigned int alignment: 16; /* alignment required */ union name_pt name; /* index of subspace name */ int fixup_request_index; /* index to first fixup */ unsigned int fixup_request_quantity; /* # of fixup requests */ };

Symbol Table

The symbol table consists of a sequence of entries described by the structure shown below, from <syms.h>. Strings for symbol and qualifier names are contained in the symbol strings table, whose structure is identical with the space strings table.

struct symbol_dictionary_record { unsigned int hidden: 1; /* symbol not visible to loader */ unsigned int secondary_def: 1; /* secondary def symbol */ unsigned int symbol_type: 6; /* symbol type */ unsigned int symbol_scope: 4; /* symbol value */ unsigned int check_level: 3; /* type checking level */ unsigned int must_qualify: 1; /* qualifier required */ unsigned int initially_frozen: 1; /* lock in memory when OS booted */ unsigned int memory_resident: 1; /* lock in memory during exec */ unsigned int is_common: 1; /* common block */ unsigned int dup_common: 1; /* duplicate data symbols allowed */ unsigned int xleast: 2; /* MPE-only */ unsigned int arg_reloc: 10; /* parameter relocation bits */ union name_pt name; /* index to symbol name */ union name_pt qualifier_name; /* index to qual name */ unsigned int symbol_info; /* subspace index */ unsigned int symbol_value; /* symbol value */ }; /* Values for symbol_type */ #define ST_NULL 0 /* unused symbol entry */ #define ST_ABSOLUTE 1 /* non-relocatable symbol */ #define ST_DATA 2 /* initialized data symbol */ #define ST_CODE 3 /* generic code symbol */ #define ST_PRI_PROG 4 /* program entry point */ #define ST_SEC_PROG 5 /* secondary prog entry point*/ #define ST_ENTRY 6 /* procedure entry point */ #define ST_STORAGE 7 /* storage request */ #define ST_STUB 8 /* MPE-only */ #define ST_MODULE 9 /* Pascal module name */ #define ST_SYM_EXT 10 /* symbol extension record */ #define ST_ARG_EXT 11 /* argument extension record */ #define ST_MILLICODE 12 /* millicode entry point */ #define ST_PLABEL 13 /* MPE-only */ #define ST_OCT_DIS 14 /* Used by OCT only--ptr to translated code */ #define ST_MILLI_EXT 15 /* address of external millicode */ #define ST_TSTORAGE 16 /* TLS common symbol */ /* Values for symbol_scope */ #define SS_UNSAT 0 /* unsatisfied reference */ #define SS_EXTERNAL 1 /* import request to external symbol */ #define SS_LOCAL 2 /* local symbol */ #define SS_UNIVERSAL 3 /* global symbol */

The meaning of the symbol value depends on the symbol type. For the code symbols (generic code, program entry points, procedure and millicode entry points), the low-order two bits of the symbol value encode the execution privilege level, which is not used on HP-UX, but is generally set to 3. The symbol value with those bits masked out is the address of the symbol (which is always a multiple of 4). For data symbols, the symbol value is simply the address of the symbol. For thread local storage symbols (not commons), the symbol value is the thread local storage offset in a library or executable file, and is the size of the symbol if in a relocatable object file. For storage requests and thread local storage commons, the symbol value is the number of bytes requested; the linker allocates space for the largest request for each symbol in the $BSS$ or $TBSS$ subspaces, unless a local or universal symbol is found for that symbol (in which case the storage request is treated like an unsatisfied reference).

If a relocatable file is compiled with parameter type checking, extension records follow symbols that define and reference procedure entry points and global variables. The first extension record, the symbol extension record, defines the type of the return value or global variable, and (if a procedure or function) the number of parameters and the types of the first three parameters. If more parameter type descriptors are needed, one or more argument extension records follow, each containing four more descriptors. A check level of 0 specifies no type checking; no extension records follow. A check level of 1 or more specifies checking of the return value or global variable type. A check level of 2 or more specifies checking of the number of parameters, and a check level of 3 specifies checking the types of each individual parameter. The linker performs the requested level of type checking between unsatisfied symbols and local or universal symbols as it resolves symbol references.

union arg_descriptor { struct { unsigned int reserved: 3; /* reserved */ unsigned int packing: 1; /* packing algorithm used */ unsigned int alignment: 4; /* byte alignment */ unsigned int mode: 4; /* type of descriptor and its use */ unsigned int structure: 4; /* structure of symbol */ unsigned int hash: 1; /* set if arg_type is hashed */ int arg_type: 15; /* data type */ } arg_desc; unsigned int word; }; struct symbol_extension_record { unsigned int type: 8; /* always ST_SYM_EXT */ unsigned int max_num_args: 8; /* max # of parameters */ unsigned int min_num_args: 8; /* min # of parameters */ unsigned int num_args: 8; /* actual # of parameters */ union arg_descriptor symbol_desc; /* symbol type desc. */ union arg_descriptor argument_desc[3]; /* first 3 parameters */ }; struct argument_desc_array { unsigned int type: 8; /* always ST_ARG_EXT */ unsigned int reserved: 24; /* reserved */ union arg_descriptor argument_desc[4]; /* next 4 parameters */ };

The alignment field in arg_descriptor indicates the minimum alignment of the data, where a value of n represents 2^n byte alignment. The values for the mode, structure, and arg_type (when the data type is not hashed) fields in arg_descriptor are given in the following table.

Valuemodestructurearg_type
0anyanyany
1value parmscalarvoid
2reference parmarraysigned byte
3value-resultstructunsigned byte
4namepointersigned short
5variablelong ptrunsigned short
6function returnC stringsigned long
7procedurePascal stringunsigned long
8long ref parmproceduresigned dbl word
9 functionunsigned dbl word
10 labelshort real
11  real
12  long real
13  short complex
14  complex
15  long complex
16  packed decimal
17  struct/array

For procedure entry points, the parameter relocation bits define the locations of the formal parameters and the return value. Normally, the first four words of the parameter list are passed in general registers (r26-r23) instead of on the stack, and the return value is returned in r29. Floating-point parameters in this range are passed instead in floating-point registers (fr4-fr7) and a floating-point value is returned in fr4. The parameter relocation bits consist of five pairs of bits that describe the first four words of the parameter list and the return value. The leftmost pair of bits describes the first parameter word, and the rightmost pair of bits describes the return value. The meanings of these bits are shown in the following table.

BitsMeaning
00No parameter or return value
01Parameter or return value in general register
10Parameter or return value in floating-point register
11Double-precision floating-point value

For double-precision floating-point parameters, the odd-numbered parameter word should be marked 11 and the even-numbered parameter word should be marked 10. Double-precision return values are simply marked 11.

Every procedure call is tagged with a similar set of bits (see "Relocation Information" below), so that the linker can match each call with the expectations of the procedure entry point. If the call and entry point mismatch, the linker creates a stub that relocates the parameters and return value as appropriate.

Relocation Information

Each initialized subspace defines a range of fixups that apply to the data in that subspace. A fixup request is associated with every word that requires relocation or that contains a reference to an unsatisfied symbol. In relocatable object files created prior to HP-UX Release 3.0 on Series 800 systems, each fixup request is a five-word structure describing a code or data word to be patched at link time. Object files created on Release 3.0 or later contain variable-length fixup requests that describe every byte of the subspace. The version_id field in the file header distinguishes these two formats; the constant VERSION_ID is found in older object files, and the constant NEW_VERSION_ID is found in newer ones.

In older object files, fixups can compute an expression involving zero, one, or two symbols and a constant, then extract a field of bits from that result and deposit those bits in any of several different formats (corresponding to the Precision Architecture instruction set). The fixup_request_index field in the subspace dictionary entry indexes into the fixup request area defined by the file header and the fixup_request_quantity field refers to the number of fixup requests used for that subspace. The structure of a fixup request is contained in <reloc.h>.

struct fixup_request_record { unsigned int need_data_ref: 1; /* reserved */ unsigned int arg_reloc: 10; /* parameter relocation bits */ unsigned int expression_type: 5; /* how to compute value */ unsigned int exec_level: 2; /* reserved */ unsigned int fixup_format: 6; /* how to deposit bits */ unsigned int fixup_field: 8; /* field to extract */ unsigned int subspace_offset; /* subspace offset of word */ unsigned int symbol_index_one; /* index of first symbol */ unsigned int symbol_index_two; /* index of second symbol */ int fixup_constant; /* constant */ }; /* Values for expression_type */ #define e_one 0 /* symbol1 + constant */ #define e_two 1 /* symbol1 - symbol2 + constant */ #define e_pcrel 2 /* symbol1 - pc + constant */ #define e_con 3 /* constant */ #define e_plabel 7 /* symbol1 + constant */ #define e_abs 18 /* absolute, 1st sym index is address */ /* Values for fixup_field (assembler mnemonics shown) */ #define e_fsel 0 /* F': no change */ #define e_lssel 1 /* LS': inverse of RS' */ #define e_rssel 2 /* RS': rightmost 11 bits, signed */ #define e_lsel 3 /* L': leftmost 21 bits */ #define e_rsel 4 /* R': rightmost 11 bits */ #define e_ldsel 5 /* LD': inverse of RD' */ #define e_rdsel 6 /* RD': rightmost 11 bits, filled left with ones */ #define e_lrsel 7 /* LR': L' with "rounded" constant */ #define e_rrsel 8 /* RR': R' with "rounded" constant */ #define e_nsel 9 /* N1': set all bits to zero: for id of 3-inst code gen sequence */ /* Values for fixup_format (typical instructions shown) */ #define i_exp14 0 /* 14-bit immediate (LDW, STW) */ #define i_exp21 1 /* 21-bit immediate (LDIL, ADDIL) */ #define i_exp11 2 /* 11-bit immediate (ADDI, SUBI) */ #define i_rel17 3 /* 17-bit pc-relative (BL) */ #define i_rel12 4 /* 12 bit pc-relative (COMBT, COMBF, etc.) */ #define i_data 5 /* whole word */ #define i_none 6 #define i_abs17 7 /* 17-bit absolute (BE, BLE) */ #define i_milli 8 /* 17-bit millicode call (BLE) */ #define i_break 9 /* reserved (no effect on HP-UX) */

In newer object files, relocation entries consist of a stream of bytes. The fixup_request_index field in the subspace dictionary entry is a byte offset into the fixup dictionary defined by the file header, and the fixup_request_quantity field defines the length of the fixup request stream, in bytes, for that subspace. The first byte of each fixup request (the opcode) identifies the request and determines the length of the request.

In general, the fixup stream is a series of linker instructions that governs how the linker places data in the a.out file. Certain fixup requests cause the linker to copy one or more bytes from the input subspace to the output subspace without change, while others direct the linker to relocate words or resolve external references. Still others direct the linker to insert zeroes in the output subspace or to leave areas uninitialized without copying any data from the input subspace, and others describe points in the code without contributing any new data to the output file.

The include file <reloc.h> defines constants for each major opcode. Many fixup requests use a range of opcodes; only a constant for the beginning of the range is defined. The meaning of each fixup request is described below. The opcode ranges and parameters for each fixup are described in the table further below.

R_NO_RELOCATION

Copy L bytes with no relocation.

R_ZEROES

Insert L zero bytes into the output subspace.

R_UNINIT

Skip L bytes in the output subspace.

R_RELOCATION

Copy one data word with relocation. The word is assumed to contain a 32-bit pointer relative to its own subspace.

R_DATA_ONE_SYMBOL

Copy one data word with relocation relative to an external symbol whose symbol index is S.

R_DATA_PLABEL

Copy one data word as a 32-bit procedure label, referring to the symbol S. The original contents of the word should be 0 (no static link) or 2 (static link required).

R_SPACE_REF

Copy one data word as a space reference. This fixup request is not currently supported.

R_REPEATED_INIT

Copy L bytes from the input subspace, replicating the data to fill M bytes in the output subspace.

R_PCREL_CALL

Copy one instruction word with relocation. The word is assumed to be a pc-relative procedure call instruction (for example, BL). The target procedure is identified by symbol S, and the parameter relocation bits are R.

R_ABS_CALL

Copy one instruction word with relocation. The word is assumed to be an absolute procedure call instruction (for example, BLE). The target procedure is identified by symbol S, and the parameter relocation bits are R.

R_DP_RELATIVE

Copy one instruction word with relocation. The word is assumed to be a dp-relative load or store instruction (for example, ADDIL, LDW, STW). The target symbol is identified by symbol S. The linker forms the difference between the value of the symbol S and the value of the symbol $global$. By convention, the value of $global$ is always contained in register 27. Instructions may have a small constant in the displacement field of the instruction.

R_DLT_REL

Copy one instruction word with relocation. The word is assumed to be a register-18-relative load or store instruction (for example, LDW, LDO, STW). The target symbol is identified by symbol S. The linker computes a linkage table offset relative to register 18 (reserved for a linkage table pointer in position-independent code) for the symbol S.

R_CODE_ONE_SYMBOL

Copy one instruction word with relocation. The word is assumed to be an instruction referring to symbol S (for example, LDIL, LDW, BE). Instructions may have a small constant in the displacement field of the instruction.

R_MILLI_REL

Copy one instruction word with relocation. The word is assumed to be a short millicode call instruction (for example, BLE). The linker forms the difference between the value of the target symbol S and the value of symbol 1 in the module's symbol table. By convention, the value of symbol 1 should have been previously loaded into the base register used in the BLE instruction. The instruction may have a small constant in the displacement field of the instruction.

R_CODE_PLABEL

Copy one instruction word with relocation. The word is assumed to be part of a code sequence forming a procedure label (for example, LDIL, LDO), referring to symbol S. The LDO instruction should contain the value 0 (no static link) or 2 (static link required) in its displacement field.

R_BREAKPOINT

Copy one instruction word conditionally. On HP-UX, the linker always replaces the word with a NOP instruction.

R_ENTRY

Define a procedure entry point. The stack unwind bits, U, and the frame size, F, are recorded in a stack unwind descriptor.

R_ALT_ENTRY

Define an alternate procedure entry point.

R_EXIT

Define a procedure exit point.

R_BEGIN_TRY

Define the beginning of a try/recover region.

R_END_TRY

Define the end of a try/recover region. The offset R defines the distance in bytes from the end of the region to the beginning of the recover block.

R_BEGIN_BRTAB

Define the beginning of a branch table.

R_END_BRTAB

Define the end of a branch table.

R_AUX_UNWIND

Define an auxiliary unwind table. CN is a symbol index of the symbol that labels the beginning of the compilation unit string table. SN is the offset, relative to the CN symbol, of the scope name string. SK is an integer specifying the scope kind.

R_STATEMENT

Define the beginning of statement number N.

R_SEC_STATEMENT

Define the beginning of a secondary statement number N.

R_DATA_EXPR

Pop one word from the expression stack and copy one data word from the input subspace to the output subspace, adding the popped value to it.

R_CODE_EXPR

Pop one word from the expression stack, and copy one instruction word from the input subspace to the output subspace, adding the popped value to the displacement field of the instruction.

R_FSEL

Use an F' field selector for the next fixup request instead of the default appropriate for the instruction.

R_LSEL

Use an L-class field selector for the next fixup request instead of the default appropriate for the instruction. Depending on the current rounding mode, L', LS', LD', or LR' may be used.

R_RSEL

Use an R-class field selector for the next fixup request instead of the default appropriate for the instruction. Depending on the current rounding mode, R', RS', RD', or RR' may be used.

R_N_MODE

Select round-down mode (L'/R'). This is the default mode at the beginning of each subspace. This setting remains in effect until explicitly changed or until the end of the subspace.

R_S_MODE

Select round-to-nearest-page mode (LS'/RS'). This setting remains in effect until explicitly changed or until the end of the subspace.

R_D_MODE

Select round-up mode (LD'/RD'). This setting remains in effect until explicitly changed or until the end of the subspace.

R_R_MODE

Select round-down-with-adjusted-constant mode (LR'/RR'). This setting remains in effect until explicitly changed or until the end of the subspace.

R_DATA_OVERRIDE

Use the constant V for the next fixup request in place of the constant from the data word or instruction in the input subspace.

R_TRANSLATED

Toggle "translated" mode. This fixup request is generated only by the linker during a relocatable link to indicate a subspace that was originally read from an old-format relocatable object file.

R_COMP1

Stack operations. The second byte of this fixup request contains a secondary opcode. In the descriptions below, A refers to the top of the stack and B refers to the next item on the stack. All items on the stack are considered signed 32-bit integers.

R_PUSH_PCON1

Push the (positive) constant V.

R_PUSH_DOT

Push the current virtual address.

R_MAX

Pop A and B, then push max(A, B).

R_MIN

Pop A and B, then push min(A, B).

R_ADD

Pop A and B, then push A + B.

R_SUB

Pop A and B, then push B - A.

R_MULT

Pop A and B, then push A * B.

R_DIV

Pop A and B, then push B / A.

R_MOD

Pop A and B, then push B % A.

R_AND

Pop A and B, then push A & B.

R_OR

Pop A and B, then push A | B.

R_XOR

Pop A and B, then push A XOR B.

R_NOT

Replace A with its complement.

R_LSHIFT

If C = 0, pop A and B, then push B << A. Otherwise, replace A with A << C.

R_ARITH_RSHIFT

If C = 0, pop A and B, then push B >> A. Otherwise, replace A with A >> C. The shifting is done with sign extension.

R_LOGIC_RSHIFT

If C = 0, pop A and B, then push B >> A. Otherwise, replace A with A >> C. The shifting is done with zero fill.

R_PUSH_NCON1

Push the (negative) constant V.

R_COMP2

More stack operations.

R_PUSH_PCON2

Push the (positive) constant V.

R_PUSH_SYM

Push the value of the symbol S.

R_PUSH_PLABEL

Push the value of a procedure label for symbol S. The static link bit is L.

R_PUSH_NCON2

Push the (negative) constant V.

R_COMP3

More stack operations.

R_PUSH_PROC

Push the value of the procedure entry point S. The parameter relocation bits are R.

R_PUSH_CONST

Push the constant V.

R_PREV_FIXUP

The linker keeps a queue of the last four unique multi-byte fixup requests. This is an abbreviation for a fixup request identical to one on the queue. The queue index X references one of the four; X = 0 refers to the most recent. As a side effect of this fixup request, the referenced fixup is moved to the front of the queue.

R_N0SEL

Indicates that the following fixup is applied to the first of a three-instruction sequence to access data, generated by the compilers to enable the importing of shared library data.

R_N1SEL

Uses a (N') field selector for the next fixup request. This indicates that zero bits are to be used for the displacement on the instruction. This fixup is used to identify three-instruction sequences to access data (for importing shared library data).

R_LINETAB

Defines the beginning of a line table. CU is a symbol index of the symbol that labels the beginning of the line table. SM is the offset relative to the CU symbol. ES designates the version information for the current line table.

R_LINETAB_ESC

Defines an escape entry to be entered into the line table. ES designates the escape entry entered in the table. M designates the number of R_STATEMENT fixups to be interpreted as raw 8-bit table data.

R_LTP_OVERRIDE

Override the following fixup, which is expected to be a R_DATA_ONE_SYMBOL fixup to copy one data word without relocation when building a shared library. The absolute byte offset of the symbol relative to the linkage table pointer is copied. If the linker is building a complete executable, the absolute virtual address is copied.

R_COMMENT

Fixup used to pass comment information from the compiler to the linker. This fixup has a 5 byte argument that can be skipped and ignored by applications.

R_TP_OVERRIDE

Override the next one of these fixups seen: R_DP_RELATIVE, R_DLT_REL, or R_DATA_ONE_SYMBOL, to use the thread local storage offset when fixing the instruction. This fixup is also used to catch thread local storage symbol mismatches.

R_RESERVED

Fixups in this range are reserved for internal use by the compilers and linker.

The following table shows the mnemonic fixup request type and length and parameter information for each range of opcodes. In the parameters column, the symbol D refers to the difference between the opcode and the beginning of the range described by that table entry; the symbols B1, B2, B3, and B4 refer to the value of the next one, two, three, or four bytes of the fixup request, respectively.

MnemonicOpcodesLengthParameters
R_NO_RELOCATION 0-231L = (D+1) * 4
24-272L = (D<<8 + B1 + 1) * 4
28-303L = (D<<16 + B2 + 1) * 4
314L = B3 + 1
R_ZEROES322L = (B1 + 1) * 4
334L = B3 + 1
R_UNINIT342L = (B1 + 1) * 4
354L = B3 + 1
R_RELOCATION361none
R_DATA_ONE_SYMBOL372S = B1
384S = B3
R_DATA_PLABEL392S = B1
404S = B3
R_SPACE_REF411none
R_REPEATED_INIT422L = 4; M = (B1 + 1) * 4
433L = (B1 + 1) * 4; M = (B1 + 1) * L
445L = (B1 + 1) * 4; M = (B3 + 1) * 4
458L = B3 + 1; M = B4 + 1
R_PCREL_CALL48-572R = rbits1(D); S = B1
58-593R = rbits2(D<<8 + B1); S = B1
60-615R = rbits2(D<<8 + B1); S = B3
R_ABS_CALL64-732R = rbits1(D); S = B1
74-753R = rbits2(D<<8 + B1); S = B1
76-775R = rbits2(D<<8 + B1); S = B3
R_DP_RELATIVE 80-1111S = D
1122S = B1
1134S = B3
R_DLT_REL1202S = B1
1214S = B3
R_CODE_ONE_SYMBOL128-1591S = D
1602S = B1
1614S = B3
R_MILLI_REL1742S = B1
1754S = B3
R_CODE_PLABEL1762S = B1
1774S = B3
R_BREAKPOINT1781none
R_ENTRY1799U,F = B8 (U is 37 bits; F is 27 bits)
1806U = B5 >> 3; F = pop A
R_ALT_ENTRY1811none
R_EXIT1821none
R_BEGIN_TRY1831none
R_END_TRY1841R = 0
1852R = sign_extend(B1) * 4
1864R = sign_extend(B3) * 4
R_BEGIN_BRTAB1871none
R_END_BRTAB1881none
R_STATEMENT1892N = B1
1903N = B2
1914N = B3
R_DATA_EXPR1921none
R_CODE_EXPR1931none
R_FSEL1941none
R_LSEL1951none
R_RSEL1961none
R_N_MODE1971none
R_S_MODE1981none
R_D_MODE1991none
R_R_MODE2001none
R_DATA_OVERRIDE2011V = 0
2022V = sign_extend(B1)
2033V = sign_extend(B2)
2044V = sign_extend(B3)
2055V = B4
R_TRANSLATED2061none
R_AUX_UNWIND20712CU,SN,SK = B11 (CU is 24 bits;
  SN is 32 bits; SK is 32 bits)
R_COMP12082OP = B1; V = OP & 0x3f; C = OP & 0x1f
R_COMP22095OP = B1; S = B3; L = OP & 1;
  V = ((OP & 0x7f) << 24) | S
R_COMP32106OP = B1; V = B4;
  R = ((OP & 1) << 8) | (V >> 16);
  S = V & 0xffffff
R_PREV_FIXUP211-2141X = D
R_N0SEL2161none
R_N1SEL2171none
R_SEC_STMT2151none
R_LINETAB2189ES = B1; CU = B3; SM = B4
R_LINETAB_ESC2193ES = B1; M = B1
R_LTP_OVERRIDE2201none
R_COMMENT2216OP = B1; V = B2 to B6
R_TP_OVERRIDE2221none
R_RESERVED224-255 reserved

Parameter relocation bits are encoded in the fixup requests in two ways, noted as rbits1 and rbits2 in the above table.

The first encoding recognizes that the most common procedure calls have only general register arguments with no holes in the parameter list. The encoding for such calls is simply the number of parameters in general registers (0 to 4), plus 5 if there is a return value in a general register.

The second encoding is more complex. The 10 argument relocation bits are compressed into 9 bits by eliminating some impossible combinations. The encoding is the combination of three contributions. The first contribution is the pair of bits for the return value, which are not modified. The second contribution is 9 if the first two parameter words together form a double-precision parameter; otherwise, it is 3 times the pair of bits for the first word plus the pair of bits for the second word. Similarly, the third contribution is formed based on the third and fourth parameter words. The second contribution is multiplied by 40, the third is multiplied by 4, then the three are added together.

Compiler Records

Compiler records are placed in relocatable files by each compiler or assembler to identify the version of the compiler that was used to produce the file. These records are copied into the executable file by the linker, but are strippable. The structure of a compiler record is shown below. All strings are contained in the symbol string table.

The format of the compilation record is described by the following structure declaration from <compunit.h>.

struct compilation_unit { union name_pt name; /* entry name */ union name_pt language_name; /* language used */ union name_pt product_id; /* compiler ID */ union name_pt version_id; /* compiler version */ unsigned int reserved: 31; /* reserved */ unsigned int chunk_flag: 1; /* MPE-only */ struct sys_clock compile_time; /* time file was compiled */ struct sys_clock source_time; /* time file was last modified */ };

FILES

<a.out.h> <aouthdr.h> <compunit.h> <elf.h> <filehdr.h> <reloc.h> <scnhdr.h> <spacehdr.h> <syms.h>

SEE ALSO

System Tools

as(1)

Translate assembly code to machine code

cc(1)

Invoke the HP-UX C compiler

ld(1)

Invoke the link editor

Miscellaneous

crt0(3)

Execution startup routine

elf(3E)

For the ELF a.out only

end(3C)

Symbol of the last locations in program

magic(4)

Magic number for HP-UX implementations

nm(1)

Print name list of object file

strip(1)

Strip symbol and line number information from an object file

Printable version
Privacy statement Using this site means you accept its terms Feedback to webmaster
© 1983-2007 Hewlett-Packard Development Company, L.P.