mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-28 12:33:36 +08:00
* config/tc-alpha.c (alpha_cur_ent_sym): Remove.
(all_frame_data, plast_frame_data, cur_frame_data): New. (s_alpha_ent): Record data for dwarf2 cfi. (s_alpha_end, s_alpha_mask, s_alpha_frame, s_alpha_prologue): Likewise.[ (alpha_elf_md_end): Emit dwarf2 cfi for ecoff unwind directives. * config/tc-alpha.h (md_end): New. (DWARF2_DEFAULT_RETURN_COLUMN): New. (DWARF2_CIE_DATA_ALIGNMENT): New. * gas/alpha/elf-reloc-8.d: Add .eh_frame relocs. * gas/cfi/cfi-alpha-1.d: New. * gas/cfi/cfi-alpha-1.s: New. * gas/cfi/cfi.exp: Run it.
This commit is contained in:
parent
acf4b81681
commit
f37f01cff7
@ -1,3 +1,13 @@
|
||||
2003-05-29 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/tc-alpha.c (alpha_cur_ent_sym): Remove.
|
||||
(all_frame_data, plast_frame_data, cur_frame_data): New.
|
||||
(s_alpha_ent): Record data for dwarf2 cfi.
|
||||
(s_alpha_end, s_alpha_mask, s_alpha_frame, s_alpha_prologue): Likewise.[ (alpha_elf_md_end): Emit dwarf2 cfi for ecoff unwind directives.
|
||||
* config/tc-alpha.h (md_end): New.
|
||||
(DWARF2_DEFAULT_RETURN_COLUMN): New.
|
||||
(DWARF2_CIE_DATA_ALIGNMENT): New.
|
||||
|
||||
2003-05-29 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* configure.in: Add i386-*-freebsd* entry.
|
||||
|
@ -60,6 +60,7 @@
|
||||
#ifdef OBJ_ELF
|
||||
#include "elf/alpha.h"
|
||||
#include "dwarf2dbg.h"
|
||||
#include "dw2gencfi.h"
|
||||
#endif
|
||||
|
||||
#include "safe-ctype.h"
|
||||
@ -407,11 +408,6 @@ static symbolS *alpha_lit8_symbol;
|
||||
static offsetT alpha_lit8_literal;
|
||||
#endif
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
/* The active .ent symbol. */
|
||||
static symbolS *alpha_cur_ent_sym;
|
||||
#endif
|
||||
|
||||
/* Is the assembler not allowed to use $at? */
|
||||
static int alpha_noat_on = 0;
|
||||
|
||||
@ -4382,6 +4378,25 @@ s_alpha_sdata (ignore)
|
||||
#endif
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
struct alpha_elf_frame_data
|
||||
{
|
||||
symbolS *func_sym;
|
||||
symbolS *func_end_sym;
|
||||
symbolS *prologue_sym;
|
||||
unsigned int mask;
|
||||
unsigned int fmask;
|
||||
int fp_regno;
|
||||
int ra_regno;
|
||||
offsetT frame_size;
|
||||
offsetT mask_offset;
|
||||
offsetT fmask_offset;
|
||||
|
||||
struct alpha_elf_frame_data *next;
|
||||
};
|
||||
|
||||
static struct alpha_elf_frame_data *all_frame_data;
|
||||
static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data;
|
||||
static struct alpha_elf_frame_data *cur_frame_data;
|
||||
|
||||
/* Handle the .section pseudo-op. This is like the usual one, but it
|
||||
clears alpha_insn_label and restores auto alignment. */
|
||||
@ -4418,12 +4433,21 @@ s_alpha_ent (dummy)
|
||||
{
|
||||
symbolS *sym;
|
||||
|
||||
if (alpha_cur_ent_sym)
|
||||
if (cur_frame_data)
|
||||
as_warn (_("nested .ent directives"));
|
||||
|
||||
sym = symbol_find_or_make (name);
|
||||
symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
|
||||
alpha_cur_ent_sym = sym;
|
||||
|
||||
cur_frame_data = calloc (1, sizeof (*cur_frame_data));
|
||||
cur_frame_data->func_sym = sym;
|
||||
|
||||
/* Provide sensible defaults. */
|
||||
cur_frame_data->fp_regno = 30; /* sp */
|
||||
cur_frame_data->ra_regno = 26; /* ra */
|
||||
|
||||
*plast_frame_data = cur_frame_data;
|
||||
plast_frame_data = &cur_frame_data->next;
|
||||
|
||||
/* The .ent directive is sometimes followed by a number. Not sure
|
||||
what it really means, but ignore it. */
|
||||
@ -4463,22 +4487,27 @@ s_alpha_end (dummy)
|
||||
symbolS *sym;
|
||||
|
||||
sym = symbol_find (name);
|
||||
if (sym != alpha_cur_ent_sym)
|
||||
if (!cur_frame_data)
|
||||
as_warn (_(".end directive without matching .ent"));
|
||||
else if (sym != cur_frame_data->func_sym)
|
||||
as_warn (_(".end directive names different symbol than .ent"));
|
||||
|
||||
/* Create an expression to calculate the size of the function. */
|
||||
if (sym)
|
||||
{
|
||||
symbol_get_obj (sym)->size =
|
||||
(expressionS *) xmalloc (sizeof (expressionS));
|
||||
symbol_get_obj (sym)->size->X_op = O_subtract;
|
||||
symbol_get_obj (sym)->size->X_add_symbol
|
||||
= symbol_new ("L0\001", now_seg, frag_now_fix (), frag_now);
|
||||
symbol_get_obj (sym)->size->X_op_symbol = sym;
|
||||
symbol_get_obj (sym)->size->X_add_number = 0;
|
||||
OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
|
||||
expressionS *exp = xmalloc (sizeof (expressionS));
|
||||
|
||||
obj->size = exp;
|
||||
exp->X_op = O_subtract;
|
||||
exp->X_add_symbol = symbol_temp_new_now ();
|
||||
exp->X_op_symbol = sym;
|
||||
exp->X_add_number = 0;
|
||||
|
||||
cur_frame_data->func_end_sym = exp->X_add_symbol;
|
||||
}
|
||||
|
||||
alpha_cur_ent_sym = NULL;
|
||||
cur_frame_data = NULL;
|
||||
|
||||
*input_line_pointer = name_end;
|
||||
}
|
||||
@ -4498,7 +4527,45 @@ s_alpha_mask (fp)
|
||||
ecoff_directive_mask (0);
|
||||
}
|
||||
else
|
||||
discard_rest_of_line ();
|
||||
{
|
||||
long val;
|
||||
offsetT offset;
|
||||
|
||||
if (!cur_frame_data)
|
||||
{
|
||||
if (fp)
|
||||
as_warn (_(".fmask outside of .ent"));
|
||||
else
|
||||
as_warn (_(".mask outside of .ent"));
|
||||
discard_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_absolute_expression_and_terminator (&val) != ',')
|
||||
{
|
||||
if (fp)
|
||||
as_warn (_("bad .fmask directive"));
|
||||
else
|
||||
as_warn (_("bad .mask directive"));
|
||||
--input_line_pointer;
|
||||
discard_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
|
||||
offset = get_absolute_expression ();
|
||||
demand_empty_rest_of_line ();
|
||||
|
||||
if (fp)
|
||||
{
|
||||
cur_frame_data->fmask = val;
|
||||
cur_frame_data->fmask_offset = offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_frame_data->mask = val;
|
||||
cur_frame_data->mask_offset = offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4508,7 +4575,36 @@ s_alpha_frame (dummy)
|
||||
if (ECOFF_DEBUGGING)
|
||||
ecoff_directive_frame (0);
|
||||
else
|
||||
discard_rest_of_line ();
|
||||
{
|
||||
long val;
|
||||
|
||||
if (!cur_frame_data)
|
||||
{
|
||||
as_warn (_(".frame outside of .ent"));
|
||||
discard_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
|
||||
cur_frame_data->fp_regno = tc_get_register (1);
|
||||
|
||||
SKIP_WHITESPACE ();
|
||||
if (*input_line_pointer++ != ','
|
||||
|| get_absolute_expression_and_terminator (&val) != ',')
|
||||
{
|
||||
as_warn (_("bad .frame directive"));
|
||||
--input_line_pointer;
|
||||
discard_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
cur_frame_data->frame_size = val;
|
||||
|
||||
cur_frame_data->ra_regno = tc_get_register (0);
|
||||
|
||||
/* Next comes the "offset of saved $a0 from $sp". In gcc terms
|
||||
this is current_function_pretend_args_size. There's no place
|
||||
to put this value, so ignore it. */
|
||||
s_ignore (42);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4524,7 +4620,7 @@ s_alpha_prologue (ignore)
|
||||
if (ECOFF_DEBUGGING)
|
||||
sym = ecoff_get_cur_proc_sym ();
|
||||
else
|
||||
sym = alpha_cur_ent_sym;
|
||||
sym = cur_frame_data ? cur_frame_data->func_sym : NULL;
|
||||
|
||||
if (sym == NULL)
|
||||
{
|
||||
@ -4549,6 +4645,9 @@ s_alpha_prologue (ignore)
|
||||
as_bad (_("Invalid argument %d to .prologue."), arg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (cur_frame_data)
|
||||
cur_frame_data->prologue_sym = symbol_temp_new_now ();
|
||||
}
|
||||
|
||||
static char *first_file_directive;
|
||||
@ -4642,6 +4741,87 @@ s_alpha_coff_wrapper (which)
|
||||
ignore_rest_of_line ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Called at the end of assembly. Here we emit unwind info for frames
|
||||
unless the compiler has done it for us. */
|
||||
|
||||
void
|
||||
alpha_elf_md_end (void)
|
||||
{
|
||||
struct alpha_elf_frame_data *p;
|
||||
|
||||
if (cur_frame_data)
|
||||
as_warn (_(".ent directive without matching .end"));
|
||||
|
||||
/* If someone has generated the unwind info themselves, great. */
|
||||
if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL)
|
||||
return;
|
||||
|
||||
/* Generate .eh_frame data for the unwind directives specified. */
|
||||
for (p = all_frame_data; p ; p = p->next)
|
||||
if (p->prologue_sym)
|
||||
{
|
||||
/* Create a temporary symbol at the same location as our
|
||||
function symbol. This prevents problems with globals. */
|
||||
cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p->func_sym),
|
||||
S_GET_VALUE (p->func_sym),
|
||||
symbol_get_frag (p->func_sym)));
|
||||
|
||||
cfi_set_return_column (p->ra_regno);
|
||||
cfi_add_CFA_def_cfa_register (30);
|
||||
if (p->fp_regno != 30 || p->mask || p->fmask || p->frame_size)
|
||||
{
|
||||
unsigned int mask;
|
||||
offsetT offset;
|
||||
|
||||
cfi_add_advance_loc (p->prologue_sym);
|
||||
|
||||
if (p->fp_regno != 30)
|
||||
if (p->frame_size != 0)
|
||||
cfi_add_CFA_def_cfa (p->fp_regno, p->frame_size);
|
||||
else
|
||||
cfi_add_CFA_def_cfa_register (p->fp_regno);
|
||||
else if (p->frame_size != 0)
|
||||
cfi_add_CFA_def_cfa_offset (p->frame_size);
|
||||
|
||||
mask = p->mask;
|
||||
offset = p->mask_offset;
|
||||
|
||||
/* Recall that $26 is special-cased and stored first. */
|
||||
if ((mask >> 26) & 1)
|
||||
{
|
||||
cfi_add_CFA_offset (26, offset);
|
||||
offset += 8;
|
||||
mask &= ~(1 << 26);
|
||||
}
|
||||
while (mask)
|
||||
{
|
||||
unsigned int i;
|
||||
i = mask & -mask;
|
||||
mask ^= i;
|
||||
i = ffs (i) - 1;
|
||||
|
||||
cfi_add_CFA_offset (i, offset);
|
||||
offset += 8;
|
||||
}
|
||||
|
||||
mask = p->fmask;
|
||||
offset = p->fmask_offset;
|
||||
while (mask)
|
||||
{
|
||||
unsigned int i;
|
||||
i = mask & -mask;
|
||||
mask ^= i;
|
||||
i = ffs (i) - 1;
|
||||
|
||||
cfi_add_CFA_offset (i + 32, offset);
|
||||
offset += 8;
|
||||
}
|
||||
}
|
||||
|
||||
cfi_end_fde (p->func_end_sym);
|
||||
}
|
||||
}
|
||||
#endif /* OBJ_ELF */
|
||||
|
||||
#ifdef OBJ_EVAX
|
||||
|
@ -128,6 +128,11 @@ extern flagword alpha_elf_section_flags PARAMS ((flagword, int, int));
|
||||
#define tc_frob_file_before_fix() alpha_before_fix ()
|
||||
extern void alpha_before_fix PARAMS ((void));
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
#define md_end alpha_elf_md_end
|
||||
extern void alpha_elf_md_end PARAMS ((void));
|
||||
#endif
|
||||
|
||||
/* New fields for supporting explicit relocations (such as !literal to mark
|
||||
where a pointer is loaded from the global table, and !lituse_base to track
|
||||
all of the normal uses of that pointer). */
|
||||
@ -156,4 +161,6 @@ do { \
|
||||
(long) FIX->tc_fix_data.next_reloc); \
|
||||
} while (0)
|
||||
|
||||
#define DWARF2_LINE_MIN_INSN_LENGTH 4
|
||||
#define DWARF2_LINE_MIN_INSN_LENGTH 4
|
||||
#define DWARF2_DEFAULT_RETURN_COLUMN 26
|
||||
#define DWARF2_CIE_DATA_ALIGNMENT -8
|
||||
|
@ -1,3 +1,10 @@
|
||||
2003-05-29 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* gas/alpha/elf-reloc-8.d: Add .eh_frame relocs.
|
||||
* gas/cfi/cfi-alpha-1.d: New.
|
||||
* gas/cfi/cfi-alpha-1.s: New.
|
||||
* gas/cfi/cfi.exp: Run it.
|
||||
|
||||
2003-05-27 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* gas/cfi/cfi-i386.d: Update for dw2gencfi rewrite.
|
||||
|
@ -307,3 +307,24 @@ OFFSET *TYPE *VALUE
|
||||
0*0000048 REFQUAD \.init\.text\+0x0*00005f0
|
||||
0*0000050 REFQUAD \.init\.data\+0x0*0000029
|
||||
0*0000058 REFQUAD \.init\.text\+0x0*0000610
|
||||
|
||||
|
||||
RELOCATION RECORDS FOR \[\.eh_frame\]:
|
||||
OFFSET *TYPE *VALUE
|
||||
0*000001c SREL32 \.init\.text\+0xf*ffffff8
|
||||
0*0000034 SREL32 \.init\.text\+0x0*0000048
|
||||
0*0000048 SREL32 \.init\.text\+0x0*0000078
|
||||
0*000005c SREL32 \.init\.text\+0x0*00000a8
|
||||
0*0000080 SREL32 \.init\.text\+0x0*00002b8
|
||||
0*00000a0 SREL32 \.init\.text\+0x0*0000598
|
||||
0*00000b8 SREL32 \.init\.text\+0x0*00005e8
|
||||
0*00000cc SREL32 \.init\.text\+0x0*0000608
|
||||
0*00000e0 SREL32 \.init\.text\+0x0*0000628
|
||||
0*00000fc SREL32 \.init\.text\+0x0*0000748
|
||||
0*0000120 SREL32 \.init\.text\+0x0*0000988
|
||||
0*000013c SREL32 \.init\.text\+0x0*0000a08
|
||||
0*0000150 SREL32 \.init\.text\+0x0*0000a18
|
||||
0*0000164 SREL32 \.init\.text\+0x0*0000a38
|
||||
0*000017c SREL32 \.init\.text\+0x0*0000a88
|
||||
0*0000190 SREL32 \.init\.text\+0x0*0000a98
|
||||
0*00001a4 SREL32 \.text\+0xf*ffffff8
|
||||
|
26
gas/testsuite/gas/cfi/cfi-alpha-1.d
Normal file
26
gas/testsuite/gas/cfi/cfi-alpha-1.d
Normal file
@ -0,0 +1,26 @@
|
||||
#readelf: -wf
|
||||
#name: CFI on alpha
|
||||
The section .eh_frame contains:
|
||||
|
||||
00000000 00000010 00000000 CIE
|
||||
Version: 1
|
||||
Augmentation: "zR"
|
||||
Code alignment factor: 4
|
||||
Data alignment factor: -8
|
||||
Return address column: 26
|
||||
Augmentation data: 1b
|
||||
|
||||
DW_CFA_def_cfa_reg: r30
|
||||
DW_CFA_nop
|
||||
|
||||
00000014 0000001c 00000018 FDE cie=00000000 pc=0000001c..00000050
|
||||
DW_CFA_advance_loc: 24 to 00000034
|
||||
DW_CFA_def_cfa: r15 ofs 32
|
||||
DW_CFA_offset: r26 at cfa-32
|
||||
DW_CFA_offset: r9 at cfa-24
|
||||
DW_CFA_offset: r15 at cfa-16
|
||||
DW_CFA_offset: r34 at cfa-8
|
||||
DW_CFA_nop
|
||||
DW_CFA_nop
|
||||
DW_CFA_nop
|
||||
|
28
gas/testsuite/gas/cfi/cfi-alpha-1.s
Normal file
28
gas/testsuite/gas/cfi/cfi-alpha-1.s
Normal file
@ -0,0 +1,28 @@
|
||||
.file 1 "z.c"
|
||||
.set noat
|
||||
.set noreorder
|
||||
.text
|
||||
.align 4
|
||||
.globl f
|
||||
.ent f
|
||||
$f..ng:
|
||||
f:
|
||||
.frame $15,32,$26,0
|
||||
.mask 0x4008200,-32
|
||||
.fmask 0x4,-8
|
||||
lda $30,-32($30)
|
||||
stq $26,0($30)
|
||||
stq $9,8($30)
|
||||
stq $15,16($30)
|
||||
stt $f2,24($30)
|
||||
mov $30,$15
|
||||
.prologue 0
|
||||
mov $15,$30
|
||||
ldq $26,0($30)
|
||||
ldq $9,8($30)
|
||||
ldt $f2,24($30)
|
||||
ldq $15,16($30)
|
||||
lda $30,32($30)
|
||||
ret $31,($26),1
|
||||
.end f
|
||||
.ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.1)"
|
@ -5,3 +5,15 @@ if [istarget "x86_64-*"] then {
|
||||
if [istarget "i?86-*"] then {
|
||||
run_dump_test "cfi-i386"
|
||||
}
|
||||
|
||||
if { [istarget alpha*-*-*] } then {
|
||||
|
||||
set elf [expr [istarget *-*-elf*] \
|
||||
|| [istarget *-*-linux*] \
|
||||
|| [istarget *-*-freebsd*] \
|
||||
|| [istarget *-*-netbsd*] ]
|
||||
|
||||
if $elf {
|
||||
run_dump_test "cfi-alpha-1"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user