


    /* EPC Imp to C Translation Release 4 Version Apr 95 */


#include "imptoc.h"
#include <elf.h>

#ifndef ELF32_ST_BIND
#define ELF32_ST_BIND(info)             ((info) >> 4)
#endif
#ifndef ELF32_ST_TYPE
#define ELF32_ST_TYPE(info)             ((info) & 0xf)
#endif
#ifndef ELF32_ST_INFO
#define ELF32_ST_INFO(bind, type)       (((bind)<<4)+((type)&0xf))
#endif

/* #include <sys/elf_386.h> */
/* This contains formats and constants for generating ELF on Intel, Sparc, 88K */
/* and MIPS to the System V ABI interface. It also contains notes and thoughts.*/
/*      Select the correct values for target, targetdata and targetrel         */
/*            when moving between architectures                                */
/*                                                               elf6.mips.inc */
/* 10/02/95 - define the constant commonnamesuffix which defines               */
/*            the suffix to be applied to all Fortran non-Blank                */
/*            Common names on all platforms apart from 88K                     */
/*                                                               elf5.mips.inc */
/*                                                               elf4.mips.inc */
/* 23/07/93 - correct sdblnbreg for MIPS - should be $sp. (rt)                 */
/*                                                               elf3.mips.inc*/
/* 08/04/93 - common version created for Intel, Sparc, 88K and MIPS	          */
/*                                                               elf2.m88k.inc*/
/* 09/03/93 - common version created for Sparc, 88K and MIPS	                 */
/*                                                                           */
 
#define elfsparc 2
#define elf386 3
#define elf68k 4
#define elf88k 5
#define elfmips 8	/*values for _machine    */
 
#define target elf386			/* current target machine    */
 
#define elfdatalsb 1
#define elfdatamsb 2	/* vax bytes or IBM bytes */
 

#if((target==elfsparc)||(target==elf88k)||(target==elfmips)) 
#define targetdata elfdatamsb		/* IBM bytes for Sparc, 88K, MIPS    */
#define elfmagic (0x7F454C46)
#define ftentryname ("MAIN_")

#else
#define targetdata elfdatalsb		/* vax bytes for Intel     */
#define elfmagic (0x464C457F)
#define ftentryname ("MAIN__")

#endif;
 
#define userela 1
#define userel 2
 

#if((target==elfsparc)||(target==elf88k)) 
#define targetrels userela	/*for Sparc, 88K*/

#else
#define targetrels userel	/*for Mips, Intel*/

#endif;
 
/*ELF                                                                        */
/* ELF is an extension to COFF to permit a crude form of shared libraries    */
/* for generating unshared material only the changes are confined to the     */
/* detailed generation sequences of PUT                                      */
/*                                                                           */
/* An ELF file consists of                                                   */
/*       1) a file header                                                    */
/*       2) a program header (shareable files only)                          */
/*       3) N sections       ( at least text,data,bss,symtabs and strings)   */
/*       4) a section table  (last)                                          */
 
/*The header has a pointer to program header and section table.              */
/* All other sections are found via the section table.                       */
/*                                                                           */
/*                                                                           */
/* The COFF expert will note the following  differences with unsharable ELF  */
/* a) The symbol table has no text. All names areoffsets into .strtab.       */
/* b) The presence of .strtab which is PUT's array Dict (more or less)       */
/* c) Relocations are in sections one section of relocations for each        */
/*    section of text or data which has relocations. This enables global     */
/*    information to be put into the header and not duplicated               */
/*                                                                           */
/*There are many tedious detailed differnces                                 */
/*                                                                           */
/*                                                                           */
/* Dynamic Loading and Program Sharing ith ELF                               */
/*                                                                           */
/* An unshared program is linked to load at a fixed address (0 or x10000)    */
/* and fixups fixed thus. A shared program is fixed the same way but         */
/* will normally loaded somewhere else as a contiguous chunk. All fixups     */
/* will be out by the same factor (ie load address - fix address) which the  */
/* program can determine by BAL or CALL to the next instruction.             */
/* Since the factor is constant all relative fixes and all PC+N references   */
/* will still work. Data (and switches) are the problem.                     */
/* Elfs solution is to add to new sections to the file.                      */
/* A procedure linkage table or PLT(dont confuse with ICL/EPCs PLT!)         */
/* This is a jump table provided by the linker for calls. All external calls */
/* are fixed to jump PC relative to a PLT entry which goes to the procedure  */
/* or into the dynamic loader. When more files are loaded the PLT is updated */
/* but the piggy back jump always takes place (EMAS was better)              */
/*                                                                           */
/* a Global OFFset table or GOT contains the adresses of data items. It is   */
/* produced by the compiler and is very like the EPC PLT. All absolute fixes must*/
/* be in here for a sharable module. The loader will maintain it and all     */
/* external data references should go thro here.                             */
/*                                                                           */
/*The official strategy for producing dynamic loading code is                */
/* 1) Put all addresses in the GOT                                           */
/* 2) Locate the GOT on each proc entry and keep in a register               */
/* 3) Only relative fixups in all other areas.                               */
/*                                                                           */
/* However a less disruptive solution is available for epc                   */
/* 1) Make all fixups relative to head of GLA (presumed in a register)       */
/* 2) Locate GLA via GOT or Otherwise                                        */
/* 3) Reserve GOT for External data and Common area addresses which must     */
/*    be updated when new modules load.                                      */
 
