gas/
* dwarf2dbg.c (out_sleb128): Delete. (size_fixed_inc_line_addr, emit_fixed_inc_line_addr): New. (out_fixed_inc_line_addr): Delete. (relax_inc_line_addr, dwarf2dbg_estimate_size_before_relax): Call new size_fixed_inc_line_addr if DWARF2_USE_FIXED_ADVANCE_PC is set. (dwarf2dbg_convert_frag): Likewise for emit_fixed_inc_line_addr. (process_entries): Remove calls to out_fixed_inc_line_addr. When DWARF2_USE_FIXED_ADVANCE_PC is set, call relax_inc_line_addr. * read.h (emit_expr_fix): New prototype. * read.c (emit_expr): Move code to emit_expr_fix and use it here. (emit_expr_fix): New. testsuite/ * gas/lns/lns.exp: Run new lns-big-delta test for targets that set DWARF2_USE_FIXED_ADVANCE_PC. * gas/lns/lns-big-delta.s: New. * gas/lns/lns-big-delta.d: New.
This commit is contained in:
parent
39d5313e31
commit
7ddd14deff
@ -1,3 +1,17 @@
|
||||
2008-01-09 Bob Wilson <bob.wilson@acm.org>
|
||||
|
||||
* dwarf2dbg.c (out_sleb128): Delete.
|
||||
(size_fixed_inc_line_addr, emit_fixed_inc_line_addr): New.
|
||||
(out_fixed_inc_line_addr): Delete.
|
||||
(relax_inc_line_addr, dwarf2dbg_estimate_size_before_relax): Call new
|
||||
size_fixed_inc_line_addr if DWARF2_USE_FIXED_ADVANCE_PC is set.
|
||||
(dwarf2dbg_convert_frag): Likewise for emit_fixed_inc_line_addr.
|
||||
(process_entries): Remove calls to out_fixed_inc_line_addr. When
|
||||
DWARF2_USE_FIXED_ADVANCE_PC is set, call relax_inc_line_addr.
|
||||
* read.h (emit_expr_fix): New prototype.
|
||||
* read.c (emit_expr): Move code to emit_expr_fix and use it here.
|
||||
(emit_expr_fix): New.
|
||||
|
||||
2008-01-09 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* config/tc-i386.c (match_template): Check register size
|
||||
|
159
gas/dwarf2dbg.c
159
gas/dwarf2dbg.c
@ -1,5 +1,5 @@
|
||||
/* dwarf2dbg.c - DWARF2 debug support
|
||||
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
||||
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
|
||||
@ -198,13 +198,13 @@ static void out_two (int);
|
||||
static void out_four (int);
|
||||
static void out_abbrev (int, int);
|
||||
static void out_uleb128 (addressT);
|
||||
static void out_sleb128 (addressT);
|
||||
static offsetT get_frag_fix (fragS *, segT);
|
||||
static void out_set_addr (symbolS *);
|
||||
static int size_inc_line_addr (int, addressT);
|
||||
static void emit_inc_line_addr (int, addressT, char *, int);
|
||||
static int size_fixed_inc_line_addr (int, addressT);
|
||||
static void emit_fixed_inc_line_addr (int, addressT, fragS *, char *, int);
|
||||
static void out_inc_line_addr (int, addressT);
|
||||
static void out_fixed_inc_line_addr (int, symbolS *, symbolS *);
|
||||
static void relax_inc_line_addr (int, symbolS *, symbolS *);
|
||||
static void process_entries (segT, struct line_entry *);
|
||||
static void out_file_list (void);
|
||||
@ -762,14 +762,6 @@ out_uleb128 (addressT value)
|
||||
output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
|
||||
}
|
||||
|
||||
/* Emit a signed "little-endian base 128" number. */
|
||||
|
||||
static void
|
||||
out_sleb128 (addressT value)
|
||||
{
|
||||
output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1);
|
||||
}
|
||||
|
||||
/* Emit a tuple for .debug_abbrev. */
|
||||
|
||||
static inline void
|
||||
@ -1005,41 +997,103 @@ out_inc_line_addr (int line_delta, addressT addr_delta)
|
||||
|
||||
/* Write out an alternative form of line and address skips using
|
||||
DW_LNS_fixed_advance_pc opcodes. This uses more space than the default
|
||||
line and address information, but it helps support linker relaxation that
|
||||
changes the code offsets. */
|
||||
line and address information, but it is required if linker relaxation
|
||||
could change the code offsets. The following two routines *must* be
|
||||
kept in sync. */
|
||||
|
||||
static void
|
||||
out_fixed_inc_line_addr (int line_delta, symbolS *to_sym, symbolS *from_sym)
|
||||
static int
|
||||
size_fixed_inc_line_addr (int line_delta, addressT addr_delta)
|
||||
{
|
||||
expressionS expr;
|
||||
int len = 0;
|
||||
|
||||
/* INT_MAX is a signal that this is actually a DW_LNE_end_sequence. */
|
||||
if (line_delta == INT_MAX)
|
||||
{
|
||||
out_opcode (DW_LNS_fixed_advance_pc);
|
||||
expr.X_op = O_subtract;
|
||||
expr.X_add_symbol = to_sym;
|
||||
expr.X_op_symbol = from_sym;
|
||||
expr.X_add_number = 0;
|
||||
emit_expr (&expr, 2);
|
||||
if (line_delta != INT_MAX)
|
||||
len = 1 + sizeof_leb128 (line_delta, 1);
|
||||
|
||||
out_opcode (DW_LNS_extended_op);
|
||||
out_byte (1);
|
||||
out_opcode (DW_LNE_end_sequence);
|
||||
return;
|
||||
if (addr_delta > 50000)
|
||||
{
|
||||
/* DW_LNS_extended_op */
|
||||
len += 1 + sizeof_leb128 (sizeof_address + 1, 0);
|
||||
/* DW_LNE_set_address */
|
||||
len += 1 + sizeof_address;
|
||||
}
|
||||
else
|
||||
/* DW_LNS_fixed_advance_pc */
|
||||
len += 3;
|
||||
|
||||
if (line_delta == INT_MAX)
|
||||
/* DW_LNS_extended_op + DW_LNE_end_sequence */
|
||||
len += 3;
|
||||
else
|
||||
/* DW_LNS_copy */
|
||||
len += 1;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void
|
||||
emit_fixed_inc_line_addr (int line_delta, addressT addr_delta, fragS *frag,
|
||||
char *p, int len)
|
||||
{
|
||||
expressionS *exp;
|
||||
segT line_seg;
|
||||
char *end = p + len;
|
||||
|
||||
/* Line number sequences cannot go backward in addresses. This means
|
||||
we've incorrectly ordered the statements in the sequence. */
|
||||
assert ((offsetT) addr_delta >= 0);
|
||||
|
||||
/* INT_MAX is a signal that this is actually a DW_LNE_end_sequence. */
|
||||
if (line_delta != INT_MAX)
|
||||
{
|
||||
*p++ = DW_LNS_advance_line;
|
||||
p += output_leb128 (p, line_delta, 1);
|
||||
}
|
||||
|
||||
out_opcode (DW_LNS_advance_line);
|
||||
out_sleb128 (line_delta);
|
||||
exp = symbol_get_value_expression (frag->fr_symbol);
|
||||
line_seg = subseg_get (".debug_line", 0);
|
||||
|
||||
out_opcode (DW_LNS_fixed_advance_pc);
|
||||
expr.X_op = O_subtract;
|
||||
expr.X_add_symbol = to_sym;
|
||||
expr.X_op_symbol = from_sym;
|
||||
expr.X_add_number = 0;
|
||||
emit_expr (&expr, 2);
|
||||
/* The DW_LNS_fixed_advance_pc opcode has a 2-byte operand so it can
|
||||
advance the address by at most 64K. Linker relaxation (without
|
||||
which this function would not be used) could change the operand by
|
||||
an unknown amount. If the address increment is getting close to
|
||||
the limit, just reset the address. */
|
||||
if (addr_delta > 50000)
|
||||
{
|
||||
symbolS *to_sym;
|
||||
expressionS expr;
|
||||
|
||||
out_opcode (DW_LNS_copy);
|
||||
assert (exp->X_op = O_subtract);
|
||||
to_sym = exp->X_add_symbol;
|
||||
|
||||
*p++ = DW_LNS_extended_op;
|
||||
p += output_leb128 (p, sizeof_address + 1, 0);
|
||||
*p++ = DW_LNE_set_address;
|
||||
expr.X_op = O_symbol;
|
||||
expr.X_add_symbol = to_sym;
|
||||
expr.X_add_number = 0;
|
||||
subseg_change (line_seg, 0);
|
||||
emit_expr_fix (&expr, sizeof_address, frag, p);
|
||||
p += sizeof_address;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = DW_LNS_fixed_advance_pc;
|
||||
subseg_change (line_seg, 0);
|
||||
emit_expr_fix (exp, 2, frag, p);
|
||||
p += 2;
|
||||
}
|
||||
|
||||
if (line_delta == INT_MAX)
|
||||
{
|
||||
*p++ = DW_LNS_extended_op;
|
||||
*p++ = 1;
|
||||
*p++ = DW_LNE_end_sequence;
|
||||
}
|
||||
else
|
||||
*p++ = DW_LNS_copy;
|
||||
|
||||
assert (p == end);
|
||||
}
|
||||
|
||||
/* Generate a variant frag that we can use to relax address/line
|
||||
@ -1058,7 +1112,11 @@ relax_inc_line_addr (int line_delta, symbolS *to_sym, symbolS *from_sym)
|
||||
|
||||
/* The maximum size of the frag is the line delta with a maximum
|
||||
sized address delta. */
|
||||
max_chars = size_inc_line_addr (line_delta, -DWARF2_LINE_MIN_INSN_LENGTH);
|
||||
if (DWARF2_USE_FIXED_ADVANCE_PC)
|
||||
max_chars = size_fixed_inc_line_addr (line_delta,
|
||||
-DWARF2_LINE_MIN_INSN_LENGTH);
|
||||
else
|
||||
max_chars = size_inc_line_addr (line_delta, -DWARF2_LINE_MIN_INSN_LENGTH);
|
||||
|
||||
frag_var (rs_dwarf2dbg, max_chars, max_chars, 1,
|
||||
make_expr_symbol (&expr), line_delta, NULL);
|
||||
@ -1075,7 +1133,10 @@ dwarf2dbg_estimate_size_before_relax (fragS *frag)
|
||||
int size;
|
||||
|
||||
addr_delta = resolve_symbol_value (frag->fr_symbol);
|
||||
size = size_inc_line_addr (frag->fr_offset, addr_delta);
|
||||
if (DWARF2_USE_FIXED_ADVANCE_PC)
|
||||
size = size_fixed_inc_line_addr (frag->fr_offset, addr_delta);
|
||||
else
|
||||
size = size_inc_line_addr (frag->fr_offset, addr_delta);
|
||||
|
||||
frag->fr_subtype = size;
|
||||
|
||||
@ -1113,8 +1174,13 @@ dwarf2dbg_convert_frag (fragS *frag)
|
||||
course, have allocated enough memory earlier. */
|
||||
assert (frag->fr_var >= (int) frag->fr_subtype);
|
||||
|
||||
emit_inc_line_addr (frag->fr_offset, addr_diff,
|
||||
frag->fr_literal + frag->fr_fix, frag->fr_subtype);
|
||||
if (DWARF2_USE_FIXED_ADVANCE_PC)
|
||||
emit_fixed_inc_line_addr (frag->fr_offset, addr_diff, frag,
|
||||
frag->fr_literal + frag->fr_fix,
|
||||
frag->fr_subtype);
|
||||
else
|
||||
emit_inc_line_addr (frag->fr_offset, addr_diff,
|
||||
frag->fr_literal + frag->fr_fix, frag->fr_subtype);
|
||||
|
||||
frag->fr_fix += frag->fr_subtype;
|
||||
frag->fr_type = rs_fill;
|
||||
@ -1192,9 +1258,7 @@ process_entries (segT seg, struct line_entry *e)
|
||||
out_set_addr (lab);
|
||||
out_inc_line_addr (line_delta, 0);
|
||||
}
|
||||
else if (DWARF2_USE_FIXED_ADVANCE_PC)
|
||||
out_fixed_inc_line_addr (line_delta, lab, last_lab);
|
||||
else if (frag == last_frag)
|
||||
else if (frag == last_frag && ! DWARF2_USE_FIXED_ADVANCE_PC)
|
||||
out_inc_line_addr (line_delta, frag_ofs - last_frag_ofs);
|
||||
else
|
||||
relax_inc_line_addr (line_delta, lab, last_lab);
|
||||
@ -1213,12 +1277,7 @@ process_entries (segT seg, struct line_entry *e)
|
||||
/* Emit a DW_LNE_end_sequence for the end of the section. */
|
||||
frag = last_frag_for_seg (seg);
|
||||
frag_ofs = get_frag_fix (frag, seg);
|
||||
if (DWARF2_USE_FIXED_ADVANCE_PC)
|
||||
{
|
||||
lab = symbol_temp_new (seg, frag_ofs, frag);
|
||||
out_fixed_inc_line_addr (INT_MAX, lab, last_lab);
|
||||
}
|
||||
else if (frag == last_frag)
|
||||
if (frag == last_frag && ! DWARF2_USE_FIXED_ADVANCE_PC)
|
||||
out_inc_line_addr (INT_MAX, frag_ofs - last_frag_ofs);
|
||||
else
|
||||
{
|
||||
|
62
gas/read.c
62
gas/read.c
@ -1,6 +1,6 @@
|
||||
/* read.c - read a source file -
|
||||
Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
||||
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
@ -4175,41 +4175,45 @@ emit_expr (expressionS *exp, unsigned int nbytes)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (p, 0, nbytes);
|
||||
emit_expr_fix (exp, nbytes, frag_now, p);
|
||||
}
|
||||
|
||||
/* Now we need to generate a fixS to record the symbol value. */
|
||||
void
|
||||
emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p)
|
||||
{
|
||||
memset (p, 0, nbytes);
|
||||
|
||||
/* Generate a fixS to record the symbol value. */
|
||||
|
||||
#ifdef TC_CONS_FIX_NEW
|
||||
TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
|
||||
TC_CONS_FIX_NEW (frag, p - frag->fr_literal, nbytes, exp);
|
||||
#else
|
||||
{
|
||||
bfd_reloc_code_real_type r;
|
||||
{
|
||||
bfd_reloc_code_real_type r;
|
||||
|
||||
switch (nbytes)
|
||||
{
|
||||
case 1:
|
||||
r = BFD_RELOC_8;
|
||||
break;
|
||||
case 2:
|
||||
r = BFD_RELOC_16;
|
||||
break;
|
||||
case 4:
|
||||
r = BFD_RELOC_32;
|
||||
break;
|
||||
case 8:
|
||||
r = BFD_RELOC_64;
|
||||
break;
|
||||
default:
|
||||
as_bad (_("unsupported BFD relocation size %u"), nbytes);
|
||||
r = BFD_RELOC_32;
|
||||
break;
|
||||
}
|
||||
fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp,
|
||||
0, r);
|
||||
switch (nbytes)
|
||||
{
|
||||
case 1:
|
||||
r = BFD_RELOC_8;
|
||||
break;
|
||||
case 2:
|
||||
r = BFD_RELOC_16;
|
||||
break;
|
||||
case 4:
|
||||
r = BFD_RELOC_32;
|
||||
break;
|
||||
case 8:
|
||||
r = BFD_RELOC_64;
|
||||
break;
|
||||
default:
|
||||
as_bad (_("unsupported BFD relocation size %u"), nbytes);
|
||||
r = BFD_RELOC_32;
|
||||
break;
|
||||
}
|
||||
fix_new_exp (frag, p - frag->fr_literal, (int) nbytes, exp,
|
||||
0, r);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BITFIELD_CONS_EXPRESSIONS
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* read.h - of read.c
|
||||
Copyright 1986, 1990, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
2000, 2001, 2002, 2003, 2004, 2005, 2007
|
||||
2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
@ -111,6 +111,7 @@ extern void add_include_dir (char *path);
|
||||
extern void cons (int nbytes);
|
||||
extern void demand_empty_rest_of_line (void);
|
||||
extern void emit_expr (expressionS *exp, unsigned int nbytes);
|
||||
extern void emit_expr_fix (expressionS *, unsigned int, fragS *, char *);
|
||||
extern void equals (char *sym_name, int reassign);
|
||||
extern void float_cons (int float_type);
|
||||
extern void ignore_rest_of_line (void);
|
||||
|
@ -1,3 +1,10 @@
|
||||
2008-01-09 Bob Wilson <bob.wilson@acm.org>
|
||||
|
||||
* gas/lns/lns.exp: Run new lns-big-delta test for targets that set
|
||||
DWARF2_USE_FIXED_ADVANCE_PC.
|
||||
* gas/lns/lns-big-delta.s: New.
|
||||
* gas/lns/lns-big-delta.d: New.
|
||||
|
||||
2008-01-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
|
||||
|
||||
PR gas/5322
|
||||
|
14
gas/testsuite/gas/lns/lns-big-delta.d
Normal file
14
gas/testsuite/gas/lns/lns-big-delta.d
Normal file
@ -0,0 +1,14 @@
|
||||
#source: lns-big-delta.s
|
||||
#readelf: -wl
|
||||
#name: lns-big-delta
|
||||
Dump of debug contents of section \.debug_line:
|
||||
#...
|
||||
Line Number Statements:
|
||||
Extended opcode 2: set Address to .*
|
||||
Copy
|
||||
Advance Line by 1 to 2
|
||||
Extended opcode 2: set Address to .*
|
||||
Copy
|
||||
Advance PC by fixed size amount 0 to .*
|
||||
Extended opcode 1: End of Sequence
|
||||
#pass
|
5
gas/testsuite/gas/lns/lns-big-delta.s
Normal file
5
gas/testsuite/gas/lns/lns-big-delta.s
Normal file
@ -0,0 +1,5 @@
|
||||
.file 1 "foo.c"
|
||||
.loc 1 1 0
|
||||
.loc 1 2 0
|
||||
.space 75000
|
||||
.loc 1 3 0
|
@ -22,6 +22,7 @@ if {
|
||||
# Use alternate file for targets using DW_LNS_fixed_advance_pc opcodes.
|
||||
if { [istarget xtensa-*-*] } {
|
||||
run_dump_test "lns-common-1-alt"
|
||||
run_dump_test "lns-big-delta"
|
||||
} elseif { [istarget ia64*-*-*] } {
|
||||
run_dump_test "lns-common-1" { { source "lns-common-1-ia64.s" } }
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user