X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Ffrags.c;h=f35cc80a386ed0dd6e04af32e9ba7cb520ecb437;hb=0ac2b354ee006d94d6fc46bea08f39f99b18f869;hp=a9fc003fbdf05b1d6dc9e0384367d108e84aca17;hpb=871a6bd2d852b0fb677386e1be78c3f4c6939b48;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/frags.c b/gas/frags.c index a9fc003fbd..f35cc80a38 100644 --- a/gas/frags.c +++ b/gas/frags.c @@ -395,7 +395,12 @@ frag_now_fix_octets (void) addressT frag_now_fix (void) { - return frag_now_fix_octets () / OCTETS_PER_BYTE; + /* Symbols whose section has SEC_ELF_OCTETS set, + resolve to octets instead of target bytes. */ + if (now_seg->flags & SEC_OCTETS) + return frag_now_fix_octets (); + else + return frag_now_fix_octets () / OCTETS_PER_BYTE; } void @@ -462,3 +467,58 @@ frag_offset_fixed_p (const fragS *frag1, const fragS *frag2, offsetT *offset) return FALSE; } + +/* Return TRUE if we can determine whether FRAG2 OFF2 appears after + (strict >, not >=) FRAG1 OFF1, assuming it is not before. Set + *OFFSET so that resolve_expression will resolve an O_gt operation + between them to false (0) if they are guaranteed to be at the same + location, or to true (-1) if they are guaranteed to be at different + locations. Return FALSE conservatively, e.g. if neither result can + be guaranteed (yet). + + They are known to be in the same segment, and not the same frag + (this is a fallback for frag_offset_fixed_p, that always takes care + of this case), and it is expected (from the uses this is designed + to simplify, namely location view increments) that frag2 is + reachable from frag1 following the fr_next links, rather than the + other way round. */ + +bfd_boolean +frag_gtoffset_p (valueT off2, const fragS *frag2, + valueT off1, const fragS *frag1, offsetT *offset) +{ + /* Insanity check. */ + if (frag2 == frag1 || off1 > frag1->fr_fix) + return FALSE; + + /* If the first symbol offset is at the end of the first frag and + the second symbol offset at the beginning of the second frag then + it is possible they are at the same address. Go looking for a + non-zero fr_fix in any frag between these frags. If found then + we can say the O_gt result will be true. If no such frag is + found we assume that frag1 or any of the following frags might + have a variable tail and thus the answer is unknown. This isn't + strictly true; some frags don't have a variable tail, but it + doesn't seem worth optimizing for those cases. */ + const fragS *frag = frag1; + offsetT delta = off2 - off1; + for (;;) + { + delta += frag->fr_fix; + frag = frag->fr_next; + if (frag == frag2) + { + if (delta == 0) + return FALSE; + break; + } + /* If we run off the end of the frag chain then we have a case + where frag2 is not after frag1, ie. an O_gt expression not + created for .loc view. */ + if (frag == NULL) + return FALSE; + } + + *offset = (off2 - off1 - delta) * OCTETS_PER_BYTE; + return TRUE; +}