Blame include/aout/sun4.h

Packit bbfece
/* SPARC-specific values for a.out files 
Packit bbfece
Packit bbfece
   Copyright (C) 2001-2018 Free Software Foundation, Inc.
Packit bbfece
Packit bbfece
   This program is free software; you can redistribute it and/or modify
Packit bbfece
   it under the terms of the GNU General Public License as published by
Packit bbfece
   the Free Software Foundation; either version 3 of the License, or
Packit bbfece
   (at your option) any later version.
Packit bbfece
   
Packit bbfece
   This program is distributed in the hope that it will be useful,
Packit bbfece
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit bbfece
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit bbfece
   GNU General Public License for more details.
Packit bbfece
   
Packit bbfece
   You should have received a copy of the GNU General Public License
Packit bbfece
   along with this program; if not, write to the Free Software
Packit bbfece
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
Packit bbfece
   MA 02110-1301, USA.  */
Packit bbfece
Packit bbfece
/* Some systems, e.g., AIX, may have defined this in header files already
Packit bbfece
   included.  */
Packit bbfece
#undef  TARGET_PAGE_SIZE
Packit bbfece
#define TARGET_PAGE_SIZE	0x2000		/* 8K.  aka NBPG in <sys/param.h> */
Packit bbfece
/* Note that some SPARCs have 4K pages, some 8K, some others.  */
Packit bbfece
Packit bbfece
#define SEG_SIZE_SPARC	TARGET_PAGE_SIZE
Packit bbfece
#define	SEG_SIZE_SUN3	0x20000		/* Resolution of r/w protection hw */
Packit bbfece
Packit bbfece
#define TEXT_START_ADDR	TARGET_PAGE_SIZE	/* Location 0 is not accessible */
Packit bbfece
#define N_HEADER_IN_TEXT(x) 1
Packit bbfece
Packit bbfece
/* Non-default definitions of the accessor macros... */
Packit bbfece
Packit bbfece
/* Segment size varies on Sun-3 versus Sun-4.  */
Packit bbfece
Packit bbfece
#define N_SEGSIZE(x)	(N_MACHTYPE(x) == M_SPARC?	SEG_SIZE_SPARC:	\
Packit bbfece
			 N_MACHTYPE(x) == M_68020?	SEG_SIZE_SUN3:	\
Packit bbfece
			/* Guess? */			TARGET_PAGE_SIZE)
Packit bbfece
Packit bbfece
/* Virtual Address of text segment from the a.out file.  For OMAGIC,
Packit bbfece
   (almost always "unlinked .o's" these days), should be zero.
Packit bbfece
   Sun added a kludge so that shared libraries linked ZMAGIC get
Packit bbfece
   an address of zero if a_entry (!!!) is lower than the otherwise
Packit bbfece
   expected text address.  These kludges have gotta go!
Packit bbfece
   For linked files, should reflect reality if we know it.  */
Packit bbfece
Packit bbfece
#define N_SHARED_LIB(x) ((x)->a_entry < TEXT_START_ADDR \
Packit bbfece
			 && (x)->a_text >= EXEC_BYTES_SIZE)
Packit bbfece
Packit bbfece
/* This differs from the version in aout64.h (which we override by defining
Packit bbfece
   it here) only for NMAGIC (we return TEXT_START_ADDR+EXEC_BYTES_SIZE;
Packit bbfece
   they return 0).  */
Packit bbfece
Packit bbfece
#define N_TXTADDR(x) \
Packit bbfece
    (N_MAGIC(x)==OMAGIC? 0 \
Packit bbfece
     : (N_MAGIC(x) == ZMAGIC && (x)->a_entry < TEXT_START_ADDR)? 0 \
Packit bbfece
     : TEXT_START_ADDR+EXEC_BYTES_SIZE)
Packit bbfece
Packit bbfece
/* When a file is linked against a shared library on SunOS 4, the
Packit bbfece
   dynamic bit in the exec header is set, and the first symbol in the
Packit bbfece
   symbol table is __DYNAMIC.  Its value is the address of the
Packit bbfece
   following structure.  */
Packit bbfece
Packit bbfece
struct external_sun4_dynamic
Packit bbfece
{
Packit bbfece
  /* The version number of the structure.  SunOS 4.1.x creates files
Packit bbfece
     with version number 3, which is what this structure is based on.
Packit bbfece
     According to gdb, version 2 is similar.  I believe that version 2
Packit bbfece
     used a different type of procedure linkage table, and there may
Packit bbfece
     have been other differences.  */
Packit bbfece
  bfd_byte ld_version[4];
Packit bbfece
  /* The virtual address of a 28 byte structure used in debugging.
Packit bbfece
     The contents are filled in at run time by ld.so.  */
Packit bbfece
  bfd_byte ldd[4];
Packit bbfece
  /* The virtual address of another structure with information about
Packit bbfece
     how to relocate the executable at run time.  */
Packit bbfece
  bfd_byte ld[4];
Packit bbfece
};
Packit bbfece
Packit bbfece
/* The size of the debugging structure pointed to by the debugger
Packit bbfece
   field of __DYNAMIC.  */
