- kmod_info_t *k;
- kmod_reference_t *r;
- int i, found_one = 0;
-
- // find backtrace addresses that are inside a kmod
- for (i=0; i < cnt; i++, addr++) {
- k = kmod;
- while (k) {
- // XXX - validate page(s) that k points to
- if(pmap_extract(kernel_pmap, (vm_offset_t)k) == 0) { /* Exit loop if page not mapped */
- printf("kmod scan stopped due to missing page: %08X\n", k);
- break;
- }
- if ((*addr >= k->address) && (*addr < (k->address + k->size))) {
- // got one, blast info_version, we don't need it at this point
- k->info_version = IS_IN_BACKTRACE;
- found_one++;
- break;
- }
- k = k->next;
- }
- }
- if (!found_one) return;
-
- printf("kernel modules in backtrace: ");
- k = kmod;
- while (k) {
- if(pmap_extract(kernel_pmap, (vm_offset_t)k) == 0) { /* Exit loop if page not mapped */
- printf("kmod scan stopped due to missing page: %08X\n", k);
- break;
- }
- if (k->info_version == IS_IN_BACKTRACE) {
- printf("%s(%s)@0x%x ", k->name, k->version, k->address);
- }
- k = k->next;
- }
- printf("\n");
-
- // look for dependencies
- k = kmod; found_one = 0;
- while (k) {
- if(pmap_extract(kernel_pmap, (vm_offset_t)k) == 0) { /* Exit loop if page not mapped */
- printf("kmod dependency scan stopped due to missing page: %08X\n", k);
- break;
- }
- if (k->info_version == IS_IN_BACKTRACE) {
- r = k->reference_list;
- while (r) {
- // XXX - validate page(s) that r and r->info point to
- if(pmap_extract(kernel_pmap, (vm_offset_t)r) == 0) { /* Exit loop if page not mapped */
- printf("kmod validation scan stopped due to missing page: %08X\n", r);
- break;
- }
- if (r->info->info_version != IS_IN_BACKTRACE) {
- r->info->info_version = IS_A_DEPENDENCY;
- found_one++;
- }
- r = r->next;
- }
- }
- k = k->next;
- }
- if (!found_one) goto cleanup;
-
- printf("kernel module dependencies: ");
- k = kmod;
- while (k) {
- if(pmap_extract(kernel_pmap, (vm_offset_t)k) == 0) { /* Exit loop if page not mapped */
- printf("kmod dependency print stopped due to missing page: %08X\n", k);
- break;
- }
- if (k->info_version == IS_A_DEPENDENCY) {
- printf("%s(%s)@0x%x ", k->name, k->version, k->address);
- }
- k = k->next;
+ vm_offset_t * kscan_addr = 0;
+ vm_offset_t * rscan_addr = 0;
+ kmod_info_t * k;
+ kmod_reference_t * r;
+ int i, j;
+ int found_kmod = 0;
+ int kmod_scan_stopped = 0;
+ kmod_info_t * stop_kmod = 0;
+ int ref_scan_stopped = 0;
+ kmod_reference_t * stop_ref = 0;
+
+ for (k = kmod; k; k = k->next) {
+ if (!k->address) {
+ continue; // skip fake entries for built-in kernel components
+ }
+ if (pmap_find_phys(kernel_pmap, (addr64_t)((uintptr_t)k)) == 0) {
+ kdb_printf(" kmod scan stopped due to missing "
+ "kmod page: %08x\n", stop_kmod);
+ break;
+ }
+ for (i = 0, kscan_addr = addr; i < cnt; i++, kscan_addr++) {
+ if ((*kscan_addr >= k->address) &&
+ (*kscan_addr < (k->address + k->size))) {
+
+ if (!found_kmod) {
+ kdb_printf(" Kernel loadable modules in backtrace "
+ "(with dependencies):\n");
+ }
+ found_kmod = 1;
+ kdb_printf(" %s(%s)@0x%x\n",
+ k->name, k->version, k->address);
+
+ for (r = k->reference_list; r; r = r->next) {
+ kmod_info_t * rinfo;
+
+ if (pmap_find_phys(kernel_pmap, (addr64_t)((uintptr_t)r)) == 0) {
+ kdb_printf(" kmod dependency scan stopped "
+ "due to missing dependency page: %08x\n", r);
+ break;
+ }
+
+ rinfo = r->info;
+
+ if (!rinfo->address) {
+ continue; // skip fake entries for built-ins
+ }
+
+ if (pmap_find_phys(kernel_pmap, (addr64_t)((uintptr_t)rinfo)) == 0) {
+ kdb_printf(" kmod dependency scan stopped "
+ "due to missing kmod page: %08x\n", rinfo);
+ break;
+ }
+
+ kdb_printf(" dependency: %s(%s)@0x%x\n",
+ rinfo->name, rinfo->version, rinfo->address);
+ }
+
+ break; // only report this kmod for one backtrace address
+ }
+ }