aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2001-02-06 02:52:09 +0000
committerAlan Modra <amodra@gmail.com>2001-02-06 02:52:09 +0000
commitda6c73e0803ae9831f64aa81ffebcb8851208c39 (patch)
tree39c6c3706e9e27d430d33dcab6a04a3955b54af3 /gas
parente594303548cc2b89f5c8efa7360f6e32ab45af96 (diff)
downloadfsf-binutils-gdb-da6c73e0803ae9831f64aa81ffebcb8851208c39.zip
fsf-binutils-gdb-da6c73e0803ae9831f64aa81ffebcb8851208c39.tar.gz
fsf-binutils-gdb-da6c73e0803ae9831f64aa81ffebcb8851208c39.tar.bz2
Fix unwind info when cross-compiling from little-endian machines.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog13
-rw-r--r--gas/config/tc-hppa.c98
2 files changed, 74 insertions, 37 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 3a14652..c50ced7 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,16 @@
+2001-02-06 Alan Modra <alan@linuxcare.com.au>
+
+ * config/tc-hppa.c (fix_new_hppa): Pass in unwind directly rather
+ than via pointer. Update all callers.
+ (UNWIND_LOW32): Define.
+ (UNWIND_HIGH32): Define.
+ (pa_build_unwind_subspace): Use the above macros instead of dumping
+ bitfields directly. Call frag_more once rather than multiple times.
+ (md_assemble): Use UNWIND_LOW32.
+ (pa_entry): Likewise
+ (pa_procend): Likewise.
+ (process_exit): Use UNWIND_HIGH32.
+
2001-02-04 Stephane Carrez <Stephane.Carrez@worldnet.fr>
* config/tc-m68hc11.h (LISTING_HEADER): Use m68hc11_listing_header
diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c
index 568becd..1b3a4ef 100644
--- a/gas/config/tc-hppa.c
+++ b/gas/config/tc-hppa.c
@@ -133,6 +133,31 @@ struct unwind_desc
unsigned int frame_size:27;
};
+/* We can't rely on compilers placing bitfields in any particular
+ place, so use these macros when dumping unwind descriptors to
+ object files. */
+#define UNWIND_LOW32(U) \
+ (((U)->cannot_unwind << 31) \
+ | ((U)->millicode << 30) \
+ | ((U)->millicode_save_rest << 29) \
+ | ((U)->region_desc << 27) \
+ | ((U)->save_sr << 25) \
+ | ((U)->entry_fr << 21) \
+ | ((U)->entry_gr << 16) \
+ | ((U)->args_stored << 15) \
+ | ((U)->call_fr << 10) \
+ | ((U)->call_gr << 5) \
+ | ((U)->save_sp << 4) \
+ | ((U)->save_rp << 3) \
+ | ((U)->save_rp_in_frame << 2) \
+ | ((U)->extn_ptr_defined << 1) \
+ | ((U)->cleanup_defined << 0))
+
+#define UNWIND_HIGH32(U) \
+ (((U)->hpe_interrupt_marker << 31) \
+ | ((U)->hpux_interrupt_marker << 30) \
+ | ((U)->frame_size << 0))
+
struct unwind_table
{
/* Starting and ending offsets of the region described by
@@ -546,7 +571,7 @@ static void fix_new_hppa PARAMS ((fragS *, int, int, symbolS *,
offsetT, expressionS *, int,
bfd_reloc_code_real_type,
enum hppa_reloc_field_selector_type_alt,
- int, unsigned int, int *));
+ int, unsigned int, int));
static int is_end_of_statement PARAMS ((void));
static int reg_name_search PARAMS ((char *));
static int pa_chk_field_selector PARAMS ((char **));
@@ -1278,7 +1303,7 @@ fix_new_hppa (frag, where, size, add_symbol, offset, exp, pcrel,
enum hppa_reloc_field_selector_type_alt r_field;
int r_format;
unsigned int arg_reloc;
- int* unwind_bits ATTRIBUTE_UNUSED;
+ int unwind_bits ATTRIBUTE_UNUSED;
{
fixS *new_fix;
@@ -1297,7 +1322,7 @@ fix_new_hppa (frag, where, size, add_symbol, offset, exp, pcrel,
hppa_fix->segment = now_seg;
#ifdef OBJ_SOM
if (r_type == R_ENTRY || r_type == R_EXIT)
- new_fix->fx_offset = *unwind_bits;
+ new_fix->fx_offset = unwind_bits;
#endif
/* foo-$global$ is used to access non-automatic storage. $global$
@@ -1348,7 +1373,7 @@ cons_fix_new_hppa (frag, where, size, exp)
fix_new_hppa (frag, where, size,
(symbolS *) NULL, (offsetT) 0, exp, 0, rel_type,
- hppa_field_selector, size * 8, 0, NULL);
+ hppa_field_selector, size * 8, 0, 0);
/* Reset field selector to its default state. */
hppa_field_selector = 0;
@@ -1458,12 +1483,14 @@ md_assemble (str)
information when the label appears after the proc/procend. */
if (within_entry_exit)
{
- char *where = frag_more (0);
+ char *where;
+ unsigned int u;
+ where = frag_more (0);
+ u = UNWIND_LOW32 (&last_call_info->ci_unwind.descriptor);
fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
NULL, (offsetT) 0, NULL,
- 0, R_HPPA_ENTRY, e_fsel, 0, 0,
- (int *)&last_call_info->ci_unwind.descriptor);
+ 0, R_HPPA_ENTRY, e_fsel, 0, 0, u);
}
#endif
}
@@ -1488,7 +1515,7 @@ md_assemble (str)
fix_new_hppa (frag_now, (to - frag_now->fr_literal), 4, NULL,
(offsetT) 0, &the_insn.exp, the_insn.pcrel,
the_insn.reloc, the_insn.field_selector,
- the_insn.format, the_insn.arg_reloc, NULL);
+ the_insn.format, the_insn.arg_reloc, 0);
#ifdef OBJ_ELF
dwarf2_emit_insn (4);
@@ -5923,7 +5950,7 @@ pa_brtab (begin)
fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
NULL, (offsetT) 0, NULL,
0, begin ? R_HPPA_BEGIN_BRTAB : R_HPPA_END_BRTAB,
- e_fsel, 0, 0, NULL);
+ e_fsel, 0, 0, 0);
#endif
demand_empty_rest_of_line ();
@@ -5948,7 +5975,7 @@ pa_try (begin)
fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
NULL, (offsetT) 0, begin ? NULL : &exp,
0, begin ? R_HPPA_BEGIN_TRY : R_HPPA_END_TRY,
- e_fsel, 0, 0, NULL);
+ e_fsel, 0, 0, 0);
#endif
demand_empty_rest_of_line ();
@@ -6049,12 +6076,11 @@ static void
pa_build_unwind_subspace (call_info)
struct call_info *call_info;
{
- char *unwind;
asection *seg, *save_seg;
subsegT save_subseg;
- unsigned int i;
+ unsigned int unwind;
int reloc;
- char c, *p;
+ char *p;
if ((bfd_get_section_flags (stdoutput, now_seg)
& (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
@@ -6081,17 +6107,14 @@ pa_build_unwind_subspace (call_info)
/* Get some space to hold relocation information for the unwind
descriptor. */
- p = frag_more (4);
- md_number_to_chars (p, 0, 4);
+ p = frag_more (16);
+ md_number_to_chars (p, 0, 8);
/* Relocation info. for start offset of the function. */
fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
call_info->start_symbol, (offsetT) 0,
(expressionS *) NULL, 0, reloc,
- e_fsel, 32, 0, NULL);
-
- p = frag_more (4);
- md_number_to_chars (p, 0, 4);
+ e_fsel, 32, 0, 0);
/* Relocation info. for end offset of the function.
@@ -6101,20 +6124,17 @@ pa_build_unwind_subspace (call_info)
value as call_info->start_symbol + function size once the linker is
finished with its work. */
- fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
+ fix_new_hppa (frag_now, p + 4 - frag_now->fr_literal, 4,
call_info->end_symbol, (offsetT) 0,
(expressionS *) NULL, 0, reloc,
- e_fsel, 32, 0, NULL);
+ e_fsel, 32, 0, 0);
- /* Dump it. */
- unwind = (char *) &call_info->ci_unwind;
- for (i = 8; i < sizeof (struct unwind_table); i++)
- {
- c = *(unwind + i);
- {
- FRAG_APPEND_1_CHAR (c);
- }
- }
+ /* Dump the descriptor. */
+ unwind = UNWIND_LOW32 (&call_info->ci_unwind.descriptor);
+ md_number_to_chars (p + 8, unwind, 4);
+
+ unwind = UNWIND_HIGH32 (&call_info->ci_unwind.descriptor);
+ md_number_to_chars (p + 12, unwind, 4);
/* Return back to the original segment/subsegment. */
subseg_set (save_seg, save_subseg);
@@ -6404,12 +6424,14 @@ pa_entry (unused)
denote the entry and exit points. */
if (last_call_info->start_symbol != NULL)
{
- char *where = frag_more (0);
+ char *where;
+ unsigned int u;
+ where = frag_more (0);
+ u = UNWIND_LOW32 (&last_call_info->ci_unwind.descriptor);
fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
NULL, (offsetT) 0, NULL,
- 0, R_HPPA_ENTRY, e_fsel, 0, 0,
- (int *) &last_call_info->ci_unwind.descriptor);
+ 0, R_HPPA_ENTRY, e_fsel, 0, 0, u);
}
#endif
}
@@ -6517,7 +6539,7 @@ process_exit ()
fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
NULL, (offsetT) 0,
NULL, 0, R_HPPA_EXIT, e_fsel, 0, 0,
- (int *) &last_call_info->ci_unwind.descriptor + 1);
+ UNWIND_HIGH32 (&last_call_info->ci_unwind.descriptor));
#endif
}
@@ -7048,12 +7070,14 @@ pa_procend (unused)
information when the label appears after the proc/procend. */
if (within_entry_exit)
{
- char *where = frag_more (0);
+ char *where;
+ unsigned int u;
+ where = frag_more (0);
+ u = UNWIND_LOW32 (&last_call_info->ci_unwind.descriptor);
fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
NULL, (offsetT) 0, NULL,
- 0, R_HPPA_ENTRY, e_fsel, 0, 0,
- (int *) &last_call_info->ci_unwind.descriptor);
+ 0, R_HPPA_ENTRY, e_fsel, 0, 0, u);
}
#endif
}