xref: /dflybsd-src/contrib/gdb-7/gdb/prologue-value.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Prologue value handling for GDB.
2*ef5ccd6cSJohn Marino    Copyright (C) 2003-2013 Free Software Foundation, Inc.
35796c8dcSSimon Schubert 
45796c8dcSSimon Schubert    This file is part of GDB.
55796c8dcSSimon Schubert 
65796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
75796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
85796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
95796c8dcSSimon Schubert    (at your option) any later version.
105796c8dcSSimon Schubert 
115796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
125796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
135796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
145796c8dcSSimon Schubert    GNU General Public License for more details.
155796c8dcSSimon Schubert 
165796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
175796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
185796c8dcSSimon Schubert 
195796c8dcSSimon Schubert #include "defs.h"
205796c8dcSSimon Schubert #include "gdb_string.h"
215796c8dcSSimon Schubert #include "gdb_assert.h"
225796c8dcSSimon Schubert #include "prologue-value.h"
235796c8dcSSimon Schubert #include "regcache.h"
245796c8dcSSimon Schubert 
255796c8dcSSimon Schubert 
265796c8dcSSimon Schubert /* Constructors.  */
275796c8dcSSimon Schubert 
285796c8dcSSimon Schubert pv_t
pv_unknown(void)295796c8dcSSimon Schubert pv_unknown (void)
305796c8dcSSimon Schubert {
315796c8dcSSimon Schubert   pv_t v = { pvk_unknown, 0, 0 };
325796c8dcSSimon Schubert 
335796c8dcSSimon Schubert   return v;
345796c8dcSSimon Schubert }
355796c8dcSSimon Schubert 
365796c8dcSSimon Schubert 
375796c8dcSSimon Schubert pv_t
pv_constant(CORE_ADDR k)385796c8dcSSimon Schubert pv_constant (CORE_ADDR k)
395796c8dcSSimon Schubert {
405796c8dcSSimon Schubert   pv_t v;
415796c8dcSSimon Schubert 
425796c8dcSSimon Schubert   v.kind = pvk_constant;
435796c8dcSSimon Schubert   v.reg = -1;                   /* for debugging */
445796c8dcSSimon Schubert   v.k = k;
455796c8dcSSimon Schubert 
465796c8dcSSimon Schubert   return v;
475796c8dcSSimon Schubert }
485796c8dcSSimon Schubert 
495796c8dcSSimon Schubert 
505796c8dcSSimon Schubert pv_t
pv_register(int reg,CORE_ADDR k)515796c8dcSSimon Schubert pv_register (int reg, CORE_ADDR k)
525796c8dcSSimon Schubert {
535796c8dcSSimon Schubert   pv_t v;
545796c8dcSSimon Schubert 
555796c8dcSSimon Schubert   v.kind = pvk_register;
565796c8dcSSimon Schubert   v.reg = reg;
575796c8dcSSimon Schubert   v.k = k;
585796c8dcSSimon Schubert 
595796c8dcSSimon Schubert   return v;
605796c8dcSSimon Schubert }
615796c8dcSSimon Schubert 
625796c8dcSSimon Schubert 
635796c8dcSSimon Schubert 
645796c8dcSSimon Schubert /* Arithmetic operations.  */
655796c8dcSSimon Schubert 
665796c8dcSSimon Schubert /* If one of *A and *B is a constant, and the other isn't, swap the
675796c8dcSSimon Schubert    values as necessary to ensure that *B is the constant.  This can
685796c8dcSSimon Schubert    reduce the number of cases we need to analyze in the functions
695796c8dcSSimon Schubert    below.  */
705796c8dcSSimon Schubert static void
constant_last(pv_t * a,pv_t * b)715796c8dcSSimon Schubert constant_last (pv_t *a, pv_t *b)
725796c8dcSSimon Schubert {
735796c8dcSSimon Schubert   if (a->kind == pvk_constant
745796c8dcSSimon Schubert       && b->kind != pvk_constant)
755796c8dcSSimon Schubert     {
765796c8dcSSimon Schubert       pv_t temp = *a;
775796c8dcSSimon Schubert       *a = *b;
785796c8dcSSimon Schubert       *b = temp;
795796c8dcSSimon Schubert     }
805796c8dcSSimon Schubert }
815796c8dcSSimon Schubert 
825796c8dcSSimon Schubert 
835796c8dcSSimon Schubert pv_t
pv_add(pv_t a,pv_t b)845796c8dcSSimon Schubert pv_add (pv_t a, pv_t b)
855796c8dcSSimon Schubert {
865796c8dcSSimon Schubert   constant_last (&a, &b);
875796c8dcSSimon Schubert 
885796c8dcSSimon Schubert   /* We can add a constant to a register.  */
895796c8dcSSimon Schubert   if (a.kind == pvk_register
905796c8dcSSimon Schubert       && b.kind == pvk_constant)
915796c8dcSSimon Schubert     return pv_register (a.reg, a.k + b.k);
925796c8dcSSimon Schubert 
935796c8dcSSimon Schubert   /* We can add a constant to another constant.  */
945796c8dcSSimon Schubert   else if (a.kind == pvk_constant
955796c8dcSSimon Schubert            && b.kind == pvk_constant)
965796c8dcSSimon Schubert     return pv_constant (a.k + b.k);
975796c8dcSSimon Schubert 
985796c8dcSSimon Schubert   /* Anything else we don't know how to add.  We don't have a
995796c8dcSSimon Schubert      representation for, say, the sum of two registers, or a multiple
1005796c8dcSSimon Schubert      of a register's value (adding a register to itself).  */
1015796c8dcSSimon Schubert   else
1025796c8dcSSimon Schubert     return pv_unknown ();
1035796c8dcSSimon Schubert }
1045796c8dcSSimon Schubert 
1055796c8dcSSimon Schubert 
1065796c8dcSSimon Schubert pv_t
pv_add_constant(pv_t v,CORE_ADDR k)1075796c8dcSSimon Schubert pv_add_constant (pv_t v, CORE_ADDR k)
1085796c8dcSSimon Schubert {
1095796c8dcSSimon Schubert   /* Rather than thinking of all the cases we can and can't handle,
1105796c8dcSSimon Schubert      we'll just let pv_add take care of that for us.  */
1115796c8dcSSimon Schubert   return pv_add (v, pv_constant (k));
1125796c8dcSSimon Schubert }
1135796c8dcSSimon Schubert 
1145796c8dcSSimon Schubert 
1155796c8dcSSimon Schubert pv_t
pv_subtract(pv_t a,pv_t b)1165796c8dcSSimon Schubert pv_subtract (pv_t a, pv_t b)
1175796c8dcSSimon Schubert {
1185796c8dcSSimon Schubert   /* This isn't quite the same as negating B and adding it to A, since
1195796c8dcSSimon Schubert      we don't have a representation for the negation of anything but a
1205796c8dcSSimon Schubert      constant.  For example, we can't negate { pvk_register, R1, 10 },
1215796c8dcSSimon Schubert      but we do know that { pvk_register, R1, 10 } minus { pvk_register,
1225796c8dcSSimon Schubert      R1, 5 } is { pvk_constant, <ignored>, 5 }.
1235796c8dcSSimon Schubert 
1245796c8dcSSimon Schubert      This means, for example, that we could subtract two stack
1255796c8dcSSimon Schubert      addresses; they're both relative to the original SP.  Since the
1265796c8dcSSimon Schubert      frame pointer is set based on the SP, its value will be the
1275796c8dcSSimon Schubert      original SP plus some constant (probably zero), so we can use its
1285796c8dcSSimon Schubert      value just fine, too.  */
1295796c8dcSSimon Schubert 
1305796c8dcSSimon Schubert   constant_last (&a, &b);
1315796c8dcSSimon Schubert 
1325796c8dcSSimon Schubert   /* We can subtract two constants.  */
1335796c8dcSSimon Schubert   if (a.kind == pvk_constant
1345796c8dcSSimon Schubert       && b.kind == pvk_constant)
1355796c8dcSSimon Schubert     return pv_constant (a.k - b.k);
1365796c8dcSSimon Schubert 
1375796c8dcSSimon Schubert   /* We can subtract a constant from a register.  */
1385796c8dcSSimon Schubert   else if (a.kind == pvk_register
1395796c8dcSSimon Schubert            && b.kind == pvk_constant)
1405796c8dcSSimon Schubert     return pv_register (a.reg, a.k - b.k);
1415796c8dcSSimon Schubert 
1425796c8dcSSimon Schubert   /* We can subtract a register from itself, yielding a constant.  */
1435796c8dcSSimon Schubert   else if (a.kind == pvk_register
1445796c8dcSSimon Schubert            && b.kind == pvk_register
1455796c8dcSSimon Schubert            && a.reg == b.reg)
1465796c8dcSSimon Schubert     return pv_constant (a.k - b.k);
1475796c8dcSSimon Schubert 
1485796c8dcSSimon Schubert   /* We don't know how to subtract anything else.  */
1495796c8dcSSimon Schubert   else
1505796c8dcSSimon Schubert     return pv_unknown ();
1515796c8dcSSimon Schubert }
1525796c8dcSSimon Schubert 
1535796c8dcSSimon Schubert 
1545796c8dcSSimon Schubert pv_t
pv_logical_and(pv_t a,pv_t b)1555796c8dcSSimon Schubert pv_logical_and (pv_t a, pv_t b)
1565796c8dcSSimon Schubert {
1575796c8dcSSimon Schubert   constant_last (&a, &b);
1585796c8dcSSimon Schubert 
1595796c8dcSSimon Schubert   /* We can 'and' two constants.  */
1605796c8dcSSimon Schubert   if (a.kind == pvk_constant
1615796c8dcSSimon Schubert       && b.kind == pvk_constant)
1625796c8dcSSimon Schubert     return pv_constant (a.k & b.k);
1635796c8dcSSimon Schubert 
1645796c8dcSSimon Schubert   /* We can 'and' anything with the constant zero.  */
1655796c8dcSSimon Schubert   else if (b.kind == pvk_constant
1665796c8dcSSimon Schubert            && b.k == 0)
1675796c8dcSSimon Schubert     return pv_constant (0);
1685796c8dcSSimon Schubert 
1695796c8dcSSimon Schubert   /* We can 'and' anything with ~0.  */
1705796c8dcSSimon Schubert   else if (b.kind == pvk_constant
1715796c8dcSSimon Schubert            && b.k == ~ (CORE_ADDR) 0)
1725796c8dcSSimon Schubert     return a;
1735796c8dcSSimon Schubert 
1745796c8dcSSimon Schubert   /* We can 'and' a register with itself.  */
1755796c8dcSSimon Schubert   else if (a.kind == pvk_register
1765796c8dcSSimon Schubert            && b.kind == pvk_register
1775796c8dcSSimon Schubert            && a.reg == b.reg
1785796c8dcSSimon Schubert            && a.k == b.k)
1795796c8dcSSimon Schubert     return a;
1805796c8dcSSimon Schubert 
1815796c8dcSSimon Schubert   /* Otherwise, we don't know.  */
1825796c8dcSSimon Schubert   else
1835796c8dcSSimon Schubert     return pv_unknown ();
1845796c8dcSSimon Schubert }
1855796c8dcSSimon Schubert 
1865796c8dcSSimon Schubert 
1875796c8dcSSimon Schubert 
1885796c8dcSSimon Schubert /* Examining prologue values.  */
1895796c8dcSSimon Schubert 
1905796c8dcSSimon Schubert int
pv_is_identical(pv_t a,pv_t b)1915796c8dcSSimon Schubert pv_is_identical (pv_t a, pv_t b)
1925796c8dcSSimon Schubert {
1935796c8dcSSimon Schubert   if (a.kind != b.kind)
1945796c8dcSSimon Schubert     return 0;
1955796c8dcSSimon Schubert 
1965796c8dcSSimon Schubert   switch (a.kind)
1975796c8dcSSimon Schubert     {
1985796c8dcSSimon Schubert     case pvk_unknown:
1995796c8dcSSimon Schubert       return 1;
2005796c8dcSSimon Schubert     case pvk_constant:
2015796c8dcSSimon Schubert       return (a.k == b.k);
2025796c8dcSSimon Schubert     case pvk_register:
2035796c8dcSSimon Schubert       return (a.reg == b.reg && a.k == b.k);
2045796c8dcSSimon Schubert     default:
205c50c785cSJohn Marino       gdb_assert_not_reached ("unexpected prologue value kind");
2065796c8dcSSimon Schubert     }
2075796c8dcSSimon Schubert }
2085796c8dcSSimon Schubert 
2095796c8dcSSimon Schubert 
2105796c8dcSSimon Schubert int
pv_is_constant(pv_t a)2115796c8dcSSimon Schubert pv_is_constant (pv_t a)
2125796c8dcSSimon Schubert {
2135796c8dcSSimon Schubert   return (a.kind == pvk_constant);
2145796c8dcSSimon Schubert }
2155796c8dcSSimon Schubert 
2165796c8dcSSimon Schubert 
2175796c8dcSSimon Schubert int
pv_is_register(pv_t a,int r)2185796c8dcSSimon Schubert pv_is_register (pv_t a, int r)
2195796c8dcSSimon Schubert {
2205796c8dcSSimon Schubert   return (a.kind == pvk_register
2215796c8dcSSimon Schubert           && a.reg == r);
2225796c8dcSSimon Schubert }
2235796c8dcSSimon Schubert 
2245796c8dcSSimon Schubert 
2255796c8dcSSimon Schubert int
pv_is_register_k(pv_t a,int r,CORE_ADDR k)2265796c8dcSSimon Schubert pv_is_register_k (pv_t a, int r, CORE_ADDR k)
2275796c8dcSSimon Schubert {
2285796c8dcSSimon Schubert   return (a.kind == pvk_register
2295796c8dcSSimon Schubert           && a.reg == r
2305796c8dcSSimon Schubert           && a.k == k);
2315796c8dcSSimon Schubert }
2325796c8dcSSimon Schubert 
2335796c8dcSSimon Schubert 
2345796c8dcSSimon Schubert enum pv_boolean
pv_is_array_ref(pv_t addr,CORE_ADDR size,pv_t array_addr,CORE_ADDR array_len,CORE_ADDR elt_size,int * i)2355796c8dcSSimon Schubert pv_is_array_ref (pv_t addr, CORE_ADDR size,
2365796c8dcSSimon Schubert                  pv_t array_addr, CORE_ADDR array_len,
2375796c8dcSSimon Schubert                  CORE_ADDR elt_size,
2385796c8dcSSimon Schubert                  int *i)
2395796c8dcSSimon Schubert {
2405796c8dcSSimon Schubert   /* Note that, since .k is a CORE_ADDR, and CORE_ADDR is unsigned, if
2415796c8dcSSimon Schubert      addr is *before* the start of the array, then this isn't going to
2425796c8dcSSimon Schubert      be negative...  */
2435796c8dcSSimon Schubert   pv_t offset = pv_subtract (addr, array_addr);
2445796c8dcSSimon Schubert 
2455796c8dcSSimon Schubert   if (offset.kind == pvk_constant)
2465796c8dcSSimon Schubert     {
2475796c8dcSSimon Schubert       /* This is a rather odd test.  We want to know if the SIZE bytes
2485796c8dcSSimon Schubert          at ADDR don't overlap the array at all, so you'd expect it to
2495796c8dcSSimon Schubert          be an || expression: "if we're completely before || we're
2505796c8dcSSimon Schubert          completely after".  But with unsigned arithmetic, things are
2515796c8dcSSimon Schubert          different: since it's a number circle, not a number line, the
2525796c8dcSSimon Schubert          right values for offset.k are actually one contiguous range.  */
2535796c8dcSSimon Schubert       if (offset.k <= -size
2545796c8dcSSimon Schubert           && offset.k >= array_len * elt_size)
2555796c8dcSSimon Schubert         return pv_definite_no;
2565796c8dcSSimon Schubert       else if (offset.k % elt_size != 0
2575796c8dcSSimon Schubert                || size != elt_size)
2585796c8dcSSimon Schubert         return pv_maybe;
2595796c8dcSSimon Schubert       else
2605796c8dcSSimon Schubert         {
2615796c8dcSSimon Schubert           *i = offset.k / elt_size;
2625796c8dcSSimon Schubert           return pv_definite_yes;
2635796c8dcSSimon Schubert         }
2645796c8dcSSimon Schubert     }
2655796c8dcSSimon Schubert   else
2665796c8dcSSimon Schubert     return pv_maybe;
2675796c8dcSSimon Schubert }
2685796c8dcSSimon Schubert 
2695796c8dcSSimon Schubert 
2705796c8dcSSimon Schubert 
2715796c8dcSSimon Schubert /* Areas.  */
2725796c8dcSSimon Schubert 
2735796c8dcSSimon Schubert 
2745796c8dcSSimon Schubert /* A particular value known to be stored in an area.
2755796c8dcSSimon Schubert 
2765796c8dcSSimon Schubert    Entries form a ring, sorted by unsigned offset from the area's base
2775796c8dcSSimon Schubert    register's value.  Since entries can straddle the wrap-around point,
2785796c8dcSSimon Schubert    unsigned offsets form a circle, not a number line, so the list
2795796c8dcSSimon Schubert    itself is structured the same way --- there is no inherent head.
2805796c8dcSSimon Schubert    The entry with the lowest offset simply follows the entry with the
2815796c8dcSSimon Schubert    highest offset.  Entries may abut, but never overlap.  The area's
2825796c8dcSSimon Schubert    'entry' pointer points to an arbitrary node in the ring.  */
2835796c8dcSSimon Schubert struct area_entry
2845796c8dcSSimon Schubert {
2855796c8dcSSimon Schubert   /* Links in the doubly-linked ring.  */
2865796c8dcSSimon Schubert   struct area_entry *prev, *next;
2875796c8dcSSimon Schubert 
2885796c8dcSSimon Schubert   /* Offset of this entry's address from the value of the base
2895796c8dcSSimon Schubert      register.  */
2905796c8dcSSimon Schubert   CORE_ADDR offset;
2915796c8dcSSimon Schubert 
2925796c8dcSSimon Schubert   /* The size of this entry.  Note that an entry may wrap around from
2935796c8dcSSimon Schubert      the end of the address space to the beginning.  */
2945796c8dcSSimon Schubert   CORE_ADDR size;
2955796c8dcSSimon Schubert 
2965796c8dcSSimon Schubert   /* The value stored here.  */
2975796c8dcSSimon Schubert   pv_t value;
2985796c8dcSSimon Schubert };
2995796c8dcSSimon Schubert 
3005796c8dcSSimon Schubert 
3015796c8dcSSimon Schubert struct pv_area
3025796c8dcSSimon Schubert {
3035796c8dcSSimon Schubert   /* This area's base register.  */
3045796c8dcSSimon Schubert   int base_reg;
3055796c8dcSSimon Schubert 
3065796c8dcSSimon Schubert   /* The mask to apply to addresses, to make the wrap-around happen at
3075796c8dcSSimon Schubert      the right place.  */
3085796c8dcSSimon Schubert   CORE_ADDR addr_mask;
3095796c8dcSSimon Schubert 
3105796c8dcSSimon Schubert   /* An element of the doubly-linked ring of entries, or zero if we
3115796c8dcSSimon Schubert      have none.  */
3125796c8dcSSimon Schubert   struct area_entry *entry;
3135796c8dcSSimon Schubert };
3145796c8dcSSimon Schubert 
3155796c8dcSSimon Schubert 
3165796c8dcSSimon Schubert struct pv_area *
make_pv_area(int base_reg,int addr_bit)3175796c8dcSSimon Schubert make_pv_area (int base_reg, int addr_bit)
3185796c8dcSSimon Schubert {
3195796c8dcSSimon Schubert   struct pv_area *a = (struct pv_area *) xmalloc (sizeof (*a));
3205796c8dcSSimon Schubert 
3215796c8dcSSimon Schubert   memset (a, 0, sizeof (*a));
3225796c8dcSSimon Schubert 
3235796c8dcSSimon Schubert   a->base_reg = base_reg;
3245796c8dcSSimon Schubert   a->entry = 0;
3255796c8dcSSimon Schubert 
3265796c8dcSSimon Schubert   /* Remember that shift amounts equal to the type's width are
3275796c8dcSSimon Schubert      undefined.  */
3285796c8dcSSimon Schubert   a->addr_mask = ((((CORE_ADDR) 1 << (addr_bit - 1)) - 1) << 1) | 1;
3295796c8dcSSimon Schubert 
3305796c8dcSSimon Schubert   return a;
3315796c8dcSSimon Schubert }
3325796c8dcSSimon Schubert 
3335796c8dcSSimon Schubert 
3345796c8dcSSimon Schubert /* Delete all entries from AREA.  */
3355796c8dcSSimon Schubert static void
clear_entries(struct pv_area * area)3365796c8dcSSimon Schubert clear_entries (struct pv_area *area)
3375796c8dcSSimon Schubert {
3385796c8dcSSimon Schubert   struct area_entry *e = area->entry;
3395796c8dcSSimon Schubert 
3405796c8dcSSimon Schubert   if (e)
3415796c8dcSSimon Schubert     {
3425796c8dcSSimon Schubert       /* This needs to be a do-while loop, in order to actually
3435796c8dcSSimon Schubert          process the node being checked for in the terminating
3445796c8dcSSimon Schubert          condition.  */
3455796c8dcSSimon Schubert       do
3465796c8dcSSimon Schubert         {
3475796c8dcSSimon Schubert           struct area_entry *next = e->next;
348cf7f2e2dSJohn Marino 
3495796c8dcSSimon Schubert           xfree (e);
3505796c8dcSSimon Schubert           e = next;
3515796c8dcSSimon Schubert         }
3525796c8dcSSimon Schubert       while (e != area->entry);
3535796c8dcSSimon Schubert 
3545796c8dcSSimon Schubert       area->entry = 0;
3555796c8dcSSimon Schubert     }
3565796c8dcSSimon Schubert }
3575796c8dcSSimon Schubert 
3585796c8dcSSimon Schubert 
3595796c8dcSSimon Schubert void
free_pv_area(struct pv_area * area)3605796c8dcSSimon Schubert free_pv_area (struct pv_area *area)
3615796c8dcSSimon Schubert {
3625796c8dcSSimon Schubert   clear_entries (area);
3635796c8dcSSimon Schubert   xfree (area);
3645796c8dcSSimon Schubert }
3655796c8dcSSimon Schubert 
3665796c8dcSSimon Schubert 
3675796c8dcSSimon Schubert static void
do_free_pv_area_cleanup(void * arg)3685796c8dcSSimon Schubert do_free_pv_area_cleanup (void *arg)
3695796c8dcSSimon Schubert {
3705796c8dcSSimon Schubert   free_pv_area ((struct pv_area *) arg);
3715796c8dcSSimon Schubert }
3725796c8dcSSimon Schubert 
3735796c8dcSSimon Schubert 
3745796c8dcSSimon Schubert struct cleanup *
make_cleanup_free_pv_area(struct pv_area * area)3755796c8dcSSimon Schubert make_cleanup_free_pv_area (struct pv_area *area)
3765796c8dcSSimon Schubert {
3775796c8dcSSimon Schubert   return make_cleanup (do_free_pv_area_cleanup, (void *) area);
3785796c8dcSSimon Schubert }
3795796c8dcSSimon Schubert 
3805796c8dcSSimon Schubert 
3815796c8dcSSimon Schubert int
pv_area_store_would_trash(struct pv_area * area,pv_t addr)3825796c8dcSSimon Schubert pv_area_store_would_trash (struct pv_area *area, pv_t addr)
3835796c8dcSSimon Schubert {
3845796c8dcSSimon Schubert   /* It may seem odd that pvk_constant appears here --- after all,
3855796c8dcSSimon Schubert      that's the case where we know the most about the address!  But
3865796c8dcSSimon Schubert      pv_areas are always relative to a register, and we don't know the
3875796c8dcSSimon Schubert      value of the register, so we can't compare entry addresses to
3885796c8dcSSimon Schubert      constants.  */
3895796c8dcSSimon Schubert   return (addr.kind == pvk_unknown
3905796c8dcSSimon Schubert           || addr.kind == pvk_constant
3915796c8dcSSimon Schubert           || (addr.kind == pvk_register && addr.reg != area->base_reg));
3925796c8dcSSimon Schubert }
3935796c8dcSSimon Schubert 
3945796c8dcSSimon Schubert 
3955796c8dcSSimon Schubert /* Return a pointer to the first entry we hit in AREA starting at
3965796c8dcSSimon Schubert    OFFSET and going forward.
3975796c8dcSSimon Schubert 
3985796c8dcSSimon Schubert    This may return zero, if AREA has no entries.
3995796c8dcSSimon Schubert 
4005796c8dcSSimon Schubert    And since the entries are a ring, this may return an entry that
401a45ae5f8SJohn Marino    entirely precedes OFFSET.  This is the correct behavior: depending
4025796c8dcSSimon Schubert    on the sizes involved, we could still overlap such an area, with
4035796c8dcSSimon Schubert    wrap-around.  */
4045796c8dcSSimon Schubert static struct area_entry *
find_entry(struct pv_area * area,CORE_ADDR offset)4055796c8dcSSimon Schubert find_entry (struct pv_area *area, CORE_ADDR offset)
4065796c8dcSSimon Schubert {
4075796c8dcSSimon Schubert   struct area_entry *e = area->entry;
4085796c8dcSSimon Schubert 
4095796c8dcSSimon Schubert   if (! e)
4105796c8dcSSimon Schubert     return 0;
4115796c8dcSSimon Schubert 
4125796c8dcSSimon Schubert   /* If the next entry would be better than the current one, then scan
4135796c8dcSSimon Schubert      forward.  Since we use '<' in this loop, it always terminates.
4145796c8dcSSimon Schubert 
4155796c8dcSSimon Schubert      Note that, even setting aside the addr_mask stuff, we must not
4165796c8dcSSimon Schubert      simplify this, in high school algebra fashion, to
4175796c8dcSSimon Schubert      (e->next->offset < e->offset), because of the way < interacts
4185796c8dcSSimon Schubert      with wrap-around.  We have to subtract offset from both sides to
4195796c8dcSSimon Schubert      make sure both things we're comparing are on the same side of the
4205796c8dcSSimon Schubert      discontinuity.  */
4215796c8dcSSimon Schubert   while (((e->next->offset - offset) & area->addr_mask)
4225796c8dcSSimon Schubert          < ((e->offset - offset) & area->addr_mask))
4235796c8dcSSimon Schubert     e = e->next;
4245796c8dcSSimon Schubert 
4255796c8dcSSimon Schubert   /* If the previous entry would be better than the current one, then
4265796c8dcSSimon Schubert      scan backwards.  */
4275796c8dcSSimon Schubert   while (((e->prev->offset - offset) & area->addr_mask)
4285796c8dcSSimon Schubert          < ((e->offset - offset) & area->addr_mask))
4295796c8dcSSimon Schubert     e = e->prev;
4305796c8dcSSimon Schubert 
4315796c8dcSSimon Schubert   /* In case there's some locality to the searches, set the area's
4325796c8dcSSimon Schubert      pointer to the entry we've found.  */
4335796c8dcSSimon Schubert   area->entry = e;
4345796c8dcSSimon Schubert 
4355796c8dcSSimon Schubert   return e;
4365796c8dcSSimon Schubert }
4375796c8dcSSimon Schubert 
4385796c8dcSSimon Schubert 
4395796c8dcSSimon Schubert /* Return non-zero if the SIZE bytes at OFFSET would overlap ENTRY;
4405796c8dcSSimon Schubert    return zero otherwise.  AREA is the area to which ENTRY belongs.  */
4415796c8dcSSimon Schubert static int
overlaps(struct pv_area * area,struct area_entry * entry,CORE_ADDR offset,CORE_ADDR size)4425796c8dcSSimon Schubert overlaps (struct pv_area *area,
4435796c8dcSSimon Schubert           struct area_entry *entry,
4445796c8dcSSimon Schubert           CORE_ADDR offset,
4455796c8dcSSimon Schubert           CORE_ADDR size)
4465796c8dcSSimon Schubert {
4475796c8dcSSimon Schubert   /* Think carefully about wrap-around before simplifying this.  */
4485796c8dcSSimon Schubert   return (((entry->offset - offset) & area->addr_mask) < size
4495796c8dcSSimon Schubert           || ((offset - entry->offset) & area->addr_mask) < entry->size);
4505796c8dcSSimon Schubert }
4515796c8dcSSimon Schubert 
4525796c8dcSSimon Schubert 
4535796c8dcSSimon Schubert void
pv_area_store(struct pv_area * area,pv_t addr,CORE_ADDR size,pv_t value)4545796c8dcSSimon Schubert pv_area_store (struct pv_area *area,
4555796c8dcSSimon Schubert                pv_t addr,
4565796c8dcSSimon Schubert                CORE_ADDR size,
4575796c8dcSSimon Schubert                pv_t value)
4585796c8dcSSimon Schubert {
4595796c8dcSSimon Schubert   /* Remove any (potentially) overlapping entries.  */
4605796c8dcSSimon Schubert   if (pv_area_store_would_trash (area, addr))
4615796c8dcSSimon Schubert     clear_entries (area);
4625796c8dcSSimon Schubert   else
4635796c8dcSSimon Schubert     {
4645796c8dcSSimon Schubert       CORE_ADDR offset = addr.k;
4655796c8dcSSimon Schubert       struct area_entry *e = find_entry (area, offset);
4665796c8dcSSimon Schubert 
4675796c8dcSSimon Schubert       /* Delete all entries that we would overlap.  */
4685796c8dcSSimon Schubert       while (e && overlaps (area, e, offset, size))
4695796c8dcSSimon Schubert         {
4705796c8dcSSimon Schubert           struct area_entry *next = (e->next == e) ? 0 : e->next;
471cf7f2e2dSJohn Marino 
4725796c8dcSSimon Schubert           e->prev->next = e->next;
4735796c8dcSSimon Schubert           e->next->prev = e->prev;
4745796c8dcSSimon Schubert 
4755796c8dcSSimon Schubert           xfree (e);
4765796c8dcSSimon Schubert           e = next;
4775796c8dcSSimon Schubert         }
4785796c8dcSSimon Schubert 
4795796c8dcSSimon Schubert       /* Move the area's pointer to the next remaining entry.  This
4805796c8dcSSimon Schubert          will also zero the pointer if we've deleted all the entries.  */
4815796c8dcSSimon Schubert       area->entry = e;
4825796c8dcSSimon Schubert     }
4835796c8dcSSimon Schubert 
4845796c8dcSSimon Schubert   /* Now, there are no entries overlapping us, and area->entry is
4855796c8dcSSimon Schubert      either zero or pointing at the closest entry after us.  We can
4865796c8dcSSimon Schubert      just insert ourselves before that.
4875796c8dcSSimon Schubert 
4885796c8dcSSimon Schubert      But if we're storing an unknown value, don't bother --- that's
4895796c8dcSSimon Schubert      the default.  */
4905796c8dcSSimon Schubert   if (value.kind == pvk_unknown)
4915796c8dcSSimon Schubert     return;
4925796c8dcSSimon Schubert   else
4935796c8dcSSimon Schubert     {
4945796c8dcSSimon Schubert       CORE_ADDR offset = addr.k;
4955796c8dcSSimon Schubert       struct area_entry *e = (struct area_entry *) xmalloc (sizeof (*e));
496cf7f2e2dSJohn Marino 
4975796c8dcSSimon Schubert       e->offset = offset;
4985796c8dcSSimon Schubert       e->size = size;
4995796c8dcSSimon Schubert       e->value = value;
5005796c8dcSSimon Schubert 
5015796c8dcSSimon Schubert       if (area->entry)
5025796c8dcSSimon Schubert         {
5035796c8dcSSimon Schubert           e->prev = area->entry->prev;
5045796c8dcSSimon Schubert           e->next = area->entry;
5055796c8dcSSimon Schubert           e->prev->next = e->next->prev = e;
5065796c8dcSSimon Schubert         }
5075796c8dcSSimon Schubert       else
5085796c8dcSSimon Schubert         {
5095796c8dcSSimon Schubert           e->prev = e->next = e;
5105796c8dcSSimon Schubert           area->entry = e;
5115796c8dcSSimon Schubert         }
5125796c8dcSSimon Schubert     }
5135796c8dcSSimon Schubert }
5145796c8dcSSimon Schubert 
5155796c8dcSSimon Schubert 
5165796c8dcSSimon Schubert pv_t
pv_area_fetch(struct pv_area * area,pv_t addr,CORE_ADDR size)5175796c8dcSSimon Schubert pv_area_fetch (struct pv_area *area, pv_t addr, CORE_ADDR size)
5185796c8dcSSimon Schubert {
5195796c8dcSSimon Schubert   /* If we have no entries, or we can't decide how ADDR relates to the
5205796c8dcSSimon Schubert      entries we do have, then the value is unknown.  */
5215796c8dcSSimon Schubert   if (! area->entry
5225796c8dcSSimon Schubert       || pv_area_store_would_trash (area, addr))
5235796c8dcSSimon Schubert     return pv_unknown ();
5245796c8dcSSimon Schubert   else
5255796c8dcSSimon Schubert     {
5265796c8dcSSimon Schubert       CORE_ADDR offset = addr.k;
5275796c8dcSSimon Schubert       struct area_entry *e = find_entry (area, offset);
5285796c8dcSSimon Schubert 
5295796c8dcSSimon Schubert       /* If this entry exactly matches what we're looking for, then
5305796c8dcSSimon Schubert          we're set.  Otherwise, say it's unknown.  */
5315796c8dcSSimon Schubert       if (e->offset == offset && e->size == size)
5325796c8dcSSimon Schubert         return e->value;
5335796c8dcSSimon Schubert       else
5345796c8dcSSimon Schubert         return pv_unknown ();
5355796c8dcSSimon Schubert     }
5365796c8dcSSimon Schubert }
5375796c8dcSSimon Schubert 
5385796c8dcSSimon Schubert 
5395796c8dcSSimon Schubert int
pv_area_find_reg(struct pv_area * area,struct gdbarch * gdbarch,int reg,CORE_ADDR * offset_p)5405796c8dcSSimon Schubert pv_area_find_reg (struct pv_area *area,
5415796c8dcSSimon Schubert                   struct gdbarch *gdbarch,
5425796c8dcSSimon Schubert                   int reg,
5435796c8dcSSimon Schubert                   CORE_ADDR *offset_p)
5445796c8dcSSimon Schubert {
5455796c8dcSSimon Schubert   struct area_entry *e = area->entry;
5465796c8dcSSimon Schubert 
5475796c8dcSSimon Schubert   if (e)
5485796c8dcSSimon Schubert     do
5495796c8dcSSimon Schubert       {
5505796c8dcSSimon Schubert         if (e->value.kind == pvk_register
5515796c8dcSSimon Schubert             && e->value.reg == reg
5525796c8dcSSimon Schubert             && e->value.k == 0
5535796c8dcSSimon Schubert             && e->size == register_size (gdbarch, reg))
5545796c8dcSSimon Schubert           {
5555796c8dcSSimon Schubert             if (offset_p)
5565796c8dcSSimon Schubert               *offset_p = e->offset;
5575796c8dcSSimon Schubert             return 1;
5585796c8dcSSimon Schubert           }
5595796c8dcSSimon Schubert 
5605796c8dcSSimon Schubert         e = e->next;
5615796c8dcSSimon Schubert       }
5625796c8dcSSimon Schubert     while (e != area->entry);
5635796c8dcSSimon Schubert 
5645796c8dcSSimon Schubert   return 0;
5655796c8dcSSimon Schubert }
5665796c8dcSSimon Schubert 
5675796c8dcSSimon Schubert 
5685796c8dcSSimon Schubert void
pv_area_scan(struct pv_area * area,void (* func)(void * closure,pv_t addr,CORE_ADDR size,pv_t value),void * closure)5695796c8dcSSimon Schubert pv_area_scan (struct pv_area *area,
5705796c8dcSSimon Schubert               void (*func) (void *closure,
5715796c8dcSSimon Schubert                             pv_t addr,
5725796c8dcSSimon Schubert                             CORE_ADDR size,
5735796c8dcSSimon Schubert                             pv_t value),
5745796c8dcSSimon Schubert               void *closure)
5755796c8dcSSimon Schubert {
5765796c8dcSSimon Schubert   struct area_entry *e = area->entry;
5775796c8dcSSimon Schubert   pv_t addr;
5785796c8dcSSimon Schubert 
5795796c8dcSSimon Schubert   addr.kind = pvk_register;
5805796c8dcSSimon Schubert   addr.reg = area->base_reg;
5815796c8dcSSimon Schubert 
5825796c8dcSSimon Schubert   if (e)
5835796c8dcSSimon Schubert     do
5845796c8dcSSimon Schubert       {
5855796c8dcSSimon Schubert         addr.k = e->offset;
5865796c8dcSSimon Schubert         func (closure, addr, e->size, e->value);
5875796c8dcSSimon Schubert         e = e->next;
5885796c8dcSSimon Schubert       }
5895796c8dcSSimon Schubert     while (e != area->entry);
5905796c8dcSSimon Schubert }
591