1*5fe72782Skrw /* $OpenBSD: dump.c,v 1.75 2016/02/23 02:39:54 krw Exp $ */
2fb04e59aSjasper
386ec409aSkrw /*
486ec409aSkrw * dump.c - dumping partition maps
586ec409aSkrw *
686ec409aSkrw * Written by Eryk Vershen
786ec409aSkrw */
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
300392b273Skrw #include <sys/queue.h>
310392b273Skrw
32dce63815Sdrahn #include <stdio.h>
33dce63815Sdrahn #include <stdlib.h>
34dce63815Sdrahn #include <string.h>
35a8aa5af7Skrw #include <util.h>
36dce63815Sdrahn
373f55d322Skrw #include "partition_map.h"
38dce63815Sdrahn #include "dump.h"
39dce63815Sdrahn #include "io.h"
40dce63815Sdrahn
4171c5b58dSkrw void dump_block(unsigned char *, int);
42356b92ceSkrw void dump_block_zero(struct partition_map *);
43f4c16b6bSkrw void dump_partition_entry(struct entry *, int, int, int);
44356b92ceSkrw int get_max_base_or_length(struct partition_map *);
45356b92ceSkrw int get_max_name_string_length(struct partition_map *);
46356b92ceSkrw int get_max_type_string_length(struct partition_map *);
47dce63815Sdrahn
48dce63815Sdrahn void
dump_block_zero(struct partition_map * map)49356b92ceSkrw dump_block_zero(struct partition_map *map)
50dce63815Sdrahn {
51a8aa5af7Skrw char buf[FMT_SCALED_STRSIZE];
5270060700Skrw struct ddmap *m;
53a8aa5af7Skrw int i;
54dce63815Sdrahn
55a8aa5af7Skrw printf("\nDevice block size=%u, Number of Blocks=%u",
56a8aa5af7Skrw map->sbBlkSize, map->sbBlkCount);
57*5fe72782Skrw if (fmt_scaled((long long)map->sbBlkCount * map->sbBlkSize, buf) == 0)
58a8aa5af7Skrw printf(" (%s)\n", buf);
59a8aa5af7Skrw else
60a8aa5af7Skrw printf("\n");
61dce63815Sdrahn
626f012227Skrw printf("DeviceType=0x%x, DeviceId=0x%x\n", map->sbDevType,
636f012227Skrw map->sbDevId);
646f012227Skrw if (map->sbDrvrCount > 0) {
65dce63815Sdrahn printf("Drivers-\n");
666f012227Skrw m = map->sbDDMap;
676f012227Skrw for (i = 0; i < map->sbDrvrCount; i++) {
6837e225b6Skrw printf("%d: %3u @ %u, ", i + 1, m[i].ddSize,
6937e225b6Skrw m[i].ddBlock);
70b42d9302Smartin printf("type=0x%x\n", m[i].ddType);
71dce63815Sdrahn }
72dce63815Sdrahn }
73dce63815Sdrahn printf("\n");
74dce63815Sdrahn }
75dce63815Sdrahn
76dce63815Sdrahn
77dce63815Sdrahn void
dump_partition_map(struct partition_map * map)78356b92ceSkrw dump_partition_map(struct partition_map *map)
79dce63815Sdrahn {
80f4c16b6bSkrw struct entry *entry;
813f012ab0Skrw int digits, max_type_length, max_name_length;
82dce63815Sdrahn
83dce63815Sdrahn printf("\nPartition map (with %d byte blocks) on '%s'\n",
84ead46a34Skrw map->sbBlkSize, map->name);
85dce63815Sdrahn
86dce63815Sdrahn digits = number_of_digits(get_max_base_or_length(map));
87a8b53b4cSkrw if (digits < 6)
88dce63815Sdrahn digits = 6;
89dce63815Sdrahn max_type_length = get_max_type_string_length(map);
90a8b53b4cSkrw if (max_type_length < 4)
91dce63815Sdrahn max_type_length = 4;
92dce63815Sdrahn max_name_length = get_max_name_string_length(map);
93a8b53b4cSkrw if (max_name_length < 6)
94dce63815Sdrahn max_name_length = 6;
95a8aa5af7Skrw printf(" #: %*s %-*s %*s %-*s\n", max_type_length, "type",
9635985165Skrw max_name_length, "name", digits, "length", digits, "base");
97dce63815Sdrahn
980392b273Skrw LIST_FOREACH(entry, &map->disk_order, disk_entry) {
993f012ab0Skrw dump_partition_entry(entry, max_type_length,
1003f012ab0Skrw max_name_length, digits);
101dce63815Sdrahn }
102dce63815Sdrahn dump_block_zero(map);
103dce63815Sdrahn }
104dce63815Sdrahn
105dce63815Sdrahn
106dce63815Sdrahn void
dump_partition_entry(struct entry * entry,int type_length,int name_length,int digits)107a8aa5af7Skrw dump_partition_entry(struct entry *entry, int type_length, int name_length,
108a8aa5af7Skrw int digits)
109dce63815Sdrahn {
110a8aa5af7Skrw char buf[FMT_SCALED_STRSIZE];
111dce63815Sdrahn
112f8fa35e5Skrw printf("%2ld: %*.32s", entry->disk_address, type_length,
113f8fa35e5Skrw entry->dpme_type);
114575b2bc1Skrw printf("%c%-*.32s ", contains_driver(entry) ? '*' : ' ',
115575b2bc1Skrw name_length, entry->dpme_name);
116b42d9302Smartin
117f8fa35e5Skrw printf("%*u @ %-*u", digits, entry->dpme_pblocks, digits,
118f8fa35e5Skrw entry->dpme_pblock_start);
119dce63815Sdrahn
120*5fe72782Skrw if (fmt_scaled((long long)entry->dpme_pblocks *
121*5fe72782Skrw entry->the_map->sbBlkSize, buf) == 0)
122a8aa5af7Skrw printf("(%s)\n", buf);
123a8aa5af7Skrw else
124dce63815Sdrahn printf("\n");
125dce63815Sdrahn }
126dce63815Sdrahn
127dce63815Sdrahn
128dce63815Sdrahn void
show_data_structures(struct partition_map * map)129356b92ceSkrw show_data_structures(struct partition_map *map)
130dce63815Sdrahn {
131f4c16b6bSkrw struct entry *entry;
13270060700Skrw struct ddmap *m;
1333f012ab0Skrw int i;
134dce63815Sdrahn
135dce63815Sdrahn printf("Header:\n");
136dce63815Sdrahn printf("map %d blocks out of %d, media %lu blocks (%d byte blocks)\n",
13735985165Skrw map->blocks_in_map, map->maximum_in_map, map->media_size,
138ead46a34Skrw map->sbBlkSize);
1393f55d322Skrw printf("Map is%s writable", rflag ? " not" : "");
1403f55d322Skrw printf(" and has%s been changed\n", (map->changed) ? "" : " not");
141dce63815Sdrahn printf("\n");
142dce63815Sdrahn
143dce63815Sdrahn printf("Block0:\n");
1446f012227Skrw printf("signature 0x%x", map->sbSig);
1456f012227Skrw printf("Block size=%u, Number of Blocks=%u\n", map->sbBlkSize,
1466f012227Skrw map->sbBlkCount);
1476f012227Skrw printf("DeviceType=0x%x, DeviceId=0x%x, sbData=0x%x\n", map->sbDevType,
1486f012227Skrw map->sbDevId, map->sbData);
1496f012227Skrw if (map->sbDrvrCount == 0) {
150dce63815Sdrahn printf("No drivers\n");
151dce63815Sdrahn } else {
1526f012227Skrw printf("%u driver%s-\n", map->sbDrvrCount,
1536f012227Skrw (map->sbDrvrCount > 1) ? "s" : "");
1546f012227Skrw m = map->sbDDMap;
1556f012227Skrw for (i = 0; i < map->sbDrvrCount; i++) {
156024cef13Skrw printf("%u: @ %u for %u, type=0x%x\n", i + 1,
15737e225b6Skrw m[i].ddBlock, m[i].ddSize, m[i].ddType);
158dce63815Sdrahn }
159dce63815Sdrahn }
160dce63815Sdrahn printf("\n");
161dce63815Sdrahn printf(" #: type length base "
162dce63815Sdrahn "flags ( logical )\n");
1630392b273Skrw LIST_FOREACH(entry, &map->disk_order, disk_entry) {
164f8fa35e5Skrw printf("%2ld: %20.32s ", entry->disk_address, entry->dpme_type);
165f8fa35e5Skrw printf("%7u @ %-7u ", entry->dpme_pblocks,
166f8fa35e5Skrw entry->dpme_pblock_start);
16731859932Skrw printf("%c%c%c%c%c%c%c%c%c ",
168f8fa35e5Skrw (entry->dpme_flags & DPME_VALID) ? 'V' : '.',
169f8fa35e5Skrw (entry->dpme_flags & DPME_ALLOCATED) ? 'A' : '.',
170f8fa35e5Skrw (entry->dpme_flags & DPME_IN_USE) ? 'I' : '.',
171f8fa35e5Skrw (entry->dpme_flags & DPME_BOOTABLE) ? 'B' : '.',
172f8fa35e5Skrw (entry->dpme_flags & DPME_READABLE) ? 'R' : '.',
173f8fa35e5Skrw (entry->dpme_flags & DPME_WRITABLE) ? 'W' : '.',
174f8fa35e5Skrw (entry->dpme_flags & DPME_OS_PIC_CODE) ? 'P' : '.',
175f8fa35e5Skrw (entry->dpme_flags & DPME_OS_SPECIFIC_2) ? '2' : '.',
176f8fa35e5Skrw (entry->dpme_flags & DPME_OS_SPECIFIC_1) ? '1' : '.');
177f8fa35e5Skrw printf("( %7u @ %-7u )\n", entry->dpme_lblocks,
178f8fa35e5Skrw entry->dpme_lblock_start);
179dce63815Sdrahn }
180dce63815Sdrahn printf("\n");
181dce63815Sdrahn printf(" #: booter bytes load_address "
182dce63815Sdrahn "goto_address checksum processor\n");
1830392b273Skrw LIST_FOREACH(entry, &map->disk_order, disk_entry) {
184dce63815Sdrahn printf("%2ld: ", entry->disk_address);
185f8fa35e5Skrw printf("%7u ", entry->dpme_boot_block);
186f8fa35e5Skrw printf("%7u ", entry->dpme_boot_bytes);
187f8fa35e5Skrw printf("%8x ", entry->dpme_load_addr);
188f8fa35e5Skrw printf("%8x ", entry->dpme_goto_addr);
189f8fa35e5Skrw printf("%8x ", entry->dpme_checksum);
190f8fa35e5Skrw printf("%.32s", entry->dpme_processor_id);
191dce63815Sdrahn printf("\n");
192dce63815Sdrahn }
193dce63815Sdrahn printf("\n");
194dce63815Sdrahn }
195dce63815Sdrahn
196dce63815Sdrahn
197dce63815Sdrahn void
full_dump_partition_entry(struct partition_map * map,int ix)198356b92ceSkrw full_dump_partition_entry(struct partition_map *map, int ix)
199dce63815Sdrahn {
200f8fa35e5Skrw struct entry *entry;
201dce63815Sdrahn int i;
202024cef13Skrw uint32_t t;
203dce63815Sdrahn
204f8fa35e5Skrw entry = find_entry_by_disk_address(ix, map);
205f8fa35e5Skrw if (entry == NULL) {
206dce63815Sdrahn printf("No such partition\n");
207dce63815Sdrahn return;
208dce63815Sdrahn }
209f8fa35e5Skrw printf(" signature: 0x%x\n", entry->dpme_signature);
210f8fa35e5Skrw printf(" number of map entries: %u\n", entry->dpme_map_entries);
2113f012ab0Skrw printf(" physical start: %10u length: %10u\n",
212f8fa35e5Skrw entry->dpme_pblock_start, entry->dpme_pblocks);
2133f012ab0Skrw printf(" logical start: %10u length: %10u\n",
214f8fa35e5Skrw entry->dpme_lblock_start, entry->dpme_lblocks);
215dce63815Sdrahn
216f8fa35e5Skrw printf(" flags: 0x%x\n", entry->dpme_flags);
217dce63815Sdrahn printf(" ");
218f8fa35e5Skrw if (entry->dpme_flags & DPME_VALID)
2193f012ab0Skrw printf("valid ");
220f8fa35e5Skrw if (entry->dpme_flags & DPME_ALLOCATED)
2213f012ab0Skrw printf("alloc ");
222f8fa35e5Skrw if (entry->dpme_flags & DPME_IN_USE)
2233f012ab0Skrw printf("in-use ");
224f8fa35e5Skrw if (entry->dpme_flags & DPME_BOOTABLE)
2253f012ab0Skrw printf("boot ");
226f8fa35e5Skrw if (entry->dpme_flags & DPME_READABLE)
2273f012ab0Skrw printf("read ");
228f8fa35e5Skrw if (entry->dpme_flags & DPME_WRITABLE)
2293f012ab0Skrw printf("write ");
230f8fa35e5Skrw if (entry->dpme_flags & DPME_OS_PIC_CODE)
2313f012ab0Skrw printf("pic ");
232f8fa35e5Skrw t = entry->dpme_flags >> 7;
233dce63815Sdrahn for (i = 7; i <= 31; i++) {
234bd45c0ecSkrw if (t & 0x1)
235dce63815Sdrahn printf("%d ", i);
236dce63815Sdrahn t = t >> 1;
237dce63815Sdrahn }
238dce63815Sdrahn printf("\n");
239dce63815Sdrahn
240f8fa35e5Skrw printf(" name: '%.32s'\n", entry->dpme_name);
241f8fa35e5Skrw printf(" type: '%.32s'\n", entry->dpme_type);
242f8fa35e5Skrw printf(" boot start block: %10u\n", entry->dpme_boot_block);
243f8fa35e5Skrw printf("boot length (in bytes): %10u\n", entry->dpme_boot_bytes);
244f8fa35e5Skrw printf(" load address: 0x%08x\n", entry->dpme_load_addr);
245f8fa35e5Skrw printf(" start address: 0x%08x\n", entry->dpme_goto_addr);
246f8fa35e5Skrw printf(" checksum: 0x%08x\n", entry->dpme_checksum);
247f8fa35e5Skrw printf(" processor: '%.32s'\n", entry->dpme_processor_id);
24835985165Skrw printf("dpme_reserved_1 -");
249f8fa35e5Skrw dump_block(entry->dpme_reserved_1, sizeof(entry->dpme_reserved_1));
25035985165Skrw printf("dpme_reserved_2 -");
251f8fa35e5Skrw dump_block(entry->dpme_reserved_2, sizeof(entry->dpme_reserved_2));
25235985165Skrw printf("dpme_reserved_3 -");
253f8fa35e5Skrw dump_block(entry->dpme_reserved_3, sizeof(entry->dpme_reserved_3));
25435985165Skrw printf("dpme_reserved_4 -");
255f8fa35e5Skrw dump_block(entry->dpme_reserved_4, sizeof(entry->dpme_reserved_4));
256dce63815Sdrahn }
257dce63815Sdrahn
258dce63815Sdrahn
259dce63815Sdrahn void
dump_block(unsigned char * addr,int len)260dce63815Sdrahn dump_block(unsigned char *addr, int len)
261dce63815Sdrahn {
2623f012ab0Skrw int i, j, limit1, limit;
2633f012ab0Skrw
264dce63815Sdrahn #define LINE_LEN 16
265dce63815Sdrahn #define UNIT_LEN 4
266dce63815Sdrahn #define OTHER_LEN 8
267dce63815Sdrahn
268dce63815Sdrahn for (i = 0; i < len; i = limit) {
269dce63815Sdrahn limit1 = i + LINE_LEN;
270bd45c0ecSkrw if (limit1 > len)
271dce63815Sdrahn limit = len;
272bd45c0ecSkrw else
273dce63815Sdrahn limit = limit1;
274dce63815Sdrahn printf("\n%03x: ", i);
275dce63815Sdrahn for (j = i; j < limit1; j++) {
276bd45c0ecSkrw if (j % UNIT_LEN == 0)
277dce63815Sdrahn printf(" ");
278bd45c0ecSkrw if (j < limit)
279dce63815Sdrahn printf("%02x", addr[j]);
280bd45c0ecSkrw else
281dce63815Sdrahn printf(" ");
282dce63815Sdrahn }
283dce63815Sdrahn printf(" ");
284dce63815Sdrahn for (j = i; j < limit; j++) {
285bd45c0ecSkrw if (j % OTHER_LEN == 0)
286dce63815Sdrahn printf(" ");
287bd45c0ecSkrw if (addr[j] < ' ')
288dce63815Sdrahn printf(".");
289bd45c0ecSkrw else
290dce63815Sdrahn printf("%c", addr[j]);
291dce63815Sdrahn }
292dce63815Sdrahn }
293dce63815Sdrahn printf("\n");
294dce63815Sdrahn }
295dce63815Sdrahn
296dce63815Sdrahn void
full_dump_block_zero(struct partition_map * map)297356b92ceSkrw full_dump_block_zero(struct partition_map *map)
298dce63815Sdrahn {
29970060700Skrw struct ddmap *m;
300dce63815Sdrahn int i;
301dce63815Sdrahn
3026f012227Skrw m = map->sbDDMap;
303dce63815Sdrahn
3046f012227Skrw printf(" signature: 0x%x\n", map->sbSig);
3056f012227Skrw printf(" size of a block: %u\n", map->sbBlkSize);
3066f012227Skrw printf(" number of blocks: %u\n", map->sbBlkCount);
3076f012227Skrw printf(" device type: 0x%x\n", map->sbDevType);
3086f012227Skrw printf(" device id: 0x%x\n", map->sbDevId);
3096f012227Skrw printf(" data: 0x%x\n", map->sbData);
3106f012227Skrw printf(" driver count: %u\n", map->sbDrvrCount);
311f7e12bbcSkrw for (i = 0; i < 8; i++) {
312f7e12bbcSkrw if (m[i].ddBlock == 0 && m[i].ddSize == 0 && m[i].ddType == 0)
313dce63815Sdrahn break;
314024cef13Skrw printf(" driver %3u block: %u\n", i + 1, m[i].ddBlock);
315024cef13Skrw printf(" size in blocks: %u\n", m[i].ddSize);
316dce63815Sdrahn printf(" driver type: 0x%x\n", m[i].ddType);
317dce63815Sdrahn }
318dce63815Sdrahn printf("remainder of block -");
3196f012227Skrw dump_block(map->sbReserved, sizeof(map->sbReserved));
320dce63815Sdrahn }
321dce63815Sdrahn
322dce63815Sdrahn int
get_max_type_string_length(struct partition_map * map)323356b92ceSkrw get_max_type_string_length(struct partition_map *map)
324dce63815Sdrahn {
325f4c16b6bSkrw struct entry *entry;
3263f012ab0Skrw int max, length;
327dce63815Sdrahn
328dce63815Sdrahn max = 0;
329dce63815Sdrahn
3300392b273Skrw LIST_FOREACH(entry, &map->disk_order, disk_entry) {
331f8fa35e5Skrw length = strnlen(entry->dpme_type, DPISTRLEN);
332bd45c0ecSkrw if (length > max)
333dce63815Sdrahn max = length;
334dce63815Sdrahn }
335dce63815Sdrahn
336dce63815Sdrahn return max;
337dce63815Sdrahn }
338dce63815Sdrahn
339dce63815Sdrahn int
get_max_name_string_length(struct partition_map * map)340356b92ceSkrw get_max_name_string_length(struct partition_map *map)
341dce63815Sdrahn {
342f4c16b6bSkrw struct entry *entry;
3433f012ab0Skrw int max, length;
344dce63815Sdrahn
345dce63815Sdrahn max = 0;
346dce63815Sdrahn
3470392b273Skrw LIST_FOREACH(entry, &map->disk_order, disk_entry) {
348f8fa35e5Skrw length = strnlen(entry->dpme_name, DPISTRLEN);
349bd45c0ecSkrw if (length > max)
350dce63815Sdrahn max = length;
351dce63815Sdrahn }
352dce63815Sdrahn
353dce63815Sdrahn return max;
354dce63815Sdrahn }
355dce63815Sdrahn
356dce63815Sdrahn int
get_max_base_or_length(struct partition_map * map)357356b92ceSkrw get_max_base_or_length(struct partition_map *map)
358dce63815Sdrahn {
359f4c16b6bSkrw struct entry *entry;
360dce63815Sdrahn int max;
361dce63815Sdrahn
362dce63815Sdrahn max = 0;
363dce63815Sdrahn
3640392b273Skrw LIST_FOREACH(entry, &map->disk_order, disk_entry) {
365f8fa35e5Skrw if (entry->dpme_pblock_start > max)
366f8fa35e5Skrw max = entry->dpme_pblock_start;
367f8fa35e5Skrw if (entry->dpme_pblocks > max)
368f8fa35e5Skrw max = entry->dpme_pblocks;
369dce63815Sdrahn }
370dce63815Sdrahn
371dce63815Sdrahn return max;
372dce63815Sdrahn }
373