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