| 54 | } |
| 55 | |
| 56 | void walk_xarray(const Engine& eng, const Off& o, VAddr entry, |
| 57 | std::vector<VAddr>& leaves, std::size_t& budget, int depth = 0) |
| 58 | { |
| 59 | if (entry == 0 || depth > 16) return; |
| 60 | if (budget == 0) return; // bound a crafted cyclic/explosive xarray |
| 61 | --budget; |
| 62 | if (xa_is_value(entry)) return; |
| 63 | if (!xa_is_internal(entry)) { |
| 64 | leaves.push_back(entry); |
| 65 | return; |
| 66 | } |
| 67 | VAddr node = xa_to_node(entry); |
| 68 | constexpr u64 kSlots = 64; |
| 69 | std::vector<VAddr> slots(kSlots, 0); |
| 70 | if (!kva_read(eng, node + o.xn_slots, slots.data(), kSlots * sizeof(VAddr))) |
| 71 | return; |
| 72 | for (u64 i = 0; i < kSlots; ++i) { |
| 73 | if (slots[i] == 0) continue; |
| 74 | walk_xarray(eng, o, slots[i], leaves, budget, depth + 1); |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | } // anonymous |
| 79 |
no test coverage detected