xref: /openbsd/sbin/pdisk/dump.c (revision 5fe72782)
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
dump_block_zero(struct partition_map * map)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
dump_partition_map(struct partition_map * map)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
dump_partition_entry(struct entry * entry,int type_length,int name_length,int digits)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
show_data_structures(struct partition_map * map)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
full_dump_partition_entry(struct partition_map * map,int ix)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
dump_block(unsigned char * addr,int len)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
full_dump_block_zero(struct partition_map * map)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
get_max_type_string_length(struct partition_map * map)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
get_max_name_string_length(struct partition_map * map)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
get_max_base_or_length(struct partition_map * map)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