/* PDS thinks that dynamic modules cant access external data that has not    */
/* been preloaded. Such modules must be marked unshareable                   */
 
/*                ELF Header and associated constants                        */
/*                ***********************************                        */
 

#define prghdrentries 0
 
 

 
#define elfversion 1
#define elftyperel 1
#define elftypeexec 2
#define elftypedyn 3		/* values for _type     */
#define elfclass 1		/* class of 32 bit objects */
				/* 2 for 64 bit objects    */

/*              Section Header Format and Consts                             */
/*              ********************************                             */
/*                                                                           */
/*                                                                           */
/* const for section_type                                                    */
/*                                                                           */
#define SHT_GPTAB (0x70000003)	/* Section is a global pointer table         */ 
#define SHT_REGINFO (0x70000006)	/* Section defines register use      */
/*                                                                           */
/* Bit values for section_flags                                              */
/*                                                                           */
/*                                                                           */
/*                                                                           */
/*                              Elf symbol table format                      */
/*                              ***********************                      */
/*                                                                           */

/*                   Elf relocation definitions                              */
/*                   **************************                              */
/*                                                                           */

#if(targetrels==userel) 
 
typedef Elf32_Rel relaf;

#define relprefix (".rel")	/* .rela when addend present                      */
#define reltype SHT_REL	/* SHTrela if addend available                        */
 

#endif;
 

#if(targetrels==userela) 
 
typedef Elf32_Rela relaf;

#define relprefix (".rela")	/* .rel when addend absent   */
#define reltype SHT_RELA	/* SHTrel if addend not available   */

#endif;
 
/* The section to which each block of relocations apply is in the section_info*/
/* field of the relocation section header.                                   */
/*     Offet(P) is the position relative to start of section of the relocation*/
/*     Info is secti<<8!reltype                                              */
/*           where secti is of the xeternal symbol or section from which the */
/*          relevant value is found (S)                                      */
/*     Reltype areas defined below                                           */
/*     Addend (A) is a signed constant                                       */
/*                                                                           */
/* If the "rel" area only is supported addend is left out of the format      */
/* This is detected when processing relocations and if the Addend is not zero*/
/* it is written into the relocation space. this only works when there are   */
/* no Hi-lo or other fancy relocations                                       */
/*                                                                           */
/* The following constants define reltype for sparc                          */
/* all relocations are checked for overflow unless truncation specified      */
 

#if(target==elfsparc) 
 
 
#define fullwordfix R_SPARC_32		/* Normal full word fixup*/
#define debugtabfix R_SPARC_UA32	/* Special unaligned fix for debugtab          */


static const unsigned char fixuprel [14] = {R_SPARC_32,
					R_SPARC_HI22,R_SPARC_32,
					R_SPARC_WDISP30,R_SPARC_GOT22,R_SPARC_PC22,
					R_SPARC_GOT13,R_SPARC_32,
					R_SPARC_HI22,R_SPARC_LO10,R_SPARC_GOT22,
					R_SPARC_GOT10,R_SPARC_PC22,R_SPARC_PC10};	
static const unsigned char fixupauxrel [14] = {0,
						R_SPARC_LO10,0,0,R_SPARC_GOT10,R_SPARC_PC10,0};	
