mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 11:39:26 +08:00
Fix region length calculations when regions end with .align padding.
* config/tc-ia64.c (output_endp): New. (count_bits): Delete. (ia64_flush_insns, process_one_record, optimize_unw_records): Handle endp unwind records. (fixup_unw_records): Handle endp unwind records. Delete code for shortening prologue regions not followed by a body record. (dot_endp): Call add_unwind_entry to emit endp unwind record. * config/tc-ia64.h (unw_record_type): Add endp.
This commit is contained in:
@ -1,3 +1,14 @@
|
|||||||
|
2004-02-05 James E Wilson <wilson@specifixinc.com>
|
||||||
|
|
||||||
|
* config/tc-ia64.c (output_endp): New.
|
||||||
|
(count_bits): Delete.
|
||||||
|
(ia64_flush_insns, process_one_record, optimize_unw_records): Handle
|
||||||
|
endp unwind records.
|
||||||
|
(fixup_unw_records): Handle endp unwind records. Delete code for
|
||||||
|
shortening prologue regions not followed by a body record.
|
||||||
|
(dot_endp): Call add_unwind_entry to emit endp unwind record.
|
||||||
|
* config/tc-ia64.h (unw_record_type): Add endp.
|
||||||
|
|
||||||
2004-02-03 James E Wilson <wilson@specifixinc.com>
|
2004-02-03 James E Wilson <wilson@specifixinc.com>
|
||||||
|
|
||||||
* config/tc-ia64.c (ia64_convert_frag): Call md_number_to_chars to
|
* config/tc-ia64.c (ia64_convert_frag): Call md_number_to_chars to
|
||||||
|
@ -822,6 +822,7 @@ static void output_X2_format PARAMS ((vbyte_func, int, int, int, int, int, unsig
|
|||||||
static void output_X3_format PARAMS ((vbyte_func, unw_record_type, int, int, int, unsigned long,
|
static void output_X3_format PARAMS ((vbyte_func, unw_record_type, int, int, int, unsigned long,
|
||||||
unsigned long));
|
unsigned long));
|
||||||
static void output_X4_format PARAMS ((vbyte_func, int, int, int, int, int, int, unsigned long));
|
static void output_X4_format PARAMS ((vbyte_func, int, int, int, int, int, int, unsigned long));
|
||||||
|
static unw_rec_list *output_endp PARAMS ((void));
|
||||||
static unw_rec_list *output_prologue PARAMS ((void));
|
static unw_rec_list *output_prologue PARAMS ((void));
|
||||||
static unw_rec_list *output_prologue_gr PARAMS ((unsigned int, unsigned int));
|
static unw_rec_list *output_prologue_gr PARAMS ((unsigned int, unsigned int));
|
||||||
static unw_rec_list *output_body PARAMS ((void));
|
static unw_rec_list *output_body PARAMS ((void));
|
||||||
@ -896,7 +897,6 @@ static void process_one_record PARAMS ((unw_rec_list *, vbyte_func));
|
|||||||
static void process_unw_records PARAMS ((unw_rec_list *, vbyte_func));
|
static void process_unw_records PARAMS ((unw_rec_list *, vbyte_func));
|
||||||
static int calc_record_size PARAMS ((unw_rec_list *));
|
static int calc_record_size PARAMS ((unw_rec_list *));
|
||||||
static void set_imask PARAMS ((unw_rec_list *, unsigned long, unsigned long, unsigned int));
|
static void set_imask PARAMS ((unw_rec_list *, unsigned long, unsigned long, unsigned int));
|
||||||
static int count_bits PARAMS ((unsigned long));
|
|
||||||
static unsigned long slot_index PARAMS ((unsigned long, fragS *,
|
static unsigned long slot_index PARAMS ((unsigned long, fragS *,
|
||||||
unsigned long, fragS *));
|
unsigned long, fragS *));
|
||||||
static unw_rec_list *optimize_unw_records PARAMS ((unw_rec_list *));
|
static unw_rec_list *optimize_unw_records PARAMS ((unw_rec_list *));
|
||||||
@ -1088,12 +1088,12 @@ ia64_flush_insns ()
|
|||||||
CURR_SLOT.tag_fixups = 0;
|
CURR_SLOT.tag_fixups = 0;
|
||||||
|
|
||||||
/* In case there are unwind directives following the last instruction,
|
/* In case there are unwind directives following the last instruction,
|
||||||
resolve those now. We only handle body and prologue directives here.
|
resolve those now. We only handle prologue, body, and endp directives
|
||||||
Give an error for others. */
|
here. Give an error for others. */
|
||||||
for (ptr = unwind.current_entry; ptr; ptr = ptr->next)
|
for (ptr = unwind.current_entry; ptr; ptr = ptr->next)
|
||||||
{
|
{
|
||||||
if (ptr->r.type == prologue || ptr->r.type == prologue_gr
|
if (ptr->r.type == prologue || ptr->r.type == prologue_gr
|
||||||
|| ptr->r.type == body)
|
|| ptr->r.type == body || ptr->r.type == endp)
|
||||||
{
|
{
|
||||||
ptr->slot_number = (unsigned long) frag_more (0);
|
ptr->slot_number = (unsigned long) frag_more (0);
|
||||||
ptr->slot_frag = frag_now;
|
ptr->slot_frag = frag_now;
|
||||||
@ -1712,6 +1712,16 @@ alloc_record (unw_record_type t)
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dummy unwind record used for calculating the length of the last prologue or
|
||||||
|
body region. */
|
||||||
|
|
||||||
|
static unw_rec_list *
|
||||||
|
output_endp ()
|
||||||
|
{
|
||||||
|
unw_rec_list *ptr = alloc_record (endp);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
static unw_rec_list *
|
static unw_rec_list *
|
||||||
output_prologue ()
|
output_prologue ()
|
||||||
{
|
{
|
||||||
@ -2332,6 +2342,10 @@ process_one_record (ptr, f)
|
|||||||
|
|
||||||
switch (ptr->r.type)
|
switch (ptr->r.type)
|
||||||
{
|
{
|
||||||
|
/* This is a dummy record that takes up no space in the output. */
|
||||||
|
case endp:
|
||||||
|
break;
|
||||||
|
|
||||||
case gr_mem:
|
case gr_mem:
|
||||||
case fr_mem:
|
case fr_mem:
|
||||||
case br_mem:
|
case br_mem:
|
||||||
@ -2574,19 +2588,6 @@ set_imask (region, regmask, t, type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
count_bits (unsigned long mask)
|
|
||||||
{
|
|
||||||
int n = 0;
|
|
||||||
|
|
||||||
while (mask)
|
|
||||||
{
|
|
||||||
mask &= mask - 1;
|
|
||||||
++n;
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the number of instruction slots from FIRST_ADDR to SLOT_ADDR.
|
/* 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
|
SLOT_FRAG is the frag containing SLOT_ADDR, and FIRST_FRAG is the frag
|
||||||
containing FIRST_ADDR. */
|
containing FIRST_ADDR. */
|
||||||
@ -2680,8 +2681,8 @@ optimize_unw_records (list)
|
|||||||
/* If the only unwind record is ".prologue" or ".prologue" followed
|
/* If the only unwind record is ".prologue" or ".prologue" followed
|
||||||
by ".body", then we can optimize the unwind directives away. */
|
by ".body", then we can optimize the unwind directives away. */
|
||||||
if (list->r.type == prologue
|
if (list->r.type == prologue
|
||||||
&& (list->next == NULL
|
&& (list->next->r.type == endp
|
||||||
|| (list->next->r.type == body && list->next->next == NULL)))
|
|| (list->next->r.type == body && list->next->next->r.type == endp)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
@ -2713,59 +2714,23 @@ fixup_unw_records (list)
|
|||||||
case body:
|
case body:
|
||||||
{
|
{
|
||||||
unw_rec_list *last;
|
unw_rec_list *last;
|
||||||
int size, dir_len = 0;
|
int size;
|
||||||
unsigned long last_addr;
|
unsigned long last_addr = 0;
|
||||||
fragS *last_frag;
|
fragS *last_frag = NULL;
|
||||||
|
|
||||||
first_addr = ptr->slot_number;
|
first_addr = ptr->slot_number;
|
||||||
first_frag = ptr->slot_frag;
|
first_frag = ptr->slot_frag;
|
||||||
/* Find either the next body/prologue start, or the end of
|
/* Find either the next body/prologue start, or the end of
|
||||||
the list, and determine the size of the region. */
|
the function, and determine the size of the region. */
|
||||||
last_addr = list->next_slot_number;
|
|
||||||
last_frag = list->next_slot_frag;
|
|
||||||
for (last = ptr->next; last != NULL; last = last->next)
|
for (last = ptr->next; last != NULL; last = last->next)
|
||||||
if (last->r.type == prologue || last->r.type == prologue_gr
|
if (last->r.type == prologue || last->r.type == prologue_gr
|
||||||
|| last->r.type == body)
|
|| last->r.type == body || last->r.type == endp)
|
||||||
{
|
{
|
||||||
last_addr = last->slot_number;
|
last_addr = last->slot_number;
|
||||||
last_frag = last->slot_frag;
|
last_frag = last->slot_frag;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (!last->next)
|
size = slot_index (last_addr, last_frag, first_addr, first_frag);
|
||||||
{
|
|
||||||
/* In the absence of an explicit .body directive,
|
|
||||||
the prologue ends after the last instruction
|
|
||||||
covered by an unwind directive. */
|
|
||||||
if (ptr->r.type != body)
|
|
||||||
{
|
|
||||||
last_addr = last->slot_number;
|
|
||||||
last_frag = last->slot_frag;
|
|
||||||
switch (last->r.type)
|
|
||||||
{
|
|
||||||
case frgr_mem:
|
|
||||||
dir_len = (count_bits (last->r.record.p.frmask)
|
|
||||||
+ count_bits (last->r.record.p.grmask));
|
|
||||||
break;
|
|
||||||
case fr_mem:
|
|
||||||
case gr_mem:
|
|
||||||
dir_len += count_bits (last->r.record.p.rmask);
|
|
||||||
break;
|
|
||||||
case br_mem:
|
|
||||||
case br_gr:
|
|
||||||
dir_len += count_bits (last->r.record.p.brmask);
|
|
||||||
break;
|
|
||||||
case gr_gr:
|
|
||||||
dir_len += count_bits (last->r.record.p.grmask);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dir_len = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
size = (slot_index (last_addr, last_frag, first_addr, first_frag)
|
|
||||||
+ dir_len);
|
|
||||||
rlen = ptr->r.record.r.rlen = size;
|
rlen = ptr->r.record.r.rlen = size;
|
||||||
if (ptr->r.type == body)
|
if (ptr->r.type == body)
|
||||||
/* End of region. */
|
/* End of region. */
|
||||||
@ -4081,6 +4046,8 @@ dot_endp (dummy)
|
|||||||
|
|
||||||
insn_group_break (1, 0, 0);
|
insn_group_break (1, 0, 0);
|
||||||
|
|
||||||
|
add_unwind_entry (output_endp ());
|
||||||
|
|
||||||
/* If there wasn't a .handlerdata, we haven't generated an image yet. */
|
/* If there wasn't a .handlerdata, we haven't generated an image yet. */
|
||||||
if (!unwind.info)
|
if (!unwind.info)
|
||||||
generate_unwind_image (text_name);
|
generate_unwind_image (text_name);
|
||||||
|
@ -202,7 +202,7 @@ typedef enum
|
|||||||
bspstore_gr, bspstore_psprel, bspstore_sprel, rnat_when, rnat_gr,
|
bspstore_gr, bspstore_psprel, bspstore_sprel, rnat_when, rnat_gr,
|
||||||
rnat_psprel, rnat_sprel, epilogue, label_state, copy_state,
|
rnat_psprel, rnat_sprel, epilogue, label_state, copy_state,
|
||||||
spill_psprel, spill_sprel, spill_reg, spill_psprel_p, spill_sprel_p,
|
spill_psprel, spill_sprel, spill_reg, spill_psprel_p, spill_sprel_p,
|
||||||
spill_reg_p, unwabi
|
spill_reg_p, unwabi, endp
|
||||||
} unw_record_type;
|
} unw_record_type;
|
||||||
|
|
||||||
/* These structures declare the fields that can be used in each of the
|
/* These structures declare the fields that can be used in each of the
|
||||||
|
Reference in New Issue
Block a user