aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2013-06-14 13:30:28 +0000
committerRichard Sandiford <rdsandiford@googlemail.com>2013-06-14 13:30:28 +0000
commite410add4157311809c0b580cf2303bd07c55ea1e (patch)
tree0c7d805e894dd462976744ceeb1c9fbad0eb55e0 /gas
parent6a50d470b71ce26110ef91d2679d4565d3a3192e (diff)
downloadgdb-e410add4157311809c0b580cf2303bd07c55ea1e.zip
gdb-e410add4157311809c0b580cf2303bd07c55ea1e.tar.gz
gdb-e410add4157311809c0b580cf2303bd07c55ea1e.tar.bz2
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.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog9
-rw-r--r--gas/config/tc-mips.c29
-rw-r--r--gas/dwarf2dbg.c38
-rw-r--r--gas/dwarf2dbg.h2
-rw-r--r--gas/testsuite/ChangeLog5
-rw-r--r--gas/testsuite/gas/mips/loc-swap-3.d16
-rw-r--r--gas/testsuite/gas/mips/loc-swap-3.s6
-rw-r--r--gas/testsuite/gas/mips/mips.exp1
8 files changed, 87 insertions, 19 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index dbe82bb..fb59e46 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,14 @@
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:
2011-09-05 Richard Sandiford <rdsandiford@googlemail.com>
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 468e40f..106f754 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -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.
-
- 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);
+ dwarf2_emit_insn (0);
+ /* We want MIPS16 and microMIPS debug info to use ISA-encoded addresses,
+ so "move" the instruction address accordingly.
+
+ 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
diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index f5623f6..6d6ee2d 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -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
diff --git a/gas/dwarf2dbg.h b/gas/dwarf2dbg.h
index 05c7bee..84ef8f6 100644
--- a/gas/dwarf2dbg.h
+++ b/gas/dwarf2dbg.h
@@ -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);
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 9a11bb16..aa57f27 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -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.
diff --git a/gas/testsuite/gas/mips/loc-swap-3.d b/gas/testsuite/gas/mips/loc-swap-3.d
new file mode 100644
index 0000000..9fc5e56
--- /dev/null
+++ b/gas/testsuite/gas/mips/loc-swap-3.d
@@ -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
diff --git a/gas/testsuite/gas/mips/loc-swap-3.s b/gas/testsuite/gas/mips/loc-swap-3.s
new file mode 100644
index 0000000..1e4eb9a
--- /dev/null
+++ b/gas/testsuite/gas/mips/loc-swap-3.s
@@ -0,0 +1,6 @@
+ .file 1 "test.cpp"
+
+ .text
+ .loc 1 1 0 prologue_end
+ .loc 1 2 0
+ nop
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index a0ba481..e00b3f2 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -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 {