1N/A * The contents of this file are subject to the terms of the 1N/A * Common Development and Distribution License, Version 1.0 only 1N/A * (the "License"). You may not use this file except in compliance 1N/A * See the License for the specific language governing permissions 1N/A * and limitations under the License. 1N/A * When distributing Covered Code, include this CDDL HEADER in each 1N/A * If applicable, add the following below this CDDL HEADER, with the 1N/A * fields enclosed by brackets "[]" replaced with your own identifying 1N/A * information: Portions Copyright [yyyy] [name of copyright owner] 1N/A * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 1N/A * Use is subject to license terms. 1N/A#
pragma ident "%Z%%M% %I% %E% SMI" 1N/A * This is the implementation of mdb's generic hexdump facility (though 1N/A * not named such in case we decide to add support for other radices). 1N/A * While it is possible to call mdb_dump_internal directly, it is 1N/A * recommended that you use mdb_dumpptr or mdb_dump64 instead. 1N/A * Output the header for the dump. pad is the width of the address 1N/A * field, and offset is the index of the byte that we want highlighted. 1N/A * If the output isn't MDB_DUMP_ALIGNed, we use offset to adjust the 1N/A * labels to reflect the true least significant address nibble. for (i = 0; i <
width; i++) {
* Output a line of data. pad is as defined above. A non-zero lmargin * and/or rmargin indicate a set of bytes that shouldn't be printed. for (i = 0; i <
width; i++) {
for (i = 0; i <
width; i++)
else if (
buf[i] <
' ' ||
buf[i] >
'~')
* Given an address and a length, compute the number of characters * needed to display addresses within that range. * Assume full width pointers * Vary width based on address and length, but first * check to see if the address is relevant. * The main dump routine, called by mdb_dump64 and (indirectly) by * mdb_dumpptr. Arguments: * addr - the address to start dumping at * len - the amount of data to dump * func - callback function used to obtain data * arg - argument to pass to callback function * bytes - size of pointer type int l, r;
/* left and right margins */ int pskip;
/* previous line was skipped */ int pvalid;
/* previous line was valid (we may skip) */ * Ensure that len doesn't wrap around the end of addressable * memory. Note that because we take an address and a length, * it isn't possible to dump from 0 to UINT64_MAX if * If a) the grouping isn't a power of two, or * b) the display width is not evenly divisible by the grouping * we ignore the specified grouping (and default to 4). * If we are reordering bytes to adjust for endianness, turn * off text output, headers, and alignment to cut down on the * number of special cases (and confusing output). For * correctness, we will continue to observe MDB_DUMP_TRIM, but * will truncate output if the specified length isn't a * multiple of the grouping. * If we are interested in seeing the data indexed relative to * the starting location, paragraph alignment is irrelevant. * The left margin will always be 0. * Compute the width of our addresses, and adjust our starting * point based on the address and the state of the alignment * Display the header (if appropriate), using the left margin * to determine what our column header offset should be. * If we aren't trimming and aligning the output, the left * margin is now irrelevant and should be zeroed. * We haven't skipped the previous line, it isn't valid to skip * the current line, and we use buffer 0 first. lint doesn't * realize that this implies pbuf won't be accessed until after * it is set, so we explicitly initialize that here, too. for (i = 0; i <
len && r == 0; i +=
width) {
* Select the current buffer. * We have a right margin only if we are on the last * line and either (1) MDB_DUMP_TRIM is set or (2) our * untrimmed output would require reading past the end * of addressable memory. In either case, we clear * pvalid since we don't want to skip the last line. * Read data into the current buffer, obeying the left * We handle read(2)-style partial results by * repeatedly calling the callback until we fill the * buffer, we get a 0 (end of file), or we get a -1 * (error). We take care to never read the same data * mdb(1)-style partial results (i.e. EMDB_PARTIAL) are * treated like any other error. If more exotic * handling is desired, the caller is free to wrap * their callback with an auxiliary function. See * mdb_dumpptr and mdb_dump64 for examples of this. * If we are eliminating repeated lines, AND it is * valid to eliminate this line, AND the current line * is the same as the previous line, don't print the * current line. If we didn't skip the previous line, * print an asterisk and set the previous-line-skipped * Otherwise, print the line and clear the * previous-line-skipped flag. * If we have a non-zero left margin then we don't have * a full buffer of data and we shouldn't try to skip * the next line. It doesn't matter if the right * margin is non-zero since we'll fall out of the loop. * Swap buffers, and zero the left margin. * If we successfully dumped everything, update . to be the * address following that of the last byte requested.