Home | History | Annotate | Download | only in bfd
      1 /* HP PA-RISC SOM object file format:  definitions internal to BFD.
      2    Copyright (C) 1990-2014 Free Software Foundation, Inc.
      3 
      4    Contributed by the Center for Software Science at the
      5    University of Utah (pa-gdb-bugs (at) cs.utah.edu).
      6 
      7    This file is part of BFD, the Binary File Descriptor library.
      8 
      9    This program is free software; you can redistribute it and/or modify
     10    it under the terms of the GNU General Public License as published by
     11    the Free Software Foundation; either version 3 of the License, or
     12    (at your option) any later version.
     13 
     14    This program is distributed in the hope that it will be useful,
     15    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17    GNU General Public License for more details.
     18 
     19    You should have received a copy of the GNU General Public License
     20    along with this program; if not, write to the Free Software
     21    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     22    MA 02110-1301, USA.  */
     23 
     24 #ifndef _LIBHPPA_H
     25 #define _LIBHPPA_H
     26 
     27 #define BYTES_IN_WORD 4
     28 #define PA_PAGESIZE 0x1000
     29 
     30 /* The PA instruction set variants.  */
     31 enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20, pa20w = 25};
     32 
     33 /* HP PA-RISC relocation types */
     34 
     35 enum hppa_reloc_field_selector_type
     36   {
     37     R_HPPA_FSEL = 0x0,
     38     R_HPPA_LSSEL = 0x1,
     39     R_HPPA_RSSEL = 0x2,
     40     R_HPPA_LSEL = 0x3,
     41     R_HPPA_RSEL = 0x4,
     42     R_HPPA_LDSEL = 0x5,
     43     R_HPPA_RDSEL = 0x6,
     44     R_HPPA_LRSEL = 0x7,
     45     R_HPPA_RRSEL = 0x8,
     46     R_HPPA_NSEL  = 0x9,
     47     R_HPPA_NLSEL  = 0xa,
     48     R_HPPA_NLRSEL  = 0xb,
     49     R_HPPA_PSEL = 0xc,
     50     R_HPPA_LPSEL = 0xd,
     51     R_HPPA_RPSEL = 0xe,
     52     R_HPPA_TSEL = 0xf,
     53     R_HPPA_LTSEL = 0x10,
     54     R_HPPA_RTSEL = 0x11,
     55     R_HPPA_LTPSEL = 0x12,
     56     R_HPPA_RTPSEL = 0x13
     57   };
     58 
     59 /* /usr/include/reloc.h defines these to constants.  We want to use
     60    them in enums, so #undef them before we start using them.  We might
     61    be able to fix this another way by simply managing not to include
     62    /usr/include/reloc.h, but currently GDB picks up these defines
     63    somewhere.  */
     64 #undef e_fsel
     65 #undef e_lssel
     66 #undef e_rssel
     67 #undef e_lsel
     68 #undef e_rsel
     69 #undef e_ldsel
     70 #undef e_rdsel
     71 #undef e_lrsel
     72 #undef e_rrsel
     73 #undef e_nsel
     74 #undef e_nlsel
     75 #undef e_nlrsel
     76 #undef e_psel
     77 #undef e_lpsel
     78 #undef e_rpsel
     79 #undef e_tsel
     80 #undef e_ltsel
     81 #undef e_rtsel
     82 #undef e_one
     83 #undef e_two
     84 #undef e_pcrel
     85 #undef e_con
     86 #undef e_plabel
     87 #undef e_abs
     88 
     89 /* for compatibility */
     90 enum hppa_reloc_field_selector_type_alt
     91   {
     92     e_fsel = R_HPPA_FSEL,
     93     e_lssel = R_HPPA_LSSEL,
     94     e_rssel = R_HPPA_RSSEL,
     95     e_lsel = R_HPPA_LSEL,
     96     e_rsel = R_HPPA_RSEL,
     97     e_ldsel = R_HPPA_LDSEL,
     98     e_rdsel = R_HPPA_RDSEL,
     99     e_lrsel = R_HPPA_LRSEL,
    100     e_rrsel = R_HPPA_RRSEL,
    101     e_nsel = R_HPPA_NSEL,
    102     e_nlsel = R_HPPA_NLSEL,
    103     e_nlrsel = R_HPPA_NLRSEL,
    104     e_psel = R_HPPA_PSEL,
    105     e_lpsel = R_HPPA_LPSEL,
    106     e_rpsel = R_HPPA_RPSEL,
    107     e_tsel = R_HPPA_TSEL,
    108     e_ltsel = R_HPPA_LTSEL,
    109     e_rtsel = R_HPPA_RTSEL,
    110     e_ltpsel = R_HPPA_LTPSEL,
    111     e_rtpsel = R_HPPA_RTPSEL
    112   };
    113 
    114 enum hppa_reloc_expr_type
    115   {
    116     R_HPPA_E_ONE = 0,
    117     R_HPPA_E_TWO = 1,
    118     R_HPPA_E_PCREL = 2,
    119     R_HPPA_E_CON = 3,
    120     R_HPPA_E_PLABEL = 7,
    121     R_HPPA_E_ABS = 18
    122   };
    123 
    124 /* for compatibility */
    125 enum hppa_reloc_expr_type_alt
    126   {
    127     e_one = R_HPPA_E_ONE,
    128     e_two = R_HPPA_E_TWO,
    129     e_pcrel = R_HPPA_E_PCREL,
    130     e_con = R_HPPA_E_CON,
    131     e_plabel = R_HPPA_E_PLABEL,
    132     e_abs = R_HPPA_E_ABS
    133   };
    134 
    135 
    136 /* Relocations for function calls must be accompanied by parameter
    137    relocation bits.  These bits describe exactly where the caller has
    138    placed the function's arguments and where it expects to find a return
    139    value.
    140 
    141    Both ELF and SOM encode this information within the addend field
    142    of the call relocation.  (Note this could break very badly if one
    143    was to make a call like bl foo + 0x12345678).
    144 
    145    The high order 10 bits contain parameter relocation information,
    146    the low order 22 bits contain the constant offset.  */
    147 
    148 #define HPPA_R_ARG_RELOC(a)	\
    149   (((a) >> 22) & 0x3ff)
    150 #define HPPA_R_CONSTANT(a)	\
    151   ((((bfd_signed_vma)(a)) << (BFD_ARCH_SIZE-22)) >> (BFD_ARCH_SIZE-22))
    152 #define HPPA_R_ADDEND(r, c)	\
    153   (((r) << 22) + ((c) & 0x3fffff))
    154 
    155 
    156 /* Some functions to manipulate PA instructions.  */
    157 
    158 /* Declare the functions with the unused attribute to avoid warnings.  */
    159 static inline int sign_extend (int, int) ATTRIBUTE_UNUSED;
    160 static inline int low_sign_extend (int, int) ATTRIBUTE_UNUSED;
    161 static inline int sign_unext (int, int) ATTRIBUTE_UNUSED;
    162 static inline int low_sign_unext (int, int) ATTRIBUTE_UNUSED;
    163 static inline int re_assemble_3 (int) ATTRIBUTE_UNUSED;
    164 static inline int re_assemble_12 (int) ATTRIBUTE_UNUSED;
    165 static inline int re_assemble_14 (int) ATTRIBUTE_UNUSED;
    166 static inline int re_assemble_16 (int) ATTRIBUTE_UNUSED;
    167 static inline int re_assemble_17 (int) ATTRIBUTE_UNUSED;
    168 static inline int re_assemble_21 (int) ATTRIBUTE_UNUSED;
    169 static inline int re_assemble_22 (int) ATTRIBUTE_UNUSED;
    170 static inline bfd_signed_vma hppa_field_adjust
    171   (bfd_vma, bfd_signed_vma, enum hppa_reloc_field_selector_type_alt)
    172   ATTRIBUTE_UNUSED;
    173 static inline int bfd_hppa_insn2fmt (bfd *, int) ATTRIBUTE_UNUSED;
    174 static inline int hppa_rebuild_insn (int, int, int) ATTRIBUTE_UNUSED;
    175 
    176 
    177 /* The *sign_extend functions are used to assemble various bitfields
    178    taken from an instruction and return the resulting immediate
    179    value.  */
    180 
    181 static inline int
    182 sign_extend (int x, int len)
    183 {
    184   int signbit = (1 << (len - 1));
    185   int mask = (signbit << 1) - 1;
    186   return ((x & mask) ^ signbit) - signbit;
    187 }
    188 
    189 static inline int
    190 low_sign_extend (int x, int len)
    191 {
    192   return (x >> 1) - ((x & 1) << (len - 1));
    193 }
    194 
    195 
    196 /* The re_assemble_* functions prepare an immediate value for
    197    insertion into an opcode. pa-risc uses all sorts of weird bitfields
    198    in the instruction to hold the value.  */
    199 
    200 static inline int
    201 sign_unext (int x, int len)
    202 {
    203   int len_ones;
    204 
    205   len_ones = (1 << len) - 1;
    206 
    207   return x & len_ones;
    208 }
    209 
    210 static inline int
    211 low_sign_unext (int x, int len)
    212 {
    213   int temp;
    214   int sign;
    215 
    216   sign = (x >> (len-1)) & 1;
    217 
    218   temp = sign_unext (x, len-1);
    219 
    220   return (temp << 1) | sign;
    221 }
    222 
    223 static inline int
    224 re_assemble_3 (int as3)
    225 {
    226   return ((  (as3 & 4) << (13-2))
    227 	  | ((as3 & 3) << (13+1)));
    228 }
    229 
    230 static inline int
    231 re_assemble_12 (int as12)
    232 {
    233   return ((  (as12 & 0x800) >> 11)
    234 	  | ((as12 & 0x400) >> (10 - 2))
    235 	  | ((as12 & 0x3ff) << (1 + 2)));
    236 }
    237 
    238 static inline int
    239 re_assemble_14 (int as14)
    240 {
    241   return ((  (as14 & 0x1fff) << 1)
    242 	  | ((as14 & 0x2000) >> 13));
    243 }
    244 
    245 static inline int
    246 re_assemble_16 (int as16)
    247 {
    248   int s, t;
    249 
    250   /* Unusual 16-bit encoding, for wide mode only.  */
    251   t = (as16 << 1) & 0xffff;
    252   s = (as16 & 0x8000);
    253   return (t ^ s ^ (s >> 1)) | (s >> 15);
    254 }
    255 
    256 static inline int
    257 re_assemble_17 (int as17)
    258 {
    259   return ((  (as17 & 0x10000) >> 16)
    260 	  | ((as17 & 0x0f800) << (16 - 11))
    261 	  | ((as17 & 0x00400) >> (10 - 2))
    262 	  | ((as17 & 0x003ff) << (1 + 2)));
    263 }
    264 
    265 static inline int
    266 re_assemble_21 (int as21)
    267 {
    268   return ((  (as21 & 0x100000) >> 20)
    269 	  | ((as21 & 0x0ffe00) >> 8)
    270 	  | ((as21 & 0x000180) << 7)
    271 	  | ((as21 & 0x00007c) << 14)
    272 	  | ((as21 & 0x000003) << 12));
    273 }
    274 
    275 static inline int
    276 re_assemble_22 (int as22)
    277 {
    278   return ((  (as22 & 0x200000) >> 21)
    279 	  | ((as22 & 0x1f0000) << (21 - 16))
    280 	  | ((as22 & 0x00f800) << (16 - 11))
    281 	  | ((as22 & 0x000400) >> (10 - 2))
    282 	  | ((as22 & 0x0003ff) << (1 + 2)));
    283 }
    284 
    285 
    286 /* Handle field selectors for PA instructions.
    287    The L and R (and LS, RS etc.) selectors are used in pairs to form a
    288    full 32 bit address.  eg.
    289 
    290    LDIL	L'start,%r1		; put left part into r1
    291    LDW	R'start(%r1),%r2	; add r1 and right part to form address
    292 
    293    This function returns sign extended values in all cases.
    294 */
    295 
    296 static inline bfd_signed_vma
    297 hppa_field_adjust (bfd_vma sym_val,
    298 		   bfd_signed_vma addend,
    299 		   enum hppa_reloc_field_selector_type_alt r_field)
    300 {
    301   bfd_signed_vma value;
    302 
    303   value = sym_val + addend;
    304   switch (r_field)
    305     {
    306     case e_fsel:
    307       /* F: No change.  */
    308       break;
    309 
    310     case e_nsel:
    311       /* N: null selector.  I don't really understand what this is all
    312 	 about, but HP's documentation says "this indicates that zero
    313 	 bits are to be used for the displacement on the instruction.
    314 	 This fixup is used to identify three-instruction sequences to
    315 	 access data (for importing shared library data)."  */
    316       value = 0;
    317       break;
    318 
    319     case e_lsel:
    320     case e_nlsel:
    321       /* L:  Select top 21 bits.  */
    322       value = value >> 11;
    323       break;
    324 
    325     case e_rsel:
    326       /* R:  Select bottom 11 bits.  */
    327       value = value & 0x7ff;
    328       break;
    329 
    330     case e_lssel:
    331       /* LS:  Round to nearest multiple of 2048 then select top 21 bits.  */
    332       value = value + 0x400;
    333       value = value >> 11;
    334       break;
    335 
    336     case e_rssel:
    337       /* RS:  Select bottom 11 bits for LS.
    338 	 We need to return a value such that 2048 * LS'x + RS'x == x.
    339 	 ie. RS'x = x - ((x + 0x400) & -0x800)
    340 	 this is just a sign extension from bit 21.  */
    341       value = ((value & 0x7ff) ^ 0x400) - 0x400;
    342       break;
    343 
    344     case e_ldsel:
    345       /* LD:  Round to next multiple of 2048 then select top 21 bits.
    346 	 Yes, if we are already on a multiple of 2048, we go up to the
    347 	 next one.  RD in this case will be -2048.  */
    348       value = value + 0x800;
    349       value = value >> 11;
    350       break;
    351 
    352     case e_rdsel:
    353       /* RD:  Set bits 0-20 to one.  */
    354       value = value | -0x800;
    355       break;
    356 
    357     case e_lrsel:
    358     case e_nlrsel:
    359       /* LR:  L with rounding of the addend to nearest 8k.  */
    360       value = sym_val + ((addend + 0x1000) & -0x2000);
    361       value = value >> 11;
    362       break;
    363 
    364     case e_rrsel:
    365       /* RR:  R with rounding of the addend to nearest 8k.
    366 	 We need to return a value such that 2048 * LR'x + RR'x == x
    367 	 ie. RR'x = s+a - (s + (((a + 0x1000) & -0x2000) & -0x800))
    368 	 .	  = s+a - ((s & -0x800) + ((a + 0x1000) & -0x2000))
    369 	 .	  = (s & 0x7ff) + a - ((a + 0x1000) & -0x2000)  */
    370       value = (sym_val & 0x7ff) + (((addend & 0x1fff) ^ 0x1000) - 0x1000);
    371       break;
    372 
    373     default:
    374       abort ();
    375     }
    376   return value;
    377 }
    378 
    379 /* PA-RISC OPCODES */
    380 #define get_opcode(insn)	(((insn) >> 26) & 0x3f)
    381 
    382 enum hppa_opcode_type
    383 {
    384   /* None of the opcodes in the first group generate relocs, so we
    385      aren't too concerned about them.  */
    386   OP_SYSOP   = 0x00,
    387   OP_MEMMNG  = 0x01,
    388   OP_ALU     = 0x02,
    389   OP_NDXMEM  = 0x03,
    390   OP_SPOP    = 0x04,
    391   OP_DIAG    = 0x05,
    392   OP_FMPYADD = 0x06,
    393   OP_UNDEF07 = 0x07,
    394   OP_COPRW   = 0x09,
    395   OP_COPRDW  = 0x0b,
    396   OP_COPR    = 0x0c,
    397   OP_FLOAT   = 0x0e,
    398   OP_PRDSPEC = 0x0f,
    399   OP_UNDEF15 = 0x15,
    400   OP_UNDEF1d = 0x1d,
    401   OP_FMPYSUB = 0x26,
    402   OP_FPFUSED = 0x2e,
    403   OP_SHEXDP0 = 0x34,
    404   OP_SHEXDP1 = 0x35,
    405   OP_SHEXDP2 = 0x36,
    406   OP_UNDEF37 = 0x37,
    407   OP_SHEXDP3 = 0x3c,
    408   OP_SHEXDP4 = 0x3d,
    409   OP_MULTMED = 0x3e,
    410   OP_UNDEF3f = 0x3f,
    411 
    412   OP_LDIL    = 0x08,
    413   OP_ADDIL   = 0x0a,
    414 
    415   OP_LDO     = 0x0d,
    416   OP_LDB     = 0x10,
    417   OP_LDH     = 0x11,
    418   OP_LDW     = 0x12,
    419   OP_LDWM    = 0x13,
    420   OP_STB     = 0x18,
    421   OP_STH     = 0x19,
    422   OP_STW     = 0x1a,
    423   OP_STWM    = 0x1b,
    424 
    425   OP_LDD     = 0x14,
    426   OP_STD     = 0x1c,
    427 
    428   OP_FLDW    = 0x16,
    429   OP_LDWL    = 0x17,
    430   OP_FSTW    = 0x1e,
    431   OP_STWL    = 0x1f,
    432 
    433   OP_COMBT   = 0x20,
    434   OP_COMIBT  = 0x21,
    435   OP_COMBF   = 0x22,
    436   OP_COMIBF  = 0x23,
    437   OP_CMPBDT  = 0x27,
    438   OP_ADDBT   = 0x28,
    439   OP_ADDIBT  = 0x29,
    440   OP_ADDBF   = 0x2a,
    441   OP_ADDIBF  = 0x2b,
    442   OP_CMPBDF  = 0x2f,
    443   OP_BVB     = 0x30,
    444   OP_BB      = 0x31,
    445   OP_MOVB    = 0x32,
    446   OP_MOVIB   = 0x33,
    447   OP_CMPIBD  = 0x3b,
    448 
    449   OP_COMICLR = 0x24,
    450   OP_SUBI    = 0x25,
    451   OP_ADDIT   = 0x2c,
    452   OP_ADDI    = 0x2d,
    453 
    454   OP_BE      = 0x38,
    455   OP_BLE     = 0x39,
    456   OP_BL      = 0x3a
    457 };
    458 
    459 
    460 /* Given a machine instruction, return its format.  */
    461 
    462 static inline int
    463 bfd_hppa_insn2fmt (bfd *abfd, int insn)
    464 {
    465   enum hppa_opcode_type op = get_opcode (insn);
    466 
    467   switch (op)
    468     {
    469     case OP_COMICLR:
    470     case OP_SUBI:
    471     case OP_ADDIT:
    472     case OP_ADDI:
    473       return 11;
    474 
    475     case OP_COMBT:
    476     case OP_COMIBT:
    477     case OP_COMBF:
    478     case OP_COMIBF:
    479     case OP_CMPBDT:
    480     case OP_ADDBT:
    481     case OP_ADDIBT:
    482     case OP_ADDBF:
    483     case OP_ADDIBF:
    484     case OP_CMPBDF:
    485     case OP_BVB:
    486     case OP_BB:
    487     case OP_MOVB:
    488     case OP_MOVIB:
    489     case OP_CMPIBD:
    490       return 12;
    491 
    492     case OP_LDO:
    493     case OP_LDB:
    494     case OP_LDH:
    495     case OP_LDW:
    496     case OP_LDWM:
    497     case OP_STB:
    498     case OP_STH:
    499     case OP_STW:
    500     case OP_STWM:
    501       if (abfd->arch_info->mach >= 25)
    502 	return 16;	/* Wide mode, format 16.  */
    503       return 14;
    504 
    505     case OP_FLDW:
    506     case OP_LDWL:
    507     case OP_FSTW:
    508     case OP_STWL:
    509       /* This is a hack.  Unfortunately, format 11 is already taken
    510 	 and we're using integers rather than an enum, so it's hard
    511 	 to describe the 11a format.  */
    512       if (abfd->arch_info->mach >= 25)
    513 	return -16;	/* Wide mode, format 16a.  */
    514       return -11;
    515 
    516     case OP_LDD:
    517     case OP_STD:
    518       if (abfd->arch_info->mach >= 25)
    519 	return -10;	/* Wide mode, format 10a.  */
    520       return 10;
    521 
    522     case OP_BL:
    523       if ((insn & 0x8000) != 0)
    524 	return 22;
    525       /* fall thru */
    526     case OP_BE:
    527     case OP_BLE:
    528       return 17;
    529 
    530     case OP_LDIL:
    531     case OP_ADDIL:
    532       return 21;
    533 
    534     default:
    535       break;
    536     }
    537   return 32;
    538 }
    539 
    540 
    541 /* Insert VALUE into INSN using R_FORMAT to determine exactly what
    542    bits to change.  */
    543 
    544 static inline int
    545 hppa_rebuild_insn (int insn, int value, int r_format)
    546 {
    547   switch (r_format)
    548     {
    549     case 11:
    550       return (insn & ~ 0x7ff) | low_sign_unext (value, 11);
    551 
    552     case 12:
    553       return (insn & ~ 0x1ffd) | re_assemble_12 (value);
    554 
    555 
    556     case 10:
    557       return (insn & ~ 0x3ff1) | re_assemble_14 (value & -8);
    558 
    559     case -11:
    560       return (insn & ~ 0x3ff9) | re_assemble_14 (value & -4);
    561 
    562     case 14:
    563       return (insn & ~ 0x3fff) | re_assemble_14 (value);
    564 
    565 
    566     case -10:
    567       return (insn & ~ 0xfff1) | re_assemble_16 (value & -8);
    568 
    569     case -16:
    570       return (insn & ~ 0xfff9) | re_assemble_16 (value & -4);
    571 
    572     case 16:
    573       return (insn & ~ 0xffff) | re_assemble_16 (value);
    574 
    575 
    576     case 17:
    577       return (insn & ~ 0x1f1ffd) | re_assemble_17 (value);
    578 
    579     case 21:
    580       return (insn & ~ 0x1fffff) | re_assemble_21 (value);
    581 
    582     case 22:
    583       return (insn & ~ 0x3ff1ffd) | re_assemble_22 (value);
    584 
    585     case 32:
    586       return value;
    587 
    588     default:
    589       abort ();
    590     }
    591   return insn;
    592 }
    593 
    594 #endif /* _LIBHPPA_H */
    595