diff options
author | Richard Henderson <rth@redhat.com> | 2008-08-21 19:49:22 +0000 |
---|---|---|
committer | Richard Henderson <rth@redhat.com> | 2008-08-21 19:49:22 +0000 |
commit | 8c9b70b1a5d4a033ce38d16981b31a1e2f67485d (patch) | |
tree | fa25136b95953f8456338d2753f3e5f9313b9ebb /gas | |
parent | aa8d5e4592d560eb7b1dd04ed8d9254b43d6f929 (diff) | |
download | binutils-8c9b70b1a5d4a033ce38d16981b31a1e2f67485d.zip binutils-8c9b70b1a5d4a033ce38d16981b31a1e2f67485d.tar.gz binutils-8c9b70b1a5d4a033ce38d16981b31a1e2f67485d.tar.bz2 |
* dw2gencfi.c (DWARF2_FDE_RELOC_SIZE): New.
(output_cie, output_fde): Use it.
(DWARF2_EH_FRAME_READ_ONLY): New.
(cfi_finish): Use it.
* config/tc-hppa.h (DWARF2_FDE_RELOC_SIZE): Set to 8 for 64-bit.
(DWARF2_CIE_DATA_ALIGNMENT): Change sign.
(DWARF2_EH_FRAME_READ_ONLY): New.
* config/tc-hppa.c (tc_gen_reloc): Generate pc-relative relocations
from the results of DIFF_EXPR_OK manipulation.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 13 | ||||
-rw-r--r-- | gas/config/tc-hppa.c | 12 | ||||
-rw-r--r-- | gas/config/tc-hppa.h | 12 | ||||
-rw-r--r-- | gas/dw2gencfi.c | 42 |
4 files changed, 67 insertions, 12 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 1815d7b..91ff6db 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +2008-08-21 Richard Henderson <rth@redhat.com> + + * dw2gencfi.c (DWARF2_FDE_RELOC_SIZE): New. + (output_cie, output_fde): Use it. + (DWARF2_EH_FRAME_READ_ONLY): New. + (cfi_finish): Use it. + + * config/tc-hppa.h (DWARF2_FDE_RELOC_SIZE): Set to 8 for 64-bit. + (DWARF2_CIE_DATA_ALIGNMENT): Change sign. + (DWARF2_EH_FRAME_READ_ONLY): New. + * config/tc-hppa.c (tc_gen_reloc): Generate pc-relative relocations + from the results of DIFF_EXPR_OK manipulation. + 2008-08-21 Sterling Augustine <sterling@tensilica.com> * config/xtensa-istack.h (MAX_INSN_ARGS): Increase to 64. diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index d31d527..f36ac2b 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -1375,6 +1375,18 @@ tc_gen_reloc (asection *section, fixS *fixp) reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); + + /* Allow fixup_segment to recognize hand-written pc-relative relocations. + When we went through cons_fix_new_hppa, we classified them as complex. */ + /* ??? It might be better to hide this +8 stuff in tc_cfi_emit_pcrel_expr, + undefine DIFF_EXPR_OK, and let these sorts of complex expressions fail + when R_HPPA_COMPLEX == R_PARISC_UNIMPLEMENTED. */ + if (fixp->fx_r_type == R_HPPA_COMPLEX && fixp->fx_pcrel) + { + fixp->fx_r_type = R_HPPA_PCREL_CALL; + fixp->fx_offset += 8; + } + codes = hppa_gen_reloc_type (stdoutput, fixp->fx_r_type, hppa_fixp->fx_r_format, diff --git a/gas/config/tc-hppa.h b/gas/config/tc-hppa.h index bf5b27f..b53527b 100644 --- a/gas/config/tc-hppa.h +++ b/gas/config/tc-hppa.h @@ -186,8 +186,6 @@ int hppa_fix_adjustable (struct fix *); #define elf_tc_final_processing elf_hppa_final_processing void elf_hppa_final_processing (void); - -#define DWARF2_LINE_MIN_INSN_LENGTH 4 #endif /* OBJ_ELF */ #define md_operand(x) @@ -213,10 +211,16 @@ extern int hppa_regname_to_dw2regnum (char *regname); #define DWARF2_LINE_MIN_INSN_LENGTH 4 #define DWARF2_DEFAULT_RETURN_COLUMN 2 #if TARGET_ARCH_SIZE == 64 -#define DWARF2_CIE_DATA_ALIGNMENT (-8) +#define DWARF2_CIE_DATA_ALIGNMENT 8 +#define DWARF2_FDE_RELOC_SIZE 8 #else -#define DWARF2_CIE_DATA_ALIGNMENT (-4) +#define DWARF2_CIE_DATA_ALIGNMENT 4 #endif + +/* Due to the way dynamic linking to personality functions is handled, + we need to have a read-write .eh_frame section. */ +#define DWARF2_EH_FRAME_READ_ONLY 0 + #endif #endif /* _TC_HPPA_H */ diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c index d7ebf8c..520d1e1 100644 --- a/gas/dw2gencfi.c +++ b/gas/dw2gencfi.c @@ -31,6 +31,16 @@ # define DWARF2_LINE_MIN_INSN_LENGTH 1 #endif +/* By default, use 32-bit relocations from .eh_frame into .text. */ +#ifndef DWARF2_FDE_RELOC_SIZE +# define DWARF2_FDE_RELOC_SIZE 4 +#endif + +/* By default, use a read-only .eh_frame section. */ +#ifndef DWARF2_EH_FRAME_READ_ONLY +# define DWARF2_EH_FRAME_READ_ONLY SEC_READONLY +#endif + #ifndef EH_FRAME_ALIGNMENT # define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2) #endif @@ -1041,6 +1051,7 @@ output_cie (struct cie_entry *cie) expressionS exp; struct cfi_insn_data *i; offsetT augmentation_size; + int enc; cie->start_address = symbol_temp_new_now (); after_size_address = symbol_temp_make (); @@ -1096,11 +1107,25 @@ output_cie (struct cie_entry *cie) } if (cie->lsda_encoding != DW_EH_PE_omit) out_one (cie->lsda_encoding); + + switch (DWARF2_FDE_RELOC_SIZE) + { + case 2: + enc = DW_EH_PE_sdata2; + break; + case 4: + enc = DW_EH_PE_sdata4; + break; + case 8: + enc = DW_EH_PE_sdata8; + break; + default: + abort (); + } #if defined DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr - out_one (DW_EH_PE_pcrel | DW_EH_PE_sdata4); -#else - out_one (DW_EH_PE_sdata4); + enc |= DW_EH_PE_pcrel; #endif + out_one (enc); if (cie->first) for (i = cie->first; i != cie->last; i = i->next) @@ -1135,22 +1160,22 @@ output_fde (struct fde_entry *fde, struct cie_entry *cie, #ifdef DIFF_EXPR_OK exp.X_add_symbol = fde->start_address; exp.X_op_symbol = symbol_temp_new_now (); - emit_expr (&exp, 4); /* Code offset. */ + emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */ #else exp.X_op = O_symbol; exp.X_add_symbol = fde->start_address; exp.X_op_symbol = NULL; #ifdef tc_cfi_emit_pcrel_expr - tc_cfi_emit_pcrel_expr (&exp, 4); /* Code offset. */ + tc_cfi_emit_pcrel_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */ #else - emit_expr (&exp, 4); /* Code offset. */ + emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */ #endif exp.X_op = O_subtract; #endif exp.X_add_symbol = fde->end_address; exp.X_op_symbol = fde->start_address; /* Code length. */ - emit_expr (&exp, 4); + emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); augmentation_size = encoding_size (fde->lsda_encoding); out_uleb128 (augmentation_size); /* Augmentation size. */ @@ -1319,7 +1344,8 @@ cfi_finish (void) /* Open .eh_frame section. */ cfi_seg = subseg_new (".eh_frame", 0); bfd_set_section_flags (stdoutput, cfi_seg, - SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_READONLY); + SEC_ALLOC | SEC_LOAD | SEC_DATA + | DWARF2_EH_FRAME_READ_ONLY); subseg_set (cfi_seg, 0); record_alignment (cfi_seg, EH_FRAME_ALIGNMENT); |