ar File Format (Big)
Purpose
Combines several files into one. This is the default ar library archive format for the operating system.
Description
The ar (archive) file format combines several files into one. The ar command creates an archive file. The ld (link editor) command searches archive files to resolve program linkage. The /usr/include/ar.h file describes the archive file format. This file format accommodates both 32-bit and 64-bit object files within the same archive.
This is the default file format used by the ar command.
Fixed-Length Header
Each archive begins with a fixed-length header that contains offsets to special archive file members. The fixed-length header also contains the magic number, which identifies the archive file. The fixed-length header has the following format:
#define __AR_BIG__
#define AIAMAGBIG "<bigaf>\n" /* Magic string */
#define SAIAMAG 8 /*Length of magic string */
struct fl_hdr /*Fixed-length header */
{
char fl_magic[SAIAMAG]; /* Archive magic string */
char fl_memoff[20]; /*Offset to member table */
char fl_gstoff[20]; /*Offset to global symbol table */
char fl_gst64off[20]; /*Offset global symbol table for 64-bit objects */
char fl_fstmoff[20]; /*Offset to first archive member */
char fl_lstmoff[20]; /*Offset to last archive member */
char fl_freeoff[20]; /*Offset to first mem on free list */
} ;
The indexed archive file format uses a double-linked list within the archive file to order the file members. Therefore, file members may not be sequentially ordered within the archive. The offsets contained in the fixed-length header locate the first and last file members of the archive. Member order is determined by the linked list.
The fixed-length header also contains the offsets to the member table, the global symbol table, and the free list. Both the member table and the global symbol table exist as members of the archive and are kept at the end of the archive file. The free list contains file members that have been deleted from the archive. When adding new file members to the archive, free list space is used before the archive file size is expanded. A zero offset in the fixed-length header indicates that the member is not present in the archive file.
File Member Header
Each archive file member is preceded by a file member header, which contains the following information about the file member:
#define AIAFMAG "`\n" /* Header trailer string*/
struct ar_hdr /* File member header*/
{
char ar_size[20]; /* File member size - decimal */
char ar_nxtmem[20]; /* Next member offset-decimal */
char ar_prvmem[20]; /* Previous member offset-dec */
char ar_date[12]; /* File member date-decimal */
char ar_uid[12]; /* File member userid-decimal */
char ar_gid[12]; /* File member group id-decimal */
char ar_mode[12]; /* File member mode-octal */
char ar_namlen[4]; /* File member name length-dec */
union
{
char ar_name[2]; /* Start of member name */
char ar_fmag[2]; /* AIAFMAG - string to end */
};
_ar_name; /* Header and member name */
};
The member header provides support for member names up to 255 characters long. The ar_namlen field contains the length of the member name. The character string containing the member name begins at the _ar_name field. The AIAFMAG string is cosmetic only.
sizeof (struct ar_hdr) + ar_namlen
The actual data for a file member begins at the first even-byte boundary beyond the member header and continues for the number of bytes specified by the ar_size field. The ar command inserts null bytes for padding where necessary.
All information in the fixed-length header and archive members is in printable ASCII format. Numeric information, with the exception of the ar_mode field, is stored as decimal numbers; the ar_mode field is stored in octal format. Thus, if the archive file contains only printable files, you can print the archive.
Member Table
A member table is always present in an indexed archive file. This table quickly locates members of the archive. The fl_memoff field in the fixed-length header contains the offset to the member table. The member table member has a zero-length name. The ar command automatically creates and updates (but does not list) the member table. A member table contains the following information:
- The number of members. This member is 20 bytes long and stored in ASCII format as a decimal number.
- The array of offsets into the archive file. The length is 20 times the number of members. Each offset is 20 bytes long and stored in ASCII format as a decimal number.
- The name string table. The size is:
ar_size - (20 * (the number of members +1));
that is, the size equals the total length of all members minus the length of the offsets, minus the length of the number of members.
The string table contains the same number of strings as offsets. All strings are null-terminated. Each offset from the array corresponds sequentially to a name in the string table.
Global Symbol Tables
Immediately following the member table, the archive file contains two global symbol tables. The first global symbol table locates 32-bit file members that define global symbols; the second global symbol table does the same for 64-bit file members. If the archive has no 32-bit or 64-bit file members, the respective global symbol table is omitted. The strip command can be used to delete one or both global symbol tables from the archive. The fl_gstoff field in the fixed-length header contains the offset to the 32-bit global symbol table, and the fl_gst64off contains the offset to the 64-bit global symbol table. The global symbol table members have zero-length names. The ar command automatically creates and updates, but does not list the global symbol tables. A global symbol table contains the following information:
- The number of symbols. This is 8 bytes long and can be accessed with the sgetl and sputl commands.
- The array of offsets into the archive file. The length is eight times the number of symbols. Each offset is 8 bytes long and can be accessed with the sgetl and sputl commands.
- The name-string table. The size is:
That is, the size equals the total length of the members, minus the length of the offsets, minus the length of the number of symbols.ar_size - (8 * (the number of symbols + 1));
The string table contains the same number of strings as offsets. All strings are null-terminated. Each offset from the array corresponds sequentially to a name in the string table.