Packit bbfece
#define EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE (24)
Packit bbfece
Packit bbfece
/* The structure pointed to by the linker field of __DYNAMIC.  As far
Packit bbfece
   as I can tell, most of the addresses in this structure are offsets
Packit bbfece
   within the file, but some are actually virtual addresses.  */
Packit bbfece
Packit bbfece
struct internal_sun4_dynamic_link
Packit bbfece
{
Packit bbfece
  /* Linked list of loaded objects.  This is filled in at runtime by
Packit bbfece
     ld.so and probably by dlopen.  */
Packit bbfece
  unsigned long ld_loaded;
Packit bbfece
Packit bbfece
  /* The address of the list of names of shared objects which must be
Packit bbfece
     included at runtime.  Each entry in the list is 16 bytes: the 4
Packit bbfece
     byte address of the string naming the object (e.g., for -lc this
Packit bbfece
     is "c"); 4 bytes of flags--the high bit is whether to search for
Packit bbfece
     the object using the library path; the 2 byte major version
Packit bbfece
     number; the 2 byte minor version number; the 4 byte address of
Packit bbfece
     the next entry in the list (zero if this is the last entry).  The
Packit bbfece
     version numbers seem to only be non-zero when doing library
Packit bbfece
     searching.  */
Packit bbfece
  unsigned long ld_need;
Packit bbfece
Packit bbfece
  /* The address of the path to search for the shared objects which
Packit bbfece
     must be included.  This points to a string in PATH format which
Packit bbfece
     is generated from the -L arguments to the linker.  According to
Packit bbfece
     the man page, ld.so implicitly adds ${LD_LIBRARY_PATH} to the
Packit bbfece
     beginning of this string and /lib:/usr/lib:/usr/local/lib to the
Packit bbfece
     end.  The string is terminated by a null byte.  This field is
Packit bbfece
     zero if there is no additional path.  */
Packit bbfece
  unsigned long ld_rules;
Packit bbfece
Packit bbfece
  /* The address of the global offset table.  This appears to be a
Packit bbfece
     virtual address, not a file offset.  The first entry in the
Packit bbfece
     global offset table seems to be the virtual address of the
Packit bbfece
     sun4_dynamic structure (the same value as the __DYNAMIC symbol).
Packit bbfece
     The global offset table is used for PIC code to hold the
Packit bbfece
     addresses of variables.  A dynamically linked file which does not
Packit bbfece
     itself contain PIC code has a four byte global offset table.  */
Packit bbfece
  unsigned long ld_got;
Packit bbfece
Packit bbfece
  /* The address of the procedure linkage table.  This appears to be a
Packit bbfece
     virtual address, not a file offset.
Packit bbfece
Packit bbfece
     On a SPARC, the table is composed of 12 byte entries, each of
Packit bbfece
     which consists of three instructions.  The first entry is
Packit bbfece
         sethi %hi(0),%g1
Packit bbfece
	 jmp %g1
Packit bbfece
	 nop
Packit bbfece
     These instructions are changed by ld.so into a jump directly into
Packit bbfece
     ld.so itself.  Each subsequent entry is
Packit bbfece
         save %sp, -96, %sp
Packit bbfece
	 call <address of first entry in procedure linkage table>
Packit bbfece
	 <reloc_number | 0x01000000>
Packit bbfece
     The reloc_number is the number of the reloc to use to resolve
Packit bbfece
     this entry.  The reloc will be a JMP_SLOT reloc against some
Packit bbfece
     symbol that is not defined in this object file but should be
Packit bbfece
     defined in a shared object (if it is not, ld.so will report a
Packit bbfece
     runtime error and exit).  The constant 0x010000000 turns the
Packit bbfece
     reloc number into a sethi of %g0, which does nothing since %g0 is
Packit bbfece
     hardwired to zero.
Packit bbfece
Packit bbfece
     When one of these entries is executed, it winds up calling into
Packit bbfece
     ld.so.  ld.so looks at the reloc number, available via the return
Packit bbfece
     address, to determine which entry this is.  It then looks at the
Packit bbfece
     reloc and patches up the entry in the table into a sethi and jmp
Packit bbfece
     to the real address followed by a nop.  This means that the reloc
Packit bbfece
     lookup only has to happen once, and it also means that the
Packit bbfece
     relocation only needs to be done if the function is actually
Packit bbfece
     called.  The relocation is expensive because ld.so must look up
Packit bbfece
     the symbol by name.
Packit bbfece
Packit bbfece
     The size of the procedure linkage table is given by the ld_plt_sz
Packit bbfece
     field.  */
Packit bbfece
  unsigned long ld_plt;
Packit bbfece
Packit bbfece
  /* The address of the relocs.  These are in the same format as
Packit bbfece
     ordinary relocs.  Symbol index numbers refer to the symbols
Packit bbfece
     pointed to by ld_stab.  I think the only way to determine the
Packit bbfece
     number of relocs is to assume that all the bytes from ld_rel to
Packit bbfece
     ld_hash contain reloc entries.  */
Packit bbfece
  unsigned long ld_rel;
Packit bbfece
Packit bbfece
  /* The address of a hash table of symbols.  The hash table has
Packit bbfece
     roughly the same number of entries as there are dynamic symbols;
Packit bbfece
     I think the only way to get the exact size is to assume that
Packit bbfece
     every byte from ld_hash to ld_stab is devoted to the hash table.
Packit bbfece
Packit bbfece
     Each entry in the hash table is eight bytes.  The first four
Packit bbfece
     bytes are a symbol index into the dynamic symbols.  The second
Packit bbfece
     four bytes are the index of the next hash table entry in the
Packit bbfece
     bucket.  The ld_buckets field gives the number of buckets, say B.
Packit bbfece
     The first B entries in the hash table each start a bucket which
Packit bbfece
     is chained through the second four bytes of each entry.  A value
Packit bbfece
     of zero ends the chain.
Packit bbfece
Packit bbfece
     The hash function is simply
Packit bbfece
         h = 0;
Packit bbfece
         while (*string != '\0')
Packit bbfece
	   h = (h << 1) + *string++;
Packit bbfece
	 h &= 0x7fffffff;
Packit bbfece
Packit bbfece
     To look up a symbol, compute the hash value of the name.  Take
Packit bbfece
     the modulos of hash value and the number of buckets.  Start at
Packit bbfece
     that entry in the hash table.  See if the symbol (from the first
Packit bbfece
     four bytes of the hash table entry) has the name you are looking
Packit bbfece
     for.  If not, use the chain field (the second four bytes of the
Packit bbfece
     hash table entry) to move on to the next entry in this bucket.
Packit bbfece
     If the chain field is zero you have reached the end of the
Packit bbfece
     bucket, and the symbol is not in the hash table.  */ 
Packit bbfece
  unsigned long ld_hash;
Packit bbfece
Packit bbfece
  /* The address of the symbol table.  This is a list of
Packit bbfece
     external_nlist structures.  The string indices are relative to
Packit bbfece
     the ld_symbols field.  I think the only way to determine the
Packit bbfece
     number of symbols is to assume that all the bytes between ld_stab
Packit bbfece
     and ld_symbols are external_nlist structures.  */
Packit bbfece
  unsigned long ld_stab;
Packit bbfece
Packit bbfece
  /* I don't know what this is for.  It seems to always be zero.  */
Packit bbfece
  unsigned long ld_stab_hash;
Packit bbfece
Packit bbfece
  /* The number of buckets in the hash table.  */
Packit bbfece
  unsigned long ld_buckets;
Packit bbfece
Packit bbfece
  /* The address of the symbol string table.  The first string in this
Packit bbfece
     string table need not be the empty string.  */
Packit bbfece
  unsigned long ld_symbols;
Packit bbfece
Packit bbfece
  /* The size in bytes of the symbol string table.  */
Packit bbfece
  unsigned long ld_symb_size;
Packit bbfece
Packit bbfece
  /* The size in bytes of the text segment.  */
Packit bbfece
  unsigned long ld_text;
Packit bbfece
Packit bbfece
  /* The size in bytes of the procedure linkage table.  */
Packit bbfece
  unsigned long ld_plt_sz;
Packit bbfece
};
Packit bbfece
Packit bbfece
/* The external form of the structure.  */
Packit bbfece
Packit bbfece
struct external_sun4_dynamic_link
Packit bbfece
{
Packit bbfece
  bfd_byte ld_loaded[4];
Packit bbfece
  bfd_byte ld_need[4];
Packit bbfece
  bfd_byte ld_rules[4];
Packit bbfece
  bfd_byte ld_got[4];
Packit bbfece
  bfd_byte ld_plt[4];
Packit bbfece
  bfd_byte ld_rel[4];
Packit bbfece
  bfd_byte ld_hash[4];
Packit bbfece
  bfd_byte ld_stab[4];
Packit bbfece
  bfd_byte ld_stab_hash[4];
Packit bbfece
  bfd_byte ld_buckets[4];
Packit bbfece
  bfd_byte ld_symbols[4];
Packit bbfece
  bfd_byte ld_symb_size[4];
Packit bbfece
  bfd_byte ld_text[4];
Packit bbfece
  bfd_byte ld_plt_sz[4];
Packit bbfece
};