mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
gas: permit LEB128 operands for .cfi_escape
Many DW_CFA_* and DW_OP_* take LEB128 operands. Having to hand-encode such when needing to resort to .cfi_escape isn't very helpful.
This commit is contained in:
@@ -5176,7 +5176,18 @@ SPARC register window has been saved.
|
|||||||
@subsection @code{.cfi_escape} @var{expression}[, @dots{}]
|
@subsection @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
|
||||||
opcodes that GAS does not yet support.
|
opcodes that GAS does not yet support. To emit multi-byte data one may
|
||||||
|
also use extended kind-of-expression forms:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
|
||||||
|
@item @code{sleb128(@var{expression})}
|
||||||
|
to emit a SLEB128 item,
|
||||||
|
|
||||||
|
@item @code{uleb128(@var{expression})}
|
||||||
|
to emit a ULEB128 item.
|
||||||
|
|
||||||
|
@end itemize
|
||||||
|
|
||||||
@subsection @code{.cfi_val_encoded_addr @var{register}, @var{encoding}, @var{label}}
|
@subsection @code{.cfi_val_encoded_addr @var{register}, @var{encoding}, @var{label}}
|
||||||
The current value of @var{register} is @var{label}. The value of @var{label}
|
The current value of @var{register} is @var{label}. The value of @var{label}
|
||||||
|
|||||||
@@ -941,7 +941,7 @@ dot_cfi (int arg)
|
|||||||
static void
|
static void
|
||||||
dot_cfi_escape (int ignored ATTRIBUTE_UNUSED)
|
dot_cfi_escape (int ignored ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
struct cfi_escape_data *head, **tail, *e;
|
struct cfi_escape_data *head, **tail;
|
||||||
struct cfi_insn_data *insn;
|
struct cfi_insn_data *insn;
|
||||||
|
|
||||||
if (frchain_now->frch_cfi_data == NULL)
|
if (frchain_now->frch_cfi_data == NULL)
|
||||||
@@ -960,8 +960,39 @@ dot_cfi_escape (int ignored ATTRIBUTE_UNUSED)
|
|||||||
tail = &head;
|
tail = &head;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
e = notes_alloc (sizeof (*e));
|
struct cfi_escape_data *e = notes_alloc (sizeof (*e));
|
||||||
e->reloc = do_parse_cons_expression (&e->exp, 1);
|
char *id, *ilp_save = input_line_pointer;
|
||||||
|
char c = get_symbol_name (&id);
|
||||||
|
|
||||||
|
if (strcmp (id, "sleb128") == 0)
|
||||||
|
e->type = CFI_ESC_sleb128;
|
||||||
|
else if (strcmp (id, "uleb128") == 0)
|
||||||
|
e->type = CFI_ESC_uleb128;
|
||||||
|
else
|
||||||
|
e->type = CFI_ESC_byte;
|
||||||
|
|
||||||
|
c = restore_line_pointer (c);
|
||||||
|
|
||||||
|
if (e->type != CFI_ESC_byte)
|
||||||
|
{
|
||||||
|
if (is_whitespace (c))
|
||||||
|
c = *++input_line_pointer;
|
||||||
|
if (c != '(')
|
||||||
|
{
|
||||||
|
input_line_pointer = ilp_save;
|
||||||
|
e->type = CFI_ESC_byte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e->type == CFI_ESC_sleb128 || e->type == CFI_ESC_uleb128)
|
||||||
|
{
|
||||||
|
/* We're still at the opening parenthesis. Leave it to expression()
|
||||||
|
to parse it and find the matching closing one. */
|
||||||
|
expression (&e->exp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
e->reloc = do_parse_cons_expression (&e->exp, 1);
|
||||||
|
|
||||||
*tail = e;
|
*tail = e;
|
||||||
tail = &e->next;
|
tail = &e->next;
|
||||||
}
|
}
|
||||||
@@ -1778,7 +1809,12 @@ output_cfi_insn (struct cfi_insn_data *insn)
|
|||||||
{
|
{
|
||||||
struct cfi_escape_data *e;
|
struct cfi_escape_data *e;
|
||||||
for (e = insn->u.esc; e ; e = e->next)
|
for (e = insn->u.esc; e ; e = e->next)
|
||||||
emit_expr_with_reloc (&e->exp, 1, e->reloc);
|
{
|
||||||
|
if (e->type == CFI_ESC_sleb128 || e->type == CFI_ESC_uleb128)
|
||||||
|
emit_leb128_expr (&e->exp, e->type == CFI_ESC_sleb128);
|
||||||
|
else
|
||||||
|
emit_expr_with_reloc (&e->exp, 1, e->reloc);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,11 @@ struct cfi_escape_data
|
|||||||
{
|
{
|
||||||
struct cfi_escape_data *next;
|
struct cfi_escape_data *next;
|
||||||
expressionS exp;
|
expressionS exp;
|
||||||
|
enum {
|
||||||
|
CFI_ESC_byte,
|
||||||
|
CFI_ESC_sleb128,
|
||||||
|
CFI_ESC_uleb128,
|
||||||
|
} type;
|
||||||
TC_PARSE_CONS_RETURN_TYPE reloc;
|
TC_PARSE_CONS_RETURN_TYPE reloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1345,6 +1345,7 @@ sframe_xlate_do_escape_expr (const struct sframe_xlate_ctx *xlate_ctx,
|
|||||||
|| i >= CFI_ESC_NUM_EXP
|
|| i >= CFI_ESC_NUM_EXP
|
||||||
|| (i < 2
|
|| (i < 2
|
||||||
&& (e->exp.X_op != O_constant
|
&& (e->exp.X_op != O_constant
|
||||||
|
|| e->type != CFI_ESC_byte
|
||||||
|| e->reloc != TC_PARSE_CONS_RETURN_NONE)))
|
|| e->reloc != TC_PARSE_CONS_RETURN_NONE)))
|
||||||
goto warn_and_exit;
|
goto warn_and_exit;
|
||||||
items[i] = e->exp.X_add_number;
|
items[i] = e->exp.X_add_number;
|
||||||
@@ -1409,6 +1410,7 @@ sframe_xlate_do_escape_val_offset (const struct sframe_xlate_ctx *xlate_ctx,
|
|||||||
{
|
{
|
||||||
e = e->next;
|
e = e->next;
|
||||||
if (i >= CFI_ESC_NUM_EXP || e->exp.X_op != O_constant
|
if (i >= CFI_ESC_NUM_EXP || e->exp.X_op != O_constant
|
||||||
|
|| e->type != CFI_ESC_byte
|
||||||
|| e->reloc != TC_PARSE_CONS_RETURN_NONE)
|
|| e->reloc != TC_PARSE_CONS_RETURN_NONE)
|
||||||
goto warn_and_exit;
|
goto warn_and_exit;
|
||||||
items[i] = e->exp.X_add_number;
|
items[i] = e->exp.X_add_number;
|
||||||
@@ -1483,7 +1485,9 @@ sframe_xlate_do_cfi_escape (const struct sframe_xlate_ctx *xlate_ctx,
|
|||||||
if (!e)
|
if (!e)
|
||||||
return SFRAME_XLATE_ERR_INVAL;
|
return SFRAME_XLATE_ERR_INVAL;
|
||||||
|
|
||||||
if (e->exp.X_op != O_constant || e->reloc != TC_PARSE_CONS_RETURN_NONE)
|
if (e->exp.X_op != O_constant
|
||||||
|
|| e->type != CFI_ESC_byte
|
||||||
|
|| e->reloc != TC_PARSE_CONS_RETURN_NONE)
|
||||||
return SFRAME_XLATE_ERR_NOTREPRESENTED;
|
return SFRAME_XLATE_ERR_NOTREPRESENTED;
|
||||||
|
|
||||||
firstop = e->exp.X_add_number;
|
firstop = e->exp.X_add_number;
|
||||||
@@ -1495,6 +1499,7 @@ sframe_xlate_do_cfi_escape (const struct sframe_xlate_ctx *xlate_ctx,
|
|||||||
{
|
{
|
||||||
e = e->next;
|
e = e->next;
|
||||||
if (e->exp.X_op != O_constant || e->exp.X_add_number != DW_CFA_nop
|
if (e->exp.X_op != O_constant || e->exp.X_add_number != DW_CFA_nop
|
||||||
|
|| e->type != CFI_ESC_byte
|
||||||
|| e->reloc != TC_PARSE_CONS_RETURN_NONE)
|
|| e->reloc != TC_PARSE_CONS_RETURN_NONE)
|
||||||
{
|
{
|
||||||
warn_p = true;
|
warn_p = true;
|
||||||
|
|||||||
@@ -20,8 +20,20 @@
|
|||||||
[ ]*[0-9]*[ ]+([0-9a-f]{4} [0 ]+)?\.cfi_endproc
|
[ ]*[0-9]*[ ]+([0-9a-f]{4} [0 ]+)?\.cfi_endproc
|
||||||
[ ]*[0-9]*[ ]*
|
[ ]*[0-9]*[ ]*
|
||||||
[ ]*[0-9]*[ ]+func2:
|
[ ]*[0-9]*[ ]+func2:
|
||||||
[ ]*[0-9]*[ ]+[0-9a-f]{4} (1[048]00 ?0000|0000 ?001[048])[ ]+\.cfi_startproc
|
[ ]*[0-9]*[ ]+[0-9a-f]{4} ((1C|2[048])00 ?0000|0000 ?00(1C|2[048]))[ ]+\.cfi_startproc
|
||||||
[ ]*[0-9]*[ ]+(4[048]00 ?0000|0000 ?004[048]) *
|
[ ]*[0-9]*[ ]+(4[048]00 ?0000|0000 ?004[048]) *
|
||||||
[ ]*[0-9]*[ ]+[0-9a-f]{4} .*[ ]\.nop
|
[ ]*[0-9]*[ ]+[0-9a-f]{4} .*[ ]\.nop
|
||||||
|
[ ]*[0-9]*[ ]+/\* DW_CFA_register reg127, reg129. \*/
|
||||||
|
[ ]*[0-9]*[ ]+[0-9a-f]{4} 4.09 ?7F81[ ]+\.cfi_escape 0x09, uleb128\(127\), uleb128\(129\)
|
||||||
|
[ ]*[0-9]*[ ]+01
|
||||||
|
[ ]*[0-9]*[ ]+/\* DW_CFA_val_expression reg250, ... \*/
|
||||||
|
[ ]*[0-9]*[ ]+[0-9a-f]{4} 16FA ?01[ ]+\.cfi_escape 0x16, uleb128\(250\)
|
||||||
|
[ ]*[0-9]*[ ]+/\* ... <len>. \*/
|
||||||
|
[ ]*[0-9]*[ ]+[0-9a-f]{4} 03[ ]+\.cfi_escape uleb128\(.LE0e - .LE0s\)
|
||||||
|
[ ]*[0-9]*[ ]+\.cfi_label .LE0s
|
||||||
|
[ ]*[0-9]*[ ]+/\* DW_OP_breg3. \*/
|
||||||
|
[ ]*[0-9]*[ ]+[0-9a-f]{4} 7380 ?78[ ]+\.cfi_escape 0x73, sleb128\(-1024\)
|
||||||
|
[ ]*[0-9]*[ ]+\.cfi_label .LE0e
|
||||||
|
[ ]*[0-9]*[ ]+[0-9a-f]{4} .*[ ]\.nop
|
||||||
[ ]*[0-9]*[ ]+([0-9a-f]{4} [0 ]+)?\.cfi_endproc
|
[ ]*[0-9]*[ ]+([0-9a-f]{4} [0 ]+)?\.cfi_endproc
|
||||||
#pass
|
#pass
|
||||||
|
|||||||
@@ -19,4 +19,15 @@ func:
|
|||||||
func2:
|
func2:
|
||||||
.cfi_startproc
|
.cfi_startproc
|
||||||
.nop
|
.nop
|
||||||
|
/* DW_CFA_register reg127, reg129. */
|
||||||
|
.cfi_escape 0x09, uleb128(127), uleb128(129)
|
||||||
|
/* DW_CFA_val_expression reg250, ... */
|
||||||
|
.cfi_escape 0x16, uleb128(250)
|
||||||
|
/* ... <len>. */
|
||||||
|
.cfi_escape uleb128(.LE0e - .LE0s)
|
||||||
|
.cfi_label .LE0s
|
||||||
|
/* DW_OP_breg3. */
|
||||||
|
.cfi_escape 0x73, sleb128(-1024)
|
||||||
|
.cfi_label .LE0e
|
||||||
|
.nop
|
||||||
.cfi_endproc
|
.cfi_endproc
|
||||||
|
|||||||
Reference in New Issue
Block a user