Fix unwind info problems with .align.
* config/tc-ia64.c (slot_index): New arg before_relax. Use instead of finalize_syms. (fixup_unw_records): New arg before_relax. Pass to slot_index. (ia64_estimate_size_before_relax): New. (ia64_convert_frag): Pass 0 to fixup_unw_records. Add comment. (generate_unwind_image): Pass 1 to fixup_unw_records. * config/tc-ia64.h (ia64_estimate_size_before_relax): Declare. (md_estimate_size_before_relax): Call ia64_estimate_size_before_relax.
This commit is contained in:
parent
1dbe47d647
commit
b5e0fabd1f
3 changed files with 60 additions and 13 deletions
|
@ -1,3 +1,14 @@
|
|||
2004-02-20 James E Wilson <wilson@specifixinc.com>
|
||||
|
||||
* config/tc-ia64.c (slot_index): New arg before_relax. Use instead of
|
||||
finalize_syms.
|
||||
(fixup_unw_records): New arg before_relax. Pass to slot_index.
|
||||
(ia64_estimate_size_before_relax): New.
|
||||
(ia64_convert_frag): Pass 0 to fixup_unw_records. Add comment.
|
||||
(generate_unwind_image): Pass 1 to fixup_unw_records.
|
||||
* config/tc-ia64.h (ia64_estimate_size_before_relax): Declare.
|
||||
(md_estimate_size_before_relax): Call ia64_estimate_size_before_relax.
|
||||
|
||||
2004-02-19 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* stabs.c (generate_asm_file): Avoid warning about use of
|
||||
|
|
|
@ -898,9 +898,10 @@ static void process_unw_records PARAMS ((unw_rec_list *, vbyte_func));
|
|||
static int calc_record_size PARAMS ((unw_rec_list *));
|
||||
static void set_imask PARAMS ((unw_rec_list *, unsigned long, unsigned long, unsigned int));
|
||||
static unsigned long slot_index PARAMS ((unsigned long, fragS *,
|
||||
unsigned long, fragS *));
|
||||
unsigned long, fragS *,
|
||||
int));
|
||||
static unw_rec_list *optimize_unw_records PARAMS ((unw_rec_list *));
|
||||
static void fixup_unw_records PARAMS ((unw_rec_list *));
|
||||
static void fixup_unw_records PARAMS ((unw_rec_list *, int));
|
||||
static int convert_expr_to_ab_reg PARAMS ((expressionS *, unsigned int *, unsigned int *));
|
||||
static int convert_expr_to_xy_reg PARAMS ((expressionS *, unsigned int *, unsigned int *));
|
||||
static void generate_unwind_image PARAMS ((const char *));
|
||||
|
@ -2612,14 +2613,16 @@ set_imask (region, regmask, t, type)
|
|||
|
||||
/* Return the number of instruction slots from FIRST_ADDR to SLOT_ADDR.
|
||||
SLOT_FRAG is the frag containing SLOT_ADDR, and FIRST_FRAG is the frag
|
||||
containing FIRST_ADDR. */
|
||||
containing FIRST_ADDR. If BEFORE_RELAX, then we use worst-case estimates
|
||||
for frag sizes. */
|
||||
|
||||
unsigned long
|
||||
slot_index (slot_addr, slot_frag, first_addr, first_frag)
|
||||
slot_index (slot_addr, slot_frag, first_addr, first_frag, before_relax)
|
||||
unsigned long slot_addr;
|
||||
fragS *slot_frag;
|
||||
unsigned long first_addr;
|
||||
fragS *first_frag;
|
||||
int before_relax;
|
||||
{
|
||||
unsigned long index = 0;
|
||||
|
||||
|
@ -2634,10 +2637,10 @@ slot_index (slot_addr, slot_frag, first_addr, first_frag)
|
|||
{
|
||||
unsigned long start_addr = (unsigned long) &first_frag->fr_literal;
|
||||
|
||||
if (finalize_syms)
|
||||
if (! before_relax)
|
||||
{
|
||||
/* We can get the final addresses only after relaxation is
|
||||
done. */
|
||||
/* We can get the final addresses only during and after
|
||||
relaxation. */
|
||||
if (first_frag->fr_next && first_frag->fr_next->fr_address)
|
||||
index += 3 * ((first_frag->fr_next->fr_address
|
||||
- first_frag->fr_address
|
||||
|
@ -2716,8 +2719,9 @@ optimize_unw_records (list)
|
|||
within each record to generate an image. */
|
||||
|
||||
static void
|
||||
fixup_unw_records (list)
|
||||
fixup_unw_records (list, before_relax)
|
||||
unw_rec_list *list;
|
||||
int before_relax;
|
||||
{
|
||||
unw_rec_list *ptr, *region = 0;
|
||||
unsigned long first_addr = 0, rlen = 0, t;
|
||||
|
@ -2728,7 +2732,7 @@ fixup_unw_records (list)
|
|||
if (ptr->slot_number == SLOT_NUM_NOT_SET)
|
||||
as_bad (" Insn slot not set in unwind record.");
|
||||
t = slot_index (ptr->slot_number, ptr->slot_frag,
|
||||
first_addr, first_frag);
|
||||
first_addr, first_frag, before_relax);
|
||||
switch (ptr->r.type)
|
||||
{
|
||||
case prologue:
|
||||
|
@ -2752,7 +2756,8 @@ fixup_unw_records (list)
|
|||
last_frag = last->slot_frag;
|
||||
break;
|
||||
}
|
||||
size = slot_index (last_addr, last_frag, first_addr, first_frag);
|
||||
size = slot_index (last_addr, last_frag, first_addr, first_frag,
|
||||
before_relax);
|
||||
rlen = ptr->r.record.r.rlen = size;
|
||||
if (ptr->r.type == body)
|
||||
/* End of region. */
|
||||
|
@ -2852,6 +2857,35 @@ fixup_unw_records (list)
|
|||
}
|
||||
}
|
||||
|
||||
/* Estimate the size of a frag before relaxing. We only have one type of frag
|
||||
to handle here, which is the unwind info frag. */
|
||||
|
||||
int
|
||||
ia64_estimate_size_before_relax (fragS *frag,
|
||||
asection *segtype ATTRIBUTE_UNUSED)
|
||||
{
|
||||
unw_rec_list *list;
|
||||
int len, size, pad;
|
||||
|
||||
/* ??? This code is identical to the first part of ia64_convert_frag. */
|
||||
list = (unw_rec_list *) frag->fr_opcode;
|
||||
fixup_unw_records (list, 0);
|
||||
|
||||
len = calc_record_size (list);
|
||||
/* pad to pointer-size boundary. */
|
||||
pad = len % md.pointer_size;
|
||||
if (pad != 0)
|
||||
len += md.pointer_size - pad;
|
||||
/* Add 8 for the header + a pointer for the personality offset. */
|
||||
size = len + 8 + md.pointer_size;
|
||||
|
||||
/* fr_var carries the max_chars that we created the fragment with.
|
||||
We must, of course, have allocated enough memory earlier. */
|
||||
assert (frag->fr_var >= size);
|
||||
|
||||
return frag->fr_fix + size;
|
||||
}
|
||||
|
||||
/* This function converts a rs_machine_dependent variant frag into a
|
||||
normal fill frag with the unwind image from the the record list. */
|
||||
void
|
||||
|
@ -2861,8 +2895,9 @@ ia64_convert_frag (fragS *frag)
|
|||
int len, size, pad;
|
||||
valueT flag_value;
|
||||
|
||||
/* ??? This code is identical to ia64_estimate_size_before_relax. */
|
||||
list = (unw_rec_list *) frag->fr_opcode;
|
||||
fixup_unw_records (list);
|
||||
fixup_unw_records (list, 0);
|
||||
|
||||
len = calc_record_size (list);
|
||||
/* pad to pointer-size boundary. */
|
||||
|
@ -3286,7 +3321,7 @@ generate_unwind_image (text_name)
|
|||
|
||||
/* Generate the unwind record. */
|
||||
list = optimize_unw_records (unwind.list);
|
||||
fixup_unw_records (list);
|
||||
fixup_unw_records (list, 1);
|
||||
size = calc_record_size (list);
|
||||
|
||||
if (size > 0 || unwind.force_unwind_entry)
|
||||
|
|
|
@ -115,6 +115,7 @@ extern void ia64_handle_align PARAMS ((fragS *f));
|
|||
extern void ia64_after_parse_args PARAMS ((void));
|
||||
extern void ia64_dwarf2_emit_offset PARAMS ((symbolS *, unsigned int));
|
||||
extern void ia64_check_label PARAMS ((symbolS *));
|
||||
extern int ia64_estimate_size_before_relax (fragS *, asection *);
|
||||
extern void ia64_convert_frag (fragS *);
|
||||
|
||||
#define md_end() ia64_end_of_source ()
|
||||
|
@ -138,7 +139,7 @@ extern void ia64_convert_frag (fragS *);
|
|||
#define md_create_short_jump(p,f,t,fr,s) \
|
||||
as_fatal ("ia64_create_short_jump")
|
||||
#define md_estimate_size_before_relax(f,s) \
|
||||
(f)->fr_var
|
||||
ia64_estimate_size_before_relax(f,s)
|
||||
#define md_elf_section_letter ia64_elf_section_letter
|
||||
#define md_elf_section_flags ia64_elf_section_flags
|
||||
#define TC_FIX_TYPE struct ia64_fix
|
||||
|
|
Loading…
Reference in a new issue