diff options
-rw-r--r-- | bfd/ChangeLog | 8 | ||||
-rw-r--r-- | bfd/libhppa.h | 67 | ||||
-rw-r--r-- | bfd/som.c | 39 |
3 files changed, 104 insertions, 10 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7820db9..1275e27 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +Tue Jul 30 14:14:57 1996 Jeffrey A Law (law@cygnus.com) + + * libhppa.h (R_HPPA_ESEL): New field selector. + (e_esel): Similarly. + * som.c (hppa_som_gen_reloc_type): If we encounter an e_esel, + then generate R_COMP2 (PUSH_SYM), R_DATA_EXPR fixup stream. + (som_write_fixups): Handle R_DATA_EXPR just like R_CODE_EXPR. + Tue Jul 30 13:31:27 1996 Ian Lance Taylor <ian@cygnus.com> * xcofflink.c (_bfd_xcoff_bfd_link_add_symbols): Do the regular diff --git a/bfd/libhppa.h b/bfd/libhppa.h index 9fdf924..2070aad 100644 --- a/bfd/libhppa.h +++ b/bfd/libhppa.h @@ -34,6 +34,46 @@ #endif /* GNU C? */ #endif /* INLINE */ +#if __GNUC__ >= 2 && __GNUC_MINOR__ >= 7 +/* Declare the functions with the unused attribute to avoid warnings. */ +static INLINE unsigned int assemble_3 (unsigned int) + __attribute__ ((__unused__)); +static INLINE void dis_assemble_3 (unsigned int, unsigned int *) + __attribute__ ((__unused__)); +static INLINE unsigned int assemble_12 (unsigned int, unsigned int) + __attribute__ ((__unused__)); +static INLINE void dis_assemble_12 (unsigned int, unsigned int *, + unsigned int *) + __attribute__ ((__unused__)); +static INLINE unsigned long assemble_17 (unsigned int, unsigned int, + unsigned int) + __attribute__ ((__unused__)); +static INLINE void dis_assemble_17 (unsigned int, unsigned int *, + unsigned int *, unsigned int *) + __attribute__ ((__unused__)); +static INLINE unsigned long assemble_21 (unsigned int) + __attribute ((__unused__)); +static INLINE void dis_assemble_21 (unsigned int, unsigned int *) + __attribute__ ((__unused__)); +static INLINE unsigned long sign_extend (unsigned int, unsigned int) + __attribute__ ((__unused__)); +static INLINE unsigned int ones (int) __attribute ((__unused__)); +static INLINE void sign_unext (unsigned int, unsigned int, unsigned int *) + __attribute__ ((__unused__)); +static INLINE unsigned long low_sign_extend (unsigned int, unsigned int) + __attribute__ ((__unused__)); +static INLINE void low_sign_unext (unsigned int, unsigned int, unsigned int *) + __attribute__ ((__unused__)); +static INLINE unsigned long hppa_field_adjust (unsigned long, unsigned long, + unsigned short) + __attribute__ ((__unused__)); +static INLINE char bfd_hppa_insn2fmt (unsigned long) + __attribute__ ((__unused__)); +static INLINE unsigned long hppa_rebuild_insn (bfd *, unsigned long, + unsigned long, unsigned long) + __attribute__ ((__unused__)); +#endif /* gcc 2.7 or higher */ + /* The PA instruction set variants. */ enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20}; @@ -58,7 +98,8 @@ enum hppa_reloc_field_selector_type R_HPPA_RPSEL = 0xe, R_HPPA_TSEL = 0xf, R_HPPA_LTSEL = 0x10, - R_HPPA_RTSEL = 0x11 + R_HPPA_RTSEL = 0x11, + R_HPPA_ESEL = 0xff }; /* /usr/include/reloc.h defines these to constants. We want to use @@ -84,6 +125,7 @@ enum hppa_reloc_field_selector_type #undef e_tsel #undef e_ltsel #undef e_rtsel +#undef e_esel #undef e_one #undef e_two #undef e_pcrel @@ -111,7 +153,8 @@ enum hppa_reloc_field_selector_type_alt e_rpsel = R_HPPA_RPSEL, e_tsel = R_HPPA_TSEL, e_ltsel = R_HPPA_LTSEL, - e_rtsel = R_HPPA_RTSEL + e_rtsel = R_HPPA_RTSEL, + e_esel = R_HPPA_ESEL }; enum hppa_reloc_expr_type @@ -517,9 +560,13 @@ hppa_rebuild_insn (abfd, insn, value, r_format) } case 14: - const_part = insn & 0xffffc000; - low_sign_unext (value, 14, &rebuilt_part); - return const_part | rebuilt_part; + { + unsigned int ext; + + const_part = insn & 0xffffc000; + low_sign_unext (value, 14, &ext); + return const_part | ext; + } case 17: { @@ -532,9 +579,13 @@ hppa_rebuild_insn (abfd, insn, value, r_format) } case 21: - const_part = insn & 0xffe00000; - dis_assemble_21 (value, &rebuilt_part); - return const_part | rebuilt_part; + { + unsigned int w; + + const_part = insn & 0xffe00000; + dis_assemble_21 (value, &w); + return const_part | w; + } case 32: const_part = 0; @@ -1585,6 +1585,15 @@ hppa_som_gen_reloc_type (abfd, base_type, format, field, sym_diff) final_types[5] = NULL; break; } + else if (field == e_esel) + { + final_types[0] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); + *final_types[0] = R_COMP2; + final_types[1] = final_type; + *final_types[1] = R_DATA_EXPR; + final_types[2] = NULL; + break;; + } /* PLABELs get their own relocation type. */ else if (field == e_psel || field == e_lpsel @@ -2631,8 +2640,6 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep) later relocation. */ switch (bfd_reloc->howto->type) { - /* This only needs to handle relocations that may be - made by hppa_som_gen_reloc. */ case R_ENTRY: case R_ALT_ENTRY: case R_EXIT: @@ -2647,6 +2654,8 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep) case R_COMP2: case R_BEGIN_BRTAB: case R_END_BRTAB: + case R_BEGIN_TRY: + case R_END_TRY: case R_N0SEL: case R_N1SEL: reloc_offset = bfd_reloc->address; @@ -2780,6 +2789,7 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep) case R_RSEL: case R_BEGIN_BRTAB: case R_END_BRTAB: + case R_BEGIN_TRY: case R_N0SEL: case R_N1SEL: bfd_put_8 (abfd, bfd_reloc->howto->type, p); @@ -2787,6 +2797,29 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep) p += 1; break; + case R_END_TRY: + /* The end of a exception handling region. The reloc's + addend contains the offset of the exception handling + code. */ + if (bfd_reloc->addend == 0) + bfd_put_8 (abfd, bfd_reloc->howto->type, p); + else if (bfd_reloc->addend < 1024) + { + bfd_put_8 (abfd, bfd_reloc->howto->type + 1, p); + bfd_put_8 (abfd, bfd_reloc->addend / 4, p + 1); + p = try_prev_fixup (abfd, &subspace_reloc_size, + p, 2, reloc_queue); + } + else + { + bfd_put_8 (abfd, bfd_reloc->howto->type + 2, p); + bfd_put_8 (abfd, (bfd_reloc->addend / 4) >> 16, p + 1); + bfd_put_16 (abfd, bfd_reloc->addend / 4, p + 2); + p = try_prev_fixup (abfd, &subspace_reloc_size, + p, 4, reloc_queue); + } + break; + case R_COMP1: /* The only time we generate R_COMP1, R_COMP2 and R_CODE_EXPR relocs is for the difference of two @@ -2810,6 +2843,7 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep) break; case R_CODE_EXPR: + case R_DATA_EXPR: /* The only time we generate R_COMP1, R_COMP2 and R_CODE_EXPR relocs is for the difference of two symbols. Hence we can cheat here. */ @@ -4625,6 +4659,7 @@ som_slurp_reloc_table (abfd, section, symbols, just_count) /* We're done with the external relocations. Free them. */ free (external_relocs); + som_section_data (section)->reloc_stream = NULL; /* Save our results and return success. */ section->relocation = internal_relocs; |