diff options
author | Alan Modra <amodra@gmail.com> | 2006-04-04 08:04:57 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2006-04-04 08:04:57 +0000 |
commit | 99630778988bcd5195fc056fbd013d32d1362d5a (patch) | |
tree | 2dcd9e309b7a988ed9fbe72ea53005e3a2d38b2d /gas/frags.c | |
parent | bb3af66b415e4c7b92894d0aca52119b05d728ec (diff) | |
download | gdb-99630778988bcd5195fc056fbd013d32d1362d5a.zip gdb-99630778988bcd5195fc056fbd013d32d1362d5a.tar.gz gdb-99630778988bcd5195fc056fbd013d32d1362d5a.tar.bz2 |
PR 997
* frags.c (frag_offset_fixed_p): New function.
* frags.h (frag_offset_fixed_p): Declare.
* expr.c (expr): Use frag_offset_fixed_p when simplifying subtraction.
(resolve_expression): Likewise.
Diffstat (limited to 'gas/frags.c')
-rw-r--r-- | gas/frags.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/gas/frags.c b/gas/frags.c index 6dae8bc..cfd183f 100644 --- a/gas/frags.c +++ b/gas/frags.c @@ -1,6 +1,6 @@ /* frags.c - manage frags - Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2003, 2004 + 1999, 2000, 2001, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -383,3 +383,55 @@ frag_append_1_char (int datum) } obstack_1grow (&frchain_now->frch_obstack, datum); } + +/* Return TRUE if FRAG1 and FRAG2 have a fixed relationship between + their start addresses. Set OFFSET to the difference in address + not already accounted for in the frag FR_ADDRESS. */ + +bfd_boolean +frag_offset_fixed_p (fragS *frag1, fragS *frag2, bfd_vma *offset) +{ + fragS *frag; + bfd_vma off; + + /* Start with offset initialised to difference between the two frags. + Prior to assigning frag addresses this will be zero. */ + off = frag1->fr_address - frag2->fr_address; + if (frag1 == frag2) + { + *offset = off; + return TRUE; + } + + /* Maybe frag2 is after frag1. */ + frag = frag1; + while (frag->fr_type == rs_fill) + { + off += frag->fr_fix + frag->fr_offset * frag->fr_var; + frag = frag->fr_next; + if (frag == NULL) + break; + if (frag == frag2) + { + *offset = off; + return TRUE; + } + } + + /* Maybe frag1 is after frag2. */ + frag = frag2; + while (frag->fr_type == rs_fill) + { + off -= frag->fr_fix + frag->fr_offset * frag->fr_var; + frag = frag->fr_next; + if (frag == NULL) + break; + if (frag == frag1) + { + *offset = off; + return TRUE; + } + } + + return FALSE; +} |