/* EPC Imp to C Translation Release 4 Version Apr 95 */ #include "imptoc.h" #include #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 */ /* 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 */