xref: /openbsd/sbin/pdisk/dump.c (revision 86ec409a)
1*86ec409aSkrw /*	$OpenBSD: dump.c,v 1.34 2016/01/17 23:18:19 krw Exp $	*/
2fb04e59aSjasper 
3*86ec409aSkrw /*
4*86ec409aSkrw  * dump.c - dumping partition maps
5*86ec409aSkrw  *
6*86ec409aSkrw  * Written by Eryk Vershen
7*86ec409aSkrw  */
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 #include <stdio.h>
35dce63815Sdrahn #include <stdlib.h>
36dce63815Sdrahn #include <string.h>
37dce63815Sdrahn #include <fcntl.h>
38dce63815Sdrahn #include <errno.h>
39dce63815Sdrahn 
40f42746d7Skrw #include "file_media.h"
41dce63815Sdrahn #include "dump.h"
42dce63815Sdrahn #include "io.h"
43dce63815Sdrahn 
44dce63815Sdrahn #define get_align_long(x)	(*(x))
45dce63815Sdrahn 
4694d20309Skrw struct patchdescriptor {
4717e07d8fSkrw     unsigned long	patchSig;
48b42d9302Smartin     unsigned short	majorVers;
49b42d9302Smartin     unsigned short	minorVers;
50b42d9302Smartin     unsigned long	flags;
51b42d9302Smartin     unsigned long	patchOffset;
52b42d9302Smartin     unsigned long	patchSize;
53b42d9302Smartin     unsigned long	patchCRC;
54b42d9302Smartin     unsigned long	patchDescriptorLen;
55b42d9302Smartin     unsigned char	patchName[33];
56b42d9302Smartin     unsigned char	patchVendor[1];
5794d20309Skrw };
58b42d9302Smartin 
5994d20309Skrw struct patchlist {
60*86ec409aSkrw     unsigned short numPatchBlocks;	/* number of disk blocks to hold the patch list */
61*86ec409aSkrw     unsigned short numPatches;		/* number of patches in list */
6294d20309Skrw     struct patchdescriptor thePatch[1];
6394d20309Skrw };
64b42d9302Smartin 
65dce63815Sdrahn const char * kStringEmpty	= "";
66dce63815Sdrahn const char * kStringNot		= " not";
67dce63815Sdrahn 
68f947f9cbSkrw void adjust_value_and_compute_prefix(double *, int *);
69f947f9cbSkrw void dump_block_zero(struct partition_map_header *);
70f947f9cbSkrw void dump_partition_entry(struct partition_map *, int, int, int);
71f947f9cbSkrw int get_max_base_or_length(struct partition_map_header *);
72f947f9cbSkrw int get_max_name_string_length(struct partition_map_header *);
73f947f9cbSkrw int get_max_type_string_length(struct partition_map_header *);
74dce63815Sdrahn 
75dce63815Sdrahn int
76dce63815Sdrahn dump(char *name)
77dce63815Sdrahn {
78eedab009Skrw     struct partition_map_header *map;
79dce63815Sdrahn     int junk;
80dce63815Sdrahn 
815d0b0825Skrw     map = open_partition_map(name, &junk);
82dce63815Sdrahn     if (map == NULL) {
83dce63815Sdrahn 	return 0;
84dce63815Sdrahn     }
85dce63815Sdrahn 
86dce63815Sdrahn     dump_partition_map(map, 1);
87dce63815Sdrahn 
88dce63815Sdrahn     close_partition_map(map);
89dce63815Sdrahn 
90dce63815Sdrahn     return 1;
91dce63815Sdrahn }
92dce63815Sdrahn 
93dce63815Sdrahn 
94dce63815Sdrahn void
95eedab009Skrw dump_block_zero(struct partition_map_header *map)
96dce63815Sdrahn {
9771bd5f9cSkrw     struct block0 *p;
9870060700Skrw     struct ddmap *m;
99dce63815Sdrahn     int i;
100dce63815Sdrahn     double value;
101dce63815Sdrahn     int prefix;
102b42d9302Smartin     long t;
103dce63815Sdrahn 
104dce63815Sdrahn     p = map->misc;
105dce63815Sdrahn     if (p->sbSig != BLOCK0_SIGNATURE) {
106dce63815Sdrahn 	return;
107dce63815Sdrahn     }
108dce63815Sdrahn 
109dce63815Sdrahn     value = ((double)p->sbBlkCount) * p->sbBlkSize;
110dce63815Sdrahn     adjust_value_and_compute_prefix(&value, &prefix);
111024cef13Skrw     printf("\nDevice block size=%u, Number of Blocks=%u (%1.1f%c)\n",
112dce63815Sdrahn 	    p->sbBlkSize, p->sbBlkCount, value, prefix);
113dce63815Sdrahn 
114dce63815Sdrahn     printf("DeviceType=0x%x, DeviceId=0x%x\n",
115dce63815Sdrahn 	    p->sbDevType, p->sbDevId);
116dce63815Sdrahn     if (p->sbDrvrCount > 0) {
117dce63815Sdrahn 	printf("Drivers-\n");
11870060700Skrw 	m = (struct ddmap *) p->sbMap;
119dce63815Sdrahn 	for (i = 0; i < p->sbDrvrCount; i++) {
120024cef13Skrw 	    printf("%d: %3u @ %u, ", i+1,
121b42d9302Smartin 		    m[i].ddSize, get_align_long(&m[i].ddBlock));
122b42d9302Smartin 	    if (map->logical_block != p->sbBlkSize) {
123b42d9302Smartin 		t = (m[i].ddSize * p->sbBlkSize) / map->logical_block;
124b42d9302Smartin 		printf("(%lu@", t);
125b42d9302Smartin 		t = (get_align_long(&m[i].ddBlock) * p->sbBlkSize)
126b42d9302Smartin 			/ map->logical_block;
127b42d9302Smartin 		printf("%lu)  ", t);
128b42d9302Smartin 	    }
129b42d9302Smartin 	    printf("type=0x%x\n", m[i].ddType);
130dce63815Sdrahn 	}
131dce63815Sdrahn     }
132dce63815Sdrahn     printf("\n");
133dce63815Sdrahn }
134dce63815Sdrahn 
135dce63815Sdrahn 
136dce63815Sdrahn void
137eedab009Skrw dump_partition_map(struct partition_map_header *map, int disk_order)
138dce63815Sdrahn {
139eedab009Skrw     struct partition_map * entry;
140dce63815Sdrahn     int max_type_length;
141dce63815Sdrahn     int max_name_length;
142dce63815Sdrahn     int digits;
143dce63815Sdrahn 
144dce63815Sdrahn     if (map == NULL) {
145dce63815Sdrahn 	bad_input("No partition map exists");
146dce63815Sdrahn 	return;
147dce63815Sdrahn     }
148dce63815Sdrahn     printf("\nPartition map (with %d byte blocks) on '%s'\n",
149dce63815Sdrahn 	map->logical_block, map->name);
150dce63815Sdrahn 
151dce63815Sdrahn     digits = number_of_digits(get_max_base_or_length(map));
152dce63815Sdrahn     if (digits < 6) {
153dce63815Sdrahn 	digits = 6;
154dce63815Sdrahn     }
155dce63815Sdrahn     max_type_length = get_max_type_string_length(map);
156dce63815Sdrahn     if (max_type_length < 4) {
157dce63815Sdrahn         max_type_length = 4;
158dce63815Sdrahn     }
159dce63815Sdrahn     max_name_length = get_max_name_string_length(map);
160dce63815Sdrahn     if (max_name_length < 6) {
161dce63815Sdrahn 	max_name_length = 6;
162dce63815Sdrahn     }
163dce63815Sdrahn     printf(" #: %*s %-*s %*s   %-*s ( size )\n",
164dce63815Sdrahn 	    max_type_length, "type",
165dce63815Sdrahn 	    max_name_length, "name",
166dce63815Sdrahn 	    digits, "length", digits, "base");
167dce63815Sdrahn 
168dce63815Sdrahn     if (disk_order) {
169dce63815Sdrahn 	for (entry = map->disk_order; entry != NULL;
170dce63815Sdrahn 		entry = entry->next_on_disk) {
171dce63815Sdrahn 
172dce63815Sdrahn 	    dump_partition_entry(entry, max_type_length, max_name_length, digits);
173dce63815Sdrahn 	}
174dce63815Sdrahn     } else {
175dce63815Sdrahn 	for (entry = map->base_order; entry != NULL;
176dce63815Sdrahn 		entry = entry->next_by_base) {
177dce63815Sdrahn 
178dce63815Sdrahn 	    dump_partition_entry(entry, max_type_length, max_name_length, digits);
179dce63815Sdrahn 	}
180dce63815Sdrahn     }
181dce63815Sdrahn     dump_block_zero(map);
182dce63815Sdrahn }
183dce63815Sdrahn 
184dce63815Sdrahn 
185dce63815Sdrahn void
186eedab009Skrw dump_partition_entry(struct partition_map *entry, int type_length, int name_length, int digits)
187dce63815Sdrahn {
188eedab009Skrw     struct partition_map_header *map;
189dce63815Sdrahn     int j;
1906521004eSkrw     struct dpme *p;
191024cef13Skrw     uint32_t size;
192dce63815Sdrahn     double bytes;
19377a25ee3Sjasper     int driver;
194b42d9302Smartin     char *buf;
195dce63815Sdrahn 
196dce63815Sdrahn     map = entry->the_map;
197dce63815Sdrahn     p = entry->data;
198dce63815Sdrahn     driver = entry->contains_driver? '*': ' ';
199b42d9302Smartin     printf("%2ld: %*.32s", entry->disk_address, type_length, p->dpme_type);
200dce63815Sdrahn 
2015ae94ef8Sderaadt     buf = malloc(name_length+1);
202b42d9302Smartin     strncpy(buf, p->dpme_name, name_length);
203b42d9302Smartin     buf[name_length] = 0;
204b42d9302Smartin     printf("%c%-*.32s ", driver, name_length, buf);
205b42d9302Smartin     free(buf);
206b42d9302Smartin 
2077446d16eSkrw     if (p->dpme_lblocks + p->dpme_lblock_start != p->dpme_pblocks) {
208024cef13Skrw 	printf("%*u+", digits, p->dpme_lblocks);
209dce63815Sdrahn 	size = p->dpme_lblocks;
210dce63815Sdrahn     } else if (p->dpme_lblock_start != 0) {
211024cef13Skrw 	printf("%*u ", digits, p->dpme_lblocks);
212dce63815Sdrahn 	size = p->dpme_lblocks;
213dce63815Sdrahn     } else {
214024cef13Skrw 	printf("%*u ", digits, p->dpme_pblocks);
215dce63815Sdrahn 	size = p->dpme_pblocks;
216dce63815Sdrahn     }
2177446d16eSkrw     if (p->dpme_lblock_start == 0) {
218024cef13Skrw 	printf("@ %-*u", digits, p->dpme_pblock_start);
219dce63815Sdrahn     } else {
220024cef13Skrw 	printf("@~%-*u", digits, p->dpme_pblock_start + p->dpme_lblock_start);
221dce63815Sdrahn     }
222dce63815Sdrahn 
223dce63815Sdrahn     bytes = ((double)size) * map->logical_block;
224dce63815Sdrahn     adjust_value_and_compute_prefix(&bytes, &j);
225dce63815Sdrahn     if (j != ' ' && j != 'K') {
226dce63815Sdrahn 	printf(" (%#5.1f%c)", bytes, j);
227dce63815Sdrahn     }
228dce63815Sdrahn 
229dce63815Sdrahn     printf("\n");
230dce63815Sdrahn }
231dce63815Sdrahn 
232dce63815Sdrahn 
233dce63815Sdrahn void
234eedab009Skrw show_data_structures(struct partition_map_header *map)
235dce63815Sdrahn {
23671bd5f9cSkrw     struct block0 *zp;
23770060700Skrw     struct ddmap *m;
238dce63815Sdrahn     int i;
239eedab009Skrw     struct partition_map * entry;
2406521004eSkrw     struct dpme *p;
241dce63815Sdrahn 
242dce63815Sdrahn     if (map == NULL) {
243dce63815Sdrahn 	printf("No partition map exists\n");
244dce63815Sdrahn 	return;
245dce63815Sdrahn     }
246dce63815Sdrahn     printf("Header:\n");
247dce63815Sdrahn     printf("map %d blocks out of %d,  media %lu blocks (%d byte blocks)\n",
248dce63815Sdrahn 	    map->blocks_in_map, map->maximum_in_map,
249dce63815Sdrahn 	    map->media_size, map->logical_block);
250b42d9302Smartin     printf("Map is%s writable", (map->writable)?kStringEmpty:kStringNot);
251b42d9302Smartin     printf(", but%s changed", (map->changed)?kStringEmpty:kStringNot);
252b42d9302Smartin     printf(" and has%s been written\n", (map->written)?kStringEmpty:kStringNot);
253dce63815Sdrahn     printf("\n");
254dce63815Sdrahn 
255dce63815Sdrahn     if (map->misc == NULL) {
256dce63815Sdrahn 	printf("No block zero\n");
257dce63815Sdrahn     } else {
258dce63815Sdrahn 	zp = map->misc;
259dce63815Sdrahn 
260dce63815Sdrahn 	printf("Block0:\n");
261dce63815Sdrahn 	printf("signature 0x%x", zp->sbSig);
262dce63815Sdrahn 	if (zp->sbSig == BLOCK0_SIGNATURE) {
263dce63815Sdrahn 	    printf("\n");
264dce63815Sdrahn 	} else {
265dce63815Sdrahn 	    printf(" should be 0x%x\n", BLOCK0_SIGNATURE);
266dce63815Sdrahn 	}
267024cef13Skrw 	printf("Block size=%u, Number of Blocks=%u\n",
268dce63815Sdrahn 		zp->sbBlkSize, zp->sbBlkCount);
269024cef13Skrw 	printf("DeviceType=0x%x, DeviceId=0x%x, sbData=0x%x\n",
270dce63815Sdrahn 		zp->sbDevType, zp->sbDevId, zp->sbData);
271dce63815Sdrahn 	if (zp->sbDrvrCount == 0) {
272dce63815Sdrahn 	    printf("No drivers\n");
273dce63815Sdrahn 	} else {
274dce63815Sdrahn 	    printf("%u driver%s-\n", zp->sbDrvrCount,
275dce63815Sdrahn 		    (zp->sbDrvrCount>1)?"s":kStringEmpty);
27670060700Skrw 	    m = (struct ddmap *) zp->sbMap;
277dce63815Sdrahn 	    for (i = 0; i < zp->sbDrvrCount; i++) {
278024cef13Skrw             printf("%u: @ %u for %u, type=0x%x\n", i+1,
279dce63815Sdrahn 		   get_align_long(&m[i].ddBlock),
280dce63815Sdrahn 		   m[i].ddSize, m[i].ddType);
281dce63815Sdrahn 	    }
282dce63815Sdrahn 	}
283dce63815Sdrahn     }
284dce63815Sdrahn     printf("\n");
285dce63815Sdrahn     printf(" #:                 type  length   base    "
286dce63815Sdrahn 	    "flags        (logical)\n");
287dce63815Sdrahn     for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
288dce63815Sdrahn 	p = entry->data;
289dce63815Sdrahn 	printf("%2ld: %20.32s ",
290dce63815Sdrahn 		entry->disk_address, p->dpme_type);
291024cef13Skrw 	printf("%7u @ %-7u ", p->dpme_pblocks, p->dpme_pblock_start);
292dce63815Sdrahn 	printf("%c%c%c%c%c%c%c%c%c%c%c%c ",
293a1ac9a96Skrw 		(p->dpme_flags & DPME_VALID)?'V':'.',
294a1ac9a96Skrw 		(p->dpme_flags & DPME_ALLOCATED)?'A':'.',
295a1ac9a96Skrw 		(p->dpme_flags & DPME_IN_USE)?'I':'.',
296a1ac9a96Skrw 		(p->dpme_flags & DPME_BOOTABLE)?'B':'.',
297a1ac9a96Skrw 		(p->dpme_flags & DPME_READABLE)?'R':'.',
298a1ac9a96Skrw 		(p->dpme_flags & DPME_WRITABLE)?'W':'.',
299a1ac9a96Skrw 		(p->dpme_flags & DPME_OS_PIC_CODE)?'P':'.',
300a1ac9a96Skrw 		(p->dpme_flags & DPME_OS_SPECIFIC_2)?'2':'.',
301a1ac9a96Skrw 		(p->dpme_flags & DPME_CHAINABLE)?'C':'.',
302a1ac9a96Skrw 		(p->dpme_flags & DPME_DISKDRIVER)?'D':'.',
303a1ac9a96Skrw 		(p->dpme_flags & (1<<30))?'M':'.',
304a1ac9a96Skrw 		(p->dpme_flags & (1<<31))?'X':'.');
305dce63815Sdrahn 	if (p->dpme_lblock_start != 0 || p->dpme_pblocks != p->dpme_lblocks) {
306024cef13Skrw 	    printf("(%u @ %u)", p->dpme_lblocks, p->dpme_lblock_start);
307dce63815Sdrahn 	}
308dce63815Sdrahn 	printf("\n");
309dce63815Sdrahn     }
310dce63815Sdrahn     printf("\n");
311dce63815Sdrahn     printf(" #:  booter   bytes      load_address      "
312dce63815Sdrahn 	    "goto_address checksum processor\n");
313dce63815Sdrahn     for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
314dce63815Sdrahn 	p = entry->data;
315dce63815Sdrahn 	printf("%2ld: ", entry->disk_address);
316024cef13Skrw 	printf("%7u ", p->dpme_boot_block);
317024cef13Skrw 	printf("%7u ", p->dpme_boot_bytes);
318024cef13Skrw 	printf("%8x ", (uint32_t)p->dpme_load_addr);
319024cef13Skrw 	printf("%8x ", (uint32_t)p->dpme_load_addr_2);
320024cef13Skrw 	printf("%8x ", (uint32_t)p->dpme_goto_addr);
321024cef13Skrw 	printf("%8x ", (uint32_t)p->dpme_goto_addr_2);
322024cef13Skrw 	printf("%8x ", p->dpme_checksum);
323dce63815Sdrahn 	printf("%.32s", p->dpme_process_id);
324dce63815Sdrahn 	printf("\n");
325dce63815Sdrahn     }
326dce63815Sdrahn     printf("\n");
327dce63815Sdrahn }
328dce63815Sdrahn 
329dce63815Sdrahn 
330dce63815Sdrahn void
331eedab009Skrw full_dump_partition_entry(struct partition_map_header *map, int ix)
332dce63815Sdrahn {
333eedab009Skrw     struct partition_map * cur;
3346521004eSkrw     struct dpme *p;
335dce63815Sdrahn     int i;
336024cef13Skrw     uint32_t t;
337dce63815Sdrahn 
338b42d9302Smartin     cur = find_entry_by_disk_address(ix, map);
339dce63815Sdrahn     if (cur == NULL) {
340dce63815Sdrahn 	printf("No such partition\n");
341dce63815Sdrahn 	return;
342dce63815Sdrahn     }
343dce63815Sdrahn 
344dce63815Sdrahn     p = cur->data;
345dce63815Sdrahn     printf("             signature: 0x%x\n", p->dpme_signature);
346dce63815Sdrahn     printf("             reserved1: 0x%x\n", p->dpme_reserved_1);
347024cef13Skrw     printf(" number of map entries: %u\n", p->dpme_map_entries);
348024cef13Skrw     printf("        physical start: %10u  length: %10u\n", p->dpme_pblock_start, p->dpme_pblocks);
349024cef13Skrw     printf("         logical start: %10u  length: %10u\n", p->dpme_lblock_start, p->dpme_lblocks);
350dce63815Sdrahn 
351024cef13Skrw     printf("                 flags: 0x%x\n", (uint32_t)p->dpme_flags);
352dce63815Sdrahn     printf("                        ");
353a1ac9a96Skrw     if (p->dpme_flags & DPME_VALID) printf("valid ");
354a1ac9a96Skrw     if (p->dpme_flags & DPME_ALLOCATED) printf("alloc ");
355a1ac9a96Skrw     if (p->dpme_flags & DPME_IN_USE) printf("in-use ");
356a1ac9a96Skrw     if (p->dpme_flags & DPME_BOOTABLE) printf("boot ");
357a1ac9a96Skrw     if (p->dpme_flags & DPME_READABLE) printf("read ");
358a1ac9a96Skrw     if (p->dpme_flags & DPME_WRITABLE) printf("write ");
359a1ac9a96Skrw     if (p->dpme_flags & DPME_OS_PIC_CODE) printf("pic ");
360dce63815Sdrahn     t = p->dpme_flags >> 7;
361dce63815Sdrahn     for (i = 7; i <= 31; i++) {
362dce63815Sdrahn 	if (t & 0x1) {
363dce63815Sdrahn 	    printf("%d ", i);
364dce63815Sdrahn 	}
365dce63815Sdrahn 	t = t >> 1;
366dce63815Sdrahn     }
367dce63815Sdrahn     printf("\n");
368dce63815Sdrahn 
369dce63815Sdrahn     printf("                  name: '%.32s'\n", p->dpme_name);
370dce63815Sdrahn     printf("                  type: '%.32s'\n", p->dpme_type);
371dce63815Sdrahn 
372024cef13Skrw     printf("      boot start block: %10u\n", p->dpme_boot_block);
373024cef13Skrw     printf("boot length (in bytes): %10u\n", p->dpme_boot_bytes);
374024cef13Skrw     printf("          load address: 0x%08x  0x%08x\n",
375024cef13Skrw 		(uint32_t)p->dpme_load_addr, (uint32_t)p->dpme_load_addr_2);
376024cef13Skrw     printf("         start address: 0x%08x  0x%08x\n",
377024cef13Skrw 		(uint32_t)p->dpme_goto_addr, (uint32_t)p->dpme_goto_addr_2);
378024cef13Skrw     printf("              checksum: 0x%08x\n", p->dpme_checksum);
379dce63815Sdrahn     printf("             processor: '%.32s'\n", p->dpme_process_id);
380dce63815Sdrahn     printf("boot args field -");
381dce63815Sdrahn     dump_block((unsigned char *)p->dpme_boot_args, 32*4);
382dce63815Sdrahn     printf("dpme_reserved_3 -");
383dce63815Sdrahn     dump_block((unsigned char *)p->dpme_reserved_3, 62*4);
384dce63815Sdrahn }
385dce63815Sdrahn 
386dce63815Sdrahn 
387dce63815Sdrahn void
388dce63815Sdrahn dump_block(unsigned char *addr, int len)
389dce63815Sdrahn {
390dce63815Sdrahn     int i;
391dce63815Sdrahn     int j;
392dce63815Sdrahn     int limit1;
393dce63815Sdrahn     int limit;
394dce63815Sdrahn #define LINE_LEN 16
395dce63815Sdrahn #define UNIT_LEN  4
396dce63815Sdrahn #define OTHER_LEN  8
397dce63815Sdrahn 
398dce63815Sdrahn     for (i = 0; i < len; i = limit) {
399dce63815Sdrahn 	limit1 = i + LINE_LEN;
400dce63815Sdrahn 	if (limit1 > len) {
401dce63815Sdrahn 	    limit = len;
402dce63815Sdrahn 	} else {
403dce63815Sdrahn 	    limit = limit1;
404dce63815Sdrahn 	}
405dce63815Sdrahn 	printf("\n%03x: ", i);
406dce63815Sdrahn 	for (j = i; j < limit1; j++) {
407dce63815Sdrahn 	    if (j % UNIT_LEN == 0) {
408dce63815Sdrahn 		printf(" ");
409dce63815Sdrahn 	    }
410dce63815Sdrahn 	    if (j < limit) {
411dce63815Sdrahn 		printf("%02x", addr[j]);
412dce63815Sdrahn 	    } else {
413dce63815Sdrahn 		printf("  ");
414dce63815Sdrahn 	    }
415dce63815Sdrahn 	}
416dce63815Sdrahn 	printf(" ");
417dce63815Sdrahn 	for (j = i; j < limit; j++) {
418dce63815Sdrahn 	    if (j % OTHER_LEN == 0) {
419dce63815Sdrahn 		printf(" ");
420dce63815Sdrahn 	    }
421dce63815Sdrahn 	    if (addr[j] < ' ') {
422dce63815Sdrahn 		printf(".");
423dce63815Sdrahn 	    } else {
424dce63815Sdrahn 		printf("%c", addr[j]);
425dce63815Sdrahn 	    }
426dce63815Sdrahn 	}
427dce63815Sdrahn     }
428dce63815Sdrahn     printf("\n");
429dce63815Sdrahn }
430dce63815Sdrahn 
431dce63815Sdrahn void
432eedab009Skrw full_dump_block_zero(struct partition_map_header *map)
433dce63815Sdrahn {
43471bd5f9cSkrw     struct block0 *zp;
43570060700Skrw     struct ddmap *m;
436dce63815Sdrahn     int i;
437dce63815Sdrahn 
438dce63815Sdrahn     if (map == NULL) {
439dce63815Sdrahn 	printf("No partition map exists\n");
440dce63815Sdrahn 	return;
441dce63815Sdrahn     }
442dce63815Sdrahn 
443dce63815Sdrahn     if (map->misc == NULL) {
444dce63815Sdrahn 	printf("No block zero\n");
445dce63815Sdrahn 	return;
446dce63815Sdrahn     }
447dce63815Sdrahn     zp = map->misc;
448dce63815Sdrahn 
449dce63815Sdrahn     printf("             signature: 0x%x\n", zp->sbSig);
450024cef13Skrw     printf("       size of a block: %u\n", zp->sbBlkSize);
451024cef13Skrw     printf("      number of blocks: %u\n", zp->sbBlkCount);
452dce63815Sdrahn     printf("           device type: 0x%x\n", zp->sbDevType);
453dce63815Sdrahn     printf("             device id: 0x%x\n", zp->sbDevId);
454024cef13Skrw     printf("                  data: 0x%x\n", zp->sbData);
455024cef13Skrw     printf("          driver count: %u\n", zp->sbDrvrCount);
45670060700Skrw     m = (struct ddmap *) zp->sbMap;
457dce63815Sdrahn     for (i = 0; &m[i].ddType < &zp->sbMap[247]; i++) {
458dce63815Sdrahn 	if (m[i].ddBlock == 0 && m[i].ddSize == 0 && m[i].ddType == 0) {
459dce63815Sdrahn 	    break;
460dce63815Sdrahn 	}
461024cef13Skrw 	printf("      driver %3u block: %u\n", i+1, m[i].ddBlock);
462024cef13Skrw 	printf("        size in blocks: %u\n", m[i].ddSize);
463dce63815Sdrahn 	printf("           driver type: 0x%x\n", m[i].ddType);
464dce63815Sdrahn     }
465dce63815Sdrahn     printf("remainder of block -");
466dce63815Sdrahn     dump_block((unsigned char *)&m[i].ddBlock, (&zp->sbMap[247]-((unsigned short *)&m[i].ddBlock))*2);
467dce63815Sdrahn }
468dce63815Sdrahn 
469b42d9302Smartin 
470dce63815Sdrahn void
471eedab009Skrw display_patches(struct partition_map *entry)
472dce63815Sdrahn {
473dce63815Sdrahn     long long offset;
4746a69102aSkrw     struct file_media *m;
475dce63815Sdrahn     static unsigned char *patch_block;
47694d20309Skrw     struct patchlist *p;
47794d20309Skrw     struct patchdescriptor *q;
478b42d9302Smartin     unsigned char *next;
479b42d9302Smartin     unsigned char *s;
480b42d9302Smartin     int i;
481dce63815Sdrahn 
482dce63815Sdrahn     offset = entry->data->dpme_pblock_start;
483dce63815Sdrahn     m = entry->the_map->m;
484dce63815Sdrahn     offset = ((long long) entry->data->dpme_pblock_start) * entry->the_map->logical_block;
485dce63815Sdrahn     if (patch_block == NULL) {
486d66063cbSkrw 	patch_block = malloc(DEV_BSIZE);
487dce63815Sdrahn 	if (patch_block == NULL) {
48868d0f91bSkrw 	    warn("can't allocate memory for patch block buffer");
489dce63815Sdrahn 	    return;
490dce63815Sdrahn 	}
491dce63815Sdrahn     }
492f42746d7Skrw     if (read_file_media(m, (long long)offset, DEV_BSIZE, (char *)patch_block) == 0) {
49368d0f91bSkrw 	warn("Can't read patch block");
494dce63815Sdrahn 	return;
495dce63815Sdrahn     }
49694d20309Skrw     p = (struct patchlist *) patch_block;
497b42d9302Smartin     if (p->numPatchBlocks != 1) {
498b42d9302Smartin 	i = p->numPatchBlocks;
499b42d9302Smartin 	free(patch_block);
500d66063cbSkrw 	patch_block = reallocarray(NULL, i, DEV_BSIZE);
501b42d9302Smartin 	if (patch_block == NULL) {
50268d0f91bSkrw 	    warn("can't allocate memory for patch blocks buffer");
503b42d9302Smartin 	    return;
504b42d9302Smartin 	}
505d66063cbSkrw 	s = patch_block + DEV_BSIZE*i;
506b42d9302Smartin 	while (i > 0) {
507d66063cbSkrw 	    s -= DEV_BSIZE;
508b42d9302Smartin 	    i -= 1;
509f42746d7Skrw 	    if (read_file_media(m, offset+i, DEV_BSIZE, (char *)s) == 0) {
51068d0f91bSkrw 		warn("Can't read patch block %d", i);
511b42d9302Smartin 		return;
512b42d9302Smartin 	    }
513b42d9302Smartin 	}
51494d20309Skrw 	p = (struct patchlist *) patch_block;
515b42d9302Smartin     }
516b42d9302Smartin     printf("Patch list (%d entries)\n", p->numPatches);
517b42d9302Smartin     q = p->thePatch;
518b42d9302Smartin     for (i = 0; i < p->numPatches; i++) {
519b42d9302Smartin 	printf("%2d signature: '%.4s'\n", i+1, (char *)&q->patchSig);
520b42d9302Smartin 	printf("     version: %d.%d\n", q->majorVers, q->minorVers);
521b42d9302Smartin 	printf("       flags: 0x%lx\n", q->flags);
522b42d9302Smartin 	printf("      offset: %ld\n", q->patchOffset);
523b42d9302Smartin 	printf("        size: %ld\n", q->patchSize);
524b42d9302Smartin 	printf("         CRC: 0x%lx\n", q->patchCRC);
525b42d9302Smartin 	printf("        name: '%.*s'\n", q->patchName[0], &q->patchName[1]);
526b42d9302Smartin 	printf("      vendor: '%.*s'\n", q->patchVendor[0], &q->patchVendor[1]);
527b42d9302Smartin 	next = ((unsigned char *)q) + q->patchDescriptorLen;
528b42d9302Smartin 	s = &q->patchVendor[q->patchVendor[0]+1];
529b42d9302Smartin 	if (next > s) {
530b42d9302Smartin 	    printf("remainder of entry -");
531b42d9302Smartin 	    dump_block(s, next-s);
532b42d9302Smartin 	}
53394d20309Skrw 	q = (struct patchdescriptor *)next;
534b42d9302Smartin     }
535dce63815Sdrahn }
536dce63815Sdrahn 
537dce63815Sdrahn int
538eedab009Skrw get_max_type_string_length(struct partition_map_header *map)
539dce63815Sdrahn {
540eedab009Skrw     struct partition_map * entry;
541dce63815Sdrahn     int max;
542dce63815Sdrahn     int length;
543dce63815Sdrahn 
544dce63815Sdrahn     if (map == NULL) {
545dce63815Sdrahn 	return 0;
546dce63815Sdrahn     }
547dce63815Sdrahn 
548dce63815Sdrahn     max = 0;
549dce63815Sdrahn 
550dce63815Sdrahn     for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
551dce63815Sdrahn 	length = strnlen(entry->data->dpme_type, DPISTRLEN);
552dce63815Sdrahn 	if (length > max) {
553dce63815Sdrahn 	    max = length;
554dce63815Sdrahn 	}
555dce63815Sdrahn     }
556dce63815Sdrahn 
557dce63815Sdrahn     return max;
558dce63815Sdrahn }
559dce63815Sdrahn 
560dce63815Sdrahn int
561eedab009Skrw get_max_name_string_length(struct partition_map_header *map)
562dce63815Sdrahn {
563eedab009Skrw     struct partition_map * entry;
564dce63815Sdrahn     int max;
565dce63815Sdrahn     int length;
566dce63815Sdrahn 
567dce63815Sdrahn     if (map == NULL) {
568dce63815Sdrahn 	return 0;
569dce63815Sdrahn     }
570dce63815Sdrahn 
571dce63815Sdrahn     max = 0;
572dce63815Sdrahn 
573dce63815Sdrahn     for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
574dce63815Sdrahn 	length = strnlen(entry->data->dpme_name, DPISTRLEN);
575dce63815Sdrahn 	if (length > max) {
576dce63815Sdrahn 	    max = length;
577dce63815Sdrahn 	}
578dce63815Sdrahn     }
579dce63815Sdrahn 
580dce63815Sdrahn     return max;
581dce63815Sdrahn }
582dce63815Sdrahn 
583dce63815Sdrahn int
584eedab009Skrw get_max_base_or_length(struct partition_map_header *map)
585dce63815Sdrahn {
586eedab009Skrw     struct partition_map * entry;
587dce63815Sdrahn     int max;
588dce63815Sdrahn 
589dce63815Sdrahn     if (map == NULL) {
590dce63815Sdrahn 	return 0;
591dce63815Sdrahn     }
592dce63815Sdrahn 
593dce63815Sdrahn     max = 0;
594dce63815Sdrahn 
595dce63815Sdrahn     for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
596dce63815Sdrahn 	if (entry->data->dpme_pblock_start > max) {
597dce63815Sdrahn 	    max = entry->data->dpme_pblock_start;
598dce63815Sdrahn 	}
599dce63815Sdrahn 	if (entry->data->dpme_pblocks > max) {
600dce63815Sdrahn 	    max = entry->data->dpme_pblocks;
601dce63815Sdrahn 	}
602dce63815Sdrahn 	if (entry->data->dpme_lblock_start > max) {
603dce63815Sdrahn 	    max = entry->data->dpme_lblock_start;
604dce63815Sdrahn 	}
605dce63815Sdrahn 	if (entry->data->dpme_lblocks > max) {
606dce63815Sdrahn 	    max = entry->data->dpme_lblocks;
607dce63815Sdrahn 	}
608dce63815Sdrahn     }
609dce63815Sdrahn 
610dce63815Sdrahn     return max;
611dce63815Sdrahn }
612dce63815Sdrahn 
613dce63815Sdrahn void
614dce63815Sdrahn adjust_value_and_compute_prefix(double *value, int *prefix)
615dce63815Sdrahn {
616dce63815Sdrahn     double bytes;
617dce63815Sdrahn     int multiplier;
618dce63815Sdrahn 
619dce63815Sdrahn     bytes = *value;
620dce63815Sdrahn     if (bytes < 1024.0) {
621dce63815Sdrahn 	multiplier = ' ';
622dce63815Sdrahn     } else {
623dce63815Sdrahn 	bytes = bytes / 1024.0;
624dce63815Sdrahn 	if (bytes < 1024.0) {
625dce63815Sdrahn 	    multiplier = 'K';
626dce63815Sdrahn 	} else {
627dce63815Sdrahn 	    bytes = bytes / 1024.0;
628dce63815Sdrahn 	    if (bytes < 1024.0) {
629dce63815Sdrahn 		multiplier = 'M';
630dce63815Sdrahn 	    } else {
631dce63815Sdrahn 		bytes = bytes / 1024.0;
632dce63815Sdrahn 		if (bytes < 1024.0) {
633dce63815Sdrahn 		    multiplier = 'G';
634dce63815Sdrahn 		} else {
635dce63815Sdrahn 		    bytes = bytes / 1024.0;
636dce63815Sdrahn 		    multiplier = 'T';
637dce63815Sdrahn 		}
638dce63815Sdrahn 	    }
639dce63815Sdrahn 	}
640dce63815Sdrahn     }
641dce63815Sdrahn     *value = bytes;
642dce63815Sdrahn     *prefix = multiplier;
643dce63815Sdrahn }
644