static void check_blocks(void) { unsigned int current_page; int do_seek = 1; char *buffer; buffer = xmalloc(pagesize); current_page = 0; while (current_page < PAGES) { if (!check && version == 0) { page_ok(current_page++); continue; } if (do_seek && lseek(DEV, current_page * pagesize, SEEK_SET) != current_page * pagesize) bb_error_msg_and_die("seek failed in check_blocks"); if ((do_seek = (pagesize != read(DEV, buffer, pagesize)))) { current_page++; if (version == 0) bit_test_and_clear(signature_page, current_page); else { if (badpages == MAX_BADPAGES) bb_error_msg_and_die("too many bad pages"); p->badpages[badpages] = current_page; } badpages++; continue; } page_ok(current_page++); } if (ENABLE_FEATURE_CLEAN_UP) free(buffer); if (badpages > 0) printf("%d bad page%s\n", badpages, (badpages==1)?"":"s"); }
static void check_blocks(void) { unsigned int current_page; int do_seek = 1; char *buffer; buffer = xmalloc(pagesize); current_page = 0; while (current_page < PAGES) { if (!check) { page_ok(current_page++); continue; } if (do_seek && lseek(DEV, current_page * pagesize, SEEK_SET) != current_page * pagesize) bb_error_msg_and_die("seek failed in check_blocks"); if ((do_seek = (pagesize != read(DEV, buffer, pagesize)))) { page_bad(current_page++); continue; } page_ok(current_page++); } if (badpages == 1) printf("one bad page\n"); else if (badpages > 1) printf("%d bad pages\n", badpages); }
unsigned long os_get_top_address(void) { struct sigaction sa, old; unsigned long bottom = 0; /* */ unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT; unsigned long test, original; printf("Locating the bottom of the address space ... "); fflush(stdout); /* */ sa.sa_handler = segfault; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_NODEFER; if (sigaction(SIGSEGV, &sa, &old)) { perror("os_get_top_address"); exit(1); } /* */ for (bottom = 0; bottom < top; bottom++) { if (page_ok(bottom)) break; } /* */ if (bottom == top) { fprintf(stderr, "Unable to determine bottom of address " "space.\n"); exit(1); } printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT); printf("Locating the top of the address space ... "); fflush(stdout); original = bottom; /* */ if (page_ok(top)) goto out; do { test = bottom + (top - bottom) / 2; if (page_ok(test)) bottom = test; else top = test; } while (top - bottom > 1); out: /* */ if (sigaction(SIGSEGV, &old, NULL)) { perror("os_get_top_address"); exit(1); } top <<= UM_KERN_PAGE_SHIFT; printf("0x%x\n", top); return top; }
unsigned long os_get_top_address(void) { struct sigaction sa, old; unsigned long bottom = 0; /* * A 32-bit UML on a 64-bit host gets confused about the VDSO at * 0xffffe000. It is mapped, is readable, can be reprotected writeable * and written. However, exec discovers later that it can't be * unmapped. So, just set the highest address to be checked to just * below it. This might waste some address space on 4G/4G 32-bit * hosts, but shouldn't hurt otherwise. */ unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT; unsigned long test, original; printf("Locating the bottom of the address space ... "); fflush(stdout); /* * We're going to be longjmping out of the signal handler, so * SA_DEFER needs to be set. */ sa.sa_handler = segfault; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_NODEFER; if (sigaction(SIGSEGV, &sa, &old)) { perror("os_get_top_address"); exit(1); } /* Manually scan the address space, bottom-up, until we find * the first valid page (or run out of them). */ for (bottom = 0; bottom < top; bottom++) { if (page_ok(bottom)) break; } /* If we've got this far, we ran out of pages. */ if (bottom == top) { fprintf(stderr, "Unable to determine bottom of address " "space.\n"); exit(1); } printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT); printf("Locating the top of the address space ... "); fflush(stdout); original = bottom; /* This could happen with a 4G/4G split */ if (page_ok(top)) goto out; do { test = bottom + (top - bottom) / 2; if (page_ok(test)) bottom = test; else top = test; } while (top - bottom > 1); out: /* Restore the old SIGSEGV handling */ if (sigaction(SIGSEGV, &old, NULL)) { perror("os_get_top_address"); exit(1); } top <<= UM_KERN_PAGE_SHIFT; printf("0x%x\n", top); return top; }