1*86ec409aSkrw /* $OpenBSD: dump.c,v 1.34 2016/01/17 23:18:19 krw Exp $ */ 2fb04e59aSjasper 3*86ec409aSkrw /* 4*86ec409aSkrw * dump.c - dumping partition maps 5*86ec409aSkrw * 6*86ec409aSkrw * Written by Eryk Vershen 7*86ec409aSkrw */ 8dce63815Sdrahn 9dce63815Sdrahn /* 10dce63815Sdrahn * Copyright 1996,1997,1998 by Apple Computer, Inc. 11dce63815Sdrahn * All Rights Reserved 12dce63815Sdrahn * 13dce63815Sdrahn * Permission to use, copy, modify, and distribute this software and 14dce63815Sdrahn * its documentation for any purpose and without fee is hereby granted, 15dce63815Sdrahn * provided that the above copyright notice appears in all copies and 16dce63815Sdrahn * that both the copyright notice and this permission notice appear in 17dce63815Sdrahn * supporting documentation. 18dce63815Sdrahn * 19dce63815Sdrahn * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 20dce63815Sdrahn * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21dce63815Sdrahn * FOR A PARTICULAR PURPOSE. 22dce63815Sdrahn * 23dce63815Sdrahn * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 24dce63815Sdrahn * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 25dce63815Sdrahn * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 26dce63815Sdrahn * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 27dce63815Sdrahn * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 28dce63815Sdrahn */ 29dce63815Sdrahn 30d66063cbSkrw #include <sys/param.h> /* DEV_BSIZE */ 31d66063cbSkrw 3268d0f91bSkrw #include <err.h> 3368d0f91bSkrw 34dce63815Sdrahn #include <stdio.h> 35dce63815Sdrahn #include <stdlib.h> 36dce63815Sdrahn #include <string.h> 37dce63815Sdrahn #include <fcntl.h> 38dce63815Sdrahn #include <errno.h> 39dce63815Sdrahn 40f42746d7Skrw #include "file_media.h" 41dce63815Sdrahn #include "dump.h" 42dce63815Sdrahn #include "io.h" 43dce63815Sdrahn 44dce63815Sdrahn #define get_align_long(x) (*(x)) 45dce63815Sdrahn 4694d20309Skrw struct patchdescriptor { 4717e07d8fSkrw unsigned long patchSig; 48b42d9302Smartin unsigned short majorVers; 49b42d9302Smartin unsigned short minorVers; 50b42d9302Smartin unsigned long flags; 51b42d9302Smartin unsigned long patchOffset; 52b42d9302Smartin unsigned long patchSize; 53b42d9302Smartin unsigned long patchCRC; 54b42d9302Smartin unsigned long patchDescriptorLen; 55b42d9302Smartin unsigned char patchName[33]; 56b42d9302Smartin unsigned char patchVendor[1]; 5794d20309Skrw }; 58b42d9302Smartin 5994d20309Skrw struct patchlist { 60*86ec409aSkrw unsigned short numPatchBlocks; /* number of disk blocks to hold the patch list */ 61*86ec409aSkrw unsigned short numPatches; /* number of patches in list */ 6294d20309Skrw struct patchdescriptor thePatch[1]; 6394d20309Skrw }; 64b42d9302Smartin 65dce63815Sdrahn const char * kStringEmpty = ""; 66dce63815Sdrahn const char * kStringNot = " not"; 67dce63815Sdrahn 68f947f9cbSkrw void adjust_value_and_compute_prefix(double *, int *); 69f947f9cbSkrw void dump_block_zero(struct partition_map_header *); 70f947f9cbSkrw void dump_partition_entry(struct partition_map *, int, int, int); 71f947f9cbSkrw int get_max_base_or_length(struct partition_map_header *); 72f947f9cbSkrw int get_max_name_string_length(struct partition_map_header *); 73f947f9cbSkrw int get_max_type_string_length(struct partition_map_header *); 74dce63815Sdrahn 75dce63815Sdrahn int 76dce63815Sdrahn dump(char *name) 77dce63815Sdrahn { 78eedab009Skrw struct partition_map_header *map; 79dce63815Sdrahn int junk; 80dce63815Sdrahn 815d0b0825Skrw map = open_partition_map(name, &junk); 82dce63815Sdrahn if (map == NULL) { 83dce63815Sdrahn return 0; 84dce63815Sdrahn } 85dce63815Sdrahn 86dce63815Sdrahn dump_partition_map(map, 1); 87dce63815Sdrahn 88dce63815Sdrahn close_partition_map(map); 89dce63815Sdrahn 90dce63815Sdrahn return 1; 91dce63815Sdrahn } 92dce63815Sdrahn 93dce63815Sdrahn 94dce63815Sdrahn void 95eedab009Skrw dump_block_zero(struct partition_map_header *map) 96dce63815Sdrahn { 9771bd5f9cSkrw struct block0 *p; 9870060700Skrw struct ddmap *m; 99dce63815Sdrahn int i; 100dce63815Sdrahn double value; 101dce63815Sdrahn int prefix; 102b42d9302Smartin long t; 103dce63815Sdrahn 104dce63815Sdrahn p = map->misc; 105dce63815Sdrahn if (p->sbSig != BLOCK0_SIGNATURE) { 106dce63815Sdrahn return; 107dce63815Sdrahn } 108dce63815Sdrahn 109dce63815Sdrahn value = ((double)p->sbBlkCount) * p->sbBlkSize; 110dce63815Sdrahn adjust_value_and_compute_prefix(&value, &prefix); 111024cef13Skrw printf("\nDevice block size=%u, Number of Blocks=%u (%1.1f%c)\n", 112dce63815Sdrahn p->sbBlkSize, p->sbBlkCount, value, prefix); 113dce63815Sdrahn 114dce63815Sdrahn printf("DeviceType=0x%x, DeviceId=0x%x\n", 115dce63815Sdrahn p->sbDevType, p->sbDevId); 116dce63815Sdrahn if (p->sbDrvrCount > 0) { 117dce63815Sdrahn printf("Drivers-\n"); 11870060700Skrw m = (struct ddmap *) p->sbMap; 119dce63815Sdrahn for (i = 0; i < p->sbDrvrCount; i++) { 120024cef13Skrw printf("%d: %3u @ %u, ", i+1, 121b42d9302Smartin m[i].ddSize, get_align_long(&m[i].ddBlock)); 122b42d9302Smartin if (map->logical_block != p->sbBlkSize) { 123b42d9302Smartin t = (m[i].ddSize * p->sbBlkSize) / map->logical_block; 124b42d9302Smartin printf("(%lu@", t); 125b42d9302Smartin t = (get_align_long(&m[i].ddBlock) * p->sbBlkSize) 126b42d9302Smartin / map->logical_block; 127b42d9302Smartin printf("%lu) ", t); 128b42d9302Smartin } 129b42d9302Smartin printf("type=0x%x\n", m[i].ddType); 130dce63815Sdrahn } 131dce63815Sdrahn } 132dce63815Sdrahn printf("\n"); 133dce63815Sdrahn } 134dce63815Sdrahn 135dce63815Sdrahn 136dce63815Sdrahn void 137eedab009Skrw dump_partition_map(struct partition_map_header *map, int disk_order) 138dce63815Sdrahn { 139eedab009Skrw struct partition_map * entry; 140dce63815Sdrahn int max_type_length; 141dce63815Sdrahn int max_name_length; 142dce63815Sdrahn int digits; 143dce63815Sdrahn 144dce63815Sdrahn if (map == NULL) { 145dce63815Sdrahn bad_input("No partition map exists"); 146dce63815Sdrahn return; 147dce63815Sdrahn } 148dce63815Sdrahn printf("\nPartition map (with %d byte blocks) on '%s'\n", 149dce63815Sdrahn map->logical_block, map->name); 150dce63815Sdrahn 151dce63815Sdrahn digits = number_of_digits(get_max_base_or_length(map)); 152dce63815Sdrahn if (digits < 6) { 153dce63815Sdrahn digits = 6; 154dce63815Sdrahn } 155dce63815Sdrahn max_type_length = get_max_type_string_length(map); 156dce63815Sdrahn if (max_type_length < 4) { 157dce63815Sdrahn max_type_length = 4; 158dce63815Sdrahn } 159dce63815Sdrahn max_name_length = get_max_name_string_length(map); 160dce63815Sdrahn if (max_name_length < 6) { 161dce63815Sdrahn max_name_length = 6; 162dce63815Sdrahn } 163dce63815Sdrahn printf(" #: %*s %-*s %*s %-*s ( size )\n", 164dce63815Sdrahn max_type_length, "type", 165dce63815Sdrahn max_name_length, "name", 166dce63815Sdrahn digits, "length", digits, "base"); 167dce63815Sdrahn 168dce63815Sdrahn if (disk_order) { 169dce63815Sdrahn for (entry = map->disk_order; entry != NULL; 170dce63815Sdrahn entry = entry->next_on_disk) { 171dce63815Sdrahn 172dce63815Sdrahn dump_partition_entry(entry, max_type_length, max_name_length, digits); 173dce63815Sdrahn } 174dce63815Sdrahn } else { 175dce63815Sdrahn for (entry = map->base_order; entry != NULL; 176dce63815Sdrahn entry = entry->next_by_base) { 177dce63815Sdrahn 178dce63815Sdrahn dump_partition_entry(entry, max_type_length, max_name_length, digits); 179dce63815Sdrahn } 180dce63815Sdrahn } 181dce63815Sdrahn dump_block_zero(map); 182dce63815Sdrahn } 183dce63815Sdrahn 184dce63815Sdrahn 185dce63815Sdrahn void 186eedab009Skrw dump_partition_entry(struct partition_map *entry, int type_length, int name_length, int digits) 187dce63815Sdrahn { 188eedab009Skrw struct partition_map_header *map; 189dce63815Sdrahn int j; 1906521004eSkrw struct dpme *p; 191024cef13Skrw uint32_t size; 192dce63815Sdrahn double bytes; 19377a25ee3Sjasper int driver; 194b42d9302Smartin char *buf; 195dce63815Sdrahn 196dce63815Sdrahn map = entry->the_map; 197dce63815Sdrahn p = entry->data; 198dce63815Sdrahn driver = entry->contains_driver? '*': ' '; 199b42d9302Smartin printf("%2ld: %*.32s", entry->disk_address, type_length, p->dpme_type); 200dce63815Sdrahn 2015ae94ef8Sderaadt buf = malloc(name_length+1); 202b42d9302Smartin strncpy(buf, p->dpme_name, name_length); 203b42d9302Smartin buf[name_length] = 0; 204b42d9302Smartin printf("%c%-*.32s ", driver, name_length, buf); 205b42d9302Smartin free(buf); 206b42d9302Smartin 2077446d16eSkrw if (p->dpme_lblocks + p->dpme_lblock_start != p->dpme_pblocks) { 208024cef13Skrw printf("%*u+", digits, p->dpme_lblocks); 209dce63815Sdrahn size = p->dpme_lblocks; 210dce63815Sdrahn } else if (p->dpme_lblock_start != 0) { 211024cef13Skrw printf("%*u ", digits, p->dpme_lblocks); 212dce63815Sdrahn size = p->dpme_lblocks; 213dce63815Sdrahn } else { 214024cef13Skrw printf("%*u ", digits, p->dpme_pblocks); 215dce63815Sdrahn size = p->dpme_pblocks; 216dce63815Sdrahn } 2177446d16eSkrw if (p->dpme_lblock_start == 0) { 218024cef13Skrw printf("@ %-*u", digits, p->dpme_pblock_start); 219dce63815Sdrahn } else { 220024cef13Skrw printf("@~%-*u", digits, p->dpme_pblock_start + p->dpme_lblock_start); 221dce63815Sdrahn } 222dce63815Sdrahn 223dce63815Sdrahn bytes = ((double)size) * map->logical_block; 224dce63815Sdrahn adjust_value_and_compute_prefix(&bytes, &j); 225dce63815Sdrahn if (j != ' ' && j != 'K') { 226dce63815Sdrahn printf(" (%#5.1f%c)", bytes, j); 227dce63815Sdrahn } 228dce63815Sdrahn 229dce63815Sdrahn printf("\n"); 230dce63815Sdrahn } 231dce63815Sdrahn 232dce63815Sdrahn 233dce63815Sdrahn void 234eedab009Skrw show_data_structures(struct partition_map_header *map) 235dce63815Sdrahn { 23671bd5f9cSkrw struct block0 *zp; 23770060700Skrw struct ddmap *m; 238dce63815Sdrahn int i; 239eedab009Skrw struct partition_map * entry; 2406521004eSkrw struct dpme *p; 241dce63815Sdrahn 242dce63815Sdrahn if (map == NULL) { 243dce63815Sdrahn printf("No partition map exists\n"); 244dce63815Sdrahn return; 245dce63815Sdrahn } 246dce63815Sdrahn printf("Header:\n"); 247dce63815Sdrahn printf("map %d blocks out of %d, media %lu blocks (%d byte blocks)\n", 248dce63815Sdrahn map->blocks_in_map, map->maximum_in_map, 249dce63815Sdrahn map->media_size, map->logical_block); 250b42d9302Smartin printf("Map is%s writable", (map->writable)?kStringEmpty:kStringNot); 251b42d9302Smartin printf(", but%s changed", (map->changed)?kStringEmpty:kStringNot); 252b42d9302Smartin printf(" and has%s been written\n", (map->written)?kStringEmpty:kStringNot); 253dce63815Sdrahn printf("\n"); 254dce63815Sdrahn 255dce63815Sdrahn if (map->misc == NULL) { 256dce63815Sdrahn printf("No block zero\n"); 257dce63815Sdrahn } else { 258dce63815Sdrahn zp = map->misc; 259dce63815Sdrahn 260dce63815Sdrahn printf("Block0:\n"); 261dce63815Sdrahn printf("signature 0x%x", zp->sbSig); 262dce63815Sdrahn if (zp->sbSig == BLOCK0_SIGNATURE) { 263dce63815Sdrahn printf("\n"); 264dce63815Sdrahn } else { 265dce63815Sdrahn printf(" should be 0x%x\n", BLOCK0_SIGNATURE); 266dce63815Sdrahn } 267024cef13Skrw printf("Block size=%u, Number of Blocks=%u\n", 268dce63815Sdrahn zp->sbBlkSize, zp->sbBlkCount); 269024cef13Skrw printf("DeviceType=0x%x, DeviceId=0x%x, sbData=0x%x\n", 270dce63815Sdrahn zp->sbDevType, zp->sbDevId, zp->sbData); 271dce63815Sdrahn if (zp->sbDrvrCount == 0) { 272dce63815Sdrahn printf("No drivers\n"); 273dce63815Sdrahn } else { 274dce63815Sdrahn printf("%u driver%s-\n", zp->sbDrvrCount, 275dce63815Sdrahn (zp->sbDrvrCount>1)?"s":kStringEmpty); 27670060700Skrw m = (struct ddmap *) zp->sbMap; 277dce63815Sdrahn for (i = 0; i < zp->sbDrvrCount; i++) { 278024cef13Skrw printf("%u: @ %u for %u, type=0x%x\n", i+1, 279dce63815Sdrahn get_align_long(&m[i].ddBlock), 280dce63815Sdrahn m[i].ddSize, m[i].ddType); 281dce63815Sdrahn } 282dce63815Sdrahn } 283dce63815Sdrahn } 284dce63815Sdrahn printf("\n"); 285dce63815Sdrahn printf(" #: type length base " 286dce63815Sdrahn "flags (logical)\n"); 287dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 288dce63815Sdrahn p = entry->data; 289dce63815Sdrahn printf("%2ld: %20.32s ", 290dce63815Sdrahn entry->disk_address, p->dpme_type); 291024cef13Skrw printf("%7u @ %-7u ", p->dpme_pblocks, p->dpme_pblock_start); 292dce63815Sdrahn printf("%c%c%c%c%c%c%c%c%c%c%c%c ", 293a1ac9a96Skrw (p->dpme_flags & DPME_VALID)?'V':'.', 294a1ac9a96Skrw (p->dpme_flags & DPME_ALLOCATED)?'A':'.', 295a1ac9a96Skrw (p->dpme_flags & DPME_IN_USE)?'I':'.', 296a1ac9a96Skrw (p->dpme_flags & DPME_BOOTABLE)?'B':'.', 297a1ac9a96Skrw (p->dpme_flags & DPME_READABLE)?'R':'.', 298a1ac9a96Skrw (p->dpme_flags & DPME_WRITABLE)?'W':'.', 299a1ac9a96Skrw (p->dpme_flags & DPME_OS_PIC_CODE)?'P':'.', 300a1ac9a96Skrw (p->dpme_flags & DPME_OS_SPECIFIC_2)?'2':'.', 301a1ac9a96Skrw (p->dpme_flags & DPME_CHAINABLE)?'C':'.', 302a1ac9a96Skrw (p->dpme_flags & DPME_DISKDRIVER)?'D':'.', 303a1ac9a96Skrw (p->dpme_flags & (1<<30))?'M':'.', 304a1ac9a96Skrw (p->dpme_flags & (1<<31))?'X':'.'); 305dce63815Sdrahn if (p->dpme_lblock_start != 0 || p->dpme_pblocks != p->dpme_lblocks) { 306024cef13Skrw printf("(%u @ %u)", p->dpme_lblocks, p->dpme_lblock_start); 307dce63815Sdrahn } 308dce63815Sdrahn printf("\n"); 309dce63815Sdrahn } 310dce63815Sdrahn printf("\n"); 311dce63815Sdrahn printf(" #: booter bytes load_address " 312dce63815Sdrahn "goto_address checksum processor\n"); 313dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 314dce63815Sdrahn p = entry->data; 315dce63815Sdrahn printf("%2ld: ", entry->disk_address); 316024cef13Skrw printf("%7u ", p->dpme_boot_block); 317024cef13Skrw printf("%7u ", p->dpme_boot_bytes); 318024cef13Skrw printf("%8x ", (uint32_t)p->dpme_load_addr); 319024cef13Skrw printf("%8x ", (uint32_t)p->dpme_load_addr_2); 320024cef13Skrw printf("%8x ", (uint32_t)p->dpme_goto_addr); 321024cef13Skrw printf("%8x ", (uint32_t)p->dpme_goto_addr_2); 322024cef13Skrw printf("%8x ", p->dpme_checksum); 323dce63815Sdrahn printf("%.32s", p->dpme_process_id); 324dce63815Sdrahn printf("\n"); 325dce63815Sdrahn } 326dce63815Sdrahn printf("\n"); 327dce63815Sdrahn } 328dce63815Sdrahn 329dce63815Sdrahn 330dce63815Sdrahn void 331eedab009Skrw full_dump_partition_entry(struct partition_map_header *map, int ix) 332dce63815Sdrahn { 333eedab009Skrw struct partition_map * cur; 3346521004eSkrw struct dpme *p; 335dce63815Sdrahn int i; 336024cef13Skrw uint32_t t; 337dce63815Sdrahn 338b42d9302Smartin cur = find_entry_by_disk_address(ix, map); 339dce63815Sdrahn if (cur == NULL) { 340dce63815Sdrahn printf("No such partition\n"); 341dce63815Sdrahn return; 342dce63815Sdrahn } 343dce63815Sdrahn 344dce63815Sdrahn p = cur->data; 345dce63815Sdrahn printf(" signature: 0x%x\n", p->dpme_signature); 346dce63815Sdrahn printf(" reserved1: 0x%x\n", p->dpme_reserved_1); 347024cef13Skrw printf(" number of map entries: %u\n", p->dpme_map_entries); 348024cef13Skrw printf(" physical start: %10u length: %10u\n", p->dpme_pblock_start, p->dpme_pblocks); 349024cef13Skrw printf(" logical start: %10u length: %10u\n", p->dpme_lblock_start, p->dpme_lblocks); 350dce63815Sdrahn 351024cef13Skrw printf(" flags: 0x%x\n", (uint32_t)p->dpme_flags); 352dce63815Sdrahn printf(" "); 353a1ac9a96Skrw if (p->dpme_flags & DPME_VALID) printf("valid "); 354a1ac9a96Skrw if (p->dpme_flags & DPME_ALLOCATED) printf("alloc "); 355a1ac9a96Skrw if (p->dpme_flags & DPME_IN_USE) printf("in-use "); 356a1ac9a96Skrw if (p->dpme_flags & DPME_BOOTABLE) printf("boot "); 357a1ac9a96Skrw if (p->dpme_flags & DPME_READABLE) printf("read "); 358a1ac9a96Skrw if (p->dpme_flags & DPME_WRITABLE) printf("write "); 359a1ac9a96Skrw if (p->dpme_flags & DPME_OS_PIC_CODE) printf("pic "); 360dce63815Sdrahn t = p->dpme_flags >> 7; 361dce63815Sdrahn for (i = 7; i <= 31; i++) { 362dce63815Sdrahn if (t & 0x1) { 363dce63815Sdrahn printf("%d ", i); 364dce63815Sdrahn } 365dce63815Sdrahn t = t >> 1; 366dce63815Sdrahn } 367dce63815Sdrahn printf("\n"); 368dce63815Sdrahn 369dce63815Sdrahn printf(" name: '%.32s'\n", p->dpme_name); 370dce63815Sdrahn printf(" type: '%.32s'\n", p->dpme_type); 371dce63815Sdrahn 372024cef13Skrw printf(" boot start block: %10u\n", p->dpme_boot_block); 373024cef13Skrw printf("boot length (in bytes): %10u\n", p->dpme_boot_bytes); 374024cef13Skrw printf(" load address: 0x%08x 0x%08x\n", 375024cef13Skrw (uint32_t)p->dpme_load_addr, (uint32_t)p->dpme_load_addr_2); 376024cef13Skrw printf(" start address: 0x%08x 0x%08x\n", 377024cef13Skrw (uint32_t)p->dpme_goto_addr, (uint32_t)p->dpme_goto_addr_2); 378024cef13Skrw printf(" checksum: 0x%08x\n", p->dpme_checksum); 379dce63815Sdrahn printf(" processor: '%.32s'\n", p->dpme_process_id); 380dce63815Sdrahn printf("boot args field -"); 381dce63815Sdrahn dump_block((unsigned char *)p->dpme_boot_args, 32*4); 382dce63815Sdrahn printf("dpme_reserved_3 -"); 383dce63815Sdrahn dump_block((unsigned char *)p->dpme_reserved_3, 62*4); 384dce63815Sdrahn } 385dce63815Sdrahn 386dce63815Sdrahn 387dce63815Sdrahn void 388dce63815Sdrahn dump_block(unsigned char *addr, int len) 389dce63815Sdrahn { 390dce63815Sdrahn int i; 391dce63815Sdrahn int j; 392dce63815Sdrahn int limit1; 393dce63815Sdrahn int limit; 394dce63815Sdrahn #define LINE_LEN 16 395dce63815Sdrahn #define UNIT_LEN 4 396dce63815Sdrahn #define OTHER_LEN 8 397dce63815Sdrahn 398dce63815Sdrahn for (i = 0; i < len; i = limit) { 399dce63815Sdrahn limit1 = i + LINE_LEN; 400dce63815Sdrahn if (limit1 > len) { 401dce63815Sdrahn limit = len; 402dce63815Sdrahn } else { 403dce63815Sdrahn limit = limit1; 404dce63815Sdrahn } 405dce63815Sdrahn printf("\n%03x: ", i); 406dce63815Sdrahn for (j = i; j < limit1; j++) { 407dce63815Sdrahn if (j % UNIT_LEN == 0) { 408dce63815Sdrahn printf(" "); 409dce63815Sdrahn } 410dce63815Sdrahn if (j < limit) { 411dce63815Sdrahn printf("%02x", addr[j]); 412dce63815Sdrahn } else { 413dce63815Sdrahn printf(" "); 414dce63815Sdrahn } 415dce63815Sdrahn } 416dce63815Sdrahn printf(" "); 417dce63815Sdrahn for (j = i; j < limit; j++) { 418dce63815Sdrahn if (j % OTHER_LEN == 0) { 419dce63815Sdrahn printf(" "); 420dce63815Sdrahn } 421dce63815Sdrahn if (addr[j] < ' ') { 422dce63815Sdrahn printf("."); 423dce63815Sdrahn } else { 424dce63815Sdrahn printf("%c", addr[j]); 425dce63815Sdrahn } 426dce63815Sdrahn } 427dce63815Sdrahn } 428dce63815Sdrahn printf("\n"); 429dce63815Sdrahn } 430dce63815Sdrahn 431dce63815Sdrahn void 432eedab009Skrw full_dump_block_zero(struct partition_map_header *map) 433dce63815Sdrahn { 43471bd5f9cSkrw struct block0 *zp; 43570060700Skrw struct ddmap *m; 436dce63815Sdrahn int i; 437dce63815Sdrahn 438dce63815Sdrahn if (map == NULL) { 439dce63815Sdrahn printf("No partition map exists\n"); 440dce63815Sdrahn return; 441dce63815Sdrahn } 442dce63815Sdrahn 443dce63815Sdrahn if (map->misc == NULL) { 444dce63815Sdrahn printf("No block zero\n"); 445dce63815Sdrahn return; 446dce63815Sdrahn } 447dce63815Sdrahn zp = map->misc; 448dce63815Sdrahn 449dce63815Sdrahn printf(" signature: 0x%x\n", zp->sbSig); 450024cef13Skrw printf(" size of a block: %u\n", zp->sbBlkSize); 451024cef13Skrw printf(" number of blocks: %u\n", zp->sbBlkCount); 452dce63815Sdrahn printf(" device type: 0x%x\n", zp->sbDevType); 453dce63815Sdrahn printf(" device id: 0x%x\n", zp->sbDevId); 454024cef13Skrw printf(" data: 0x%x\n", zp->sbData); 455024cef13Skrw printf(" driver count: %u\n", zp->sbDrvrCount); 45670060700Skrw m = (struct ddmap *) zp->sbMap; 457dce63815Sdrahn for (i = 0; &m[i].ddType < &zp->sbMap[247]; i++) { 458dce63815Sdrahn if (m[i].ddBlock == 0 && m[i].ddSize == 0 && m[i].ddType == 0) { 459dce63815Sdrahn break; 460dce63815Sdrahn } 461024cef13Skrw printf(" driver %3u block: %u\n", i+1, m[i].ddBlock); 462024cef13Skrw printf(" size in blocks: %u\n", m[i].ddSize); 463dce63815Sdrahn printf(" driver type: 0x%x\n", m[i].ddType); 464dce63815Sdrahn } 465dce63815Sdrahn printf("remainder of block -"); 466dce63815Sdrahn dump_block((unsigned char *)&m[i].ddBlock, (&zp->sbMap[247]-((unsigned short *)&m[i].ddBlock))*2); 467dce63815Sdrahn } 468dce63815Sdrahn 469b42d9302Smartin 470dce63815Sdrahn void 471eedab009Skrw display_patches(struct partition_map *entry) 472dce63815Sdrahn { 473dce63815Sdrahn long long offset; 4746a69102aSkrw struct file_media *m; 475dce63815Sdrahn static unsigned char *patch_block; 47694d20309Skrw struct patchlist *p; 47794d20309Skrw struct patchdescriptor *q; 478b42d9302Smartin unsigned char *next; 479b42d9302Smartin unsigned char *s; 480b42d9302Smartin int i; 481dce63815Sdrahn 482dce63815Sdrahn offset = entry->data->dpme_pblock_start; 483dce63815Sdrahn m = entry->the_map->m; 484dce63815Sdrahn offset = ((long long) entry->data->dpme_pblock_start) * entry->the_map->logical_block; 485dce63815Sdrahn if (patch_block == NULL) { 486d66063cbSkrw patch_block = malloc(DEV_BSIZE); 487dce63815Sdrahn if (patch_block == NULL) { 48868d0f91bSkrw warn("can't allocate memory for patch block buffer"); 489dce63815Sdrahn return; 490dce63815Sdrahn } 491dce63815Sdrahn } 492f42746d7Skrw if (read_file_media(m, (long long)offset, DEV_BSIZE, (char *)patch_block) == 0) { 49368d0f91bSkrw warn("Can't read patch block"); 494dce63815Sdrahn return; 495dce63815Sdrahn } 49694d20309Skrw p = (struct patchlist *) patch_block; 497b42d9302Smartin if (p->numPatchBlocks != 1) { 498b42d9302Smartin i = p->numPatchBlocks; 499b42d9302Smartin free(patch_block); 500d66063cbSkrw patch_block = reallocarray(NULL, i, DEV_BSIZE); 501b42d9302Smartin if (patch_block == NULL) { 50268d0f91bSkrw warn("can't allocate memory for patch blocks buffer"); 503b42d9302Smartin return; 504b42d9302Smartin } 505d66063cbSkrw s = patch_block + DEV_BSIZE*i; 506b42d9302Smartin while (i > 0) { 507d66063cbSkrw s -= DEV_BSIZE; 508b42d9302Smartin i -= 1; 509f42746d7Skrw if (read_file_media(m, offset+i, DEV_BSIZE, (char *)s) == 0) { 51068d0f91bSkrw warn("Can't read patch block %d", i); 511b42d9302Smartin return; 512b42d9302Smartin } 513b42d9302Smartin } 51494d20309Skrw p = (struct patchlist *) patch_block; 515b42d9302Smartin } 516b42d9302Smartin printf("Patch list (%d entries)\n", p->numPatches); 517b42d9302Smartin q = p->thePatch; 518b42d9302Smartin for (i = 0; i < p->numPatches; i++) { 519b42d9302Smartin printf("%2d signature: '%.4s'\n", i+1, (char *)&q->patchSig); 520b42d9302Smartin printf(" version: %d.%d\n", q->majorVers, q->minorVers); 521b42d9302Smartin printf(" flags: 0x%lx\n", q->flags); 522b42d9302Smartin printf(" offset: %ld\n", q->patchOffset); 523b42d9302Smartin printf(" size: %ld\n", q->patchSize); 524b42d9302Smartin printf(" CRC: 0x%lx\n", q->patchCRC); 525b42d9302Smartin printf(" name: '%.*s'\n", q->patchName[0], &q->patchName[1]); 526b42d9302Smartin printf(" vendor: '%.*s'\n", q->patchVendor[0], &q->patchVendor[1]); 527b42d9302Smartin next = ((unsigned char *)q) + q->patchDescriptorLen; 528b42d9302Smartin s = &q->patchVendor[q->patchVendor[0]+1]; 529b42d9302Smartin if (next > s) { 530b42d9302Smartin printf("remainder of entry -"); 531b42d9302Smartin dump_block(s, next-s); 532b42d9302Smartin } 53394d20309Skrw q = (struct patchdescriptor *)next; 534b42d9302Smartin } 535dce63815Sdrahn } 536dce63815Sdrahn 537dce63815Sdrahn int 538eedab009Skrw get_max_type_string_length(struct partition_map_header *map) 539dce63815Sdrahn { 540eedab009Skrw struct partition_map * entry; 541dce63815Sdrahn int max; 542dce63815Sdrahn int length; 543dce63815Sdrahn 544dce63815Sdrahn if (map == NULL) { 545dce63815Sdrahn return 0; 546dce63815Sdrahn } 547dce63815Sdrahn 548dce63815Sdrahn max = 0; 549dce63815Sdrahn 550dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 551dce63815Sdrahn length = strnlen(entry->data->dpme_type, DPISTRLEN); 552dce63815Sdrahn if (length > max) { 553dce63815Sdrahn max = length; 554dce63815Sdrahn } 555dce63815Sdrahn } 556dce63815Sdrahn 557dce63815Sdrahn return max; 558dce63815Sdrahn } 559dce63815Sdrahn 560dce63815Sdrahn int 561eedab009Skrw get_max_name_string_length(struct partition_map_header *map) 562dce63815Sdrahn { 563eedab009Skrw struct partition_map * entry; 564dce63815Sdrahn int max; 565dce63815Sdrahn int length; 566dce63815Sdrahn 567dce63815Sdrahn if (map == NULL) { 568dce63815Sdrahn return 0; 569dce63815Sdrahn } 570dce63815Sdrahn 571dce63815Sdrahn max = 0; 572dce63815Sdrahn 573dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 574dce63815Sdrahn length = strnlen(entry->data->dpme_name, DPISTRLEN); 575dce63815Sdrahn if (length > max) { 576dce63815Sdrahn max = length; 577dce63815Sdrahn } 578dce63815Sdrahn } 579dce63815Sdrahn 580dce63815Sdrahn return max; 581dce63815Sdrahn } 582dce63815Sdrahn 583dce63815Sdrahn int 584eedab009Skrw get_max_base_or_length(struct partition_map_header *map) 585dce63815Sdrahn { 586eedab009Skrw struct partition_map * entry; 587dce63815Sdrahn int max; 588dce63815Sdrahn 589dce63815Sdrahn if (map == NULL) { 590dce63815Sdrahn return 0; 591dce63815Sdrahn } 592dce63815Sdrahn 593dce63815Sdrahn max = 0; 594dce63815Sdrahn 595dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 596dce63815Sdrahn if (entry->data->dpme_pblock_start > max) { 597dce63815Sdrahn max = entry->data->dpme_pblock_start; 598dce63815Sdrahn } 599dce63815Sdrahn if (entry->data->dpme_pblocks > max) { 600dce63815Sdrahn max = entry->data->dpme_pblocks; 601dce63815Sdrahn } 602dce63815Sdrahn if (entry->data->dpme_lblock_start > max) { 603dce63815Sdrahn max = entry->data->dpme_lblock_start; 604dce63815Sdrahn } 605dce63815Sdrahn if (entry->data->dpme_lblocks > max) { 606dce63815Sdrahn max = entry->data->dpme_lblocks; 607dce63815Sdrahn } 608dce63815Sdrahn } 609dce63815Sdrahn 610dce63815Sdrahn return max; 611dce63815Sdrahn } 612dce63815Sdrahn 613dce63815Sdrahn void 614dce63815Sdrahn adjust_value_and_compute_prefix(double *value, int *prefix) 615dce63815Sdrahn { 616dce63815Sdrahn double bytes; 617dce63815Sdrahn int multiplier; 618dce63815Sdrahn 619dce63815Sdrahn bytes = *value; 620dce63815Sdrahn if (bytes < 1024.0) { 621dce63815Sdrahn multiplier = ' '; 622dce63815Sdrahn } else { 623dce63815Sdrahn bytes = bytes / 1024.0; 624dce63815Sdrahn if (bytes < 1024.0) { 625dce63815Sdrahn multiplier = 'K'; 626dce63815Sdrahn } else { 627dce63815Sdrahn bytes = bytes / 1024.0; 628dce63815Sdrahn if (bytes < 1024.0) { 629dce63815Sdrahn multiplier = 'M'; 630dce63815Sdrahn } else { 631dce63815Sdrahn bytes = bytes / 1024.0; 632dce63815Sdrahn if (bytes < 1024.0) { 633dce63815Sdrahn multiplier = 'G'; 634dce63815Sdrahn } else { 635dce63815Sdrahn bytes = bytes / 1024.0; 636dce63815Sdrahn multiplier = 'T'; 637dce63815Sdrahn } 638dce63815Sdrahn } 639dce63815Sdrahn } 640dce63815Sdrahn } 641dce63815Sdrahn *value = bytes; 642dce63815Sdrahn *prefix = multiplier; 643dce63815Sdrahn } 644