gas/
* dwarf2dbg.h (dwarf2_move_insn): Declare. * dwarf2dbg.c (line_subseg): Add pmove_tail. (get_line_subseg): Add create_p argument. Initialize pmove_tail. (dwarf2_gen_line_info_1): Update call accordingly. (dwarf2_move_insn): New function. * config/tc-mips.c (append_insn): Use dwarf2_move_insn. gas/testsuite/ * gas/mips/loc-swap-3.d, gas/mips/loc-swap-3.s: New test. * gas/mips/mips.exp: Run it.
This commit is contained in:
parent
6a50d470b7
commit
e410add415
@ -1,3 +1,12 @@
|
||||
2013-06-14 Richard Sandiford <rsandifo@linux.vnet.ibm.com>
|
||||
|
||||
* dwarf2dbg.h (dwarf2_move_insn): Declare.
|
||||
* dwarf2dbg.c (line_subseg): Add pmove_tail.
|
||||
(get_line_subseg): Add create_p argument. Initialize pmove_tail.
|
||||
(dwarf2_gen_line_info_1): Update call accordingly.
|
||||
(dwarf2_move_insn): New function.
|
||||
* config/tc-mips.c (append_insn): Use dwarf2_move_insn.
|
||||
|
||||
2013-06-14 Richard Sandiford <rsandifo@linux.vnet.ibm.com>
|
||||
|
||||
Revert:
|
||||
|
@ -4373,22 +4373,19 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
|
||||
branch_disp = method == APPEND_SWAP ? insn_length (history) : 0;
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
/* The value passed to dwarf2_emit_insn is the distance between
|
||||
the beginning of the current instruction and the address that
|
||||
should be recorded in the debug tables. This is normally the
|
||||
current address.
|
||||
dwarf2_emit_insn (0);
|
||||
/* We want MIPS16 and microMIPS debug info to use ISA-encoded addresses,
|
||||
so "move" the instruction address accordingly.
|
||||
|
||||
For MIPS16/microMIPS debug info we want to use ISA-encoded
|
||||
addresses, so we use -1 for an address higher by one than the
|
||||
current one.
|
||||
|
||||
If the instruction produced is a branch that we will swap with
|
||||
the preceding instruction, then we add the displacement by which
|
||||
the branch will be moved backwards. This is more appropriate
|
||||
and for MIPS16/microMIPS code also prevents a debugger from
|
||||
placing a breakpoint in the middle of the branch (and corrupting
|
||||
code if software breakpoints are used). */
|
||||
dwarf2_emit_insn ((HAVE_CODE_COMPRESSION ? -1 : 0) + branch_disp);
|
||||
Also, it doesn't seem appropriate for the assembler to reorder .loc
|
||||
entries. If this instruction is a branch that we are going to swap
|
||||
with the previous instruction, the two instructions should be
|
||||
treated as a unit, and the debug information for both instructions
|
||||
should refer to the start of the branch sequence. Using the
|
||||
current position is certainly wrong when swapping a 32-bit branch
|
||||
and a 16-bit delay slot, since the current position would then be
|
||||
in the middle of a branch. */
|
||||
dwarf2_move_insn ((HAVE_CODE_COMPRESSION ? 1 : 0) - branch_disp);
|
||||
#endif
|
||||
|
||||
relax32 = (mips_relax_branch
|
||||
|
@ -169,6 +169,7 @@ struct line_subseg {
|
||||
subsegT subseg;
|
||||
struct line_entry *head;
|
||||
struct line_entry **ptail;
|
||||
struct line_entry **pmove_tail;
|
||||
};
|
||||
|
||||
struct line_seg {
|
||||
@ -238,10 +239,10 @@ generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Find or create an entry for SEG+SUBSEG in ALL_SEGS. */
|
||||
/* Find or create (if CREATE_P) an entry for SEG+SUBSEG in ALL_SEGS. */
|
||||
|
||||
static struct line_subseg *
|
||||
get_line_subseg (segT seg, subsegT subseg)
|
||||
get_line_subseg (segT seg, subsegT subseg, bfd_boolean create_p)
|
||||
{
|
||||
static segT last_seg;
|
||||
static subsegT last_subseg;
|
||||
@ -256,6 +257,9 @@ get_line_subseg (segT seg, subsegT subseg)
|
||||
s = (struct line_seg *) hash_find (all_segs_hash, seg->name);
|
||||
if (s == NULL)
|
||||
{
|
||||
if (!create_p)
|
||||
return NULL;
|
||||
|
||||
s = (struct line_seg *) xmalloc (sizeof (*s));
|
||||
s->next = NULL;
|
||||
s->seg = seg;
|
||||
@ -279,6 +283,7 @@ get_line_subseg (segT seg, subsegT subseg)
|
||||
lss->subseg = subseg;
|
||||
lss->head = NULL;
|
||||
lss->ptail = &lss->head;
|
||||
lss->pmove_tail = &lss->head;
|
||||
*pss = lss;
|
||||
|
||||
found_subseg:
|
||||
@ -302,7 +307,7 @@ dwarf2_gen_line_info_1 (symbolS *label, struct dwarf2_line_info *loc)
|
||||
e->label = label;
|
||||
e->loc = *loc;
|
||||
|
||||
lss = get_line_subseg (now_seg, now_subseg);
|
||||
lss = get_line_subseg (now_seg, now_subseg, TRUE);
|
||||
*lss->ptail = e;
|
||||
lss->ptail = &e->next;
|
||||
}
|
||||
@ -396,6 +401,33 @@ dwarf2_emit_insn (int size)
|
||||
dwarf2_consume_line_info ();
|
||||
}
|
||||
|
||||
/* Move all previously-emitted line entries for the current position by
|
||||
DELTA bytes. This function cannot be used to move the same entries
|
||||
twice. */
|
||||
|
||||
void
|
||||
dwarf2_move_insn (int delta)
|
||||
{
|
||||
struct line_subseg *lss;
|
||||
struct line_entry *e;
|
||||
valueT now;
|
||||
|
||||
if (delta == 0)
|
||||
return;
|
||||
|
||||
lss = get_line_subseg (now_seg, now_subseg, FALSE);
|
||||
if (!lss)
|
||||
return;
|
||||
|
||||
now = frag_now_fix ();
|
||||
while ((e = *lss->pmove_tail))
|
||||
{
|
||||
if (S_GET_VALUE (e->label) == now)
|
||||
S_SET_VALUE (e->label, now + delta);
|
||||
lss->pmove_tail = &e->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Called after the current line information has been either used with
|
||||
dwarf2_gen_line_info or saved with a machine instruction for later use.
|
||||
This resets the state of the line number information to reflect that
|
||||
|
@ -74,6 +74,8 @@ extern void dwarf2_gen_line_info (addressT addr, struct dwarf2_line_info *l);
|
||||
/* Must be called for each generated instruction. */
|
||||
extern void dwarf2_emit_insn (int);
|
||||
|
||||
void dwarf2_move_insn (int);
|
||||
|
||||
/* Reset the state of the line number information to reflect that
|
||||
it has been used. */
|
||||
extern void dwarf2_consume_line_info (void);
|
||||
|
@ -1,3 +1,8 @@
|
||||
2013-06-14 Richard Sandiford <rsandifo@linux.vnet.ibm.com>
|
||||
|
||||
* gas/mips/loc-swap-3.d, gas/mips/loc-swap-3.s: New test.
|
||||
* gas/mips/mips.exp: Run it.
|
||||
|
||||
2013-06-13 Chao-ying Fu <Chao-ying.Fu@imgtec.com>
|
||||
|
||||
* gas/mips/micromips@virt.d: New file.
|
||||
|
16
gas/testsuite/gas/mips/loc-swap-3.d
Normal file
16
gas/testsuite/gas/mips/loc-swap-3.d
Normal file
@ -0,0 +1,16 @@
|
||||
#PROG: readelf
|
||||
#readelf: -wl
|
||||
#name: MIPS DWARF-2 location information with branch swapping (3)
|
||||
#...
|
||||
Line Number Statements:
|
||||
.* Set prologue_end to true
|
||||
.* Extended opcode 2: set Address to 0x[01]
|
||||
.* Copy
|
||||
#------------------------------------------------------------------------
|
||||
# There used to be a bogus:
|
||||
# Set prologue_end to true
|
||||
# here
|
||||
#------------------------------------------------------------------------
|
||||
.* Special opcode 6: advance Address by 0 to 0x[01] and Line by 1 to 2
|
||||
.* Advance PC by .*
|
||||
.* Extended opcode 1: End of Sequence
|
6
gas/testsuite/gas/mips/loc-swap-3.s
Normal file
6
gas/testsuite/gas/mips/loc-swap-3.s
Normal file
@ -0,0 +1,6 @@
|
||||
.file 1 "test.cpp"
|
||||
|
||||
.text
|
||||
.loc 1 1 0 prologue_end
|
||||
.loc 1 2 0
|
||||
nop
|
@ -999,6 +999,7 @@ if { [istarget mips*-*-vxworks*] } {
|
||||
run_dump_test_arches "loc-swap-dis" \
|
||||
[mips_arch_list_all]
|
||||
run_dump_test_arches "loc-swap-2" [mips_arch_list_all]
|
||||
run_dump_test_arches "loc-swap-3" [mips_arch_list_all]
|
||||
}
|
||||
|
||||
if $has_newabi {
|
||||
|
Loading…
x
Reference in New Issue
Block a user