1*f42746d7Skrw /* $OpenBSD: dump.c,v 1.19 2016/01/16 20:00:50 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 47*f42746d7Skrw #include "file_media.h" 48dce63815Sdrahn #include "dump.h" 49dce63815Sdrahn #include "io.h" 50dce63815Sdrahn 51dce63815Sdrahn 52dce63815Sdrahn // 53dce63815Sdrahn // Defines 54dce63815Sdrahn // 55dce63815Sdrahn #if DPISTRLEN != 32 56dce63815Sdrahn #error Change in strlen in partition entries! Fix constants 57dce63815Sdrahn #endif 58dce63815Sdrahn 59dce63815Sdrahn #define get_align_long(x) (*(x)) 60dce63815Sdrahn 61dce63815Sdrahn 62dce63815Sdrahn // 63dce63815Sdrahn // Types 64dce63815Sdrahn // 65dce63815Sdrahn typedef struct names { 66b42d9302Smartin const char *abbr; 67b42d9302Smartin const char *full; 68dce63815Sdrahn } NAMES; 69dce63815Sdrahn 70b42d9302Smartin typedef unsigned long OSType; 71b42d9302Smartin 72b42d9302Smartin typedef struct PatchDescriptor { 73b42d9302Smartin OSType patchSig; 74b42d9302Smartin unsigned short majorVers; 75b42d9302Smartin unsigned short minorVers; 76b42d9302Smartin unsigned long flags; 77b42d9302Smartin unsigned long patchOffset; 78b42d9302Smartin unsigned long patchSize; 79b42d9302Smartin unsigned long patchCRC; 80b42d9302Smartin unsigned long patchDescriptorLen; 81b42d9302Smartin unsigned char patchName[33]; 82b42d9302Smartin unsigned char patchVendor[1]; 83b42d9302Smartin } PatchDescriptor; 84b42d9302Smartin typedef PatchDescriptor * PatchDescriptorPtr; 85b42d9302Smartin 86b42d9302Smartin typedef struct PatchList { 87b42d9302Smartin unsigned short numPatchBlocks; // number of disk blocks to hold the patch list 88b42d9302Smartin unsigned short numPatches; // number of patches in list 89b42d9302Smartin PatchDescriptor thePatch[1]; 90b42d9302Smartin } PatchList; 91b42d9302Smartin typedef PatchList *PatchListPtr; 92b42d9302Smartin 93dce63815Sdrahn 94dce63815Sdrahn // 95dce63815Sdrahn // Global Constants 96dce63815Sdrahn // 97dce63815Sdrahn NAMES plist[] = { 98dce63815Sdrahn {"Drvr", "Apple_Driver"}, 99b42d9302Smartin {"Drv4", "Apple_Driver43"}, 100dce63815Sdrahn {"Free", "Apple_Free"}, 101b42d9302Smartin {"Patc", "Apple_Patches"}, 102dce63815Sdrahn {" HFS", "Apple_HFS"}, 103dce63815Sdrahn {" MFS", "Apple_MFS"}, 104dce63815Sdrahn {"PDOS", "Apple_PRODOS"}, 105dce63815Sdrahn {"junk", "Apple_Scratch"}, 106dce63815Sdrahn {"unix", "Apple_UNIX_SVR2"}, 107dce63815Sdrahn {" map", "Apple_partition_map"}, 108dce63815Sdrahn {0, 0}, 109dce63815Sdrahn }; 110dce63815Sdrahn 111dce63815Sdrahn const char * kStringEmpty = ""; 112dce63815Sdrahn const char * kStringNot = " not"; 113dce63815Sdrahn 114dce63815Sdrahn 115dce63815Sdrahn // 116dce63815Sdrahn // Global Variables 117dce63815Sdrahn // 118dce63815Sdrahn 119dce63815Sdrahn 120dce63815Sdrahn // 121dce63815Sdrahn // Forward declarations 122dce63815Sdrahn // 123dce63815Sdrahn void adjust_value_and_compute_prefix(double *value, int *prefix); 124dce63815Sdrahn void dump_block_zero(partition_map_header *map); 125dce63815Sdrahn void dump_partition_entry(partition_map *entry, int type_length, int name_length, int digits); 126dce63815Sdrahn int get_max_base_or_length(partition_map_header *map); 127dce63815Sdrahn int get_max_name_string_length(partition_map_header *map); 128dce63815Sdrahn int get_max_type_string_length(partition_map_header *map); 129dce63815Sdrahn 130dce63815Sdrahn 131dce63815Sdrahn // 132dce63815Sdrahn // Routines 133dce63815Sdrahn // 134dce63815Sdrahn int 135dce63815Sdrahn dump(char *name) 136dce63815Sdrahn { 137dce63815Sdrahn partition_map_header *map; 138dce63815Sdrahn int junk; 139dce63815Sdrahn 1405d0b0825Skrw map = open_partition_map(name, &junk); 141dce63815Sdrahn if (map == NULL) { 142dce63815Sdrahn return 0; 143dce63815Sdrahn } 144dce63815Sdrahn 145dce63815Sdrahn dump_partition_map(map, 1); 146dce63815Sdrahn 147dce63815Sdrahn close_partition_map(map); 148dce63815Sdrahn 149dce63815Sdrahn return 1; 150dce63815Sdrahn } 151dce63815Sdrahn 152dce63815Sdrahn 153dce63815Sdrahn void 154dce63815Sdrahn dump_block_zero(partition_map_header *map) 155dce63815Sdrahn { 156dce63815Sdrahn Block0 *p; 157dce63815Sdrahn DDMap *m; 158dce63815Sdrahn int i; 159dce63815Sdrahn double value; 160dce63815Sdrahn int prefix; 161b42d9302Smartin long t; 162dce63815Sdrahn 163dce63815Sdrahn p = map->misc; 164dce63815Sdrahn if (p->sbSig != BLOCK0_SIGNATURE) { 165dce63815Sdrahn return; 166dce63815Sdrahn } 167dce63815Sdrahn 168dce63815Sdrahn value = ((double)p->sbBlkCount) * p->sbBlkSize; 169dce63815Sdrahn adjust_value_and_compute_prefix(&value, &prefix); 170dce63815Sdrahn printf("\nDevice block size=%u, Number of Blocks=%lu (%1.1f%c)\n", 171dce63815Sdrahn p->sbBlkSize, p->sbBlkCount, value, prefix); 172dce63815Sdrahn 173dce63815Sdrahn printf("DeviceType=0x%x, DeviceId=0x%x\n", 174dce63815Sdrahn p->sbDevType, p->sbDevId); 175dce63815Sdrahn if (p->sbDrvrCount > 0) { 176dce63815Sdrahn printf("Drivers-\n"); 177dce63815Sdrahn m = (DDMap *) p->sbMap; 178dce63815Sdrahn for (i = 0; i < p->sbDrvrCount; i++) { 179b42d9302Smartin printf("%u: %3u @ %lu, ", i+1, 180b42d9302Smartin m[i].ddSize, get_align_long(&m[i].ddBlock)); 181b42d9302Smartin if (map->logical_block != p->sbBlkSize) { 182b42d9302Smartin t = (m[i].ddSize * p->sbBlkSize) / map->logical_block; 183b42d9302Smartin printf("(%lu@", t); 184b42d9302Smartin t = (get_align_long(&m[i].ddBlock) * p->sbBlkSize) 185b42d9302Smartin / map->logical_block; 186b42d9302Smartin printf("%lu) ", t); 187b42d9302Smartin } 188b42d9302Smartin printf("type=0x%x\n", m[i].ddType); 189dce63815Sdrahn } 190dce63815Sdrahn } 191dce63815Sdrahn printf("\n"); 192dce63815Sdrahn } 193dce63815Sdrahn 194dce63815Sdrahn 195dce63815Sdrahn void 196dce63815Sdrahn dump_partition_map(partition_map_header *map, int disk_order) 197dce63815Sdrahn { 198dce63815Sdrahn partition_map * entry; 199dce63815Sdrahn int max_type_length; 200dce63815Sdrahn int max_name_length; 201dce63815Sdrahn int digits; 202dce63815Sdrahn 203dce63815Sdrahn if (map == NULL) { 204dce63815Sdrahn bad_input("No partition map exists"); 205dce63815Sdrahn return; 206dce63815Sdrahn } 207dce63815Sdrahn printf("\nPartition map (with %d byte blocks) on '%s'\n", 208dce63815Sdrahn map->logical_block, map->name); 209dce63815Sdrahn 210dce63815Sdrahn digits = number_of_digits(get_max_base_or_length(map)); 211dce63815Sdrahn if (digits < 6) { 212dce63815Sdrahn digits = 6; 213dce63815Sdrahn } 214dce63815Sdrahn max_type_length = get_max_type_string_length(map); 215dce63815Sdrahn if (max_type_length < 4) { 216dce63815Sdrahn max_type_length = 4; 217dce63815Sdrahn } 218dce63815Sdrahn max_name_length = get_max_name_string_length(map); 219dce63815Sdrahn if (max_name_length < 6) { 220dce63815Sdrahn max_name_length = 6; 221dce63815Sdrahn } 222dce63815Sdrahn printf(" #: %*s %-*s %*s %-*s ( size )\n", 223dce63815Sdrahn max_type_length, "type", 224dce63815Sdrahn max_name_length, "name", 225dce63815Sdrahn digits, "length", digits, "base"); 226dce63815Sdrahn 227dce63815Sdrahn if (disk_order) { 228dce63815Sdrahn for (entry = map->disk_order; entry != NULL; 229dce63815Sdrahn entry = entry->next_on_disk) { 230dce63815Sdrahn 231dce63815Sdrahn dump_partition_entry(entry, max_type_length, max_name_length, digits); 232dce63815Sdrahn } 233dce63815Sdrahn } else { 234dce63815Sdrahn for (entry = map->base_order; entry != NULL; 235dce63815Sdrahn entry = entry->next_by_base) { 236dce63815Sdrahn 237dce63815Sdrahn dump_partition_entry(entry, max_type_length, max_name_length, digits); 238dce63815Sdrahn } 239dce63815Sdrahn } 240dce63815Sdrahn dump_block_zero(map); 241dce63815Sdrahn } 242dce63815Sdrahn 243dce63815Sdrahn 244dce63815Sdrahn void 245dce63815Sdrahn dump_partition_entry(partition_map *entry, int type_length, int name_length, int digits) 246dce63815Sdrahn { 247dce63815Sdrahn partition_map_header *map; 248dce63815Sdrahn int j; 249dce63815Sdrahn DPME *p; 250b42d9302Smartin const char *s; 251dce63815Sdrahn u32 size; 252dce63815Sdrahn double bytes; 253a1ac9a96Skrw int driver, slice; 254b42d9302Smartin // int kind; 255b42d9302Smartin char *buf; 256b42d9302Smartin #if 1 257b42d9302Smartin BZB *bp; 258b42d9302Smartin #endif 259dce63815Sdrahn 260dce63815Sdrahn map = entry->the_map; 261dce63815Sdrahn p = entry->data; 262dce63815Sdrahn driver = entry->contains_driver? '*': ' '; 263b42d9302Smartin printf("%2ld: %*.32s", entry->disk_address, type_length, p->dpme_type); 264dce63815Sdrahn 2655ae94ef8Sderaadt buf = malloc(name_length+1); 266b42d9302Smartin strncpy(buf, p->dpme_name, name_length); 267b42d9302Smartin buf[name_length] = 0; 268b42d9302Smartin printf("%c%-*.32s ", driver, name_length, buf); 269b42d9302Smartin free(buf); 270b42d9302Smartin /* 271b42d9302Smartin switch (entry->HFS_kind) { 272b42d9302Smartin case kHFS_std: kind = 'h'; break; 273b42d9302Smartin case kHFS_embed: kind = 'e'; break; 274b42d9302Smartin case kHFS_plus: kind = '+'; break; 275b42d9302Smartin default: 276b42d9302Smartin case kHFS_not: kind = ' '; break; 277b42d9302Smartin } 278b42d9302Smartin printf("%c ", kind); 279b42d9302Smartin */ 280b42d9302Smartin 2817446d16eSkrw if (p->dpme_lblocks + p->dpme_lblock_start != p->dpme_pblocks) { 282dce63815Sdrahn printf("%*lu+", digits, p->dpme_lblocks); 283dce63815Sdrahn size = p->dpme_lblocks; 284dce63815Sdrahn } else if (p->dpme_lblock_start != 0) { 285dce63815Sdrahn printf("%*lu ", digits, p->dpme_lblocks); 286dce63815Sdrahn size = p->dpme_lblocks; 287dce63815Sdrahn } else { 288dce63815Sdrahn printf("%*lu ", digits, p->dpme_pblocks); 289dce63815Sdrahn size = p->dpme_pblocks; 290dce63815Sdrahn } 2917446d16eSkrw if (p->dpme_lblock_start == 0) { 292dce63815Sdrahn printf("@ %-*lu", digits, p->dpme_pblock_start); 293dce63815Sdrahn } else { 294dce63815Sdrahn printf("@~%-*lu", digits, p->dpme_pblock_start + p->dpme_lblock_start); 295dce63815Sdrahn } 296dce63815Sdrahn 297dce63815Sdrahn bytes = ((double)size) * map->logical_block; 298dce63815Sdrahn adjust_value_and_compute_prefix(&bytes, &j); 299dce63815Sdrahn if (j != ' ' && j != 'K') { 300dce63815Sdrahn printf(" (%#5.1f%c)", bytes, j); 301dce63815Sdrahn } 302dce63815Sdrahn 303b42d9302Smartin #if 1 304dce63815Sdrahn // Old A/UX fields that no one pays attention to anymore. 305dce63815Sdrahn bp = (BZB *) (p->dpme_bzb); 306dce63815Sdrahn j = -1; 307dce63815Sdrahn if (bp->bzb_magic == BZBMAGIC) { 308dce63815Sdrahn switch (bp->bzb_type) { 309dce63815Sdrahn case FSTEFS: 310dce63815Sdrahn s = "EFS"; 311dce63815Sdrahn break; 312dce63815Sdrahn case FSTSFS: 313dce63815Sdrahn s = "SFS"; 314dce63815Sdrahn j = 1; 315dce63815Sdrahn break; 316dce63815Sdrahn case FST: 317dce63815Sdrahn default: 318a1ac9a96Skrw if ((bp->bzb_flags & BZB_ROOT) != 0) { 319a1ac9a96Skrw if ((bp->bzb_flags & BZB_USR) != 0) { 320dce63815Sdrahn s = "RUFS"; 321dce63815Sdrahn } else { 322dce63815Sdrahn s = "RFS"; 323dce63815Sdrahn } 324dce63815Sdrahn j = 0; 325a1ac9a96Skrw } else if ((bp->bzb_flags & BZB_USR) != 0) { 326dce63815Sdrahn s = "UFS"; 327dce63815Sdrahn j = 2; 328dce63815Sdrahn } else { 329dce63815Sdrahn s = "FS"; 330dce63815Sdrahn } 331dce63815Sdrahn break; 332dce63815Sdrahn } 333a1ac9a96Skrw slice = ((bp->bzb_flags >> BZB_SLICE_SHIFT) & BZB_SLICE_MASK); 334a1ac9a96Skrw if (slice != 0) { 335a1ac9a96Skrw printf(" s%1d %4s", slice - 1, s); 336dce63815Sdrahn } else if (j >= 0) { 337dce63815Sdrahn printf(" S%1d %4s", j, s); 338dce63815Sdrahn } else { 339dce63815Sdrahn printf(" %4s", s); 340dce63815Sdrahn } 341a1ac9a96Skrw if ((bp->bzb_flags & BZB_CRIT) != 0) { 342dce63815Sdrahn printf(" K%1d", bp->bzb_cluster); 343dce63815Sdrahn } else if (j < 0) { 344dce63815Sdrahn printf(" "); 345dce63815Sdrahn } else { 346dce63815Sdrahn printf(" k%1d", bp->bzb_cluster); 347dce63815Sdrahn } 348dce63815Sdrahn if (bp->bzb_mount_point[0] != 0) { 349dce63815Sdrahn printf(" %.64s", bp->bzb_mount_point); 350dce63815Sdrahn } 351dce63815Sdrahn } 352dce63815Sdrahn #endif 353dce63815Sdrahn printf("\n"); 354dce63815Sdrahn } 355dce63815Sdrahn 356dce63815Sdrahn 357dce63815Sdrahn void 358dce63815Sdrahn show_data_structures(partition_map_header *map) 359dce63815Sdrahn { 360dce63815Sdrahn Block0 *zp; 361dce63815Sdrahn DDMap *m; 362dce63815Sdrahn int i; 363a1ac9a96Skrw int j, slice; 364dce63815Sdrahn partition_map * entry; 365dce63815Sdrahn DPME *p; 366dce63815Sdrahn BZB *bp; 367b42d9302Smartin const char *s; 368dce63815Sdrahn 369dce63815Sdrahn if (map == NULL) { 370dce63815Sdrahn printf("No partition map exists\n"); 371dce63815Sdrahn return; 372dce63815Sdrahn } 373dce63815Sdrahn printf("Header:\n"); 374dce63815Sdrahn printf("map %d blocks out of %d, media %lu blocks (%d byte blocks)\n", 375dce63815Sdrahn map->blocks_in_map, map->maximum_in_map, 376dce63815Sdrahn map->media_size, map->logical_block); 377b42d9302Smartin printf("Map is%s writable", (map->writable)?kStringEmpty:kStringNot); 378b42d9302Smartin printf(", but%s changed", (map->changed)?kStringEmpty:kStringNot); 379b42d9302Smartin printf(" and has%s been written\n", (map->written)?kStringEmpty:kStringNot); 380dce63815Sdrahn printf("\n"); 381dce63815Sdrahn 382dce63815Sdrahn if (map->misc == NULL) { 383dce63815Sdrahn printf("No block zero\n"); 384dce63815Sdrahn } else { 385dce63815Sdrahn zp = map->misc; 386dce63815Sdrahn 387dce63815Sdrahn printf("Block0:\n"); 388dce63815Sdrahn printf("signature 0x%x", zp->sbSig); 389dce63815Sdrahn if (zp->sbSig == BLOCK0_SIGNATURE) { 390dce63815Sdrahn printf("\n"); 391dce63815Sdrahn } else { 392dce63815Sdrahn printf(" should be 0x%x\n", BLOCK0_SIGNATURE); 393dce63815Sdrahn } 394dce63815Sdrahn printf("Block size=%u, Number of Blocks=%lu\n", 395dce63815Sdrahn zp->sbBlkSize, zp->sbBlkCount); 396dce63815Sdrahn printf("DeviceType=0x%x, DeviceId=0x%x, sbData=0x%lx\n", 397dce63815Sdrahn zp->sbDevType, zp->sbDevId, zp->sbData); 398dce63815Sdrahn if (zp->sbDrvrCount == 0) { 399dce63815Sdrahn printf("No drivers\n"); 400dce63815Sdrahn } else { 401dce63815Sdrahn printf("%u driver%s-\n", zp->sbDrvrCount, 402dce63815Sdrahn (zp->sbDrvrCount>1)?"s":kStringEmpty); 403dce63815Sdrahn m = (DDMap *) zp->sbMap; 404dce63815Sdrahn for (i = 0; i < zp->sbDrvrCount; i++) { 405dce63815Sdrahn printf("%u: @ %lu for %u, type=0x%x\n", i+1, 406dce63815Sdrahn get_align_long(&m[i].ddBlock), 407dce63815Sdrahn m[i].ddSize, m[i].ddType); 408dce63815Sdrahn } 409dce63815Sdrahn } 410dce63815Sdrahn } 411dce63815Sdrahn printf("\n"); 412dce63815Sdrahn 413dce63815Sdrahn /* 414dce63815Sdrahn u32 dpme_boot_args[32] ; 415dce63815Sdrahn u32 dpme_reserved_3[62] ; 416dce63815Sdrahn */ 417dce63815Sdrahn printf(" #: type length base " 418dce63815Sdrahn "flags (logical)\n"); 419dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 420dce63815Sdrahn p = entry->data; 421dce63815Sdrahn printf("%2ld: %20.32s ", 422dce63815Sdrahn entry->disk_address, p->dpme_type); 423dce63815Sdrahn printf("%7lu @ %-7lu ", p->dpme_pblocks, p->dpme_pblock_start); 424dce63815Sdrahn printf("%c%c%c%c%c%c%c%c%c%c%c%c ", 425a1ac9a96Skrw (p->dpme_flags & DPME_VALID)?'V':'.', 426a1ac9a96Skrw (p->dpme_flags & DPME_ALLOCATED)?'A':'.', 427a1ac9a96Skrw (p->dpme_flags & DPME_IN_USE)?'I':'.', 428a1ac9a96Skrw (p->dpme_flags & DPME_BOOTABLE)?'B':'.', 429a1ac9a96Skrw (p->dpme_flags & DPME_READABLE)?'R':'.', 430a1ac9a96Skrw (p->dpme_flags & DPME_WRITABLE)?'W':'.', 431a1ac9a96Skrw (p->dpme_flags & DPME_OS_PIC_CODE)?'P':'.', 432a1ac9a96Skrw (p->dpme_flags & DPME_OS_SPECIFIC_2)?'2':'.', 433a1ac9a96Skrw (p->dpme_flags & DPME_CHAINABLE)?'C':'.', 434a1ac9a96Skrw (p->dpme_flags & DPME_DISKDRIVER)?'D':'.', 435a1ac9a96Skrw (p->dpme_flags & (1<<30))?'M':'.', 436a1ac9a96Skrw (p->dpme_flags & (1<<31))?'X':'.'); 437dce63815Sdrahn if (p->dpme_lblock_start != 0 || p->dpme_pblocks != p->dpme_lblocks) { 438dce63815Sdrahn printf("(%lu @ %lu)", p->dpme_lblocks, p->dpme_lblock_start); 439dce63815Sdrahn } 440dce63815Sdrahn printf("\n"); 441dce63815Sdrahn } 442dce63815Sdrahn printf("\n"); 443dce63815Sdrahn printf(" #: booter bytes load_address " 444dce63815Sdrahn "goto_address checksum processor\n"); 445dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 446dce63815Sdrahn p = entry->data; 447dce63815Sdrahn printf("%2ld: ", entry->disk_address); 448dce63815Sdrahn printf("%7lu ", p->dpme_boot_block); 449dce63815Sdrahn printf("%7lu ", p->dpme_boot_bytes); 450dce63815Sdrahn printf("%8lx ", (u32)p->dpme_load_addr); 451dce63815Sdrahn printf("%8lx ", (u32)p->dpme_load_addr_2); 452dce63815Sdrahn printf("%8lx ", (u32)p->dpme_goto_addr); 453dce63815Sdrahn printf("%8lx ", (u32)p->dpme_goto_addr_2); 454dce63815Sdrahn printf("%8lx ", p->dpme_checksum); 455dce63815Sdrahn printf("%.32s", p->dpme_process_id); 456dce63815Sdrahn printf("\n"); 457dce63815Sdrahn } 458dce63815Sdrahn printf("\n"); 459dce63815Sdrahn /* 460dce63815Sdrahn xx: cccc RU *dd s... 461dce63815Sdrahn */ 462dce63815Sdrahn printf(" #: type RU *slice mount_point (A/UX only fields)\n"); 463dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 464dce63815Sdrahn p = entry->data; 465dce63815Sdrahn printf("%2ld: ", entry->disk_address); 466dce63815Sdrahn 467dce63815Sdrahn bp = (BZB *) (p->dpme_bzb); 468dce63815Sdrahn j = -1; 469dce63815Sdrahn if (bp->bzb_magic == BZBMAGIC) { 470dce63815Sdrahn switch (bp->bzb_type) { 471dce63815Sdrahn case FSTEFS: 472dce63815Sdrahn s = "esch"; 473dce63815Sdrahn break; 474dce63815Sdrahn case FSTSFS: 475dce63815Sdrahn s = "swap"; 476dce63815Sdrahn j = 1; 477dce63815Sdrahn break; 478dce63815Sdrahn case FST: 479dce63815Sdrahn default: 480dce63815Sdrahn s = "fsys"; 481a1ac9a96Skrw if ((bp->bzb_flags & BZB_ROOT) != 0) { 482dce63815Sdrahn j = 0; 483a1ac9a96Skrw } else if ((bp->bzb_flags & BZB_USR) != 0) { 484dce63815Sdrahn j = 2; 485dce63815Sdrahn } 486dce63815Sdrahn break; 487dce63815Sdrahn } 488dce63815Sdrahn printf("%4s ", s); 489dce63815Sdrahn printf("%c%c ", 490a1ac9a96Skrw (bp->bzb_flags & BZB_ROOT)?'R':' ', 491a1ac9a96Skrw (bp->bzb_flags & BZB_USR)?'U':' '); 492a1ac9a96Skrw slice = ((bp->bzb_flags >> BZB_SLICE_SHIFT) & BZB_SLICE_MASK); 493a1ac9a96Skrw if (slice != 0) { 494a1ac9a96Skrw printf(" %2d", slice); 495dce63815Sdrahn } else if (j >= 0) { 496dce63815Sdrahn printf(" *%2d", j); 497dce63815Sdrahn } else { 498dce63815Sdrahn printf(" "); 499dce63815Sdrahn } 500dce63815Sdrahn if (bp->bzb_mount_point[0] != 0) { 501dce63815Sdrahn printf(" %.64s", bp->bzb_mount_point); 502dce63815Sdrahn } 503dce63815Sdrahn } 504dce63815Sdrahn printf("\n"); 505dce63815Sdrahn } 506dce63815Sdrahn } 507dce63815Sdrahn 508dce63815Sdrahn 509dce63815Sdrahn void 510b42d9302Smartin full_dump_partition_entry(partition_map_header *map, int ix) 511dce63815Sdrahn { 512dce63815Sdrahn partition_map * cur; 513dce63815Sdrahn DPME *p; 514dce63815Sdrahn int i; 515dce63815Sdrahn u32 t; 516dce63815Sdrahn 517b42d9302Smartin cur = find_entry_by_disk_address(ix, map); 518dce63815Sdrahn if (cur == NULL) { 519dce63815Sdrahn printf("No such partition\n"); 520dce63815Sdrahn return; 521dce63815Sdrahn } 522dce63815Sdrahn 523dce63815Sdrahn p = cur->data; 524dce63815Sdrahn printf(" signature: 0x%x\n", p->dpme_signature); 525dce63815Sdrahn printf(" reserved1: 0x%x\n", p->dpme_reserved_1); 526dce63815Sdrahn printf(" number of map entries: %ld\n", p->dpme_map_entries); 527dce63815Sdrahn printf(" physical start: %10lu length: %10lu\n", p->dpme_pblock_start, p->dpme_pblocks); 528dce63815Sdrahn printf(" logical start: %10lu length: %10lu\n", p->dpme_lblock_start, p->dpme_lblocks); 529dce63815Sdrahn 530dce63815Sdrahn printf(" flags: 0x%lx\n", (u32)p->dpme_flags); 531dce63815Sdrahn printf(" "); 532a1ac9a96Skrw if (p->dpme_flags & DPME_VALID) printf("valid "); 533a1ac9a96Skrw if (p->dpme_flags & DPME_ALLOCATED) printf("alloc "); 534a1ac9a96Skrw if (p->dpme_flags & DPME_IN_USE) printf("in-use "); 535a1ac9a96Skrw if (p->dpme_flags & DPME_BOOTABLE) printf("boot "); 536a1ac9a96Skrw if (p->dpme_flags & DPME_READABLE) printf("read "); 537a1ac9a96Skrw if (p->dpme_flags & DPME_WRITABLE) printf("write "); 538a1ac9a96Skrw if (p->dpme_flags & DPME_OS_PIC_CODE) printf("pic "); 539dce63815Sdrahn t = p->dpme_flags >> 7; 540dce63815Sdrahn for (i = 7; i <= 31; i++) { 541dce63815Sdrahn if (t & 0x1) { 542dce63815Sdrahn printf("%d ", i); 543dce63815Sdrahn } 544dce63815Sdrahn t = t >> 1; 545dce63815Sdrahn } 546dce63815Sdrahn printf("\n"); 547dce63815Sdrahn 548dce63815Sdrahn printf(" name: '%.32s'\n", p->dpme_name); 549dce63815Sdrahn printf(" type: '%.32s'\n", p->dpme_type); 550dce63815Sdrahn 551dce63815Sdrahn printf(" boot start block: %10lu\n", p->dpme_boot_block); 552dce63815Sdrahn printf("boot length (in bytes): %10lu\n", p->dpme_boot_bytes); 553dce63815Sdrahn printf(" load address: 0x%08lx 0x%08lx\n", 554dce63815Sdrahn (u32)p->dpme_load_addr, (u32)p->dpme_load_addr_2); 555dce63815Sdrahn printf(" start address: 0x%08lx 0x%08lx\n", 556dce63815Sdrahn (u32)p->dpme_goto_addr, (u32)p->dpme_goto_addr_2); 557dce63815Sdrahn printf(" checksum: 0x%08lx\n", p->dpme_checksum); 558dce63815Sdrahn printf(" processor: '%.32s'\n", p->dpme_process_id); 559dce63815Sdrahn printf("boot args field -"); 560dce63815Sdrahn dump_block((unsigned char *)p->dpme_boot_args, 32*4); 561dce63815Sdrahn printf("dpme_reserved_3 -"); 562dce63815Sdrahn dump_block((unsigned char *)p->dpme_reserved_3, 62*4); 563dce63815Sdrahn } 564dce63815Sdrahn 565dce63815Sdrahn 566dce63815Sdrahn void 567dce63815Sdrahn dump_block(unsigned char *addr, int len) 568dce63815Sdrahn { 569dce63815Sdrahn int i; 570dce63815Sdrahn int j; 571dce63815Sdrahn int limit1; 572dce63815Sdrahn int limit; 573dce63815Sdrahn #define LINE_LEN 16 574dce63815Sdrahn #define UNIT_LEN 4 575dce63815Sdrahn #define OTHER_LEN 8 576dce63815Sdrahn 577dce63815Sdrahn for (i = 0; i < len; i = limit) { 578dce63815Sdrahn limit1 = i + LINE_LEN; 579dce63815Sdrahn if (limit1 > len) { 580dce63815Sdrahn limit = len; 581dce63815Sdrahn } else { 582dce63815Sdrahn limit = limit1; 583dce63815Sdrahn } 584dce63815Sdrahn printf("\n%03x: ", i); 585dce63815Sdrahn for (j = i; j < limit1; j++) { 586dce63815Sdrahn if (j % UNIT_LEN == 0) { 587dce63815Sdrahn printf(" "); 588dce63815Sdrahn } 589dce63815Sdrahn if (j < limit) { 590dce63815Sdrahn printf("%02x", addr[j]); 591dce63815Sdrahn } else { 592dce63815Sdrahn printf(" "); 593dce63815Sdrahn } 594dce63815Sdrahn } 595dce63815Sdrahn printf(" "); 596dce63815Sdrahn for (j = i; j < limit; j++) { 597dce63815Sdrahn if (j % OTHER_LEN == 0) { 598dce63815Sdrahn printf(" "); 599dce63815Sdrahn } 600dce63815Sdrahn if (addr[j] < ' ') { 601dce63815Sdrahn printf("."); 602dce63815Sdrahn } else { 603dce63815Sdrahn printf("%c", addr[j]); 604dce63815Sdrahn } 605dce63815Sdrahn } 606dce63815Sdrahn } 607dce63815Sdrahn printf("\n"); 608dce63815Sdrahn } 609dce63815Sdrahn 610dce63815Sdrahn void 611dce63815Sdrahn full_dump_block_zero(partition_map_header *map) 612dce63815Sdrahn { 613dce63815Sdrahn Block0 *zp; 614dce63815Sdrahn DDMap *m; 615dce63815Sdrahn int i; 616dce63815Sdrahn 617dce63815Sdrahn if (map == NULL) { 618dce63815Sdrahn printf("No partition map exists\n"); 619dce63815Sdrahn return; 620dce63815Sdrahn } 621dce63815Sdrahn 622dce63815Sdrahn if (map->misc == NULL) { 623dce63815Sdrahn printf("No block zero\n"); 624dce63815Sdrahn return; 625dce63815Sdrahn } 626dce63815Sdrahn zp = map->misc; 627dce63815Sdrahn 628dce63815Sdrahn printf(" signature: 0x%x\n", zp->sbSig); 629dce63815Sdrahn printf(" size of a block: %d\n", zp->sbBlkSize); 630dce63815Sdrahn printf(" number of blocks: %ld\n", zp->sbBlkCount); 631dce63815Sdrahn printf(" device type: 0x%x\n", zp->sbDevType); 632dce63815Sdrahn printf(" device id: 0x%x\n", zp->sbDevId); 633dce63815Sdrahn printf(" data: 0x%lx\n", zp->sbData); 634dce63815Sdrahn printf(" driver count: %d\n", zp->sbDrvrCount); 635dce63815Sdrahn m = (DDMap *) zp->sbMap; 636dce63815Sdrahn for (i = 0; &m[i].ddType < &zp->sbMap[247]; i++) { 637dce63815Sdrahn if (m[i].ddBlock == 0 && m[i].ddSize == 0 && m[i].ddType == 0) { 638dce63815Sdrahn break; 639dce63815Sdrahn } 640dce63815Sdrahn printf(" driver %3u block: %ld\n", i+1, m[i].ddBlock); 641dce63815Sdrahn printf(" size in blocks: %d\n", m[i].ddSize); 642dce63815Sdrahn printf(" driver type: 0x%x\n", m[i].ddType); 643dce63815Sdrahn } 644dce63815Sdrahn printf("remainder of block -"); 645dce63815Sdrahn dump_block((unsigned char *)&m[i].ddBlock, (&zp->sbMap[247]-((unsigned short *)&m[i].ddBlock))*2); 646dce63815Sdrahn } 647dce63815Sdrahn 648b42d9302Smartin 649dce63815Sdrahn void 650dce63815Sdrahn display_patches(partition_map *entry) 651dce63815Sdrahn { 652dce63815Sdrahn long long offset; 653dce63815Sdrahn MEDIA m; 654dce63815Sdrahn static unsigned char *patch_block; 655b42d9302Smartin PatchListPtr p; 656b42d9302Smartin PatchDescriptorPtr q; 657b42d9302Smartin unsigned char *next; 658b42d9302Smartin unsigned char *s; 659b42d9302Smartin int i; 660dce63815Sdrahn 661dce63815Sdrahn offset = entry->data->dpme_pblock_start; 662dce63815Sdrahn m = entry->the_map->m; 663dce63815Sdrahn offset = ((long long) entry->data->dpme_pblock_start) * entry->the_map->logical_block; 664dce63815Sdrahn if (patch_block == NULL) { 665d66063cbSkrw patch_block = malloc(DEV_BSIZE); 666dce63815Sdrahn if (patch_block == NULL) { 66768d0f91bSkrw warn("can't allocate memory for patch block buffer"); 668dce63815Sdrahn return; 669dce63815Sdrahn } 670dce63815Sdrahn } 671*f42746d7Skrw if (read_file_media(m, (long long)offset, DEV_BSIZE, (char *)patch_block) == 0) { 67268d0f91bSkrw warn("Can't read patch block"); 673dce63815Sdrahn return; 674dce63815Sdrahn } 675b42d9302Smartin p = (PatchListPtr) patch_block; 676b42d9302Smartin if (p->numPatchBlocks != 1) { 677b42d9302Smartin i = p->numPatchBlocks; 678b42d9302Smartin free(patch_block); 679d66063cbSkrw patch_block = reallocarray(NULL, i, DEV_BSIZE); 680b42d9302Smartin if (patch_block == NULL) { 68168d0f91bSkrw warn("can't allocate memory for patch blocks buffer"); 682b42d9302Smartin return; 683b42d9302Smartin } 684d66063cbSkrw s = patch_block + DEV_BSIZE*i; 685b42d9302Smartin while (i > 0) { 686d66063cbSkrw s -= DEV_BSIZE; 687b42d9302Smartin i -= 1; 688*f42746d7Skrw if (read_file_media(m, offset+i, DEV_BSIZE, (char *)s) == 0) { 68968d0f91bSkrw warn("Can't read patch block %d", i); 690b42d9302Smartin return; 691b42d9302Smartin } 692b42d9302Smartin } 693b42d9302Smartin p = (PatchListPtr) patch_block; 694b42d9302Smartin } 695b42d9302Smartin printf("Patch list (%d entries)\n", p->numPatches); 696b42d9302Smartin q = p->thePatch; 697b42d9302Smartin for (i = 0; i < p->numPatches; i++) { 698b42d9302Smartin printf("%2d signature: '%.4s'\n", i+1, (char *)&q->patchSig); 699b42d9302Smartin printf(" version: %d.%d\n", q->majorVers, q->minorVers); 700b42d9302Smartin printf(" flags: 0x%lx\n", q->flags); 701b42d9302Smartin printf(" offset: %ld\n", q->patchOffset); 702b42d9302Smartin printf(" size: %ld\n", q->patchSize); 703b42d9302Smartin printf(" CRC: 0x%lx\n", q->patchCRC); 704b42d9302Smartin printf(" name: '%.*s'\n", q->patchName[0], &q->patchName[1]); 705b42d9302Smartin printf(" vendor: '%.*s'\n", q->patchVendor[0], &q->patchVendor[1]); 706b42d9302Smartin next = ((unsigned char *)q) + q->patchDescriptorLen; 707b42d9302Smartin s = &q->patchVendor[q->patchVendor[0]+1]; 708b42d9302Smartin if (next > s) { 709b42d9302Smartin printf("remainder of entry -"); 710b42d9302Smartin dump_block(s, next-s); 711b42d9302Smartin } 712b42d9302Smartin q = (PatchDescriptorPtr)next; 713b42d9302Smartin } 714dce63815Sdrahn } 715dce63815Sdrahn 716dce63815Sdrahn int 717dce63815Sdrahn get_max_type_string_length(partition_map_header *map) 718dce63815Sdrahn { 719dce63815Sdrahn partition_map * entry; 720dce63815Sdrahn int max; 721dce63815Sdrahn int length; 722dce63815Sdrahn 723dce63815Sdrahn if (map == NULL) { 724dce63815Sdrahn return 0; 725dce63815Sdrahn } 726dce63815Sdrahn 727dce63815Sdrahn max = 0; 728dce63815Sdrahn 729dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 730dce63815Sdrahn length = strnlen(entry->data->dpme_type, DPISTRLEN); 731dce63815Sdrahn if (length > max) { 732dce63815Sdrahn max = length; 733dce63815Sdrahn } 734dce63815Sdrahn } 735dce63815Sdrahn 736dce63815Sdrahn return max; 737dce63815Sdrahn } 738dce63815Sdrahn 739dce63815Sdrahn int 740dce63815Sdrahn get_max_name_string_length(partition_map_header *map) 741dce63815Sdrahn { 742dce63815Sdrahn partition_map * entry; 743dce63815Sdrahn int max; 744dce63815Sdrahn int length; 745dce63815Sdrahn 746dce63815Sdrahn if (map == NULL) { 747dce63815Sdrahn return 0; 748dce63815Sdrahn } 749dce63815Sdrahn 750dce63815Sdrahn max = 0; 751dce63815Sdrahn 752dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 753dce63815Sdrahn length = strnlen(entry->data->dpme_name, DPISTRLEN); 754dce63815Sdrahn if (length > max) { 755dce63815Sdrahn max = length; 756dce63815Sdrahn } 757dce63815Sdrahn } 758dce63815Sdrahn 759dce63815Sdrahn return max; 760dce63815Sdrahn } 761dce63815Sdrahn 762dce63815Sdrahn int 763dce63815Sdrahn get_max_base_or_length(partition_map_header *map) 764dce63815Sdrahn { 765dce63815Sdrahn partition_map * entry; 766dce63815Sdrahn int max; 767dce63815Sdrahn 768dce63815Sdrahn if (map == NULL) { 769dce63815Sdrahn return 0; 770dce63815Sdrahn } 771dce63815Sdrahn 772dce63815Sdrahn max = 0; 773dce63815Sdrahn 774dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 775dce63815Sdrahn if (entry->data->dpme_pblock_start > max) { 776dce63815Sdrahn max = entry->data->dpme_pblock_start; 777dce63815Sdrahn } 778dce63815Sdrahn if (entry->data->dpme_pblocks > max) { 779dce63815Sdrahn max = entry->data->dpme_pblocks; 780dce63815Sdrahn } 781dce63815Sdrahn if (entry->data->dpme_lblock_start > max) { 782dce63815Sdrahn max = entry->data->dpme_lblock_start; 783dce63815Sdrahn } 784dce63815Sdrahn if (entry->data->dpme_lblocks > max) { 785dce63815Sdrahn max = entry->data->dpme_lblocks; 786dce63815Sdrahn } 787dce63815Sdrahn } 788dce63815Sdrahn 789dce63815Sdrahn return max; 790dce63815Sdrahn } 791dce63815Sdrahn 792dce63815Sdrahn void 793dce63815Sdrahn adjust_value_and_compute_prefix(double *value, int *prefix) 794dce63815Sdrahn { 795dce63815Sdrahn double bytes; 796dce63815Sdrahn int multiplier; 797dce63815Sdrahn 798dce63815Sdrahn bytes = *value; 799dce63815Sdrahn if (bytes < 1024.0) { 800dce63815Sdrahn multiplier = ' '; 801dce63815Sdrahn } else { 802dce63815Sdrahn bytes = bytes / 1024.0; 803dce63815Sdrahn if (bytes < 1024.0) { 804dce63815Sdrahn multiplier = 'K'; 805dce63815Sdrahn } else { 806dce63815Sdrahn bytes = bytes / 1024.0; 807dce63815Sdrahn if (bytes < 1024.0) { 808dce63815Sdrahn multiplier = 'M'; 809dce63815Sdrahn } else { 810dce63815Sdrahn bytes = bytes / 1024.0; 811dce63815Sdrahn if (bytes < 1024.0) { 812dce63815Sdrahn multiplier = 'G'; 813dce63815Sdrahn } else { 814dce63815Sdrahn bytes = bytes / 1024.0; 815dce63815Sdrahn multiplier = 'T'; 816dce63815Sdrahn } 817dce63815Sdrahn } 818dce63815Sdrahn } 819dce63815Sdrahn } 820dce63815Sdrahn *value = bytes; 821dce63815Sdrahn *prefix = multiplier; 822dce63815Sdrahn } 823