mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-29 08:24:05 +08:00
* dw2gencfi.c (cfi_pseudo_table): Add cfi_gnu_window_save.
(dot_cfi, output_cfi_insn): Handle DW_CFA_GNU_window_save. (output_cie): Don't use DW_EH_PE_pcrel if neither DIFF_EXPR_OK nor tc_cfi_emit_pcrel_expr are defined. (output_fde): Use tc_cfi_emit_pcrel_expr if available and DIFF_EXPR_OK is not defined. * config/tc-sparc.h (TARGET_USE_CFIPOP): Define. (tc_cfi_frame_initial_instructions, tc_regname_to_dw2regnum, tc_cfi_emit_pcrel_expr): Define. (sparc_cfi_frame_initial_instructions, sparc_regname_to_dw2regnum, sparc_cfi_emit_pcrel_expr): New prototypes. (sparc_cie_data_alignment): New decl. (DWARF2_DEFAULT_RETURN_COLUMN, DWARF2_CIE_DATA_ALIGNMENT): Define. * config/tc-sparc.c: Include dw2gencfi.h. (sparc_cie_data_alignment): New variable. (md_begin): Initialize it. (sparc_cfi_frame_initial_instructions): New function. (sparc_regname_to_dw2regnum): Likewise. (sparc_cfi_emit_pcrel_expr): Likewise. * doc/as.texinfo: Document .cfi_gnu_window_save. * config/tc-sparc.c (s_common): Cast last argument to long and change format string to shut up warning. testsuite/ * gas/cfi/cfi-sparc-1.s: New test. * gas/cfi/cfi-sparc-1.d: New test. * gas/cfi/cfi-sparc64-1.s: New test. * gas/cfi/cfi-sparc64-1.d: New test. * gas/cfi/cfi.exp: Run them.
This commit is contained in:
@ -1,3 +1,29 @@
|
|||||||
|
2003-08-29 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
* dw2gencfi.c (cfi_pseudo_table): Add cfi_gnu_window_save.
|
||||||
|
(dot_cfi, output_cfi_insn): Handle DW_CFA_GNU_window_save.
|
||||||
|
(output_cie): Don't use DW_EH_PE_pcrel if neither DIFF_EXPR_OK
|
||||||
|
nor tc_cfi_emit_pcrel_expr are defined.
|
||||||
|
(output_fde): Use tc_cfi_emit_pcrel_expr if available and
|
||||||
|
DIFF_EXPR_OK is not defined.
|
||||||
|
* config/tc-sparc.h (TARGET_USE_CFIPOP): Define.
|
||||||
|
(tc_cfi_frame_initial_instructions, tc_regname_to_dw2regnum,
|
||||||
|
tc_cfi_emit_pcrel_expr): Define.
|
||||||
|
(sparc_cfi_frame_initial_instructions, sparc_regname_to_dw2regnum,
|
||||||
|
sparc_cfi_emit_pcrel_expr): New prototypes.
|
||||||
|
(sparc_cie_data_alignment): New decl.
|
||||||
|
(DWARF2_DEFAULT_RETURN_COLUMN, DWARF2_CIE_DATA_ALIGNMENT): Define.
|
||||||
|
* config/tc-sparc.c: Include dw2gencfi.h.
|
||||||
|
(sparc_cie_data_alignment): New variable.
|
||||||
|
(md_begin): Initialize it.
|
||||||
|
(sparc_cfi_frame_initial_instructions): New function.
|
||||||
|
(sparc_regname_to_dw2regnum): Likewise.
|
||||||
|
(sparc_cfi_emit_pcrel_expr): Likewise.
|
||||||
|
* doc/as.texinfo: Document .cfi_gnu_window_save.
|
||||||
|
|
||||||
|
* config/tc-sparc.c (s_common): Cast last argument to long and
|
||||||
|
change format string to shut up warning.
|
||||||
|
|
||||||
2003-08-25 Jason Eckhardt <jle@rice.edu>
|
2003-08-25 Jason Eckhardt <jle@rice.edu>
|
||||||
|
|
||||||
* doc/c-i860.texi: Update text about relocatable address expansions.
|
* doc/c-i860.texi: Update text about relocatable address expansions.
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "subsegs.h"
|
#include "subsegs.h"
|
||||||
|
|
||||||
#include "opcode/sparc.h"
|
#include "opcode/sparc.h"
|
||||||
|
#include "dw2gencfi.h"
|
||||||
|
|
||||||
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
||||||
#include "elf/sparc.h"
|
#include "elf/sparc.h"
|
||||||
@ -116,6 +117,9 @@ static int target_little_endian_data;
|
|||||||
/* Symbols for global registers on v9. */
|
/* Symbols for global registers on v9. */
|
||||||
static symbolS *globals[8];
|
static symbolS *globals[8];
|
||||||
|
|
||||||
|
/* The dwarf2 data alignment, adjusted for 32 or 64 bit. */
|
||||||
|
int sparc_cie_data_alignment;
|
||||||
|
|
||||||
/* V9 and 86x have big and little endian data, but instructions are always big
|
/* V9 and 86x have big and little endian data, but instructions are always big
|
||||||
endian. The sparclet has bi-endian support but both data and insns have
|
endian. The sparclet has bi-endian support but both data and insns have
|
||||||
the same endianness. Global `target_big_endian' is used for data.
|
the same endianness. Global `target_big_endian' is used for data.
|
||||||
@ -798,6 +802,7 @@ md_begin ()
|
|||||||
if (! default_init_p)
|
if (! default_init_p)
|
||||||
init_default_arch ();
|
init_default_arch ();
|
||||||
|
|
||||||
|
sparc_cie_data_alignment = sparc_arch_size == 64 ? -8 : -4;
|
||||||
op_hash = hash_new ();
|
op_hash = hash_new ();
|
||||||
|
|
||||||
while (i < (unsigned int) sparc_num_opcodes)
|
while (i < (unsigned int) sparc_num_opcodes)
|
||||||
@ -3804,8 +3809,8 @@ s_common (ignore)
|
|||||||
{
|
{
|
||||||
if (S_GET_VALUE (symbolP) != (valueT) size)
|
if (S_GET_VALUE (symbolP) != (valueT) size)
|
||||||
{
|
{
|
||||||
as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."),
|
as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
|
||||||
S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
|
S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), (long) size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -4482,4 +4487,63 @@ cons_fix_new_sparc (frag, where, nbytes, exp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
|
fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
|
||||||
|
sparc_cons_special_reloc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sparc_cfi_frame_initial_instructions ()
|
||||||
|
{
|
||||||
|
cfi_add_CFA_def_cfa (14, sparc_arch_size == 64 ? 0x7ff : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sparc_regname_to_dw2regnum (const char *regname)
|
||||||
|
{
|
||||||
|
char *p, *q;
|
||||||
|
|
||||||
|
if (!regname[0])
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
q = "goli";
|
||||||
|
p = strchr (q, regname[0]);
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
if (regname[1] < '0' || regname[1] > '8' || regname[2])
|
||||||
|
return -1;
|
||||||
|
return (p - q) * 8 + regname[1] - '0';
|
||||||
|
}
|
||||||
|
if (regname[0] == 's' && regname[1] == 'p' && !regname[2])
|
||||||
|
return 14;
|
||||||
|
if (regname[0] == 'f' && regname[1] == 'p' && !regname[2])
|
||||||
|
return 30;
|
||||||
|
if (regname[0] == 'f' || regname[0] == 'r')
|
||||||
|
{
|
||||||
|
unsigned int regnum;
|
||||||
|
|
||||||
|
regnum = strtoul (regname + 1, &q, 10);
|
||||||
|
if (p == q || *q)
|
||||||
|
return -1;
|
||||||
|
if (regnum >= ((regname[0] == 'f'
|
||||||
|
&& SPARC_OPCODE_ARCH_V9_P (max_architecture))
|
||||||
|
? 64 : 32))
|
||||||
|
return -1;
|
||||||
|
if (regname[0] == 'f')
|
||||||
|
{
|
||||||
|
regnum += 32;
|
||||||
|
if (regnum >= 64 && (regnum & 1))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return regnum;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sparc_cfi_emit_pcrel_expr (expressionS *exp, unsigned int nbytes)
|
||||||
|
{
|
||||||
|
sparc_cons_special_reloc = "disp";
|
||||||
|
sparc_no_align_cons = 1;
|
||||||
|
emit_expr (exp, nbytes);
|
||||||
|
sparc_no_align_cons = 0;
|
||||||
|
sparc_cons_special_reloc = NULL;
|
||||||
}
|
}
|
||||||
|
@ -174,6 +174,21 @@ extern void cons_fix_new_sparc
|
|||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
#define DWARF2_LINE_MIN_INSN_LENGTH 4
|
#define TARGET_USE_CFIPOP 1
|
||||||
|
|
||||||
|
#define tc_cfi_frame_initial_instructions sparc_cfi_frame_initial_instructions
|
||||||
|
extern void sparc_cfi_frame_initial_instructions PARAMS ((void));
|
||||||
|
|
||||||
|
#define tc_regname_to_dw2regnum sparc_regname_to_dw2regnum
|
||||||
|
extern int sparc_regname_to_dw2regnum PARAMS ((const char *regname));
|
||||||
|
|
||||||
|
#define tc_cfi_emit_pcrel_expr sparc_cfi_emit_pcrel_expr
|
||||||
|
extern void sparc_cfi_emit_pcrel_expr PARAMS ((expressionS *, unsigned int));
|
||||||
|
|
||||||
|
extern int sparc_cie_data_alignment;
|
||||||
|
|
||||||
|
#define DWARF2_LINE_MIN_INSN_LENGTH 4
|
||||||
|
#define DWARF2_DEFAULT_RETURN_COLUMN 15
|
||||||
|
#define DWARF2_CIE_DATA_ALIGNMENT sparc_cie_data_alignment
|
||||||
|
|
||||||
/* end of tc-sparc.h */
|
/* end of tc-sparc.h */
|
||||||
|
@ -4050,6 +4050,9 @@ using the known displacement of the CFA register from the CFA.
|
|||||||
This is often easier to use, because the number will match the
|
This is often easier to use, because the number will match the
|
||||||
code it's annotating.
|
code it's annotating.
|
||||||
|
|
||||||
|
@section @code{.cfi_gnu_window_save}
|
||||||
|
SPARC register window has been saved.
|
||||||
|
|
||||||
@section @code{.cfi_escape} @var{expression}[, @dots{}]
|
@section @code{.cfi_escape} @var{expression}[, @dots{}]
|
||||||
Allows the user to add arbitrary bytes to the unwind info. One
|
Allows the user to add arbitrary bytes to the unwind info. One
|
||||||
might use this to add OS-specific CFI opcodes, or generic CFI
|
might use this to add OS-specific CFI opcodes, or generic CFI
|
||||||
|
@ -374,6 +374,7 @@ const pseudo_typeS cfi_pseudo_table[] =
|
|||||||
{ "cfi_same_value", dot_cfi, DW_CFA_same_value },
|
{ "cfi_same_value", dot_cfi, DW_CFA_same_value },
|
||||||
{ "cfi_remember_state", dot_cfi, DW_CFA_remember_state },
|
{ "cfi_remember_state", dot_cfi, DW_CFA_remember_state },
|
||||||
{ "cfi_restore_state", dot_cfi, DW_CFA_restore_state },
|
{ "cfi_restore_state", dot_cfi, DW_CFA_restore_state },
|
||||||
|
{ "cfi_gnu_window_save", dot_cfi, DW_CFA_GNU_window_save },
|
||||||
{ "cfi_escape", dot_cfi_escape, 0 },
|
{ "cfi_escape", dot_cfi_escape, 0 },
|
||||||
{ NULL, NULL, 0 }
|
{ NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
@ -529,6 +530,10 @@ dot_cfi (int arg)
|
|||||||
cfi_add_CFA_restore_state ();
|
cfi_add_CFA_restore_state ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DW_CFA_GNU_window_save:
|
||||||
|
cfi_add_CFA_insn (DW_CFA_GNU_window_save);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
@ -798,6 +803,10 @@ output_cfi_insn (struct cfi_insn_data *insn)
|
|||||||
out_one (insn->insn);
|
out_one (insn->insn);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DW_CFA_GNU_window_save:
|
||||||
|
out_one (DW_CFA_GNU_window_save);
|
||||||
|
break;
|
||||||
|
|
||||||
case CFI_escape:
|
case CFI_escape:
|
||||||
{
|
{
|
||||||
struct cfi_escape_data *e;
|
struct cfi_escape_data *e;
|
||||||
@ -838,7 +847,11 @@ output_cie (struct cie_entry *cie)
|
|||||||
out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment */
|
out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment */
|
||||||
out_one (cie->return_column); /* Return column */
|
out_one (cie->return_column); /* Return column */
|
||||||
out_uleb128 (1); /* Augmentation size */
|
out_uleb128 (1); /* Augmentation size */
|
||||||
|
#if defined DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
|
||||||
out_one (DW_EH_PE_pcrel | DW_EH_PE_sdata4);
|
out_one (DW_EH_PE_pcrel | DW_EH_PE_sdata4);
|
||||||
|
#else
|
||||||
|
out_one (DW_EH_PE_sdata4);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (cie->first)
|
if (cie->first)
|
||||||
for (i = cie->first; i != cie->last; i = i->next)
|
for (i = cie->first; i != cie->last; i = i->next)
|
||||||
@ -868,9 +881,21 @@ output_fde (struct fde_entry *fde, struct cie_entry *cie,
|
|||||||
exp.X_op_symbol = cie->start_address;
|
exp.X_op_symbol = cie->start_address;
|
||||||
emit_expr (&exp, 4); /* CIE offset */
|
emit_expr (&exp, 4); /* CIE offset */
|
||||||
|
|
||||||
|
#ifdef DIFF_EXPR_OK
|
||||||
exp.X_add_symbol = fde->start_address;
|
exp.X_add_symbol = fde->start_address;
|
||||||
exp.X_op_symbol = symbol_temp_new_now ();
|
exp.X_op_symbol = symbol_temp_new_now ();
|
||||||
emit_expr (&exp, 4); /* Code offset */
|
emit_expr (&exp, 4); /* 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 */
|
||||||
|
#else
|
||||||
|
emit_expr (&exp, 4); /* Code offset */
|
||||||
|
#endif
|
||||||
|
exp.X_op = O_subtract;
|
||||||
|
#endif
|
||||||
|
|
||||||
exp.X_add_symbol = fde->end_address;
|
exp.X_add_symbol = fde->end_address;
|
||||||
exp.X_op_symbol = fde->start_address; /* Code length */
|
exp.X_op_symbol = fde->start_address; /* Code length */
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
2003-08-29 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
* gas/cfi/cfi-sparc-1.s: New test.
|
||||||
|
* gas/cfi/cfi-sparc-1.d: New test.
|
||||||
|
* gas/cfi/cfi-sparc64-1.s: New test.
|
||||||
|
* gas/cfi/cfi-sparc64-1.d: New test.
|
||||||
|
* gas/cfi/cfi.exp: Run them.
|
||||||
|
|
||||||
2003-08-19 Nick Clifton <nickc@redhat.com>
|
2003-08-19 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* gas/arm/copro.s: Add tests of Addressing Mode 5 (Unindexed).
|
* gas/arm/copro.s: Add tests of Addressing Mode 5 (Unindexed).
|
||||||
|
22
gas/testsuite/gas/cfi/cfi-sparc-1.d
Normal file
22
gas/testsuite/gas/cfi/cfi-sparc-1.d
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#readelf: -wf
|
||||||
|
#name: CFI on SPARC 32-bit
|
||||||
|
#as: -32
|
||||||
|
|
||||||
|
The section .eh_frame contains:
|
||||||
|
|
||||||
|
00000000 00000010 00000000 CIE
|
||||||
|
Version: 1
|
||||||
|
Augmentation: "zR"
|
||||||
|
Code alignment factor: 4
|
||||||
|
Data alignment factor: -4
|
||||||
|
Return address column: 15
|
||||||
|
Augmentation data: 1b
|
||||||
|
|
||||||
|
DW_CFA_def_cfa: r14 ofs 0
|
||||||
|
|
||||||
|
00000014 00000014 00000018 FDE cie=00000000 pc=0000001c..00000040
|
||||||
|
DW_CFA_advance_loc: 4 to 00000020
|
||||||
|
DW_CFA_def_cfa_reg: r30
|
||||||
|
DW_CFA_GNU_window_save
|
||||||
|
DW_CFA_register: r15 in r31
|
||||||
|
|
23
gas/testsuite/gas/cfi/cfi-sparc-1.s
Normal file
23
gas/testsuite/gas/cfi/cfi-sparc-1.s
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#; $ as -o test.o -32 gas-cfi-test.s && gcc -m32 -nostdlib -o test test.o
|
||||||
|
|
||||||
|
.file "a.c"
|
||||||
|
.text
|
||||||
|
.align 4
|
||||||
|
.globl foo
|
||||||
|
.type foo, @function
|
||||||
|
foo:
|
||||||
|
.cfi_startproc
|
||||||
|
save %sp, -104, %sp
|
||||||
|
.cfi_def_cfa_register %fp
|
||||||
|
.cfi_gnu_window_save
|
||||||
|
.cfi_register %o7, %i7
|
||||||
|
add %i0, 1, %o0
|
||||||
|
call bar, 0
|
||||||
|
add %i0, 2, %i0
|
||||||
|
call bar, 0
|
||||||
|
mov %i0, %o0
|
||||||
|
add %o0, 3, %o0
|
||||||
|
ret
|
||||||
|
restore %g0, %o0, %o0
|
||||||
|
.cfi_endproc
|
||||||
|
.size foo, .-foo
|
25
gas/testsuite/gas/cfi/cfi-sparc64-1.d
Normal file
25
gas/testsuite/gas/cfi/cfi-sparc64-1.d
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#readelf: -wf
|
||||||
|
#name: CFI on SPARC 64-bit
|
||||||
|
#as: -64
|
||||||
|
|
||||||
|
The section .eh_frame contains:
|
||||||
|
|
||||||
|
00000000 00000011 00000000 CIE
|
||||||
|
Version: 1
|
||||||
|
Augmentation: "zR"
|
||||||
|
Code alignment factor: 4
|
||||||
|
Data alignment factor: -8
|
||||||
|
Return address column: 15
|
||||||
|
Augmentation data: 1b
|
||||||
|
|
||||||
|
DW_CFA_def_cfa: r14 ofs 2047
|
||||||
|
|
||||||
|
00000015 00000017 00000019 FDE cie=00000000 pc=0000001d..0000004d
|
||||||
|
DW_CFA_advance_loc: 4 to 00000021
|
||||||
|
DW_CFA_def_cfa_reg: r30
|
||||||
|
DW_CFA_GNU_window_save
|
||||||
|
DW_CFA_register: r15 in r31
|
||||||
|
DW_CFA_nop
|
||||||
|
DW_CFA_nop
|
||||||
|
DW_CFA_nop
|
||||||
|
|
26
gas/testsuite/gas/cfi/cfi-sparc64-1.s
Normal file
26
gas/testsuite/gas/cfi/cfi-sparc64-1.s
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#; $ as -o test.o -64 gas-cfi-test.s && gcc -m64 -nostdlib -o test test.o
|
||||||
|
|
||||||
|
.file "a.c"
|
||||||
|
.text
|
||||||
|
.align 4
|
||||||
|
.globl foo
|
||||||
|
.type foo, @function
|
||||||
|
foo:
|
||||||
|
.cfi_startproc
|
||||||
|
save %sp, -192, %sp
|
||||||
|
.cfi_def_cfa_register %fp
|
||||||
|
.cfi_gnu_window_save
|
||||||
|
.cfi_register %o7, %i7
|
||||||
|
add %i0, 1, %o0
|
||||||
|
add %i0, 2, %i0
|
||||||
|
call bar, 0
|
||||||
|
sra %o0, 0, %o0
|
||||||
|
sra %i0, 0, %i0
|
||||||
|
call bar, 0
|
||||||
|
mov %i0, %o0
|
||||||
|
add %o0, 3, %o0
|
||||||
|
sra %o0, 0, %o0
|
||||||
|
ret
|
||||||
|
restore %g0, %o0, %o0
|
||||||
|
.cfi_endproc
|
||||||
|
.size foo, .-foo
|
@ -39,6 +39,16 @@ if [istarget "x86_64-*"] then {
|
|||||||
} elseif { [istarget "m68*-*"] } then {
|
} elseif { [istarget "m68*-*"] } then {
|
||||||
run_dump_test "cfi-m68k"
|
run_dump_test "cfi-m68k"
|
||||||
|
|
||||||
|
} elseif { [istarget sparc*-*-*] } then {
|
||||||
|
global NM
|
||||||
|
global NMFLAGS
|
||||||
|
global srcdir
|
||||||
|
|
||||||
|
catch "exec $srcdir/lib/run $NM $NMFLAGS --help" nm_help
|
||||||
|
run_dump_test "cfi-sparc-1"
|
||||||
|
if { [regexp "elf64\[_-\]sparc" $nm_help] } then {
|
||||||
|
run_dump_test "cfi-sparc64-1"
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user