1 /* $OpenBSD: dump.c,v 1.75 2016/02/23 02:39:54 krw Exp $ */ 2 3 /* 4 * dump.c - dumping partition maps 5 * 6 * Written by Eryk Vershen 7 */ 8 9 /* 10 * Copyright 1996,1997,1998 by Apple Computer, Inc. 11 * All Rights Reserved 12 * 13 * Permission to use, copy, modify, and distribute this software and 14 * its documentation for any purpose and without fee is hereby granted, 15 * provided that the above copyright notice appears in all copies and 16 * that both the copyright notice and this permission notice appear in 17 * supporting documentation. 18 * 19 * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 20 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 * FOR A PARTICULAR PURPOSE. 22 * 23 * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 25 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 26 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 27 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 28 */ 29 30 #include <sys/queue.h> 31 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <util.h> 36 37 #include "partition_map.h" 38 #include "dump.h" 39 #include "io.h" 40 41 void dump_block(unsigned char *, int); 42 void dump_block_zero(struct partition_map *); 43 void dump_partition_entry(struct entry *, int, int, int); 44 int get_max_base_or_length(struct partition_map *); 45 int get_max_name_string_length(struct partition_map *); 46 int get_max_type_string_length(struct partition_map *); 47 48 void 49 dump_block_zero(struct partition_map *map) 50 { 51 char buf[FMT_SCALED_STRSIZE]; 52 struct ddmap *m; 53 int i; 54 55 printf("\nDevice block size=%u, Number of Blocks=%u", 56 map->sbBlkSize, map->sbBlkCount); 57 if (fmt_scaled((long long)map->sbBlkCount * map->sbBlkSize, buf) == 0) 58 printf(" (%s)\n", buf); 59 else 60 printf("\n"); 61 62 printf("DeviceType=0x%x, DeviceId=0x%x\n", map->sbDevType, 63 map->sbDevId); 64 if (map->sbDrvrCount > 0) { 65 printf("Drivers-\n"); 66 m = map->sbDDMap; 67 for (i = 0; i < map->sbDrvrCount; i++) { 68 printf("%d: %3u @ %u, ", i + 1, m[i].ddSize, 69 m[i].ddBlock); 70 printf("type=0x%x\n", m[i].ddType); 71 } 72 } 73 printf("\n"); 74 } 75 76 77 void 78 dump_partition_map(struct partition_map *map) 79 { 80 struct entry *entry; 81 int digits, max_type_length, max_name_length; 82 83 printf("\nPartition map (with %d byte blocks) on '%s'\n", 84 map->sbBlkSize, map->name); 85 86 digits = number_of_digits(get_max_base_or_length(map)); 87 if (digits < 6) 88 digits = 6; 89 max_type_length = get_max_type_string_length(map); 90 if (max_type_length < 4) 91 max_type_length = 4; 92 max_name_length = get_max_name_string_length(map); 93 if (max_name_length < 6) 94 max_name_length = 6; 95 printf(" #: %*s %-*s %*s %-*s\n", max_type_length, "type", 96 max_name_length, "name", digits, "length", digits, "base"); 97 98 LIST_FOREACH(entry, &map->disk_order, disk_entry) { 99 dump_partition_entry(entry, max_type_length, 100 max_name_length, digits); 101 } 102 dump_block_zero(map); 103 } 104 105 106 void 107 dump_partition_entry(struct entry *entry, int type_length, int name_length, 108 int digits) 109 { 110 char buf[FMT_SCALED_STRSIZE]; 111 112 printf("%2ld: %*.32s", entry->disk_address, type_length, 113 entry->dpme_type); 114 printf("%c%-*.32s ", contains_driver(entry) ? '*' : ' ', 115 name_length, entry->dpme_name); 116 117 printf("%*u @ %-*u", digits, entry->dpme_pblocks, digits, 118 entry->dpme_pblock_start); 119 120 if (fmt_scaled((long long)entry->dpme_pblocks * 121 entry->the_map->sbBlkSize, buf) == 0) 122 printf("(%s)\n", buf); 123 else 124 printf("\n"); 125 } 126 127 128 void 129 show_data_structures(struct partition_map *map) 130 { 131 struct entry *entry; 132 struct ddmap *m; 133 int i; 134 135 printf("Header:\n"); 136 printf("map %d blocks out of %d, media %lu blocks (%d byte blocks)\n", 137 map->blocks_in_map, map->maximum_in_map, map->media_size, 138 map->sbBlkSize); 139 printf("Map is%s writable", rflag ? " not" : ""); 140 printf(" and has%s been changed\n", (map->changed) ? "" : " not"); 141 printf("\n"); 142 143 printf("Block0:\n"); 144 printf("signature 0x%x", map->sbSig); 145 printf("Block size=%u, Number of Blocks=%u\n", map->sbBlkSize, 146 map->sbBlkCount); 147 printf("DeviceType=0x%x, DeviceId=0x%x, sbData=0x%x\n", map->sbDevType, 148 map->sbDevId, map->sbData); 149 if (map->sbDrvrCount == 0) { 150 printf("No drivers\n"); 151 } else { 152 printf("%u driver%s-\n", map->sbDrvrCount, 153 (map->sbDrvrCount > 1) ? "s" : ""); 154 m = map->sbDDMap; 155 for (i = 0; i < map->sbDrvrCount; i++) { 156 printf("%u: @ %u for %u, type=0x%x\n", i + 1, 157 m[i].ddBlock, m[i].ddSize, m[i].ddType); 158 } 159 } 160 printf("\n"); 161 printf(" #: type length base " 162 "flags ( logical )\n"); 163 LIST_FOREACH(entry, &map->disk_order, disk_entry) { 164 printf("%2ld: %20.32s ", entry->disk_address, entry->dpme_type); 165 printf("%7u @ %-7u ", entry->dpme_pblocks, 166 entry->dpme_pblock_start); 167 printf("%c%c%c%c%c%c%c%c%c ", 168 (entry->dpme_flags & DPME_VALID) ? 'V' : '.', 169 (entry->dpme_flags & DPME_ALLOCATED) ? 'A' : '.', 170 (entry->dpme_flags & DPME_IN_USE) ? 'I' : '.', 171 (entry->dpme_flags & DPME_BOOTABLE) ? 'B' : '.', 172 (entry->dpme_flags & DPME_READABLE) ? 'R' : '.', 173 (entry->dpme_flags & DPME_WRITABLE) ? 'W' : '.', 174 (entry->dpme_flags & DPME_OS_PIC_CODE) ? 'P' : '.', 175 (entry->dpme_flags & DPME_OS_SPECIFIC_2) ? '2' : '.', 176 (entry->dpme_flags & DPME_OS_SPECIFIC_1) ? '1' : '.'); 177 printf("( %7u @ %-7u )\n", entry->dpme_lblocks, 178 entry->dpme_lblock_start); 179 } 180 printf("\n"); 181 printf(" #: booter bytes load_address " 182 "goto_address checksum processor\n"); 183 LIST_FOREACH(entry, &map->disk_order, disk_entry) { 184 printf("%2ld: ", entry->disk_address); 185 printf("%7u ", entry->dpme_boot_block); 186 printf("%7u ", entry->dpme_boot_bytes); 187 printf("%8x ", entry->dpme_load_addr); 188 printf("%8x ", entry->dpme_goto_addr); 189 printf("%8x ", entry->dpme_checksum); 190 printf("%.32s", entry->dpme_processor_id); 191 printf("\n"); 192 } 193 printf("\n"); 194 } 195 196 197 void 198 full_dump_partition_entry(struct partition_map *map, int ix) 199 { 200 struct entry *entry; 201 int i; 202 uint32_t t; 203 204 entry = find_entry_by_disk_address(ix, map); 205 if (entry == NULL) { 206 printf("No such partition\n"); 207 return; 208 } 209 printf(" signature: 0x%x\n", entry->dpme_signature); 210 printf(" number of map entries: %u\n", entry->dpme_map_entries); 211 printf(" physical start: %10u length: %10u\n", 212 entry->dpme_pblock_start, entry->dpme_pblocks); 213 printf(" logical start: %10u length: %10u\n", 214 entry->dpme_lblock_start, entry->dpme_lblocks); 215 216 printf(" flags: 0x%x\n", entry->dpme_flags); 217 printf(" "); 218 if (entry->dpme_flags & DPME_VALID) 219 printf("valid "); 220 if (entry->dpme_flags & DPME_ALLOCATED) 221 printf("alloc "); 222 if (entry->dpme_flags & DPME_IN_USE) 223 printf("in-use "); 224 if (entry->dpme_flags & DPME_BOOTABLE) 225 printf("boot "); 226 if (entry->dpme_flags & DPME_READABLE) 227 printf("read "); 228 if (entry->dpme_flags & DPME_WRITABLE) 229 printf("write "); 230 if (entry->dpme_flags & DPME_OS_PIC_CODE) 231 printf("pic "); 232 t = entry->dpme_flags >> 7; 233 for (i = 7; i <= 31; i++) { 234 if (t & 0x1) 235 printf("%d ", i); 236 t = t >> 1; 237 } 238 printf("\n"); 239 240 printf(" name: '%.32s'\n", entry->dpme_name); 241 printf(" type: '%.32s'\n", entry->dpme_type); 242 printf(" boot start block: %10u\n", entry->dpme_boot_block); 243 printf("boot length (in bytes): %10u\n", entry->dpme_boot_bytes); 244 printf(" load address: 0x%08x\n", entry->dpme_load_addr); 245 printf(" start address: 0x%08x\n", entry->dpme_goto_addr); 246 printf(" checksum: 0x%08x\n", entry->dpme_checksum); 247 printf(" processor: '%.32s'\n", entry->dpme_processor_id); 248 printf("dpme_reserved_1 -"); 249 dump_block(entry->dpme_reserved_1, sizeof(entry->dpme_reserved_1)); 250 printf("dpme_reserved_2 -"); 251 dump_block(entry->dpme_reserved_2, sizeof(entry->dpme_reserved_2)); 252 printf("dpme_reserved_3 -"); 253 dump_block(entry->dpme_reserved_3, sizeof(entry->dpme_reserved_3)); 254 printf("dpme_reserved_4 -"); 255 dump_block(entry->dpme_reserved_4, sizeof(entry->dpme_reserved_4)); 256 } 257 258 259 void 260 dump_block(unsigned char *addr, int len) 261 { 262 int i, j, limit1, limit; 263 264 #define LINE_LEN 16 265 #define UNIT_LEN 4 266 #define OTHER_LEN 8 267 268 for (i = 0; i < len; i = limit) { 269 limit1 = i + LINE_LEN; 270 if (limit1 > len) 271 limit = len; 272 else 273 limit = limit1; 274 printf("\n%03x: ", i); 275 for (j = i; j < limit1; j++) { 276 if (j % UNIT_LEN == 0) 277 printf(" "); 278 if (j < limit) 279 printf("%02x", addr[j]); 280 else 281 printf(" "); 282 } 283 printf(" "); 284 for (j = i; j < limit; j++) { 285 if (j % OTHER_LEN == 0) 286 printf(" "); 287 if (addr[j] < ' ') 288 printf("."); 289 else 290 printf("%c", addr[j]); 291 } 292 } 293 printf("\n"); 294 } 295 296 void 297 full_dump_block_zero(struct partition_map *map) 298 { 299 struct ddmap *m; 300 int i; 301 302 m = map->sbDDMap; 303 304 printf(" signature: 0x%x\n", map->sbSig); 305 printf(" size of a block: %u\n", map->sbBlkSize); 306 printf(" number of blocks: %u\n", map->sbBlkCount); 307 printf(" device type: 0x%x\n", map->sbDevType); 308 printf(" device id: 0x%x\n", map->sbDevId); 309 printf(" data: 0x%x\n", map->sbData); 310 printf(" driver count: %u\n", map->sbDrvrCount); 311 for (i = 0; i < 8; i++) { 312 if (m[i].ddBlock == 0 && m[i].ddSize == 0 && m[i].ddType == 0) 313 break; 314 printf(" driver %3u block: %u\n", i + 1, m[i].ddBlock); 315 printf(" size in blocks: %u\n", m[i].ddSize); 316 printf(" driver type: 0x%x\n", m[i].ddType); 317 } 318 printf("remainder of block -"); 319 dump_block(map->sbReserved, sizeof(map->sbReserved)); 320 } 321 322 int 323 get_max_type_string_length(struct partition_map *map) 324 { 325 struct entry *entry; 326 int max, length; 327 328 max = 0; 329 330 LIST_FOREACH(entry, &map->disk_order, disk_entry) { 331 length = strnlen(entry->dpme_type, DPISTRLEN); 332 if (length > max) 333 max = length; 334 } 335 336 return max; 337 } 338 339 int 340 get_max_name_string_length(struct partition_map *map) 341 { 342 struct entry *entry; 343 int max, length; 344 345 max = 0; 346 347 LIST_FOREACH(entry, &map->disk_order, disk_entry) { 348 length = strnlen(entry->dpme_name, DPISTRLEN); 349 if (length > max) 350 max = length; 351 } 352 353 return max; 354 } 355 356 int 357 get_max_base_or_length(struct partition_map *map) 358 { 359 struct entry *entry; 360 int max; 361 362 max = 0; 363 364 LIST_FOREACH(entry, &map->disk_order, disk_entry) { 365 if (entry->dpme_pblock_start > max) 366 max = entry->dpme_pblock_start; 367 if (entry->dpme_pblocks > max) 368 max = entry->dpme_pblocks; 369 } 370 371 return max; 372 } 373