1239400Sandreast/* $OpenBSD: dump.c,v 1.75 2016/02/23 02:39:54 krw Exp $ */ 2239400Sandreast 3239400Sandreast/* 4239400Sandreast * dump.c - dumping partition maps 5239400Sandreast * 6239400Sandreast * Written by Eryk Vershen 7239400Sandreast */ 8239400Sandreast 9239400Sandreast/* 10239400Sandreast * Copyright 1996,1997,1998 by Apple Computer, Inc. 11239400Sandreast * All Rights Reserved 12239400Sandreast * 13239400Sandreast * Permission to use, copy, modify, and distribute this software and 14239400Sandreast * its documentation for any purpose and without fee is hereby granted, 15239400Sandreast * provided that the above copyright notice appears in all copies and 16239400Sandreast * that both the copyright notice and this permission notice appear in 17239400Sandreast * supporting documentation. 18239400Sandreast * 19239400Sandreast * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 20239400Sandreast * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21239400Sandreast * FOR A PARTICULAR PURPOSE. 22239400Sandreast * 23239400Sandreast * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 24239400Sandreast * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 25239400Sandreast * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 26239400Sandreast * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 27239400Sandreast * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 28239400Sandreast */ 29239400Sandreast 30239400Sandreast#include <sys/queue.h> 31239400Sandreast 32239400Sandreast#include <stdio.h> 33239400Sandreast#include <stdlib.h> 34239400Sandreast#include <string.h> 35239400Sandreast#include <util.h> 36239400Sandreast 37239400Sandreast#include "partition_map.h" 38239400Sandreast#include "dump.h" 39239400Sandreast#include "io.h" 40239400Sandreast 41239400Sandreastvoid dump_block(unsigned char *, int); 42239400Sandreastvoid dump_block_zero(struct partition_map *); 43239400Sandreastvoid dump_partition_entry(struct entry *, int, int, int); 44239400Sandreastint get_max_base_or_length(struct partition_map *); 45239400Sandreastint get_max_name_string_length(struct partition_map *); 46239400Sandreastint get_max_type_string_length(struct partition_map *); 47239400Sandreast 48239400Sandreastvoid 49239400Sandreastdump_block_zero(struct partition_map *map) 50239400Sandreast{ 51239400Sandreast char buf[FMT_SCALED_STRSIZE]; 52239400Sandreast struct ddmap *m; 53239400Sandreast int i; 54239400Sandreast 55239400Sandreast printf("\nDevice block size=%u, Number of Blocks=%u", 56239400Sandreast map->sbBlkSize, map->sbBlkCount); 57239400Sandreast if (fmt_scaled((long long)map->sbBlkCount * map->sbBlkSize, buf) == 0) 58239400Sandreast printf(" (%s)\n", buf); 59239400Sandreast else 60239400Sandreast printf("\n"); 61239400Sandreast 62239400Sandreast printf("DeviceType=0x%x, DeviceId=0x%x\n", map->sbDevType, 63239400Sandreast map->sbDevId); 64239400Sandreast if (map->sbDrvrCount > 0) { 65239400Sandreast printf("Drivers-\n"); 66239400Sandreast m = map->sbDDMap; 67239400Sandreast for (i = 0; i < map->sbDrvrCount; i++) { 68239400Sandreast printf("%d: %3u @ %u, ", i + 1, m[i].ddSize, 69239400Sandreast m[i].ddBlock); 70239400Sandreast printf("type=0x%x\n", m[i].ddType); 71239400Sandreast } 72239400Sandreast } 73239400Sandreast printf("\n"); 74239400Sandreast} 75239400Sandreast 76239400Sandreast 77239400Sandreastvoid 78239400Sandreastdump_partition_map(struct partition_map *map) 79239400Sandreast{ 80239400Sandreast struct entry *entry; 81239400Sandreast int digits, max_type_length, max_name_length; 82239400Sandreast 83239400Sandreast printf("\nPartition map (with %d byte blocks) on '%s'\n", 84239400Sandreast map->sbBlkSize, map->name); 85239400Sandreast 86239400Sandreast digits = number_of_digits(get_max_base_or_length(map)); 87239400Sandreast if (digits < 6) 88239400Sandreast digits = 6; 89239400Sandreast max_type_length = get_max_type_string_length(map); 90239400Sandreast if (max_type_length < 4) 91239400Sandreast max_type_length = 4; 92239400Sandreast max_name_length = get_max_name_string_length(map); 93239400Sandreast if (max_name_length < 6) 94239400Sandreast max_name_length = 6; 95239400Sandreast printf(" #: %*s %-*s %*s %-*s\n", max_type_length, "type", 96239400Sandreast max_name_length, "name", digits, "length", digits, "base"); 97239400Sandreast 98239400Sandreast LIST_FOREACH(entry, &map->disk_order, disk_entry) { 99239400Sandreast dump_partition_entry(entry, max_type_length, 100239400Sandreast max_name_length, digits); 101239400Sandreast } 102239400Sandreast dump_block_zero(map); 103239400Sandreast} 104239400Sandreast 105239400Sandreast 106239400Sandreastvoid 107239400Sandreastdump_partition_entry(struct entry *entry, int type_length, int name_length, 108239400Sandreast int digits) 109239400Sandreast{ 110239400Sandreast char buf[FMT_SCALED_STRSIZE]; 111239400Sandreast 112239400Sandreast printf("%2ld: %*.32s", entry->disk_address, type_length, 113239400Sandreast entry->dpme_type); 114239400Sandreast printf("%c%-*.32s ", contains_driver(entry) ? '*' : ' ', 115239400Sandreast name_length, entry->dpme_name); 116239400Sandreast 117239400Sandreast printf("%*u @ %-*u", digits, entry->dpme_pblocks, digits, 118239400Sandreast entry->dpme_pblock_start); 119239400Sandreast 120239400Sandreast if (fmt_scaled((long long)entry->dpme_pblocks * 121239400Sandreast entry->the_map->sbBlkSize, buf) == 0) 122239400Sandreast printf("(%s)\n", buf); 123239400Sandreast else 124239400Sandreast printf("\n"); 125239400Sandreast} 126239400Sandreast 127239400Sandreast 128239400Sandreastvoid 129239400Sandreastshow_data_structures(struct partition_map *map) 130239400Sandreast{ 131239400Sandreast struct entry *entry; 132239400Sandreast struct ddmap *m; 133239400Sandreast int i; 134239400Sandreast 135239400Sandreast printf("Header:\n"); 136239400Sandreast printf("map %d blocks out of %d, media %lu blocks (%d byte blocks)\n", 137239400Sandreast map->blocks_in_map, map->maximum_in_map, map->media_size, 138239400Sandreast map->sbBlkSize); 139239400Sandreast printf("Map is%s writable", rflag ? " not" : ""); 140239400Sandreast printf(" and has%s been changed\n", (map->changed) ? "" : " not"); 141239400Sandreast printf("\n"); 142239400Sandreast 143239400Sandreast printf("Block0:\n"); 144239400Sandreast printf("signature 0x%x", map->sbSig); 145239400Sandreast printf("Block size=%u, Number of Blocks=%u\n", map->sbBlkSize, 146239400Sandreast map->sbBlkCount); 147239400Sandreast printf("DeviceType=0x%x, DeviceId=0x%x, sbData=0x%x\n", map->sbDevType, 148239400Sandreast map->sbDevId, map->sbData); 149239400Sandreast if (map->sbDrvrCount == 0) { 150239400Sandreast printf("No drivers\n"); 151239400Sandreast } else { 152239400Sandreast printf("%u driver%s-\n", map->sbDrvrCount, 153239400Sandreast (map->sbDrvrCount > 1) ? "s" : ""); 154239400Sandreast m = map->sbDDMap; 155239400Sandreast for (i = 0; i < map->sbDrvrCount; i++) { 156239400Sandreast printf("%u: @ %u for %u, type=0x%x\n", i + 1, 157239400Sandreast m[i].ddBlock, m[i].ddSize, m[i].ddType); 158239400Sandreast } 159239400Sandreast } 160239400Sandreast printf("\n"); 161239400Sandreast printf(" #: type length base " 162239400Sandreast "flags ( logical )\n"); 163239400Sandreast LIST_FOREACH(entry, &map->disk_order, disk_entry) { 164239400Sandreast printf("%2ld: %20.32s ", entry->disk_address, entry->dpme_type); 165239400Sandreast printf("%7u @ %-7u ", entry->dpme_pblocks, 166239400Sandreast entry->dpme_pblock_start); 167239400Sandreast printf("%c%c%c%c%c%c%c%c%c ", 168239400Sandreast (entry->dpme_flags & DPME_VALID) ? 'V' : '.', 169239400Sandreast (entry->dpme_flags & DPME_ALLOCATED) ? 'A' : '.', 170239400Sandreast (entry->dpme_flags & DPME_IN_USE) ? 'I' : '.', 171239400Sandreast (entry->dpme_flags & DPME_BOOTABLE) ? 'B' : '.', 172239400Sandreast (entry->dpme_flags & DPME_READABLE) ? 'R' : '.', 173239400Sandreast (entry->dpme_flags & DPME_WRITABLE) ? 'W' : '.', 174239400Sandreast (entry->dpme_flags & DPME_OS_PIC_CODE) ? 'P' : '.', 175239400Sandreast (entry->dpme_flags & DPME_OS_SPECIFIC_2) ? '2' : '.', 176239400Sandreast (entry->dpme_flags & DPME_OS_SPECIFIC_1) ? '1' : '.'); 177239400Sandreast printf("( %7u @ %-7u )\n", entry->dpme_lblocks, 178239400Sandreast entry->dpme_lblock_start); 179239400Sandreast } 180239400Sandreast printf("\n"); 181239400Sandreast printf(" #: booter bytes load_address " 182239400Sandreast "goto_address checksum processor\n"); 183239400Sandreast LIST_FOREACH(entry, &map->disk_order, disk_entry) { 184239400Sandreast printf("%2ld: ", entry->disk_address); 185239400Sandreast printf("%7u ", entry->dpme_boot_block); 186239400Sandreast printf("%7u ", entry->dpme_boot_bytes); 187239400Sandreast printf("%8x ", entry->dpme_load_addr); 188239400Sandreast printf("%8x ", entry->dpme_goto_addr); 189239400Sandreast printf("%8x ", entry->dpme_checksum); 190239400Sandreast printf("%.32s", entry->dpme_processor_id); 191239400Sandreast printf("\n"); 192239400Sandreast } 193239400Sandreast printf("\n"); 194239400Sandreast} 195239400Sandreast 196239400Sandreast 197239400Sandreastvoid 198239400Sandreastfull_dump_partition_entry(struct partition_map *map, int ix) 199239400Sandreast{ 200239400Sandreast struct entry *entry; 201239400Sandreast int i; 202239400Sandreast uint32_t t; 203239400Sandreast 204239400Sandreast entry = find_entry_by_disk_address(ix, map); 205239400Sandreast if (entry == NULL) { 206239400Sandreast printf("No such partition\n"); 207239400Sandreast return; 208239400Sandreast } 209239400Sandreast printf(" signature: 0x%x\n", entry->dpme_signature); 210239400Sandreast printf(" number of map entries: %u\n", entry->dpme_map_entries); 211239400Sandreast printf(" physical start: %10u length: %10u\n", 212239400Sandreast entry->dpme_pblock_start, entry->dpme_pblocks); 213239400Sandreast printf(" logical start: %10u length: %10u\n", 214239400Sandreast entry->dpme_lblock_start, entry->dpme_lblocks); 215239400Sandreast 216239400Sandreast printf(" flags: 0x%x\n", entry->dpme_flags); 217239400Sandreast printf(" "); 218239400Sandreast if (entry->dpme_flags & DPME_VALID) 219239400Sandreast printf("valid "); 220239400Sandreast if (entry->dpme_flags & DPME_ALLOCATED) 221239400Sandreast printf("alloc "); 222239400Sandreast if (entry->dpme_flags & DPME_IN_USE) 223239400Sandreast printf("in-use "); 224239400Sandreast if (entry->dpme_flags & DPME_BOOTABLE) 225239400Sandreast printf("boot "); 226239400Sandreast if (entry->dpme_flags & DPME_READABLE) 227239400Sandreast printf("read "); 228239400Sandreast if (entry->dpme_flags & DPME_WRITABLE) 229239400Sandreast printf("write "); 230239400Sandreast if (entry->dpme_flags & DPME_OS_PIC_CODE) 231239400Sandreast printf("pic "); 232239400Sandreast t = entry->dpme_flags >> 7; 233239400Sandreast for (i = 7; i <= 31; i++) { 234239400Sandreast if (t & 0x1) 235239400Sandreast printf("%d ", i); 236239400Sandreast t = t >> 1; 237239400Sandreast } 238239400Sandreast printf("\n"); 239239400Sandreast 240239400Sandreast printf(" name: '%.32s'\n", entry->dpme_name); 241239400Sandreast printf(" type: '%.32s'\n", entry->dpme_type); 242239400Sandreast printf(" boot start block: %10u\n", entry->dpme_boot_block); 243239400Sandreast printf("boot length (in bytes): %10u\n", entry->dpme_boot_bytes); 244239400Sandreast printf(" load address: 0x%08x\n", entry->dpme_load_addr); 245239400Sandreast printf(" start address: 0x%08x\n", entry->dpme_goto_addr); 246239400Sandreast printf(" checksum: 0x%08x\n", entry->dpme_checksum); 247239400Sandreast printf(" processor: '%.32s'\n", entry->dpme_processor_id); 248239400Sandreast printf("dpme_reserved_1 -"); 249239400Sandreast dump_block(entry->dpme_reserved_1, sizeof(entry->dpme_reserved_1)); 250239400Sandreast printf("dpme_reserved_2 -"); 251239400Sandreast dump_block(entry->dpme_reserved_2, sizeof(entry->dpme_reserved_2)); 252239400Sandreast printf("dpme_reserved_3 -"); 253239400Sandreast dump_block(entry->dpme_reserved_3, sizeof(entry->dpme_reserved_3)); 254239400Sandreast printf("dpme_reserved_4 -"); 255239400Sandreast dump_block(entry->dpme_reserved_4, sizeof(entry->dpme_reserved_4)); 256239400Sandreast} 257239400Sandreast 258239400Sandreast 259239400Sandreastvoid 260239400Sandreastdump_block(unsigned char *addr, int len) 261239400Sandreast{ 262239400Sandreast int i, j, limit1, limit; 263239400Sandreast 264239400Sandreast#define LINE_LEN 16 265239400Sandreast#define UNIT_LEN 4 266239400Sandreast#define OTHER_LEN 8 267239400Sandreast 268239400Sandreast for (i = 0; i < len; i = limit) { 269239400Sandreast limit1 = i + LINE_LEN; 270239400Sandreast if (limit1 > len) 271239400Sandreast limit = len; 272239400Sandreast else 273239400Sandreast limit = limit1; 274239400Sandreast printf("\n%03x: ", i); 275239400Sandreast for (j = i; j < limit1; j++) { 276239400Sandreast if (j % UNIT_LEN == 0) 277239400Sandreast printf(" "); 278239400Sandreast if (j < limit) 279239400Sandreast printf("%02x", addr[j]); 280239400Sandreast else 281239400Sandreast printf(" "); 282239400Sandreast } 283239400Sandreast printf(" "); 284239400Sandreast for (j = i; j < limit; j++) { 285239400Sandreast if (j % OTHER_LEN == 0) 286239400Sandreast printf(" "); 287239400Sandreast if (addr[j] < ' ') 288239400Sandreast printf("."); 289239400Sandreast else 290239400Sandreast printf("%c", addr[j]); 291239400Sandreast } 292239400Sandreast } 293239400Sandreast printf("\n"); 294239400Sandreast} 295239400Sandreast 296239400Sandreastvoid 297239400Sandreastfull_dump_block_zero(struct partition_map *map) 298239400Sandreast{ 299239400Sandreast struct ddmap *m; 300239400Sandreast int i; 301239400Sandreast 302239400Sandreast m = map->sbDDMap; 303239400Sandreast 304239400Sandreast printf(" signature: 0x%x\n", map->sbSig); 305239400Sandreast printf(" size of a block: %u\n", map->sbBlkSize); 306239400Sandreast printf(" number of blocks: %u\n", map->sbBlkCount); 307239400Sandreast printf(" device type: 0x%x\n", map->sbDevType); 308239400Sandreast printf(" device id: 0x%x\n", map->sbDevId); 309239400Sandreast printf(" data: 0x%x\n", map->sbData); 310239400Sandreast printf(" driver count: %u\n", map->sbDrvrCount); 311239400Sandreast for (i = 0; i < 8; i++) { 312239400Sandreast if (m[i].ddBlock == 0 && m[i].ddSize == 0 && m[i].ddType == 0) 313239400Sandreast break; 314239400Sandreast printf(" driver %3u block: %u\n", i + 1, m[i].ddBlock); 315239400Sandreast printf(" size in blocks: %u\n", m[i].ddSize); 316239400Sandreast printf(" driver type: 0x%x\n", m[i].ddType); 317239400Sandreast } 318239400Sandreast printf("remainder of block -"); 319239400Sandreast dump_block(map->sbReserved, sizeof(map->sbReserved)); 320239400Sandreast} 321239400Sandreast 322239400Sandreastint 323239400Sandreastget_max_type_string_length(struct partition_map *map) 324239400Sandreast{ 325239400Sandreast struct entry *entry; 326239400Sandreast int max, length; 327239400Sandreast 328239400Sandreast max = 0; 329239400Sandreast 330239400Sandreast LIST_FOREACH(entry, &map->disk_order, disk_entry) { 331239400Sandreast length = strnlen(entry->dpme_type, DPISTRLEN); 332239400Sandreast if (length > max) 333239400Sandreast max = length; 334239400Sandreast } 335239400Sandreast 336239400Sandreast return max; 337239400Sandreast} 338239400Sandreast 339239400Sandreastint 340239400Sandreastget_max_name_string_length(struct partition_map *map) 341239400Sandreast{ 342239400Sandreast struct entry *entry; 343239400Sandreast int max, length; 344239400Sandreast 345239400Sandreast max = 0; 346239400Sandreast 347239400Sandreast LIST_FOREACH(entry, &map->disk_order, disk_entry) { 348239400Sandreast length = strnlen(entry->dpme_name, DPISTRLEN); 349239400Sandreast if (length > max) 350239400Sandreast max = length; 351239400Sandreast } 352239400Sandreast 353239400Sandreast return max; 354239400Sandreast} 355239400Sandreast 356239400Sandreastint 357239400Sandreastget_max_base_or_length(struct partition_map *map) 358239400Sandreast{ 359239400Sandreast struct entry *entry; 360239400Sandreast int max; 361239400Sandreast 362239400Sandreast max = 0; 363239400Sandreast 364239400Sandreast LIST_FOREACH(entry, &map->disk_order, disk_entry) { 365239400Sandreast if (entry->dpme_pblock_start > max) 366239400Sandreast max = entry->dpme_pblock_start; 367239400Sandreast if (entry->dpme_pblocks > max) 368239400Sandreast max = entry->dpme_pblocks; 369239400Sandreast } 370239400Sandreast 371239400Sandreast return max; 372239400Sandreast} 373239400Sandreast