1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "hex_dump.h" 18 19 #include "globals.h" 20 21 #include <string.h> 22 23 namespace art { 24 25 void HexDump::Dump(std::ostream& os) const { 26 if (byte_count_ == 0) { 27 return; 28 } 29 30 if (address_ == nullptr) { 31 os << "00000000:"; 32 return; 33 } 34 35 static const char gHexDigit[] = "0123456789abcdef"; 36 const unsigned char* addr = reinterpret_cast<const unsigned char*>(address_); 37 // 01234560: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 0123456789abcdef 38 char out[(kBitsPerIntPtrT / 4) + /* offset */ 39 1 + /* colon */ 40 (16 * 3) + /* 16 hex digits and space */ 41 2 + /* white space */ 42 16 + /* 16 characters*/ 43 1 /* \0 */ ]; 44 size_t offset; /* offset to show while printing */ 45 46 if (show_actual_addresses_) { 47 offset = reinterpret_cast<size_t>(addr); 48 } else { 49 offset = 0; 50 } 51 memset(out, ' ', sizeof(out)-1); 52 out[kBitsPerIntPtrT / 4] = ':'; 53 out[sizeof(out)-1] = '\0'; 54 55 size_t byte_count = byte_count_; 56 size_t gap = offset & 0x0f; 57 while (byte_count > 0) { 58 size_t line_offset = offset & ~0x0f; 59 60 char* hex = out; 61 char* asc = out + (kBitsPerIntPtrT / 4) + /* offset */ 1 + /* colon */ 62 (16 * 3) + /* 16 hex digits and space */ 2 /* white space */; 63 64 for (int i = 0; i < (kBitsPerIntPtrT / 4); i++) { 65 *hex++ = gHexDigit[line_offset >> (kBitsPerIntPtrT - 4)]; 66 line_offset <<= 4; 67 } 68 hex++; 69 hex++; 70 71 size_t count = std::min(byte_count, 16 - gap); 72 // CHECK_NE(count, 0U); 73 // CHECK_LE(count + gap, 16U); 74 75 if (gap) { 76 /* only on first line */ 77 hex += gap * 3; 78 asc += gap; 79 } 80 81 size_t i; 82 for (i = gap ; i < count + gap; i++) { 83 *hex++ = gHexDigit[*addr >> 4]; 84 *hex++ = gHexDigit[*addr & 0x0f]; 85 hex++; 86 if (*addr >= 0x20 && *addr < 0x7f /*isprint(*addr)*/) { 87 *asc++ = *addr; 88 } else { 89 *asc++ = '.'; 90 } 91 addr++; 92 } 93 for (; i < 16; i++) { 94 /* erase extra stuff; only happens on last line */ 95 *hex++ = ' '; 96 *hex++ = ' '; 97 hex++; 98 *asc++ = ' '; 99 } 100 101 os << prefix_ << out; 102 103 gap = 0; 104 byte_count -= count; 105 offset += count; 106 if (byte_count > 0) { 107 os << "\n"; 108 } 109 } 110 } 111 112 } // namespace art 113