diff options
Diffstat (limited to 'libhurd-mm/as-lookup.c')
-rw-r--r-- | libhurd-mm/as-lookup.c | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/libhurd-mm/as-lookup.c b/libhurd-mm/as-lookup.c index 0a270ab..62343dd 100644 --- a/libhurd-mm/as-lookup.c +++ b/libhurd-mm/as-lookup.c @@ -62,6 +62,8 @@ as_lookup_rel_internal (activity_t activity, enum as_lookup_mode mode, union as_lookup_ret *rt, bool dump) { + assert (root); + struct cap *start = root; #ifndef NDEBUG @@ -99,7 +101,10 @@ as_lookup_rel_internal (activity_t activity, remaining - CAP_GUARD_BITS (root))), remaining); - assert (CAP_TYPE_MIN <= root->type && root->type <= CAP_TYPE_MAX); + assertx (CAP_TYPE_MIN <= root->type && root->type <= CAP_TYPE_MAX, + "Cap at " ADDR_FMT " has type %d?! (" ADDR_FMT ")", + ADDR_PRINTF (addr_chop (address, remaining)), root->type, + ADDR_PRINTF (address)); if (root->type == cap_rcappage) /* The page directory is read-only. Note the weakened access @@ -240,6 +245,59 @@ as_lookup_rel_internal (activity_t activity, break; + case cap_thread: + case cap_messenger: + /* Note: rmessengers don't expose their capability slots. */ + { + /* Index the object. */ + int bits; + switch (root->type) + { + case cap_thread: + bits = THREAD_SLOTS_LOG2; + break; + + case cap_messenger: + bits = VG_MESSENGER_SLOTS_LOG2; + break; + } + + if (remaining < bits) + { + debug (1, "Translating " ADDR_FMT "; not enough bits (%d) " + "to index %d-bit %s at " ADDR_FMT, + ADDR_PRINTF (address), remaining, bits, + cap_type_string (root->type), + ADDR_PRINTF (addr_chop (address, remaining))); + DUMP_OR_RET (false); + } + + struct object *object = cap_to_object (activity, root); + if (! object) + { +#ifdef RM_INTERN + debug (1, "Failed to get object with OID " OID_FMT, + OID_PRINTF (root->oid)); + DUMP_OR_RET (false); +#endif + return false; + } +#ifdef RM_INTERN + assert (object_type (object) == root->type); +#endif + + int offset = extract_bits64_inv (addr, remaining - 1, bits); + assert (0 <= offset && offset < (1 << bits)); + remaining -= bits; + + if (dump_path) + debug (0, "Indexing %s: %d/%d (%d)", + cap_type_string (root->type), offset, bits, remaining); + + root = &object->caps[offset]; + break; + } + default: /* We designate a non-address bit translating object but we have no bits left to translate. This is not an unusual |