aboutsummaryrefslogtreecommitdiff
path: root/gas/dwarf2dbg.c
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/dwarf2dbg.c
parent6a50d470b71ce26110ef91d2679d4565d3a3192e (diff)
downloadfsf-binutils-gdb-e410add4157311809c0b580cf2303bd07c55ea1e.zip
fsf-binutils-gdb-e410add4157311809c0b580cf2303bd07c55ea1e.tar.gz
fsf-binutils-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/dwarf2dbg.c')
-rw-r--r--gas/dwarf2dbg.c38
1 files changed, 35 insertions, 3 deletions
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