coreboot/util/nvramtool/hexdump.c
<<
>>
Prefs
   1/*****************************************************************************\
   2 * hexdump.c
   3\*****************************************************************************/
   4
   5#include "hexdump.h"
   6#include <ctype.h>
   7
   8/* hexdump.c
   9 *
  10 * Copyright (C) 2002
  11 *     David S. Peterson.  All rights reserved.
  12 *
  13 * Author: David S. Peterson <dave_peterson@pobox.com>
  14 *
  15 * Redistribution and use in source and binary forms, with or without
  16 * modification, are permitted provided that the following conditions are
  17 * met:
  18 * 1. Redistributions of source code must retain the above copyright notice,
  19 *    this list of conditions, and the entire permission notice, including
  20 *    the following disclaimer of warranties.
  21 * 2. Redistributions in binary form must reproduce the above copyright
  22 *    notice, this list of conditions, and the entire permission notice,
  23 *    including the following disclaimer in the documentation and/or other
  24 *    materials provided with the distribution.
  25 * 3. The name(s) of the author(s) may not be used to endorse or promote
  26 *    products derived from this software without specific prior written
  27 *    permission.
  28 *
  29 * ALTERNATIVELY, this product may be distributed under the terms of the GNU
  30 * General Public License, in which case the provisions of the GPL are
  31 * required INSTEAD OF the above restrictions.  (This clause is necessary due
  32 * to a potential bad interaction between the GPL and the restrictions
  33 * contained in a BSD-style copyright.)
  34 *
  35 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
  36 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
  38 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
  39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  40 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  41 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  42 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  43 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  44 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  45 */
  46
  47static void addrprint(FILE * outfile, uint64_t address, int width);
  48
  49/*--------------------------------------------------------------------------
  50 * hexdump
  51 *
  52 * Write a hex dump of 'mem' to 'outfile'.
  53 *
  54 * parameters:
  55 *     mem:             a pointer to the memory to display
  56 *     bytes:           the number of bytes of data to display
  57 *     addrprint_start: The address to associate with the first byte of
  58 *                      data.  For instance, a value of 0 indicates that the
  59 *                      first byte displayed should be labeled as byte 0.
  60 *     outfile:         The place where the hex dump should be written.
  61 *                      For instance, stdout or stderr may be passed here.
  62 *     format:          A structure specifying how the hex dump should be
  63 *                      formatted.
  64 *--------------------------------------------------------------------------*/
  65void hexdump(const void *mem, int bytes, uint64_t addrprint_start,
  66             FILE * outfile, const hexdump_format_t * format)
  67{
  68        int bytes_left, index, i;
  69        const unsigned char *p;
  70
  71        /* Quietly return if the caller asks us to do something unreasonable. */
  72        if ((format->bytes_per_line <= 0) || (bytes < 0))
  73                return;
  74
  75        p = (const unsigned char *)mem;
  76        index = 0;
  77
  78        /* Each iteration handles one full line of output.  When loop
  79         * terminates, the number of remaining bytes to display (if any)
  80         * will not be enough to fill an entire line.
  81         */
  82        for (bytes_left = bytes;
  83                        bytes_left >= format->bytes_per_line;
  84                        bytes_left -= format->bytes_per_line) {
  85                /* print start address for current line */
  86                fprintf(outfile, format->indent);
  87                addrprint(outfile, addrprint_start + index,
  88                          format->addrprint_width);
  89                fprintf(outfile, format->sep1);
  90
  91                /* display the bytes in hex */
  92                for (i = 0;;) {
  93                        fprintf(outfile, "%02x", p[index++]);
  94
  95                        if (++i >= format->bytes_per_line)
  96                                break;
  97
  98                        fprintf(outfile, format->sep2);
  99                }
 100
 101                index -= format->bytes_per_line;
 102                fprintf(outfile, format->sep3);
 103
 104                /* display the bytes as characters */
 105                for (i = 0; i < format->bytes_per_line; i++, index++)
 106                        fputc(isprint(p[index])?p[index]:format->nonprintable, outfile);
 107
 108                fprintf(outfile, "\n");
 109        }
 110
 111        if (bytes_left == 0)
 112                return;
 113
 114        /* print start address for last line */
 115        fprintf(outfile, format->indent);
 116        addrprint(outfile, addrprint_start + index, format->addrprint_width);
 117        fprintf(outfile, format->sep1);
 118
 119        /* display bytes for last line in hex */
 120        for (i = 0; i < bytes_left; i++) {
 121                fprintf(outfile, "%02x", p[index++]);
 122                fprintf(outfile, format->sep2);
 123        }
 124
 125        index -= bytes_left;
 126
 127        /* pad the rest of the hex byte area with spaces */
 128        for (;;) {
 129                fprintf(outfile, "  ");
 130
 131                if (++i >= format->bytes_per_line)
 132                        break;
 133
 134                fprintf(outfile, format->sep2);
 135        }
 136
 137        fprintf(outfile, format->sep3);
 138
 139        /* display bytes for last line as characters */
 140        for (i = 0; i < bytes_left; i++)
 141                fputc(isprint(p[index])?p[index++]:format->nonprintable, outfile);
 142
 143        /* pad the rest of the character area with spaces */
 144        for (; i < format->bytes_per_line; i++)
 145                fprintf(outfile, " ");
 146
 147        fprintf(outfile, "\n");
 148}
 149
 150/*--------------------------------------------------------------------------
 151 * addrprint
 152 *
 153 * Display an address as a hexadecimal number.
 154 *
 155 * parameters:
 156 *     outfile: the place where the output should be written
 157 *     address: the address to display
 158 *     width:   The number of bytes wide the address should be displayed as.
 159 *              Must be a value from 1 to 8.
 160 *--------------------------------------------------------------------------*/
 161static void addrprint(FILE * outfile, uint64_t address, int width)
 162{
 163        char s[17];
 164        int i;
 165
 166        /* force the user's input to be valid */
 167        if (width < 1)
 168                width = 1;
 169        else if (width > 8)
 170                width = 8;
 171
 172        /* convert address to string */
 173        sprintf(s, "%016llx", (unsigned long long)address);
 174
 175        /* write it out, with colons separating consecutive 16-bit
 176         * chunks of the address
 177         */
 178        for (i = 16 - (2 * width);;) {
 179                fprintf(outfile, "%c", s[i]);
 180
 181                if (++i >= 16)
 182                        break;
 183
 184                if ((i % 4) == 0)
 185                        fprintf(outfile, ":");
 186        }
 187}
 188
 189
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.