-/* `a.out' object-file definitions, including extensions to 64-bit fields */
+/* `a.out' object-file definitions, including extensions to 64-bit fields
+
+ Copyright 2001 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef __A_OUT_64_H__
#define __A_OUT_64_H__
#define OMAGIC 0407 /* ...object file or impure executable. */
#define NMAGIC 0410 /* Code indicating pure executable. */
#define ZMAGIC 0413 /* Code indicating demand-paged executable. */
+#define BMAGIC 0415 /* Used by a b.out object. */
/* This indicates a demand-paged executable with the header in the text.
- As far as I know it is only used by 386BSD and/or BSDI. */
+ It is used by 386BSD (and variants) and Linux, at least. */
+#ifndef QMAGIC
#define QMAGIC 0314
-#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
+#endif
+# ifndef N_BADMAG
+# define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
&& N_MAGIC(x) != NMAGIC \
&& N_MAGIC(x) != ZMAGIC \
&& N_MAGIC(x) != QMAGIC)
+# endif /* N_BADMAG */
#endif
#endif
-/* The difference between PAGE_SIZE and N_SEGSIZE is that PAGE_SIZE is
- the the finest granularity at which you can page something, thus it
+#ifdef QMAGIC
+#define N_IS_QMAGIC(x) (N_MAGIC (x) == QMAGIC)
+#else
+#define N_IS_QMAGIC(x) (0)
+#endif
+
+/* The difference between TARGET_PAGE_SIZE and N_SEGSIZE is that TARGET_PAGE_SIZE is
+ the finest granularity at which you can page something, thus it
controls the padding (if any) before the text segment of a ZMAGIC
file. N_SEGSIZE is the resolution at which things can be marked as
read-only versus read/write, so it controls the padding between the
- text segment and the data segment. These are the same for most
- machines, but different for sun3. */
+ text segment and the data segment (in memory; on disk the padding
+ between them is TARGET_PAGE_SIZE). TARGET_PAGE_SIZE and N_SEGSIZE are the same
+ for most machines, but different for sun3. */
/* By default, segment size is constant. But some machines override this
to be a function of the a.out header (e.g. machine type). */
* 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.
+ start at TEXT_START_ADDR, offset TARGET_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.
the entry point, perhaps with the ld -e flag.)
* QMAGIC is always like a ZMAGIC for which N_HEADER_IN_TEXT is true,
- and for which the starting address is PAGE_SIZE (or should this be
+ and for which the starting address is TARGET_PAGE_SIZE (or should this be
SEGMENT_SIZE?) (TEXT_START_ADDR only applies to ZMAGIC, not to QMAGIC).
*/
/* This macro is only relevant for ZMAGIC files; QMAGIC always has the header
in the text. */
#ifndef N_HEADER_IN_TEXT
-#define N_HEADER_IN_TEXT(x) (((x).a_entry & (PAGE_SIZE-1)) >= EXEC_BYTES_SIZE)
+#define N_HEADER_IN_TEXT(x) \
+ (((x).a_entry & (TARGET_PAGE_SIZE-1)) >= EXEC_BYTES_SIZE)
#endif
/* Sun shared libraries, not linux. This macro is only relevant for ZMAGIC
files. */
#ifndef N_SHARED_LIB
+#if defined (TEXT_START_ADDR) && TEXT_START_ADDR == 0
+#define N_SHARED_LIB(x) (0)
+#else
#define N_SHARED_LIB(x) ((x).a_entry < TEXT_START_ADDR)
#endif
+#endif
+
+/* Returning 0 not TEXT_START_ADDR for OMAGIC and NMAGIC is based on
+ the assumption that we are dealing with a .o file, not an
+ executable. This is necessary for OMAGIC (but means we don't work
+ right on the output from ld -N); more questionable for NMAGIC. */
#ifndef N_TXTADDR
#define N_TXTADDR(x) \
- (/* The address of a QMAGIC file is always one page in */ \
- /* with the header in the text. */ \
- N_MAGIC(x) == QMAGIC ? PAGE_SIZE + EXEC_BYTES_SIZE : \
- N_MAGIC(x) != ZMAGIC ? 0 : /* object file or NMAGIC */\
- N_SHARED_LIB(x) ? 0 : \
- N_HEADER_IN_TEXT(x) ? \
- TEXT_START_ADDR + EXEC_BYTES_SIZE : /* no padding */\
- TEXT_START_ADDR /* a page of padding */\
- )
+ (/* The address of a QMAGIC file is always one page in, */ \
+ /* with the header in the text. */ \
+ N_IS_QMAGIC (x) \
+ ? (bfd_vma) TARGET_PAGE_SIZE + EXEC_BYTES_SIZE \
+ : (N_MAGIC (x) != ZMAGIC \
+ ? (bfd_vma) 0 /* object file or NMAGIC */ \
+ : (N_SHARED_LIB (x) \
+ ? (bfd_vma) 0 \
+ : (N_HEADER_IN_TEXT (x) \
+ ? (bfd_vma) TEXT_START_ADDR + EXEC_BYTES_SIZE \
+ : (bfd_vma) TEXT_START_ADDR))))
+#endif
+
+/* If N_HEADER_IN_TEXT is not true for ZMAGIC, there is some padding
+ to make the text segment start at a certain boundary. For most
+ systems, this boundary is TARGET_PAGE_SIZE. But for Linux, in the
+ time-honored tradition of crazy ZMAGIC hacks, it is 1024 which is
+ not what TARGET_PAGE_SIZE needs to be for QMAGIC. */
+
+#ifndef ZMAGIC_DISK_BLOCK_SIZE
+#define ZMAGIC_DISK_BLOCK_SIZE TARGET_PAGE_SIZE
#endif
+#define N_DISK_BLOCK_SIZE(x) \
+ (N_MAGIC(x) == ZMAGIC ? ZMAGIC_DISK_BLOCK_SIZE : TARGET_PAGE_SIZE)
+
/* Offset in an a.out of the start of the text section. */
#ifndef N_TXTOFF
-#define N_TXTOFF(x) \
- (/* For {O,N,Q}MAGIC, no padding. */ \
- N_MAGIC(x) != ZMAGIC ? EXEC_BYTES_SIZE : \
- N_SHARED_LIB(x) ? 0 : \
- N_HEADER_IN_TEXT(x) ? \
- EXEC_BYTES_SIZE : /* no padding */\
- PAGE_SIZE /* a page of padding */\
- )
+#define N_TXTOFF(x) \
+ (/* For {O,N,Q}MAGIC, no padding. */ \
+ N_MAGIC (x) != ZMAGIC \
+ ? EXEC_BYTES_SIZE \
+ : (N_SHARED_LIB (x) \
+ ? 0 \
+ : (N_HEADER_IN_TEXT (x) \
+ ? EXEC_BYTES_SIZE /* no padding */ \
+ : ZMAGIC_DISK_BLOCK_SIZE /* a page of padding */)))
#endif
/* 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
exec header to be part of the text segment.) */
#ifndef N_TXTSIZE
#define N_TXTSIZE(x) \
- (/* For QMAGIC, we don't consider the header part of the text section. */\
- N_MAGIC(x) == QMAGIC ? (x).a_text - EXEC_BYTES_SIZE : \
- (N_MAGIC(x) != ZMAGIC || N_SHARED_LIB(x)) ? (x).a_text : \
- N_HEADER_IN_TEXT(x) ? \
- (x).a_text - EXEC_BYTES_SIZE: /* no padding */\
- (x).a_text /* a page of padding */\
- )
+ (/* For QMAGIC, we don't consider the header part of the text section. */\
+ N_IS_QMAGIC (x) \
+ ? (x).a_text - EXEC_BYTES_SIZE \
+ : ((N_MAGIC (x) != ZMAGIC || N_SHARED_LIB (x)) \
+ ? (x).a_text \
+ : (N_HEADER_IN_TEXT (x) \
+ ? (x).a_text - EXEC_BYTES_SIZE /* no padding */ \
+ : (x).a_text /* a page of padding */ )))
#endif
/* 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. */
#ifndef N_DATADDR
#define N_DATADDR(x) \
- (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+N_TXTSIZE(x)) \
- : (N_SEGSIZE(x) + ((N_TXTADDR(x)+N_TXTSIZE(x)-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) \
+ & ~ (bfd_vma) (N_SEGSIZE (x) - 1))))
#endif
/* 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. */
-/* For {N,Q,Z}MAGIC, there is padding to make the data segment start
- on a page boundary. Most of the time the a_text field (and thus
- N_TXTSIZE) already contains this padding. But if it doesn't (I
- think maybe this happens on BSDI and/or 386BSD), then add it. */
+/* For {Q,Z}MAGIC, there is padding to make the data segment start on
+ a page boundary. Most of the time the a_text field (and thus
+ N_TXTSIZE) already contains this padding. It is possible that for
+ BSDI and/or 386BSD it sometimes doesn't contain the padding, and
+ perhaps we should be adding it here. But this seems kind of
+ questionable and probably should be BSDI/386BSD-specific if we do
+ do it.
+
+ For NMAGIC (at least for hp300 BSD, probably others), there is
+ padding in memory only, not on disk, so we must *not* ever pad here
+ for NMAGIC. */
#ifndef N_DATOFF
-#define N_DATOFF(x) \
- (N_MAGIC(x) == OMAGIC ? N_TXTOFF(x) + N_TXTSIZE(x) : \
- N_SEGSIZE(x) + ((N_TXTOFF(x) + N_TXTSIZE(x) - 1) & ~(N_SEGSIZE(x) - 1)))
+#define N_DATOFF(x) ( N_TXTOFF (x) + N_TXTSIZE (x) )
#endif
-
#ifndef N_TRELOFF
-#define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data )
+#define N_TRELOFF(x) ( N_DATOFF (x) + (x).a_data )
#endif
#ifndef N_DRELOFF
-#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize )
+#define N_DRELOFF(x) ( N_TRELOFF (x) + (x).a_trsize )
#endif
#ifndef N_SYMOFF
-#define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize )
+#define N_SYMOFF(x) ( N_DRELOFF (x) + (x).a_drsize )
#endif
#ifndef N_STROFF
-#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms )
+#define N_STROFF(x) ( N_SYMOFF (x) + (x).a_syms )
#endif
\f
/* Symbols */
#define N_WARNING 0x1e
+/* Weak symbols. These are a GNU extension to the a.out format. The
+ semantics are those of ELF weak symbols. Weak symbols are always
+ externally visible. The N_WEAK? values are squeezed into the
+ available slots. The value of a N_WEAKU symbol is 0. The values
+ of the other types are the definitions. */
+#define N_WEAKU 0x0d /* Weak undefined symbol. */
+#define N_WEAKA 0x0e /* Weak absolute symbol. */
+#define N_WEAKT 0x0f /* Weak text symbol. */
+#define N_WEAKD 0x10 /* Weak data symbol. */
+#define N_WEAKB 0x11 /* Weak bss symbol. */
+
/* Relocations
There are two types of relocation flavours for a.out systems,
bfd_byte r_type[1]; /* relocation type */
};
-#define RELOC_STD_BITS_PCREL_BIG 0x80
-#define RELOC_STD_BITS_PCREL_LITTLE 0x01
+#define RELOC_STD_BITS_PCREL_BIG ((unsigned int) 0x80)
+#define RELOC_STD_BITS_PCREL_LITTLE ((unsigned int) 0x01)
-#define RELOC_STD_BITS_LENGTH_BIG 0x60
-#define RELOC_STD_BITS_LENGTH_SH_BIG 5 /* To shift to units place */
-#define RELOC_STD_BITS_LENGTH_LITTLE 0x06
+#define RELOC_STD_BITS_LENGTH_BIG ((unsigned int) 0x60)
+#define RELOC_STD_BITS_LENGTH_SH_BIG 5
+#define RELOC_STD_BITS_LENGTH_LITTLE ((unsigned int) 0x06)
#define RELOC_STD_BITS_LENGTH_SH_LITTLE 1
-#define RELOC_STD_BITS_EXTERN_BIG 0x10
-#define RELOC_STD_BITS_EXTERN_LITTLE 0x08
+#define RELOC_STD_BITS_EXTERN_BIG ((unsigned int) 0x10)
+#define RELOC_STD_BITS_EXTERN_LITTLE ((unsigned int) 0x08)
-#define RELOC_STD_BITS_BASEREL_BIG 0x08
-#define RELOC_STD_BITS_BASEREL_LITTLE 0x08
+#define RELOC_STD_BITS_BASEREL_BIG ((unsigned int) 0x08)
+#define RELOC_STD_BITS_BASEREL_LITTLE ((unsigned int) 0x10)
-#define RELOC_STD_BITS_JMPTABLE_BIG 0x04
-#define RELOC_STD_BITS_JMPTABLE_LITTLE 0x04
+#define RELOC_STD_BITS_JMPTABLE_BIG ((unsigned int) 0x04)
+#define RELOC_STD_BITS_JMPTABLE_LITTLE ((unsigned int) 0x20)
-#define RELOC_STD_BITS_RELATIVE_BIG 0x02
-#define RELOC_STD_BITS_RELATIVE_LITTLE 0x02
+#define RELOC_STD_BITS_RELATIVE_BIG ((unsigned int) 0x02)
+#define RELOC_STD_BITS_RELATIVE_LITTLE ((unsigned int) 0x40)
#define RELOC_STD_SIZE (BYTES_IN_WORD + 3 + 1) /* Bytes per relocation entry */
bfd_byte r_addend[BYTES_IN_WORD]; /* datum addend */
};
-#define RELOC_EXT_BITS_EXTERN_BIG 0x80
-#define RELOC_EXT_BITS_EXTERN_LITTLE 0x01
+#ifndef RELOC_EXT_BITS_EXTERN_BIG
+#define RELOC_EXT_BITS_EXTERN_BIG ((unsigned int) 0x80)
+#endif
+
+#ifndef RELOC_EXT_BITS_EXTERN_LITTLE
+#define RELOC_EXT_BITS_EXTERN_LITTLE ((unsigned int) 0x01)
+#endif
+
+#ifndef RELOC_EXT_BITS_TYPE_BIG
+#define RELOC_EXT_BITS_TYPE_BIG ((unsigned int) 0x1F)
+#endif
-#define RELOC_EXT_BITS_TYPE_BIG 0x1F
+#ifndef RELOC_EXT_BITS_TYPE_SH_BIG
#define RELOC_EXT_BITS_TYPE_SH_BIG 0
-#define RELOC_EXT_BITS_TYPE_LITTLE 0xF8
+#endif
+
+#ifndef RELOC_EXT_BITS_TYPE_LITTLE
+#define RELOC_EXT_BITS_TYPE_LITTLE ((unsigned int) 0xF8)
+#endif
+
+#ifndef RELOC_EXT_BITS_TYPE_SH_LITTLE
#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3
+#endif
/* Bytes per relocation entry */
#define RELOC_EXT_SIZE (BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD)
RELOC_CONST,
RELOC_CONSTH,
- /* All the new ones I can think of *//*v9*/
+ /* All the new ones I can think of, for sparc v9 */
- RELOC_64, /* data[0:63] = addend + sv *//*v9*/
- RELOC_DISP64, /* data[0:63] = addend - pc + sv *//*v9*/
- RELOC_WDISP21, /* data[0:20] = (addend + sv - pc)>>2 *//*v9*/
- RELOC_DISP21, /* data[0:20] = addend - pc + sv *//*v9*/
- RELOC_DISP14, /* data[0:13] = addend - pc + sv *//*v9*/
+ RELOC_64, /* data[0:63] = addend + sv */
+ RELOC_DISP64, /* data[0:63] = addend - pc + sv */
+ RELOC_WDISP21, /* data[0:20] = (addend + sv - pc)>>2 */
+ RELOC_DISP21, /* data[0:20] = addend - pc + sv */
+ RELOC_DISP14, /* data[0:13] = addend - pc + sv */
/* Q .
What are the other ones,
Since this is a clean slate, can we throw away the ones we dont