1// Copyright 2016 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <pretty/hexdump.h> 6 7#include <ctype.h> 8#include <inttypes.h> 9#include <stdint.h> 10#include <stdio.h> 11 12#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1)) 13#define MIN(a, b) (((a) < (b)) ? (a) : (b)) 14 15void hexdump_ex(const void* ptr, size_t len, uint64_t disp_addr) { 16 uintptr_t address = (uintptr_t)ptr; 17 size_t count; 18 19 for (count = 0; count < len; count += 16) { 20 union { 21 uint32_t buf[4]; 22 uint8_t cbuf[16]; 23 } u; 24 size_t s = ROUNDUP(MIN(len - count, 16), 4); 25 size_t i; 26 27 printf(((disp_addr + len) > 0xFFFFFFFF) 28 ? "0x%016" PRIx64 ": " 29 : "0x%08" PRIx64 ": ", 30 disp_addr + count); 31 32 for (i = 0; i < s / 4; i++) { 33 u.buf[i] = ((const uint32_t*)address)[i]; 34 printf("%08x ", u.buf[i]); 35 } 36 for (; i < 4; i++) { 37 printf(" "); 38 } 39 printf("|"); 40 41 for (i = 0; i < 16; i++) { 42 char c = u.cbuf[i]; 43 if (i < s && isprint(c)) { 44 printf("%c", c); 45 } else { 46 printf("."); 47 } 48 } 49 printf("|\n"); 50 address += 16; 51 } 52} 53 54void hexdump8_ex(const void* ptr, size_t len, uint64_t disp_addr) { 55 uintptr_t address = (uintptr_t)ptr; 56 size_t count; 57 size_t i; 58 59 for (count = 0; count < len; count += 16) { 60 printf(((disp_addr + len) > 0xFFFFFFFF) 61 ? "0x%016" PRIx64 ": " 62 : "0x%08" PRIx64 ": ", 63 disp_addr + count); 64 65 for (i = 0; i < MIN(len - count, 16); i++) { 66 printf("%02hhx ", *(const uint8_t*)(address + i)); 67 } 68 69 for (; i < 16; i++) { 70 printf(" "); 71 } 72 73 printf("|"); 74 75 for (i = 0; i < MIN(len - count, 16); i++) { 76 char c = ((const char*)address)[i]; 77 printf("%c", isprint(c) ? c : '.'); 78 } 79 80 printf("\n"); 81 address += 16; 82 } 83} 84