]> xenbits.xensource.com Git - people/royger/freebsd.git/commitdiff
Use casts to force an unsigned comparison in db_search_symbol().
authorjhb <jhb@FreeBSD.org>
Wed, 14 Dec 2016 00:18:12 +0000 (00:18 +0000)
committerjhb <jhb@FreeBSD.org>
Wed, 14 Dec 2016 00:18:12 +0000 (00:18 +0000)
On all of our platforms, db_expr_t is a signed integer while
db_addr_t is an unsigned integer value.  db_search_symbol used variables
of type db_expr_t to hold the current offset of the requested address from
the "best" symbol found so far.  This value was initialized to '~0'.
When a new symbol is found from a symbol table, the associated diff for the
new symbol is compared against the existing value as 'if (newdiff < diff)'
to determine if the new symbol had a smaller diff and was thus a closer
match.

On 64-bit MIPS, the '~0' was treated as a negative value (-1).  A lookup
that found a perfect match of an address against a symbol returned a diff
of 0.  However, in signed comparisons, 0 is not less than -1.  As a result,
DDB on 64-bit MIPS never resolved any addresses to symbols.  Workaround
this by using casts to force an unsigned comparison.

Probably the diff returned from db_search_symbol() and X_db_search_symbol()
should be changed to a db_addr_t instead of a db_expr_t as it is an
unsigned value (and is an offset of an address, so should fit in the same
size as an address).

Sponsored by: DARPA / AFRL

sys/ddb/db_sym.c

index 25ae4bcaa973001b6e6c9fdc44a6c51a82f20eab..12e98b112dbd189f82b317d44a857adbfc591793 100644 (file)
@@ -373,10 +373,10 @@ db_search_symbol(db_addr_t val, db_strategy_t strategy, db_expr_t *offp)
        register int    i;
        c_db_sym_t      ret = C_DB_SYM_NULL, sym;
 
-       newdiff = diff = ~0;
+       newdiff = diff = val;
        for (i = 0; i < db_nsymtab; i++) {
            sym = X_db_search_symbol(&db_symtabs[i], val, strategy, &newdiff);
-           if (newdiff < diff) {
+           if ((uintmax_t)newdiff < (uintmax_t)diff) {
                db_last_symtab = &db_symtabs[i];
                diff = newdiff;
                ret = sym;