1239400Sandreast/*	$OpenBSD: dump.c,v 1.75 2016/02/23 02:39:54 krw Exp $	*/
2239400Sandreast
3239400Sandreast/*
4239400Sandreast * dump.c - dumping partition maps
5239400Sandreast *
6239400Sandreast * Written by Eryk Vershen
7239400Sandreast */
8239400Sandreast
9239400Sandreast/*
10239400Sandreast * Copyright 1996,1997,1998 by Apple Computer, Inc.
11239400Sandreast *              All Rights Reserved
12239400Sandreast *
13239400Sandreast * Permission to use, copy, modify, and distribute this software and
14239400Sandreast * its documentation for any purpose and without fee is hereby granted,
15239400Sandreast * provided that the above copyright notice appears in all copies and
16239400Sandreast * that both the copyright notice and this permission notice appear in
17239400Sandreast * supporting documentation.
18239400Sandreast *
19239400Sandreast * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
20239400Sandreast * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21239400Sandreast * FOR A PARTICULAR PURPOSE.
22239400Sandreast *
23239400Sandreast * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
24239400Sandreast * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
25239400Sandreast * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
26239400Sandreast * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
27239400Sandreast * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28239400Sandreast */
29239400Sandreast
30239400Sandreast#include <sys/queue.h>
31239400Sandreast
32239400Sandreast#include <stdio.h>
33239400Sandreast#include <stdlib.h>
34239400Sandreast#include <string.h>
35239400Sandreast#include <util.h>
36239400Sandreast
37239400Sandreast#include "partition_map.h"
38239400Sandreast#include "dump.h"
39239400Sandreast#include "io.h"
40239400Sandreast
41239400Sandreastvoid	dump_block(unsigned char *, int);
42239400Sandreastvoid	dump_block_zero(struct partition_map *);
43239400Sandreastvoid	dump_partition_entry(struct entry *, int, int, int);
44239400Sandreastint	get_max_base_or_length(struct partition_map *);
45239400Sandreastint	get_max_name_string_length(struct partition_map *);
46239400Sandreastint	get_max_type_string_length(struct partition_map *);
47239400Sandreast
48239400Sandreastvoid
49239400Sandreastdump_block_zero(struct partition_map *map)
50239400Sandreast{
51239400Sandreast	char buf[FMT_SCALED_STRSIZE];
52239400Sandreast	struct ddmap  *m;
53239400Sandreast	int i;
54239400Sandreast
55239400Sandreast	printf("\nDevice block size=%u, Number of Blocks=%u",
56239400Sandreast	       map->sbBlkSize, map->sbBlkCount);
57239400Sandreast	if (fmt_scaled((long long)map->sbBlkCount * map->sbBlkSize, buf) == 0)
58239400Sandreast		printf(" (%s)\n", buf);
59239400Sandreast	else
60239400Sandreast		printf("\n");
61239400Sandreast
62239400Sandreast	printf("DeviceType=0x%x, DeviceId=0x%x\n", map->sbDevType,
63239400Sandreast	    map->sbDevId);
64239400Sandreast	if (map->sbDrvrCount > 0) {
65239400Sandreast		printf("Drivers-\n");
66239400Sandreast		m = map->sbDDMap;
67239400Sandreast		for (i = 0; i < map->sbDrvrCount; i++) {
68239400Sandreast			printf("%d: %3u @ %u, ", i + 1, m[i].ddSize,
69239400Sandreast			    m[i].ddBlock);
70239400Sandreast			printf("type=0x%x\n", m[i].ddType);
71239400Sandreast		}
72239400Sandreast	}
73239400Sandreast	printf("\n");
74239400Sandreast}
75239400Sandreast
76239400Sandreast
77239400Sandreastvoid
78239400Sandreastdump_partition_map(struct partition_map *map)
79239400Sandreast{
80239400Sandreast	struct entry *entry;
81239400Sandreast	int digits, max_type_length, max_name_length;
82239400Sandreast
83239400Sandreast	printf("\nPartition map (with %d byte blocks) on '%s'\n",
84239400Sandreast	       map->sbBlkSize, map->name);
85239400Sandreast
86239400Sandreast	digits = number_of_digits(get_max_base_or_length(map));
87239400Sandreast	if (digits < 6)
88239400Sandreast		digits = 6;
89239400Sandreast	max_type_length = get_max_type_string_length(map);
90239400Sandreast	if (max_type_length < 4)
91239400Sandreast		max_type_length = 4;
92239400Sandreast	max_name_length = get_max_name_string_length(map);
93239400Sandreast	if (max_name_length < 6)
94239400Sandreast		max_name_length = 6;
95239400Sandreast	printf(" #: %*s %-*s %*s   %-*s\n", max_type_length, "type",
96239400Sandreast	    max_name_length, "name", digits, "length", digits, "base");
97239400Sandreast
98239400Sandreast	LIST_FOREACH(entry, &map->disk_order, disk_entry) {
99239400Sandreast		dump_partition_entry(entry, max_type_length,
100239400Sandreast		    max_name_length, digits);
101239400Sandreast	}
102239400Sandreast	dump_block_zero(map);
103239400Sandreast}
104239400Sandreast
105239400Sandreast
106239400Sandreastvoid
107239400Sandreastdump_partition_entry(struct entry *entry, int type_length, int name_length,
108239400Sandreast    int digits)
109239400Sandreast{
110239400Sandreast	char buf[FMT_SCALED_STRSIZE];
111239400Sandreast
112239400Sandreast	printf("%2ld: %*.32s", entry->disk_address, type_length,
113239400Sandreast	    entry->dpme_type);
114239400Sandreast	printf("%c%-*.32s ", contains_driver(entry) ? '*' : ' ',
115239400Sandreast	    name_length, entry->dpme_name);
116239400Sandreast
117239400Sandreast	printf("%*u @ %-*u", digits, entry->dpme_pblocks, digits,
118239400Sandreast	    entry->dpme_pblock_start);
119239400Sandreast
120239400Sandreast	if (fmt_scaled((long long)entry->dpme_pblocks *
121239400Sandreast	    entry->the_map->sbBlkSize, buf) == 0)
122239400Sandreast		printf("(%s)\n", buf);
123239400Sandreast	else
124239400Sandreast		printf("\n");
125239400Sandreast}
126239400Sandreast
127239400Sandreast
128239400Sandreastvoid
129239400Sandreastshow_data_structures(struct partition_map *map)
130239400Sandreast{
131239400Sandreast	struct entry *entry;
132239400Sandreast	struct ddmap *m;
133239400Sandreast	int i;
134239400Sandreast
135239400Sandreast	printf("Header:\n");
136239400Sandreast	printf("map %d blocks out of %d,  media %lu blocks (%d byte blocks)\n",
137239400Sandreast	    map->blocks_in_map, map->maximum_in_map, map->media_size,
138239400Sandreast	    map->sbBlkSize);
139239400Sandreast	printf("Map is%s writable", rflag ? " not" : "");
140239400Sandreast	printf(" and has%s been changed\n", (map->changed) ? "" : " not");
141239400Sandreast	printf("\n");
142239400Sandreast
143239400Sandreast	printf("Block0:\n");
144239400Sandreast	printf("signature 0x%x", map->sbSig);
145239400Sandreast	printf("Block size=%u, Number of Blocks=%u\n", map->sbBlkSize,
146239400Sandreast	    map->sbBlkCount);
147239400Sandreast	printf("DeviceType=0x%x, DeviceId=0x%x, sbData=0x%x\n", map->sbDevType,
148239400Sandreast	    map->sbDevId, map->sbData);
149239400Sandreast	if (map->sbDrvrCount == 0) {
150239400Sandreast		printf("No drivers\n");
151239400Sandreast	} else {
152239400Sandreast		printf("%u driver%s-\n", map->sbDrvrCount,
153239400Sandreast		    (map->sbDrvrCount > 1) ? "s" : "");
154239400Sandreast		m = map->sbDDMap;
155239400Sandreast		for (i = 0; i < map->sbDrvrCount; i++) {
156239400Sandreast			printf("%u: @ %u for %u, type=0x%x\n", i + 1,
157239400Sandreast			    m[i].ddBlock, m[i].ddSize, m[i].ddType);
158239400Sandreast		}
159239400Sandreast	}
160239400Sandreast	printf("\n");
161239400Sandreast	printf(" #:                 type  length   base    "
162239400Sandreast	       "flags     (      logical      )\n");
163239400Sandreast	LIST_FOREACH(entry, &map->disk_order, disk_entry) {
164239400Sandreast		printf("%2ld: %20.32s ", entry->disk_address, entry->dpme_type);
165239400Sandreast		printf("%7u @ %-7u ", entry->dpme_pblocks,
166239400Sandreast		    entry->dpme_pblock_start);
167239400Sandreast		printf("%c%c%c%c%c%c%c%c%c ",
168239400Sandreast		       (entry->dpme_flags & DPME_VALID) ? 'V' : '.',
169239400Sandreast		       (entry->dpme_flags & DPME_ALLOCATED) ? 'A' : '.',
170239400Sandreast		       (entry->dpme_flags & DPME_IN_USE) ? 'I' : '.',
171239400Sandreast		       (entry->dpme_flags & DPME_BOOTABLE) ? 'B' : '.',
172239400Sandreast		       (entry->dpme_flags & DPME_READABLE) ? 'R' : '.',
173239400Sandreast		       (entry->dpme_flags & DPME_WRITABLE) ? 'W' : '.',
174239400Sandreast		       (entry->dpme_flags & DPME_OS_PIC_CODE) ? 'P' : '.',
175239400Sandreast		       (entry->dpme_flags & DPME_OS_SPECIFIC_2) ? '2' : '.',
176239400Sandreast		       (entry->dpme_flags & DPME_OS_SPECIFIC_1) ? '1' : '.');
177239400Sandreast		printf("( %7u @ %-7u )\n", entry->dpme_lblocks,
178239400Sandreast		    entry->dpme_lblock_start);
179239400Sandreast	}
180239400Sandreast	printf("\n");
181239400Sandreast	printf(" #:  booter   bytes      load_address      "
182239400Sandreast	    "goto_address checksum processor\n");
183239400Sandreast	LIST_FOREACH(entry, &map->disk_order, disk_entry) {
184239400Sandreast		printf("%2ld: ", entry->disk_address);
185239400Sandreast		printf("%7u ", entry->dpme_boot_block);
186239400Sandreast		printf("%7u ", entry->dpme_boot_bytes);
187239400Sandreast		printf("%8x ", entry->dpme_load_addr);
188239400Sandreast		printf("%8x ", entry->dpme_goto_addr);
189239400Sandreast		printf("%8x ", entry->dpme_checksum);
190239400Sandreast		printf("%.32s", entry->dpme_processor_id);
191239400Sandreast		printf("\n");
192239400Sandreast	}
193239400Sandreast	printf("\n");
194239400Sandreast}
195239400Sandreast
196239400Sandreast
197239400Sandreastvoid
198239400Sandreastfull_dump_partition_entry(struct partition_map *map, int ix)
199239400Sandreast{
200239400Sandreast	struct entry *entry;
201239400Sandreast	int i;
202239400Sandreast	uint32_t t;
203239400Sandreast
204239400Sandreast	entry = find_entry_by_disk_address(ix, map);
205239400Sandreast	if (entry == NULL) {
206239400Sandreast		printf("No such partition\n");
207239400Sandreast		return;
208239400Sandreast	}
209239400Sandreast	printf("             signature: 0x%x\n", entry->dpme_signature);
210239400Sandreast	printf(" number of map entries: %u\n", entry->dpme_map_entries);
211239400Sandreast	printf("        physical start: %10u  length: %10u\n",
212239400Sandreast	    entry->dpme_pblock_start, entry->dpme_pblocks);
213239400Sandreast	printf("         logical start: %10u  length: %10u\n",
214239400Sandreast	    entry->dpme_lblock_start, entry->dpme_lblocks);
215239400Sandreast
216239400Sandreast	printf("                 flags: 0x%x\n", entry->dpme_flags);
217239400Sandreast	printf("                        ");
218239400Sandreast	if (entry->dpme_flags & DPME_VALID)
219239400Sandreast		printf("valid ");
220239400Sandreast	if (entry->dpme_flags & DPME_ALLOCATED)
221239400Sandreast		printf("alloc ");
222239400Sandreast	if (entry->dpme_flags & DPME_IN_USE)
223239400Sandreast		printf("in-use ");
224239400Sandreast	if (entry->dpme_flags & DPME_BOOTABLE)
225239400Sandreast		printf("boot ");
226239400Sandreast	if (entry->dpme_flags & DPME_READABLE)
227239400Sandreast		printf("read ");
228239400Sandreast	if (entry->dpme_flags & DPME_WRITABLE)
229239400Sandreast		printf("write ");
230239400Sandreast	if (entry->dpme_flags & DPME_OS_PIC_CODE)
231239400Sandreast		printf("pic ");
232239400Sandreast	t = entry->dpme_flags >> 7;
233239400Sandreast	for (i = 7; i <= 31; i++) {
234239400Sandreast		if (t & 0x1)
235239400Sandreast			printf("%d ", i);
236239400Sandreast		t = t >> 1;
237239400Sandreast	}
238239400Sandreast	printf("\n");
239239400Sandreast
240239400Sandreast	printf("                  name: '%.32s'\n", entry->dpme_name);
241239400Sandreast	printf("                  type: '%.32s'\n", entry->dpme_type);
242239400Sandreast	printf("      boot start block: %10u\n", entry->dpme_boot_block);
243239400Sandreast	printf("boot length (in bytes): %10u\n", entry->dpme_boot_bytes);
244239400Sandreast	printf("          load address: 0x%08x\n", entry->dpme_load_addr);
245239400Sandreast	printf("         start address: 0x%08x\n", entry->dpme_goto_addr);
246239400Sandreast	printf("              checksum: 0x%08x\n", entry->dpme_checksum);
247239400Sandreast	printf("             processor: '%.32s'\n", entry->dpme_processor_id);
248239400Sandreast	printf("dpme_reserved_1 -");
249239400Sandreast	dump_block(entry->dpme_reserved_1, sizeof(entry->dpme_reserved_1));
250239400Sandreast	printf("dpme_reserved_2 -");
251239400Sandreast	dump_block(entry->dpme_reserved_2, sizeof(entry->dpme_reserved_2));
252239400Sandreast	printf("dpme_reserved_3 -");
253239400Sandreast	dump_block(entry->dpme_reserved_3, sizeof(entry->dpme_reserved_3));
254239400Sandreast	printf("dpme_reserved_4 -");
255239400Sandreast	dump_block(entry->dpme_reserved_4, sizeof(entry->dpme_reserved_4));
256239400Sandreast}
257239400Sandreast
258239400Sandreast
259239400Sandreastvoid
260239400Sandreastdump_block(unsigned char *addr, int len)
261239400Sandreast{
262239400Sandreast	int i, j, limit1, limit;
263239400Sandreast
264239400Sandreast#define LINE_LEN 16
265239400Sandreast#define UNIT_LEN  4
266239400Sandreast#define OTHER_LEN  8
267239400Sandreast
268239400Sandreast	for (i = 0; i < len; i = limit) {
269239400Sandreast		limit1 = i + LINE_LEN;
270239400Sandreast		if (limit1 > len)
271239400Sandreast			limit = len;
272239400Sandreast		else
273239400Sandreast			limit = limit1;
274239400Sandreast		printf("\n%03x: ", i);
275239400Sandreast		for (j = i; j < limit1; j++) {
276239400Sandreast			if (j % UNIT_LEN == 0)
277239400Sandreast				printf(" ");
278239400Sandreast			if (j < limit)
279239400Sandreast				printf("%02x", addr[j]);
280239400Sandreast			else
281239400Sandreast				printf("  ");
282239400Sandreast		}
283239400Sandreast		printf(" ");
284239400Sandreast		for (j = i; j < limit; j++) {
285239400Sandreast			if (j % OTHER_LEN == 0)
286239400Sandreast				printf(" ");
287239400Sandreast			if (addr[j] < ' ')
288239400Sandreast				printf(".");
289239400Sandreast			else
290239400Sandreast				printf("%c", addr[j]);
291239400Sandreast		}
292239400Sandreast	}
293239400Sandreast	printf("\n");
294239400Sandreast}
295239400Sandreast
296239400Sandreastvoid
297239400Sandreastfull_dump_block_zero(struct partition_map *map)
298239400Sandreast{
299239400Sandreast	struct ddmap *m;
300239400Sandreast	int i;
301239400Sandreast
302239400Sandreast	m = map->sbDDMap;
303239400Sandreast
304239400Sandreast	printf("             signature: 0x%x\n", map->sbSig);
305239400Sandreast	printf("       size of a block: %u\n", map->sbBlkSize);
306239400Sandreast	printf("      number of blocks: %u\n", map->sbBlkCount);
307239400Sandreast	printf("           device type: 0x%x\n", map->sbDevType);
308239400Sandreast	printf("             device id: 0x%x\n", map->sbDevId);
309239400Sandreast	printf("                  data: 0x%x\n", map->sbData);
310239400Sandreast	printf("          driver count: %u\n", map->sbDrvrCount);
311239400Sandreast	for (i = 0; i < 8; i++) {
312239400Sandreast		if (m[i].ddBlock == 0 && m[i].ddSize == 0 && m[i].ddType == 0)
313239400Sandreast			break;
314239400Sandreast		printf("      driver %3u block: %u\n", i + 1, m[i].ddBlock);
315239400Sandreast		printf("        size in blocks: %u\n", m[i].ddSize);
316239400Sandreast		printf("           driver type: 0x%x\n", m[i].ddType);
317239400Sandreast	}
318239400Sandreast	printf("remainder of block -");
319239400Sandreast	dump_block(map->sbReserved, sizeof(map->sbReserved));
320239400Sandreast}
321239400Sandreast
322239400Sandreastint
323239400Sandreastget_max_type_string_length(struct partition_map *map)
324239400Sandreast{
325239400Sandreast	struct entry *entry;
326239400Sandreast	int max, length;
327239400Sandreast
328239400Sandreast	max = 0;
329239400Sandreast
330239400Sandreast	LIST_FOREACH(entry, &map->disk_order, disk_entry) {
331239400Sandreast		length = strnlen(entry->dpme_type, DPISTRLEN);
332239400Sandreast		if (length > max)
333239400Sandreast			max = length;
334239400Sandreast	}
335239400Sandreast
336239400Sandreast	return max;
337239400Sandreast}
338239400Sandreast
339239400Sandreastint
340239400Sandreastget_max_name_string_length(struct partition_map *map)
341239400Sandreast{
342239400Sandreast	struct entry *entry;
343239400Sandreast	int max, length;
344239400Sandreast
345239400Sandreast	max = 0;
346239400Sandreast
347239400Sandreast	LIST_FOREACH(entry, &map->disk_order, disk_entry) {
348239400Sandreast		length = strnlen(entry->dpme_name, DPISTRLEN);
349239400Sandreast		if (length > max)
350239400Sandreast			max = length;
351239400Sandreast	}
352239400Sandreast
353239400Sandreast	return max;
354239400Sandreast}
355239400Sandreast
356239400Sandreastint
357239400Sandreastget_max_base_or_length(struct partition_map *map)
358239400Sandreast{
359239400Sandreast	struct entry *entry;
360239400Sandreast	int max;
361239400Sandreast
362239400Sandreast	max = 0;
363239400Sandreast
364239400Sandreast	LIST_FOREACH(entry, &map->disk_order, disk_entry) {
365239400Sandreast		if (entry->dpme_pblock_start > max)
366239400Sandreast			max = entry->dpme_pblock_start;
367239400Sandreast		if (entry->dpme_pblocks > max)
368239400Sandreast			max = entry->dpme_pblocks;
369239400Sandreast	}
370239400Sandreast
371239400Sandreast	return max;
372239400Sandreast}
373239400Sandreast