+/* `a.out' object-file definitions, including extensions to 64-bit fields */
+
#ifndef __A_OUT_64_H__
#define __A_OUT_64_H__
-
-/* This is the layout on disk of the 64 bit exec header. */
+/* This is the layout on disk of the 32-bit or 64-bit exec header. */
struct external_exec
{
bfd_byte e_drsize[BYTES_IN_WORD]; /* length of data relocation info */
};
-
#define EXEC_BYTES_SIZE (4 + BYTES_IN_WORD * 7)
-/* This is the layout in memory of a "struct exec" while we process it. */
-struct internal_exec
- {
- long a_info; /* Magic number and flags packed */
- bfd_vma a_text; /* length of text, in bytes */
- bfd_vma a_data; /* length of data, in bytes */
- bfd_vma a_bss; /* length of uninitialized data area for file */
- bfd_vma a_syms; /* length of symbol table data in file */
- bfd_vma a_entry; /* start address */
- bfd_vma a_trsize; /* length of relocation info for text, in bytes */
- bfd_vma a_drsize; /* length of relocation info for data, in bytes */
- };
-
-
-/* Magic number is written
-< MSB >
-31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
-< FLAGS > < MACHINE TYPE > < MAGIC >
-*/
-enum machine_type {
- M_UNKNOWN = 0,
- M_68010 = 1,
- M_68020 = 2,
- M_SPARC = 3,
- /* skip a bunch so we dont run into any of suns numbers */
- M_386 = 100,
- M_29K = 101,
- M_NEWONE = 200,
- M_NEWTWO = 201,
-
-};
-
-#define N_DYNAMIC(exec) ((exec).a_info & 0x8000000)
-
-#define N_MAGIC(exec) ((exec).a_info & 0xffff)
-#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
-#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
-#define N_SET_INFO(exec, magic, type, flags) \
-((exec).a_info = ((magic) & 0xffff) \
- | (((int)(type) & 0xff) << 16) \
- | (((flags) & 0xff) << 24))
-
-#define N_SET_MAGIC(exec, magic) \
-((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
-
-#define N_SET_MACHTYPE(exec, machtype) \
-((exec).a_info = \
- ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
-
-#define N_SET_FLAGS(exec, flags) \
-((exec).a_info = \
- ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
-
-/* By default, segment size is constant. But on some machines, it can
- be a function of the a.out header (e.g. machine type). */
-#ifndef N_SEGSIZE
-#define N_SEGSIZE(x) SEGMENT_SIZE
-#endif
-
-#define _N_HDROFF(x) (N_SEGSIZE(x) - EXEC_BYTES_SIZE)
-/* address in an a.out of the text section. When demand paged, it's
- set up a bit to make nothing at 0, when an object file it's 0.
- There's a special hack case when the entry point is < TEXT_START_ADDR
- for executables, then the real start is 0
-*/
-
-#define N_TXTADDR(x) \
- (N_MAGIC(x)==OMAGIC? 0 \
- : (N_MAGIC(x) == ZMAGIC && (x).a_entry < TEXT_START_ADDR)? 0 \
- : TEXT_START_ADDR)
-
-/* offset in an a.out of the start of the text section. When demand
- paged, this is the start of the file
-*/
+/* Magic numbers for a.out files */
-#define N_TXTOFF(x) ( (N_MAGIC((x)) == ZMAGIC) ? 0 : EXEC_BYTES_SIZE)
#if ARCH_SIZE==64
-#define PAGE_SIZE 0x2000
#define OMAGIC 0x1001 /* Code indicating object file */
#define ZMAGIC 0x1002 /* Code indicating demand-paged executable. */
#define NMAGIC 0x1003 /* Code indicating pure executable. */
#else
-#ifndef PAGE_SIZE
-#define PAGE_SIZE 0x2000
-#endif
-#define OMAGIC 0407 /* Code indicating object file or impure executable. */
+#define OMAGIC 0407 /* ...object file or impure executable. */
#define NMAGIC 0410 /* Code indicating pure executable. */
#define ZMAGIC 0413 /* Code indicating demand-paged executable. */
#endif
&& N_MAGIC(x) != NMAGIC \
&& N_MAGIC(x) != ZMAGIC)
+/* By default, segment size is constant. But some machines override this
+ to be a function of the a.out header (e.g. machine type). */
+#ifndef N_SEGSIZE
+#define N_SEGSIZE(x) SEGMENT_SIZE
+#endif
+\f
+/* Virtual memory address of the text section.
+ This is getting very complicated. A good reason to discard a.out format
+ for something that specifies these fields explicitly. But til then...
+
+ * OMAGIC and NMAGIC files:
+ (object files: text for "relocatable addr 0" right after the header)
+ start at 0, offset is EXEC_BYTES_SIZE, size as stated.
+ * The text address, offset, and size of ZMAGIC files depend
+ on the entry point of the file:
+ * entry point below TEXT_START_ADDR:
+ (hack for SunOS shared libraries)
+ start at 0, offset is 0, size as stated.
+ * If N_HEADER_IN_TEXT(x) is true (which defaults to being the
+ case when the entry point is EXEC_BYTES_SIZE or further into a page):
+ no padding is needed; text can start after exec header. Sun
+ considers the text segment of such files to include the exec header;
+ for BFD's purposes, we don't, which makes more work for us.
+ start at TEXT_START_ADDR + EXEC_BYTES_SIZE, offset is EXEC_BYTES_SIZE,
+ size as stated minus EXEC_BYTES_SIZE.
+ * If N_HEADER_IN_TEXT(x) is false (which defaults to being the case when
+ the entry point is less than EXEC_BYTES_SIZE into a page (e.g. page
+ aligned)): (padding is needed so that text can start at a page boundary)
+ start at TEXT_START_ADDR, offset PAGE_SIZE, size as stated.
+
+ Specific configurations may want to hardwire N_HEADER_IN_TEXT,
+ for efficiency or to allow people to play games with the entry point.
+ In that case, you would #define N_HEADER_IN_TEXT(x) as 1 for sunos,
+ and as 0 for most other hosts (Sony News, Vax Ultrix, etc).
+ (Do this in the appropriate bfd target file.)
+ (The default is a heuristic that will break if people try changing
+ the entry point, perhaps with the ld -e flag.)
+ */
+
+#ifndef N_HEADER_IN_TEXT
+#define N_HEADER_IN_TEXT(x) (((x).a_entry & (PAGE_SIZE-1)) >= EXEC_BYTES_SIZE)
+#endif
+#ifndef N_TXTADDR
+#define N_TXTADDR(x) \
+ ( (N_MAGIC(x) != ZMAGIC)? \
+ 0: /* object file or NMAGIC */\
+ ((x).a_entry < TEXT_START_ADDR)? \
+ 0: /* shared lib */\
+ (N_HEADER_IN_TEXT(x) ? \
+ TEXT_START_ADDR + EXEC_BYTES_SIZE: /* no padding */\
+ TEXT_START_ADDR /* a page of padding */\
+ ) \
+ )
+#endif
+
+/* Offset in an a.out of the start of the text section. */
+
+#define N_TXTOFF(x) \
+ ( (N_MAGIC(x) != ZMAGIC)? \
+ EXEC_BYTES_SIZE: /* object file or NMAGIC */\
+ ((x).a_entry < TEXT_START_ADDR)? \
+ 0: /* shared lib */\
+ (N_HEADER_IN_TEXT(x) ? \
+ EXEC_BYTES_SIZE: /* no padding */\
+ PAGE_SIZE /* a page of padding */\
+ ) \
+ )
+
+/* Size of the text section. It's always as stated, except that we
+ offset it to `undo' the adjustment to N_TXTADDR and N_TXTOFF
+ for NMAGIC/ZMAGIC files that nominally include the exec header
+ as part of the first page of text. (BFD doesn't consider the
+ exec header to be part of the text segment.) */
+
+#define N_TXTSIZE(x) \
+ ( (N_MAGIC(x) != ZMAGIC)? \
+ (x).a_text: /* object file or NMAGIC */\
+ ((x).a_entry < TEXT_START_ADDR)? \
+ (x).a_text: /* shared lib */\
+ (N_HEADER_IN_TEXT(x) ? \
+ (x).a_text - EXEC_BYTES_SIZE: /* no padding */\
+ (x).a_text /* a page of padding */\
+ ) \
+ )
+
+/* The address of the data segment in virtual memory.
+ It is the text segment address, plus text segment size, rounded
+ up to a N_SEGSIZE boundary for pure or pageable files. */
#define N_DATADDR(x) \
- (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+(x).a_text) \
- : (N_SEGSIZE(x) + ((N_TXTADDR(x)+(x).a_text-1) & ~(N_SEGSIZE(x)-1))))
+ (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+N_TXTSIZE(x)) \
+ : (N_SEGSIZE(x) + ((N_TXTADDR(x)+N_TXTSIZE(x)-1) & ~(N_SEGSIZE(x)-1))))
+
+/* The address of the BSS segment -- immediately after the data segment. */
-#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
+#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
+/* Offsets of the various portions of the file after the text segment. */
-#define N_DATOFF(x) ( N_TXTOFF(x) + (x).a_text )
+#define N_DATOFF(x) ( N_TXTOFF(x) + N_TXTSIZE(x) )
#define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data )
#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize )
#define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize )
#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms )
-
-
+\f
/* Symbols */
struct external_nlist {
- bfd_byte e_strx[BYTES_IN_WORD]; /* index into string table of symbol name */
- bfd_byte e_type[1]; /* type of symbol */
- bfd_byte e_other[1]; /* misc info (usually empty) */
- bfd_byte e_desc[2]; /* description field */
- bfd_byte e_value[BYTES_IN_WORD];/* value of symbol */
+ bfd_byte e_strx[BYTES_IN_WORD]; /* index into string table of name */
+ bfd_byte e_type[1]; /* type of symbol */
+ bfd_byte e_other[1]; /* misc info (usually empty) */
+ bfd_byte e_desc[2]; /* description field */
+ bfd_byte e_value[BYTES_IN_WORD]; /* value of symbol */
};
-#define EXTERNAL_LIST_SIZE (BYTES_IN_WORD+4+BYTES_IN_WORD)
+#define EXTERNAL_NLIST_SIZE (BYTES_IN_WORD+4+BYTES_IN_WORD)
+
struct internal_nlist {
- char *strx; /* index into string table of symbol name */
- uint8_type n_type; /* type of symbol */
- uint8_type n_other; /* misc info (usually empty) */
- uint16_type n_desc; /* description field */
- bfd_vma n_value; /* value of symbol */
+ unsigned long n_strx; /* index into string table of name */
+ unsigned char n_type; /* type of symbol */
+ unsigned char n_other; /* misc info (usually empty) */
+ unsigned short n_desc; /* description field */
+ bfd_vma n_value; /* value of symbol */
};
-/* The n_type field is packed :
-
- 7 6 5 4 3 2 1 0
- ^- if set the symbol is externaly visible
- 0 local
- 1 N_EXT external
- ^ ^ ^---- select which section the symbol belongs to
- 0 0 0 0 x N_UNDF, undefined
- 0 0 0 1 x N_ABS, no section, base at 0
- 0 0 1 0 x N_TEXT, text section
- 0 0 1 1 x N_DATA, data section
- 0 1 0 0 x N_BSS, bss section
- ^---------- if set the symbol is a set element
- 1 0 1 0 x N_SETA absolute set element symbol
- 1 0 1 1 x N_SETT text set element symbol
- 1 1 0 0 x N_SETD data set element symbol
- 1 1 0 1 x N_SETB bss set element symbol
- 1 1 1 0 x N_SETV pointer to set vector in data area
- 1 1 1 1 0 N_TYPE mask for all of the above
-
- 1 1 1 0 0 0 0 0 N_STAB type is a stab
-*/
-
-#define N_UNDF 0
-#define N_ABS 2
-#define N_TEXT 4
-#define N_DATA 6
-#define N_BSS 8
-#define N_FN 15
-#define N_EXT 1
+/* The n_type field is the symbol type, containing: */
+
+#define N_UNDF 0 /* Undefined symbol */
+#define N_ABS 2 /* Absolute symbol -- defined at particular addr */
+#define N_TEXT 4 /* Text sym -- defined at offset in text seg */
+#define N_DATA 6 /* Data sym -- defined at offset in data seg */
+#define N_BSS 8 /* BSS sym -- defined at offset in zero'd seg */
+#define N_COMM 0x12 /* Common symbol (visible after shared lib dynlink) */
+#define N_FN 0x1f /* File name of .o file */
+#define N_FN_SEQ 0x0C /* N_FN from Sequent compilers (sigh) */
+/* Note: N_EXT can only be usefully OR-ed with N_UNDF, N_ABS, N_TEXT,
+ N_DATA, or N_BSS. When the low-order bit of other types is set,
+ (e.g. N_WARNING versus N_FN), they are two different types. */
+#define N_EXT 1 /* External symbol (as opposed to local-to-this-file) */
#define N_TYPE 0x1e
-#define N_STAB 0xe0
+#define N_STAB 0xe0 /* If any of these bits are on, it's a debug symbol */
#define N_INDR 0x0a
/* This is output from LD. */
#define N_SETV 0x1C /* Pointer to set vector in data area. */
+/* Warning symbol. The text gives a warning message, the next symbol
+ in the table will be undefined. When the symbol is referenced, the
+ message is printed. */
+
+#define N_WARNING 0x1e
/* Relocations
There are two types of relocation flavours for a.out systems,
- standard and extended. The standard form is used on systems where
- the instruction has room for all the bits of an offset to the operand, whilst the
- extended form is used when an address operand has to be split over n
+ standard and extended. The standard form is used on systems where the
+ instruction has room for all the bits of an offset to the operand, whilst
+ the extended form is used when an address operand has to be split over n
instructions. Eg, on the 68k, each move instruction can reference
the target with a displacement of 16 or 32 bits. On the sparc, move
instructions use an offset of 14 bits, so the offset is stored in
#define RELOC_EXT_BITS_TYPE_LITTLE 0xF8
#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3
-#define RELOC_EXT_SIZE (BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD) /* Bytes per relocation entry */
+/* Bytes per relocation entry */
+#define RELOC_EXT_SIZE (BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD)
enum reloc_type
{
-
-
-
-
-
/* simple relocations */
RELOC_8, /* data[0:7] = addend + sv */
RELOC_16, /* data[0:15] = addend + sv */
*/
-#endif /* __A_OUT_GNU_H__ */
+#endif /* __A_OUT_64_H__ */