1*94d20309Skrw /* $OpenBSD: dump.c,v 1.28 2016/01/17 16:44:01 krw Exp $ */ 2fb04e59aSjasper 3dce63815Sdrahn // 4dce63815Sdrahn // dump.c - dumping partition maps 5dce63815Sdrahn // 6b42d9302Smartin // Written by Eryk Vershen 7dce63815Sdrahn // 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 // for *printf() 35dce63815Sdrahn #include <stdio.h> 36dce63815Sdrahn 37dce63815Sdrahn // for malloc() & free() 38dce63815Sdrahn #include <stdlib.h> 39dce63815Sdrahn 40dce63815Sdrahn // for strcmp() 41dce63815Sdrahn #include <string.h> 42dce63815Sdrahn // for O_RDONLY 43dce63815Sdrahn #include <fcntl.h> 44dce63815Sdrahn // for errno 45dce63815Sdrahn #include <errno.h> 46dce63815Sdrahn 47f42746d7Skrw #include "file_media.h" 48dce63815Sdrahn #include "dump.h" 49dce63815Sdrahn #include "io.h" 50dce63815Sdrahn 51dce63815Sdrahn 52dce63815Sdrahn // 53dce63815Sdrahn // Defines 54dce63815Sdrahn // 55dce63815Sdrahn #define get_align_long(x) (*(x)) 56dce63815Sdrahn 57dce63815Sdrahn 58dce63815Sdrahn // 59dce63815Sdrahn // Types 60dce63815Sdrahn // 61b42d9302Smartin 62*94d20309Skrw struct patchdescriptor { 6317e07d8fSkrw unsigned long patchSig; 64b42d9302Smartin unsigned short majorVers; 65b42d9302Smartin unsigned short minorVers; 66b42d9302Smartin unsigned long flags; 67b42d9302Smartin unsigned long patchOffset; 68b42d9302Smartin unsigned long patchSize; 69b42d9302Smartin unsigned long patchCRC; 70b42d9302Smartin unsigned long patchDescriptorLen; 71b42d9302Smartin unsigned char patchName[33]; 72b42d9302Smartin unsigned char patchVendor[1]; 73*94d20309Skrw }; 74b42d9302Smartin 75*94d20309Skrw struct patchlist { 76b42d9302Smartin unsigned short numPatchBlocks; // number of disk blocks to hold the patch list 77b42d9302Smartin unsigned short numPatches; // number of patches in list 78*94d20309Skrw struct patchdescriptor thePatch[1]; 79*94d20309Skrw }; 80b42d9302Smartin 81dce63815Sdrahn 82dce63815Sdrahn // 83dce63815Sdrahn // Global Constants 84dce63815Sdrahn // 85dce63815Sdrahn 86dce63815Sdrahn const char * kStringEmpty = ""; 87dce63815Sdrahn const char * kStringNot = " not"; 88dce63815Sdrahn 89dce63815Sdrahn 90dce63815Sdrahn // 91dce63815Sdrahn // Global Variables 92dce63815Sdrahn // 93dce63815Sdrahn 94dce63815Sdrahn 95dce63815Sdrahn // 96dce63815Sdrahn // Forward declarations 97dce63815Sdrahn // 98dce63815Sdrahn void adjust_value_and_compute_prefix(double *value, int *prefix); 99dce63815Sdrahn void dump_block_zero(partition_map_header *map); 100dce63815Sdrahn void dump_partition_entry(partition_map *entry, int type_length, int name_length, int digits); 101dce63815Sdrahn int get_max_base_or_length(partition_map_header *map); 102dce63815Sdrahn int get_max_name_string_length(partition_map_header *map); 103dce63815Sdrahn int get_max_type_string_length(partition_map_header *map); 104dce63815Sdrahn 105dce63815Sdrahn 106dce63815Sdrahn // 107dce63815Sdrahn // Routines 108dce63815Sdrahn // 109dce63815Sdrahn int 110dce63815Sdrahn dump(char *name) 111dce63815Sdrahn { 112dce63815Sdrahn partition_map_header *map; 113dce63815Sdrahn int junk; 114dce63815Sdrahn 1155d0b0825Skrw map = open_partition_map(name, &junk); 116dce63815Sdrahn if (map == NULL) { 117dce63815Sdrahn return 0; 118dce63815Sdrahn } 119dce63815Sdrahn 120dce63815Sdrahn dump_partition_map(map, 1); 121dce63815Sdrahn 122dce63815Sdrahn close_partition_map(map); 123dce63815Sdrahn 124dce63815Sdrahn return 1; 125dce63815Sdrahn } 126dce63815Sdrahn 127dce63815Sdrahn 128dce63815Sdrahn void 129dce63815Sdrahn dump_block_zero(partition_map_header *map) 130dce63815Sdrahn { 13171bd5f9cSkrw struct block0 *p; 13270060700Skrw struct ddmap *m; 133dce63815Sdrahn int i; 134dce63815Sdrahn double value; 135dce63815Sdrahn int prefix; 136b42d9302Smartin long t; 137dce63815Sdrahn 138dce63815Sdrahn p = map->misc; 139dce63815Sdrahn if (p->sbSig != BLOCK0_SIGNATURE) { 140dce63815Sdrahn return; 141dce63815Sdrahn } 142dce63815Sdrahn 143dce63815Sdrahn value = ((double)p->sbBlkCount) * p->sbBlkSize; 144dce63815Sdrahn adjust_value_and_compute_prefix(&value, &prefix); 145dce63815Sdrahn printf("\nDevice block size=%u, Number of Blocks=%lu (%1.1f%c)\n", 146dce63815Sdrahn p->sbBlkSize, p->sbBlkCount, value, prefix); 147dce63815Sdrahn 148dce63815Sdrahn printf("DeviceType=0x%x, DeviceId=0x%x\n", 149dce63815Sdrahn p->sbDevType, p->sbDevId); 150dce63815Sdrahn if (p->sbDrvrCount > 0) { 151dce63815Sdrahn printf("Drivers-\n"); 15270060700Skrw m = (struct ddmap *) p->sbMap; 153dce63815Sdrahn for (i = 0; i < p->sbDrvrCount; i++) { 154b42d9302Smartin printf("%u: %3u @ %lu, ", i+1, 155b42d9302Smartin m[i].ddSize, get_align_long(&m[i].ddBlock)); 156b42d9302Smartin if (map->logical_block != p->sbBlkSize) { 157b42d9302Smartin t = (m[i].ddSize * p->sbBlkSize) / map->logical_block; 158b42d9302Smartin printf("(%lu@", t); 159b42d9302Smartin t = (get_align_long(&m[i].ddBlock) * p->sbBlkSize) 160b42d9302Smartin / map->logical_block; 161b42d9302Smartin printf("%lu) ", t); 162b42d9302Smartin } 163b42d9302Smartin printf("type=0x%x\n", m[i].ddType); 164dce63815Sdrahn } 165dce63815Sdrahn } 166dce63815Sdrahn printf("\n"); 167dce63815Sdrahn } 168dce63815Sdrahn 169dce63815Sdrahn 170dce63815Sdrahn void 171dce63815Sdrahn dump_partition_map(partition_map_header *map, int disk_order) 172dce63815Sdrahn { 173dce63815Sdrahn partition_map * entry; 174dce63815Sdrahn int max_type_length; 175dce63815Sdrahn int max_name_length; 176dce63815Sdrahn int digits; 177dce63815Sdrahn 178dce63815Sdrahn if (map == NULL) { 179dce63815Sdrahn bad_input("No partition map exists"); 180dce63815Sdrahn return; 181dce63815Sdrahn } 182dce63815Sdrahn printf("\nPartition map (with %d byte blocks) on '%s'\n", 183dce63815Sdrahn map->logical_block, map->name); 184dce63815Sdrahn 185dce63815Sdrahn digits = number_of_digits(get_max_base_or_length(map)); 186dce63815Sdrahn if (digits < 6) { 187dce63815Sdrahn digits = 6; 188dce63815Sdrahn } 189dce63815Sdrahn max_type_length = get_max_type_string_length(map); 190dce63815Sdrahn if (max_type_length < 4) { 191dce63815Sdrahn max_type_length = 4; 192dce63815Sdrahn } 193dce63815Sdrahn max_name_length = get_max_name_string_length(map); 194dce63815Sdrahn if (max_name_length < 6) { 195dce63815Sdrahn max_name_length = 6; 196dce63815Sdrahn } 197dce63815Sdrahn printf(" #: %*s %-*s %*s %-*s ( size )\n", 198dce63815Sdrahn max_type_length, "type", 199dce63815Sdrahn max_name_length, "name", 200dce63815Sdrahn digits, "length", digits, "base"); 201dce63815Sdrahn 202dce63815Sdrahn if (disk_order) { 203dce63815Sdrahn for (entry = map->disk_order; entry != NULL; 204dce63815Sdrahn entry = entry->next_on_disk) { 205dce63815Sdrahn 206dce63815Sdrahn dump_partition_entry(entry, max_type_length, max_name_length, digits); 207dce63815Sdrahn } 208dce63815Sdrahn } else { 209dce63815Sdrahn for (entry = map->base_order; entry != NULL; 210dce63815Sdrahn entry = entry->next_by_base) { 211dce63815Sdrahn 212dce63815Sdrahn dump_partition_entry(entry, max_type_length, max_name_length, digits); 213dce63815Sdrahn } 214dce63815Sdrahn } 215dce63815Sdrahn dump_block_zero(map); 216dce63815Sdrahn } 217dce63815Sdrahn 218dce63815Sdrahn 219dce63815Sdrahn void 220dce63815Sdrahn dump_partition_entry(partition_map *entry, int type_length, int name_length, int digits) 221dce63815Sdrahn { 222dce63815Sdrahn partition_map_header *map; 223dce63815Sdrahn int j; 2246521004eSkrw struct dpme *p; 225dce63815Sdrahn u32 size; 226dce63815Sdrahn double bytes; 22777a25ee3Sjasper int driver; 228b42d9302Smartin char *buf; 229dce63815Sdrahn 230dce63815Sdrahn map = entry->the_map; 231dce63815Sdrahn p = entry->data; 232dce63815Sdrahn driver = entry->contains_driver? '*': ' '; 233b42d9302Smartin printf("%2ld: %*.32s", entry->disk_address, type_length, p->dpme_type); 234dce63815Sdrahn 2355ae94ef8Sderaadt buf = malloc(name_length+1); 236b42d9302Smartin strncpy(buf, p->dpme_name, name_length); 237b42d9302Smartin buf[name_length] = 0; 238b42d9302Smartin printf("%c%-*.32s ", driver, name_length, buf); 239b42d9302Smartin free(buf); 240b42d9302Smartin 2417446d16eSkrw if (p->dpme_lblocks + p->dpme_lblock_start != p->dpme_pblocks) { 242dce63815Sdrahn printf("%*lu+", digits, p->dpme_lblocks); 243dce63815Sdrahn size = p->dpme_lblocks; 244dce63815Sdrahn } else if (p->dpme_lblock_start != 0) { 245dce63815Sdrahn printf("%*lu ", digits, p->dpme_lblocks); 246dce63815Sdrahn size = p->dpme_lblocks; 247dce63815Sdrahn } else { 248dce63815Sdrahn printf("%*lu ", digits, p->dpme_pblocks); 249dce63815Sdrahn size = p->dpme_pblocks; 250dce63815Sdrahn } 2517446d16eSkrw if (p->dpme_lblock_start == 0) { 252dce63815Sdrahn printf("@ %-*lu", digits, p->dpme_pblock_start); 253dce63815Sdrahn } else { 254dce63815Sdrahn printf("@~%-*lu", digits, p->dpme_pblock_start + p->dpme_lblock_start); 255dce63815Sdrahn } 256dce63815Sdrahn 257dce63815Sdrahn bytes = ((double)size) * map->logical_block; 258dce63815Sdrahn adjust_value_and_compute_prefix(&bytes, &j); 259dce63815Sdrahn if (j != ' ' && j != 'K') { 260dce63815Sdrahn printf(" (%#5.1f%c)", bytes, j); 261dce63815Sdrahn } 262dce63815Sdrahn 263dce63815Sdrahn printf("\n"); 264dce63815Sdrahn } 265dce63815Sdrahn 266dce63815Sdrahn 267dce63815Sdrahn void 268dce63815Sdrahn show_data_structures(partition_map_header *map) 269dce63815Sdrahn { 27071bd5f9cSkrw struct block0 *zp; 27170060700Skrw struct ddmap *m; 272dce63815Sdrahn int i; 273dce63815Sdrahn partition_map * entry; 2746521004eSkrw struct dpme *p; 275dce63815Sdrahn 276dce63815Sdrahn if (map == NULL) { 277dce63815Sdrahn printf("No partition map exists\n"); 278dce63815Sdrahn return; 279dce63815Sdrahn } 280dce63815Sdrahn printf("Header:\n"); 281dce63815Sdrahn printf("map %d blocks out of %d, media %lu blocks (%d byte blocks)\n", 282dce63815Sdrahn map->blocks_in_map, map->maximum_in_map, 283dce63815Sdrahn map->media_size, map->logical_block); 284b42d9302Smartin printf("Map is%s writable", (map->writable)?kStringEmpty:kStringNot); 285b42d9302Smartin printf(", but%s changed", (map->changed)?kStringEmpty:kStringNot); 286b42d9302Smartin printf(" and has%s been written\n", (map->written)?kStringEmpty:kStringNot); 287dce63815Sdrahn printf("\n"); 288dce63815Sdrahn 289dce63815Sdrahn if (map->misc == NULL) { 290dce63815Sdrahn printf("No block zero\n"); 291dce63815Sdrahn } else { 292dce63815Sdrahn zp = map->misc; 293dce63815Sdrahn 294dce63815Sdrahn printf("Block0:\n"); 295dce63815Sdrahn printf("signature 0x%x", zp->sbSig); 296dce63815Sdrahn if (zp->sbSig == BLOCK0_SIGNATURE) { 297dce63815Sdrahn printf("\n"); 298dce63815Sdrahn } else { 299dce63815Sdrahn printf(" should be 0x%x\n", BLOCK0_SIGNATURE); 300dce63815Sdrahn } 301dce63815Sdrahn printf("Block size=%u, Number of Blocks=%lu\n", 302dce63815Sdrahn zp->sbBlkSize, zp->sbBlkCount); 303dce63815Sdrahn printf("DeviceType=0x%x, DeviceId=0x%x, sbData=0x%lx\n", 304dce63815Sdrahn zp->sbDevType, zp->sbDevId, zp->sbData); 305dce63815Sdrahn if (zp->sbDrvrCount == 0) { 306dce63815Sdrahn printf("No drivers\n"); 307dce63815Sdrahn } else { 308dce63815Sdrahn printf("%u driver%s-\n", zp->sbDrvrCount, 309dce63815Sdrahn (zp->sbDrvrCount>1)?"s":kStringEmpty); 31070060700Skrw m = (struct ddmap *) zp->sbMap; 311dce63815Sdrahn for (i = 0; i < zp->sbDrvrCount; i++) { 312dce63815Sdrahn printf("%u: @ %lu for %u, type=0x%x\n", i+1, 313dce63815Sdrahn get_align_long(&m[i].ddBlock), 314dce63815Sdrahn m[i].ddSize, m[i].ddType); 315dce63815Sdrahn } 316dce63815Sdrahn } 317dce63815Sdrahn } 318dce63815Sdrahn printf("\n"); 319dce63815Sdrahn printf(" #: type length base " 320dce63815Sdrahn "flags (logical)\n"); 321dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 322dce63815Sdrahn p = entry->data; 323dce63815Sdrahn printf("%2ld: %20.32s ", 324dce63815Sdrahn entry->disk_address, p->dpme_type); 325dce63815Sdrahn printf("%7lu @ %-7lu ", p->dpme_pblocks, p->dpme_pblock_start); 326dce63815Sdrahn printf("%c%c%c%c%c%c%c%c%c%c%c%c ", 327a1ac9a96Skrw (p->dpme_flags & DPME_VALID)?'V':'.', 328a1ac9a96Skrw (p->dpme_flags & DPME_ALLOCATED)?'A':'.', 329a1ac9a96Skrw (p->dpme_flags & DPME_IN_USE)?'I':'.', 330a1ac9a96Skrw (p->dpme_flags & DPME_BOOTABLE)?'B':'.', 331a1ac9a96Skrw (p->dpme_flags & DPME_READABLE)?'R':'.', 332a1ac9a96Skrw (p->dpme_flags & DPME_WRITABLE)?'W':'.', 333a1ac9a96Skrw (p->dpme_flags & DPME_OS_PIC_CODE)?'P':'.', 334a1ac9a96Skrw (p->dpme_flags & DPME_OS_SPECIFIC_2)?'2':'.', 335a1ac9a96Skrw (p->dpme_flags & DPME_CHAINABLE)?'C':'.', 336a1ac9a96Skrw (p->dpme_flags & DPME_DISKDRIVER)?'D':'.', 337a1ac9a96Skrw (p->dpme_flags & (1<<30))?'M':'.', 338a1ac9a96Skrw (p->dpme_flags & (1<<31))?'X':'.'); 339dce63815Sdrahn if (p->dpme_lblock_start != 0 || p->dpme_pblocks != p->dpme_lblocks) { 340dce63815Sdrahn printf("(%lu @ %lu)", p->dpme_lblocks, p->dpme_lblock_start); 341dce63815Sdrahn } 342dce63815Sdrahn printf("\n"); 343dce63815Sdrahn } 344dce63815Sdrahn printf("\n"); 345dce63815Sdrahn printf(" #: booter bytes load_address " 346dce63815Sdrahn "goto_address checksum processor\n"); 347dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 348dce63815Sdrahn p = entry->data; 349dce63815Sdrahn printf("%2ld: ", entry->disk_address); 350dce63815Sdrahn printf("%7lu ", p->dpme_boot_block); 351dce63815Sdrahn printf("%7lu ", p->dpme_boot_bytes); 352dce63815Sdrahn printf("%8lx ", (u32)p->dpme_load_addr); 353dce63815Sdrahn printf("%8lx ", (u32)p->dpme_load_addr_2); 354dce63815Sdrahn printf("%8lx ", (u32)p->dpme_goto_addr); 355dce63815Sdrahn printf("%8lx ", (u32)p->dpme_goto_addr_2); 356dce63815Sdrahn printf("%8lx ", p->dpme_checksum); 357dce63815Sdrahn printf("%.32s", p->dpme_process_id); 358dce63815Sdrahn printf("\n"); 359dce63815Sdrahn } 360dce63815Sdrahn printf("\n"); 361dce63815Sdrahn } 362dce63815Sdrahn 363dce63815Sdrahn 364dce63815Sdrahn void 365b42d9302Smartin full_dump_partition_entry(partition_map_header *map, int ix) 366dce63815Sdrahn { 367dce63815Sdrahn partition_map * cur; 3686521004eSkrw struct dpme *p; 369dce63815Sdrahn int i; 370dce63815Sdrahn u32 t; 371dce63815Sdrahn 372b42d9302Smartin cur = find_entry_by_disk_address(ix, map); 373dce63815Sdrahn if (cur == NULL) { 374dce63815Sdrahn printf("No such partition\n"); 375dce63815Sdrahn return; 376dce63815Sdrahn } 377dce63815Sdrahn 378dce63815Sdrahn p = cur->data; 379dce63815Sdrahn printf(" signature: 0x%x\n", p->dpme_signature); 380dce63815Sdrahn printf(" reserved1: 0x%x\n", p->dpme_reserved_1); 381dce63815Sdrahn printf(" number of map entries: %ld\n", p->dpme_map_entries); 382dce63815Sdrahn printf(" physical start: %10lu length: %10lu\n", p->dpme_pblock_start, p->dpme_pblocks); 383dce63815Sdrahn printf(" logical start: %10lu length: %10lu\n", p->dpme_lblock_start, p->dpme_lblocks); 384dce63815Sdrahn 385dce63815Sdrahn printf(" flags: 0x%lx\n", (u32)p->dpme_flags); 386dce63815Sdrahn printf(" "); 387a1ac9a96Skrw if (p->dpme_flags & DPME_VALID) printf("valid "); 388a1ac9a96Skrw if (p->dpme_flags & DPME_ALLOCATED) printf("alloc "); 389a1ac9a96Skrw if (p->dpme_flags & DPME_IN_USE) printf("in-use "); 390a1ac9a96Skrw if (p->dpme_flags & DPME_BOOTABLE) printf("boot "); 391a1ac9a96Skrw if (p->dpme_flags & DPME_READABLE) printf("read "); 392a1ac9a96Skrw if (p->dpme_flags & DPME_WRITABLE) printf("write "); 393a1ac9a96Skrw if (p->dpme_flags & DPME_OS_PIC_CODE) printf("pic "); 394dce63815Sdrahn t = p->dpme_flags >> 7; 395dce63815Sdrahn for (i = 7; i <= 31; i++) { 396dce63815Sdrahn if (t & 0x1) { 397dce63815Sdrahn printf("%d ", i); 398dce63815Sdrahn } 399dce63815Sdrahn t = t >> 1; 400dce63815Sdrahn } 401dce63815Sdrahn printf("\n"); 402dce63815Sdrahn 403dce63815Sdrahn printf(" name: '%.32s'\n", p->dpme_name); 404dce63815Sdrahn printf(" type: '%.32s'\n", p->dpme_type); 405dce63815Sdrahn 406dce63815Sdrahn printf(" boot start block: %10lu\n", p->dpme_boot_block); 407dce63815Sdrahn printf("boot length (in bytes): %10lu\n", p->dpme_boot_bytes); 408dce63815Sdrahn printf(" load address: 0x%08lx 0x%08lx\n", 409dce63815Sdrahn (u32)p->dpme_load_addr, (u32)p->dpme_load_addr_2); 410dce63815Sdrahn printf(" start address: 0x%08lx 0x%08lx\n", 411dce63815Sdrahn (u32)p->dpme_goto_addr, (u32)p->dpme_goto_addr_2); 412dce63815Sdrahn printf(" checksum: 0x%08lx\n", p->dpme_checksum); 413dce63815Sdrahn printf(" processor: '%.32s'\n", p->dpme_process_id); 414dce63815Sdrahn printf("boot args field -"); 415dce63815Sdrahn dump_block((unsigned char *)p->dpme_boot_args, 32*4); 416dce63815Sdrahn printf("dpme_reserved_3 -"); 417dce63815Sdrahn dump_block((unsigned char *)p->dpme_reserved_3, 62*4); 418dce63815Sdrahn } 419dce63815Sdrahn 420dce63815Sdrahn 421dce63815Sdrahn void 422dce63815Sdrahn dump_block(unsigned char *addr, int len) 423dce63815Sdrahn { 424dce63815Sdrahn int i; 425dce63815Sdrahn int j; 426dce63815Sdrahn int limit1; 427dce63815Sdrahn int limit; 428dce63815Sdrahn #define LINE_LEN 16 429dce63815Sdrahn #define UNIT_LEN 4 430dce63815Sdrahn #define OTHER_LEN 8 431dce63815Sdrahn 432dce63815Sdrahn for (i = 0; i < len; i = limit) { 433dce63815Sdrahn limit1 = i + LINE_LEN; 434dce63815Sdrahn if (limit1 > len) { 435dce63815Sdrahn limit = len; 436dce63815Sdrahn } else { 437dce63815Sdrahn limit = limit1; 438dce63815Sdrahn } 439dce63815Sdrahn printf("\n%03x: ", i); 440dce63815Sdrahn for (j = i; j < limit1; j++) { 441dce63815Sdrahn if (j % UNIT_LEN == 0) { 442dce63815Sdrahn printf(" "); 443dce63815Sdrahn } 444dce63815Sdrahn if (j < limit) { 445dce63815Sdrahn printf("%02x", addr[j]); 446dce63815Sdrahn } else { 447dce63815Sdrahn printf(" "); 448dce63815Sdrahn } 449dce63815Sdrahn } 450dce63815Sdrahn printf(" "); 451dce63815Sdrahn for (j = i; j < limit; j++) { 452dce63815Sdrahn if (j % OTHER_LEN == 0) { 453dce63815Sdrahn printf(" "); 454dce63815Sdrahn } 455dce63815Sdrahn if (addr[j] < ' ') { 456dce63815Sdrahn printf("."); 457dce63815Sdrahn } else { 458dce63815Sdrahn printf("%c", addr[j]); 459dce63815Sdrahn } 460dce63815Sdrahn } 461dce63815Sdrahn } 462dce63815Sdrahn printf("\n"); 463dce63815Sdrahn } 464dce63815Sdrahn 465dce63815Sdrahn void 466dce63815Sdrahn full_dump_block_zero(partition_map_header *map) 467dce63815Sdrahn { 46871bd5f9cSkrw struct block0 *zp; 46970060700Skrw struct ddmap *m; 470dce63815Sdrahn int i; 471dce63815Sdrahn 472dce63815Sdrahn if (map == NULL) { 473dce63815Sdrahn printf("No partition map exists\n"); 474dce63815Sdrahn return; 475dce63815Sdrahn } 476dce63815Sdrahn 477dce63815Sdrahn if (map->misc == NULL) { 478dce63815Sdrahn printf("No block zero\n"); 479dce63815Sdrahn return; 480dce63815Sdrahn } 481dce63815Sdrahn zp = map->misc; 482dce63815Sdrahn 483dce63815Sdrahn printf(" signature: 0x%x\n", zp->sbSig); 484dce63815Sdrahn printf(" size of a block: %d\n", zp->sbBlkSize); 485dce63815Sdrahn printf(" number of blocks: %ld\n", zp->sbBlkCount); 486dce63815Sdrahn printf(" device type: 0x%x\n", zp->sbDevType); 487dce63815Sdrahn printf(" device id: 0x%x\n", zp->sbDevId); 488dce63815Sdrahn printf(" data: 0x%lx\n", zp->sbData); 489dce63815Sdrahn printf(" driver count: %d\n", zp->sbDrvrCount); 49070060700Skrw m = (struct ddmap *) zp->sbMap; 491dce63815Sdrahn for (i = 0; &m[i].ddType < &zp->sbMap[247]; i++) { 492dce63815Sdrahn if (m[i].ddBlock == 0 && m[i].ddSize == 0 && m[i].ddType == 0) { 493dce63815Sdrahn break; 494dce63815Sdrahn } 495dce63815Sdrahn printf(" driver %3u block: %ld\n", i+1, m[i].ddBlock); 496dce63815Sdrahn printf(" size in blocks: %d\n", m[i].ddSize); 497dce63815Sdrahn printf(" driver type: 0x%x\n", m[i].ddType); 498dce63815Sdrahn } 499dce63815Sdrahn printf("remainder of block -"); 500dce63815Sdrahn dump_block((unsigned char *)&m[i].ddBlock, (&zp->sbMap[247]-((unsigned short *)&m[i].ddBlock))*2); 501dce63815Sdrahn } 502dce63815Sdrahn 503b42d9302Smartin 504dce63815Sdrahn void 505dce63815Sdrahn display_patches(partition_map *entry) 506dce63815Sdrahn { 507dce63815Sdrahn long long offset; 5086a69102aSkrw struct file_media *m; 509dce63815Sdrahn static unsigned char *patch_block; 510*94d20309Skrw struct patchlist *p; 511*94d20309Skrw struct patchdescriptor *q; 512b42d9302Smartin unsigned char *next; 513b42d9302Smartin unsigned char *s; 514b42d9302Smartin int i; 515dce63815Sdrahn 516dce63815Sdrahn offset = entry->data->dpme_pblock_start; 517dce63815Sdrahn m = entry->the_map->m; 518dce63815Sdrahn offset = ((long long) entry->data->dpme_pblock_start) * entry->the_map->logical_block; 519dce63815Sdrahn if (patch_block == NULL) { 520d66063cbSkrw patch_block = malloc(DEV_BSIZE); 521dce63815Sdrahn if (patch_block == NULL) { 52268d0f91bSkrw warn("can't allocate memory for patch block buffer"); 523dce63815Sdrahn return; 524dce63815Sdrahn } 525dce63815Sdrahn } 526f42746d7Skrw if (read_file_media(m, (long long)offset, DEV_BSIZE, (char *)patch_block) == 0) { 52768d0f91bSkrw warn("Can't read patch block"); 528dce63815Sdrahn return; 529dce63815Sdrahn } 530*94d20309Skrw p = (struct patchlist *) patch_block; 531b42d9302Smartin if (p->numPatchBlocks != 1) { 532b42d9302Smartin i = p->numPatchBlocks; 533b42d9302Smartin free(patch_block); 534d66063cbSkrw patch_block = reallocarray(NULL, i, DEV_BSIZE); 535b42d9302Smartin if (patch_block == NULL) { 53668d0f91bSkrw warn("can't allocate memory for patch blocks buffer"); 537b42d9302Smartin return; 538b42d9302Smartin } 539d66063cbSkrw s = patch_block + DEV_BSIZE*i; 540b42d9302Smartin while (i > 0) { 541d66063cbSkrw s -= DEV_BSIZE; 542b42d9302Smartin i -= 1; 543f42746d7Skrw if (read_file_media(m, offset+i, DEV_BSIZE, (char *)s) == 0) { 54468d0f91bSkrw warn("Can't read patch block %d", i); 545b42d9302Smartin return; 546b42d9302Smartin } 547b42d9302Smartin } 548*94d20309Skrw p = (struct patchlist *) patch_block; 549b42d9302Smartin } 550b42d9302Smartin printf("Patch list (%d entries)\n", p->numPatches); 551b42d9302Smartin q = p->thePatch; 552b42d9302Smartin for (i = 0; i < p->numPatches; i++) { 553b42d9302Smartin printf("%2d signature: '%.4s'\n", i+1, (char *)&q->patchSig); 554b42d9302Smartin printf(" version: %d.%d\n", q->majorVers, q->minorVers); 555b42d9302Smartin printf(" flags: 0x%lx\n", q->flags); 556b42d9302Smartin printf(" offset: %ld\n", q->patchOffset); 557b42d9302Smartin printf(" size: %ld\n", q->patchSize); 558b42d9302Smartin printf(" CRC: 0x%lx\n", q->patchCRC); 559b42d9302Smartin printf(" name: '%.*s'\n", q->patchName[0], &q->patchName[1]); 560b42d9302Smartin printf(" vendor: '%.*s'\n", q->patchVendor[0], &q->patchVendor[1]); 561b42d9302Smartin next = ((unsigned char *)q) + q->patchDescriptorLen; 562b42d9302Smartin s = &q->patchVendor[q->patchVendor[0]+1]; 563b42d9302Smartin if (next > s) { 564b42d9302Smartin printf("remainder of entry -"); 565b42d9302Smartin dump_block(s, next-s); 566b42d9302Smartin } 567*94d20309Skrw q = (struct patchdescriptor *)next; 568b42d9302Smartin } 569dce63815Sdrahn } 570dce63815Sdrahn 571dce63815Sdrahn int 572dce63815Sdrahn get_max_type_string_length(partition_map_header *map) 573dce63815Sdrahn { 574dce63815Sdrahn partition_map * entry; 575dce63815Sdrahn int max; 576dce63815Sdrahn int length; 577dce63815Sdrahn 578dce63815Sdrahn if (map == NULL) { 579dce63815Sdrahn return 0; 580dce63815Sdrahn } 581dce63815Sdrahn 582dce63815Sdrahn max = 0; 583dce63815Sdrahn 584dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 585dce63815Sdrahn length = strnlen(entry->data->dpme_type, DPISTRLEN); 586dce63815Sdrahn if (length > max) { 587dce63815Sdrahn max = length; 588dce63815Sdrahn } 589dce63815Sdrahn } 590dce63815Sdrahn 591dce63815Sdrahn return max; 592dce63815Sdrahn } 593dce63815Sdrahn 594dce63815Sdrahn int 595dce63815Sdrahn get_max_name_string_length(partition_map_header *map) 596dce63815Sdrahn { 597dce63815Sdrahn partition_map * entry; 598dce63815Sdrahn int max; 599dce63815Sdrahn int length; 600dce63815Sdrahn 601dce63815Sdrahn if (map == NULL) { 602dce63815Sdrahn return 0; 603dce63815Sdrahn } 604dce63815Sdrahn 605dce63815Sdrahn max = 0; 606dce63815Sdrahn 607dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 608dce63815Sdrahn length = strnlen(entry->data->dpme_name, DPISTRLEN); 609dce63815Sdrahn if (length > max) { 610dce63815Sdrahn max = length; 611dce63815Sdrahn } 612dce63815Sdrahn } 613dce63815Sdrahn 614dce63815Sdrahn return max; 615dce63815Sdrahn } 616dce63815Sdrahn 617dce63815Sdrahn int 618dce63815Sdrahn get_max_base_or_length(partition_map_header *map) 619dce63815Sdrahn { 620dce63815Sdrahn partition_map * entry; 621dce63815Sdrahn int max; 622dce63815Sdrahn 623dce63815Sdrahn if (map == NULL) { 624dce63815Sdrahn return 0; 625dce63815Sdrahn } 626dce63815Sdrahn 627dce63815Sdrahn max = 0; 628dce63815Sdrahn 629dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 630dce63815Sdrahn if (entry->data->dpme_pblock_start > max) { 631dce63815Sdrahn max = entry->data->dpme_pblock_start; 632dce63815Sdrahn } 633dce63815Sdrahn if (entry->data->dpme_pblocks > max) { 634dce63815Sdrahn max = entry->data->dpme_pblocks; 635dce63815Sdrahn } 636dce63815Sdrahn if (entry->data->dpme_lblock_start > max) { 637dce63815Sdrahn max = entry->data->dpme_lblock_start; 638dce63815Sdrahn } 639dce63815Sdrahn if (entry->data->dpme_lblocks > max) { 640dce63815Sdrahn max = entry->data->dpme_lblocks; 641dce63815Sdrahn } 642dce63815Sdrahn } 643dce63815Sdrahn 644dce63815Sdrahn return max; 645dce63815Sdrahn } 646dce63815Sdrahn 647dce63815Sdrahn void 648dce63815Sdrahn adjust_value_and_compute_prefix(double *value, int *prefix) 649dce63815Sdrahn { 650dce63815Sdrahn double bytes; 651dce63815Sdrahn int multiplier; 652dce63815Sdrahn 653dce63815Sdrahn bytes = *value; 654dce63815Sdrahn if (bytes < 1024.0) { 655dce63815Sdrahn multiplier = ' '; 656dce63815Sdrahn } else { 657dce63815Sdrahn bytes = bytes / 1024.0; 658dce63815Sdrahn if (bytes < 1024.0) { 659dce63815Sdrahn multiplier = 'K'; 660dce63815Sdrahn } else { 661dce63815Sdrahn bytes = bytes / 1024.0; 662dce63815Sdrahn if (bytes < 1024.0) { 663dce63815Sdrahn multiplier = 'M'; 664dce63815Sdrahn } else { 665dce63815Sdrahn bytes = bytes / 1024.0; 666dce63815Sdrahn if (bytes < 1024.0) { 667dce63815Sdrahn multiplier = 'G'; 668dce63815Sdrahn } else { 669dce63815Sdrahn bytes = bytes / 1024.0; 670dce63815Sdrahn multiplier = 'T'; 671dce63815Sdrahn } 672dce63815Sdrahn } 673dce63815Sdrahn } 674dce63815Sdrahn } 675dce63815Sdrahn *value = bytes; 676dce63815Sdrahn *prefix = multiplier; 677dce63815Sdrahn } 678