/*                                                                           */
/*Above two arrays are for Pfix2. The aux array allows hi-lo fixes           */
/*to be done in a controlled way without specific code.                      */
/*                                                                           */
#define sdblnbreg (0x1E)	/* reg for locals in sdb info                       */
#define gotnametext ("_GLOBAL_OFFSET_TABLE_")
 
#endif;	/*target=elfsparc*/

 
/* The following constants define reltype for 88K                            */
/* all relocations are checked for overflow unless truncation specified      */
 

#if(target==elf88k) 
 
 
#define fullwordfix R_88K_32	/* Normal full word fixup             */
#define debugtabfix R_88K_32UA	/* Special unaligned fix for debugtab */
 
static const unsigned char fixuprel [14] = {R_88K_32,
					R_88K_16H,R_88K_16L,R_88K_DISP26,
					0,0,0,R_88K_PLTDISP26,
					0,0,R_88K_GOT_ABREL_32,R_88K_GOTABREL16L,
					R_88K_ABDIFF16H,R_88K_ABDIFF16H};
 
static const unsigned char fixupauxrel [14] = {0,
					0,0,0,0,0,0,0,0,0,0,0,0,0};
/*                                                                           */
/*Above two arrays are for Pfix2. The aux array allows hi-lo fixes           */
/*to be done in a controlled way without specific code.                      */
/*                                                                           */
#define sdblnbreg (0x1F)	/* reg for locals in sdb info (sp)                  */
/* offset given by framesize                                                 */
 
	/*target=elf88k*/

#endif;
 
/* The following constants define reltype for MIPS                           */
/* all relocations are checked for overflow unless truncation specified      */
 

#if(target==elfmips) 
 
 
#define fullwordfix R_MIPS_32	/* Normal full word fixup                      */
#define debugtabfix R_MIPS_32	/* Special unaligned fix for debugtab        */

static const unsigned char fixuprel [14] = {R_MIPS_32,
					R_MIPS_HI16,R_MIPS_32,R_MIPS_26,
					R_MIPS_GOT16,R_MIPS_CALL16,R_MIPS_GOT16,
					R_MIPS_HI16,R_MIPS_HI16,R_MIPS_LO16,0};

static const unsigned char fixupauxrel [14] = {0,
					R_MIPS_LO16,0,0,0,0,0,R_MIPS_LO16,0};	

static const int fixupmasks [12+1] = {0,0xFFFF,-1,
					-1,0x3FFFFFF,0xFFFF,0xFFFF,0xFFFF,
					0xFFFF,0xFFFF,0xFFFF,0xFFFF,-1};	
/*                                                                           */
/*Above two arrays are for Pfix2. The aux array allows hi-lo fixes           */
/*to be done in a controlled way without specific code.                      */
/*                                                                           */
#define sdblnbreg (0x1D)	/* reg for locals in sdb info ($sp on mips)         */
#define gotnametext ("_gp_disp")
 
	/*target=elfmips*/

#endif;
 
/* The following constants define reltype for 386                            */
/* all relocations are checked for overflow unless truncation specified      */
 

#if(target==elf386) 
 
 
#define fullwordfix R_386_32	/* Normal full word fixup                      */
#define debugtabfix R_386_32	/* Normal fix for debugtab                     */
static const unsigned char fixuprel [7+1] = {R_386_32,
					R_386_32,R_386_32,R_386_PC32,R_386_GOT32,
					R_386_PC32,R_386_GOTOFF,R_386_GOTPC};	
static const unsigned char fixupauxrel [7+1] = {0};	

/*Above two arrays are for Pfix2. The aux array allows hi-lo fixes           */
/*to be done in a controlled way without specific code.                      */
/*                                                                           */
#define sdblnbreg (0x5)	/* reg for locals in sdb info (ebp on 386)           */
#define gotnametext ("_GLOBAL_OFFSET_TABLE_")
 
#endif;	/*target=elf386*/

 
#define commonalign 8
#define symbolprefix ("")	/* "_" on some unix versions                       */
#define centryname ("main")	/* differs between implementations */
#define commonnamesuffix ("")	/* common name suffix for Fortran  */
 
#define param1offset 8	/* for adjusting area 7 sdb records        */
 
/*  Typedefs for internal addresses and data lengths or offsets which        */
/*  will become 64 bit items on 64 bit machines. By changing these it is     */
/*  hoped that rlfput will compile and work on these newfangled chips        */

typedef int EPC_addr;
typedef int EPC_offset;


/* end of elf constants include file                                         */



