1*30fdc8d8SChris Lattner //===-- DNBDataRef.cpp ------------------------------------------*- C++ -*-===// 2*30fdc8d8SChris Lattner // 3*30fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 4*30fdc8d8SChris Lattner // 5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 7*30fdc8d8SChris Lattner // 8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 9*30fdc8d8SChris Lattner // 10*30fdc8d8SChris Lattner // Created by Greg Clayton on 1/11/06. 11*30fdc8d8SChris Lattner // 12*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 13*30fdc8d8SChris Lattner 14*30fdc8d8SChris Lattner #include "DNBDataRef.h" 15*30fdc8d8SChris Lattner #include "DNBLog.h" 16*30fdc8d8SChris Lattner #include <assert.h> 17*30fdc8d8SChris Lattner #include <ctype.h> 18*30fdc8d8SChris Lattner #include <libkern/OSByteOrder.h> 19*30fdc8d8SChris Lattner 20*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 21*30fdc8d8SChris Lattner // Constructor 22*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 23*30fdc8d8SChris Lattner 24*30fdc8d8SChris Lattner DNBDataRef::DNBDataRef() : 25*30fdc8d8SChris Lattner m_start(NULL), 26*30fdc8d8SChris Lattner m_end(NULL), 27*30fdc8d8SChris Lattner m_swap(false), 28*30fdc8d8SChris Lattner m_ptrSize(0), 29*30fdc8d8SChris Lattner m_addrPCRelative(INVALID_NUB_ADDRESS), 30*30fdc8d8SChris Lattner m_addrTEXT(INVALID_NUB_ADDRESS), 31*30fdc8d8SChris Lattner m_addrDATA(INVALID_NUB_ADDRESS) 32*30fdc8d8SChris Lattner { 33*30fdc8d8SChris Lattner } 34*30fdc8d8SChris Lattner 35*30fdc8d8SChris Lattner 36*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 37*30fdc8d8SChris Lattner // Constructor 38*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 39*30fdc8d8SChris Lattner 40*30fdc8d8SChris Lattner DNBDataRef::DNBDataRef(const uint8_t *start, size_t size, bool swap) : 41*30fdc8d8SChris Lattner m_start(start), 42*30fdc8d8SChris Lattner m_end(start+size), 43*30fdc8d8SChris Lattner m_swap(swap), 44*30fdc8d8SChris Lattner m_ptrSize(0), 45*30fdc8d8SChris Lattner m_addrPCRelative(INVALID_NUB_ADDRESS), 46*30fdc8d8SChris Lattner m_addrTEXT(INVALID_NUB_ADDRESS), 47*30fdc8d8SChris Lattner m_addrDATA(INVALID_NUB_ADDRESS) 48*30fdc8d8SChris Lattner { 49*30fdc8d8SChris Lattner } 50*30fdc8d8SChris Lattner 51*30fdc8d8SChris Lattner 52*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 53*30fdc8d8SChris Lattner // Destructor 54*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 55*30fdc8d8SChris Lattner 56*30fdc8d8SChris Lattner DNBDataRef::~DNBDataRef() 57*30fdc8d8SChris Lattner { 58*30fdc8d8SChris Lattner } 59*30fdc8d8SChris Lattner 60*30fdc8d8SChris Lattner 61*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 62*30fdc8d8SChris Lattner // Get8 63*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 64*30fdc8d8SChris Lattner uint8_t 65*30fdc8d8SChris Lattner DNBDataRef::Get8(offset_t *offset_ptr) const 66*30fdc8d8SChris Lattner { 67*30fdc8d8SChris Lattner uint8_t val = 0; 68*30fdc8d8SChris Lattner if ( ValidOffsetForDataOfSize(*offset_ptr, sizeof(val)) ) 69*30fdc8d8SChris Lattner { 70*30fdc8d8SChris Lattner val = *(m_start + *offset_ptr); 71*30fdc8d8SChris Lattner *offset_ptr += sizeof(val); 72*30fdc8d8SChris Lattner } 73*30fdc8d8SChris Lattner return val; 74*30fdc8d8SChris Lattner } 75*30fdc8d8SChris Lattner 76*30fdc8d8SChris Lattner 77*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 78*30fdc8d8SChris Lattner // Get16 79*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 80*30fdc8d8SChris Lattner uint16_t 81*30fdc8d8SChris Lattner DNBDataRef::Get16(offset_t *offset_ptr) const 82*30fdc8d8SChris Lattner { 83*30fdc8d8SChris Lattner uint16_t val = 0; 84*30fdc8d8SChris Lattner if ( ValidOffsetForDataOfSize(*offset_ptr, sizeof(val)) ) 85*30fdc8d8SChris Lattner { 86*30fdc8d8SChris Lattner const uint8_t *p = m_start + *offset_ptr; 87*30fdc8d8SChris Lattner val = *(uint16_t*)p; 88*30fdc8d8SChris Lattner 89*30fdc8d8SChris Lattner if (m_swap) 90*30fdc8d8SChris Lattner val = OSSwapInt16(val); 91*30fdc8d8SChris Lattner 92*30fdc8d8SChris Lattner // Advance the offset 93*30fdc8d8SChris Lattner *offset_ptr += sizeof(val); 94*30fdc8d8SChris Lattner } 95*30fdc8d8SChris Lattner return val; 96*30fdc8d8SChris Lattner } 97*30fdc8d8SChris Lattner 98*30fdc8d8SChris Lattner 99*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 100*30fdc8d8SChris Lattner // Get32 101*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 102*30fdc8d8SChris Lattner uint32_t 103*30fdc8d8SChris Lattner DNBDataRef::Get32(offset_t *offset_ptr) const 104*30fdc8d8SChris Lattner { 105*30fdc8d8SChris Lattner uint32_t val = 0; 106*30fdc8d8SChris Lattner if ( ValidOffsetForDataOfSize(*offset_ptr, sizeof(val)) ) 107*30fdc8d8SChris Lattner { 108*30fdc8d8SChris Lattner const uint8_t *p = m_start + *offset_ptr; 109*30fdc8d8SChris Lattner val = *(uint32_t*)p; 110*30fdc8d8SChris Lattner if (m_swap) 111*30fdc8d8SChris Lattner val = OSSwapInt32(val); 112*30fdc8d8SChris Lattner 113*30fdc8d8SChris Lattner // Advance the offset 114*30fdc8d8SChris Lattner *offset_ptr += sizeof(val); 115*30fdc8d8SChris Lattner } 116*30fdc8d8SChris Lattner return val; 117*30fdc8d8SChris Lattner } 118*30fdc8d8SChris Lattner 119*30fdc8d8SChris Lattner 120*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 121*30fdc8d8SChris Lattner // Get64 122*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 123*30fdc8d8SChris Lattner uint64_t 124*30fdc8d8SChris Lattner DNBDataRef::Get64(offset_t *offset_ptr) const 125*30fdc8d8SChris Lattner { 126*30fdc8d8SChris Lattner uint64_t val = 0; 127*30fdc8d8SChris Lattner if ( ValidOffsetForDataOfSize(*offset_ptr, sizeof(val)) ) 128*30fdc8d8SChris Lattner { 129*30fdc8d8SChris Lattner const uint8_t *p = m_start + *offset_ptr; 130*30fdc8d8SChris Lattner val = *(uint64_t*)p; 131*30fdc8d8SChris Lattner if (m_swap) 132*30fdc8d8SChris Lattner val = OSSwapInt64(val); 133*30fdc8d8SChris Lattner 134*30fdc8d8SChris Lattner // Advance the offset 135*30fdc8d8SChris Lattner *offset_ptr += sizeof(val); 136*30fdc8d8SChris Lattner } 137*30fdc8d8SChris Lattner return val; 138*30fdc8d8SChris Lattner } 139*30fdc8d8SChris Lattner 140*30fdc8d8SChris Lattner 141*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 142*30fdc8d8SChris Lattner // GetMax32 143*30fdc8d8SChris Lattner // 144*30fdc8d8SChris Lattner // Used for calls when the size can vary. Fill in extra cases if they 145*30fdc8d8SChris Lattner // are ever needed. 146*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 147*30fdc8d8SChris Lattner uint32_t 148*30fdc8d8SChris Lattner DNBDataRef::GetMax32(offset_t *offset_ptr, uint32_t byte_size) const 149*30fdc8d8SChris Lattner { 150*30fdc8d8SChris Lattner switch (byte_size) 151*30fdc8d8SChris Lattner { 152*30fdc8d8SChris Lattner case 1: return Get8 (offset_ptr); break; 153*30fdc8d8SChris Lattner case 2: return Get16(offset_ptr); break; 154*30fdc8d8SChris Lattner case 4: return Get32(offset_ptr); break; 155*30fdc8d8SChris Lattner default: 156*30fdc8d8SChris Lattner assert(!"GetMax32 unhandled case!"); 157*30fdc8d8SChris Lattner break; 158*30fdc8d8SChris Lattner } 159*30fdc8d8SChris Lattner return 0; 160*30fdc8d8SChris Lattner } 161*30fdc8d8SChris Lattner 162*30fdc8d8SChris Lattner 163*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 164*30fdc8d8SChris Lattner // GetMax64 165*30fdc8d8SChris Lattner // 166*30fdc8d8SChris Lattner // Used for calls when the size can vary. Fill in extra cases if they 167*30fdc8d8SChris Lattner // are ever needed. 168*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 169*30fdc8d8SChris Lattner uint64_t 170*30fdc8d8SChris Lattner DNBDataRef::GetMax64(offset_t *offset_ptr, uint32_t size) const 171*30fdc8d8SChris Lattner { 172*30fdc8d8SChris Lattner switch (size) 173*30fdc8d8SChris Lattner { 174*30fdc8d8SChris Lattner case 1: return Get8 (offset_ptr); break; 175*30fdc8d8SChris Lattner case 2: return Get16(offset_ptr); break; 176*30fdc8d8SChris Lattner case 4: return Get32(offset_ptr); break; 177*30fdc8d8SChris Lattner case 8: return Get64(offset_ptr); break; 178*30fdc8d8SChris Lattner default: 179*30fdc8d8SChris Lattner assert(!"GetMax64 unhandled case!"); 180*30fdc8d8SChris Lattner break; 181*30fdc8d8SChris Lattner } 182*30fdc8d8SChris Lattner return 0; 183*30fdc8d8SChris Lattner } 184*30fdc8d8SChris Lattner 185*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 186*30fdc8d8SChris Lattner // GetPointer 187*30fdc8d8SChris Lattner // 188*30fdc8d8SChris Lattner // Extract a pointer value from the buffer. The pointer size must be 189*30fdc8d8SChris Lattner // set prior to using this using one of the SetPointerSize functions. 190*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 191*30fdc8d8SChris Lattner uint64_t 192*30fdc8d8SChris Lattner DNBDataRef::GetPointer(offset_t *offset_ptr) const 193*30fdc8d8SChris Lattner { 194*30fdc8d8SChris Lattner // Must set pointer size prior to using this call 195*30fdc8d8SChris Lattner assert(m_ptrSize != 0); 196*30fdc8d8SChris Lattner return GetMax64(offset_ptr, m_ptrSize); 197*30fdc8d8SChris Lattner } 198*30fdc8d8SChris Lattner 199*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 200*30fdc8d8SChris Lattner // GetDwarfEHPtr 201*30fdc8d8SChris Lattner // 202*30fdc8d8SChris Lattner // Used for calls when the value type is specified by a DWARF EH Frame 203*30fdc8d8SChris Lattner // pointer encoding. 204*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 205*30fdc8d8SChris Lattner /* 206*30fdc8d8SChris Lattner uint64_t 207*30fdc8d8SChris Lattner DNBDataRef::GetDwarfEHPtr(offset_t *offset_ptr, uint32_t encoding) const 208*30fdc8d8SChris Lattner { 209*30fdc8d8SChris Lattner if (encoding == DW_EH_PE_omit) 210*30fdc8d8SChris Lattner return ULONG_LONG_MAX; // Value isn't in the buffer... 211*30fdc8d8SChris Lattner 212*30fdc8d8SChris Lattner uint64_t baseAddress = 0; 213*30fdc8d8SChris Lattner uint64_t addressValue = 0; 214*30fdc8d8SChris Lattner 215*30fdc8d8SChris Lattner BOOL signExtendValue = NO; 216*30fdc8d8SChris Lattner // Decode the base part or adjust our offset 217*30fdc8d8SChris Lattner switch (encoding & 0x70) 218*30fdc8d8SChris Lattner { 219*30fdc8d8SChris Lattner case DW_EH_PE_pcrel: 220*30fdc8d8SChris Lattner // SetEHPtrBaseAddresses should be called prior to extracting these 221*30fdc8d8SChris Lattner // so the base addresses are cached. 222*30fdc8d8SChris Lattner assert(m_addrPCRelative != INVALID_NUB_ADDRESS); 223*30fdc8d8SChris Lattner signExtendValue = YES; 224*30fdc8d8SChris Lattner baseAddress = *offset_ptr + m_addrPCRelative; 225*30fdc8d8SChris Lattner break; 226*30fdc8d8SChris Lattner 227*30fdc8d8SChris Lattner case DW_EH_PE_textrel: 228*30fdc8d8SChris Lattner // SetEHPtrBaseAddresses should be called prior to extracting these 229*30fdc8d8SChris Lattner // so the base addresses are cached. 230*30fdc8d8SChris Lattner assert(m_addrTEXT != INVALID_NUB_ADDRESS); 231*30fdc8d8SChris Lattner signExtendValue = YES; 232*30fdc8d8SChris Lattner baseAddress = m_addrTEXT; 233*30fdc8d8SChris Lattner break; 234*30fdc8d8SChris Lattner 235*30fdc8d8SChris Lattner case DW_EH_PE_datarel: 236*30fdc8d8SChris Lattner // SetEHPtrBaseAddresses should be called prior to extracting these 237*30fdc8d8SChris Lattner // so the base addresses are cached. 238*30fdc8d8SChris Lattner assert(m_addrDATA != INVALID_NUB_ADDRESS); 239*30fdc8d8SChris Lattner signExtendValue = YES; 240*30fdc8d8SChris Lattner baseAddress = m_addrDATA; 241*30fdc8d8SChris Lattner break; 242*30fdc8d8SChris Lattner 243*30fdc8d8SChris Lattner case DW_EH_PE_funcrel: 244*30fdc8d8SChris Lattner signExtendValue = YES; 245*30fdc8d8SChris Lattner break; 246*30fdc8d8SChris Lattner 247*30fdc8d8SChris Lattner case DW_EH_PE_aligned: 248*30fdc8d8SChris Lattner // SetPointerSize should be called prior to extracting these so the 249*30fdc8d8SChris Lattner // pointer size is cached 250*30fdc8d8SChris Lattner assert(m_ptrSize != 0); 251*30fdc8d8SChris Lattner if (m_ptrSize) 252*30fdc8d8SChris Lattner { 253*30fdc8d8SChris Lattner // Align to a address size boundary first 254*30fdc8d8SChris Lattner uint32_t alignOffset = *offset_ptr % m_ptrSize; 255*30fdc8d8SChris Lattner if (alignOffset) 256*30fdc8d8SChris Lattner offset_ptr += m_ptrSize - alignOffset; 257*30fdc8d8SChris Lattner } 258*30fdc8d8SChris Lattner break; 259*30fdc8d8SChris Lattner 260*30fdc8d8SChris Lattner default: 261*30fdc8d8SChris Lattner break; 262*30fdc8d8SChris Lattner } 263*30fdc8d8SChris Lattner 264*30fdc8d8SChris Lattner // Decode the value part 265*30fdc8d8SChris Lattner switch (encoding & DW_EH_PE_MASK_ENCODING) 266*30fdc8d8SChris Lattner { 267*30fdc8d8SChris Lattner case DW_EH_PE_absptr : addressValue = GetPointer(offset_ptr); break; 268*30fdc8d8SChris Lattner case DW_EH_PE_uleb128 : addressValue = Get_ULEB128(offset_ptr); break; 269*30fdc8d8SChris Lattner case DW_EH_PE_udata2 : addressValue = Get16(offset_ptr); break; 270*30fdc8d8SChris Lattner case DW_EH_PE_udata4 : addressValue = Get32(offset_ptr); break; 271*30fdc8d8SChris Lattner case DW_EH_PE_udata8 : addressValue = Get64(offset_ptr); break; 272*30fdc8d8SChris Lattner case DW_EH_PE_sleb128 : addressValue = Get_SLEB128(offset_ptr); break; 273*30fdc8d8SChris Lattner case DW_EH_PE_sdata2 : addressValue = (int16_t)Get16(offset_ptr); break; 274*30fdc8d8SChris Lattner case DW_EH_PE_sdata4 : addressValue = (int32_t)Get32(offset_ptr); break; 275*30fdc8d8SChris Lattner case DW_EH_PE_sdata8 : addressValue = (int64_t)Get64(offset_ptr); break; 276*30fdc8d8SChris Lattner default: 277*30fdc8d8SChris Lattner // Unhandled encoding type 278*30fdc8d8SChris Lattner assert(encoding); 279*30fdc8d8SChris Lattner break; 280*30fdc8d8SChris Lattner } 281*30fdc8d8SChris Lattner 282*30fdc8d8SChris Lattner // Since we promote everything to 64 bit, we may need to sign extend 283*30fdc8d8SChris Lattner if (signExtendValue && m_ptrSize < sizeof(baseAddress)) 284*30fdc8d8SChris Lattner { 285*30fdc8d8SChris Lattner uint64_t sign_bit = 1ull << ((m_ptrSize * 8ull) - 1ull); 286*30fdc8d8SChris Lattner if (sign_bit & addressValue) 287*30fdc8d8SChris Lattner { 288*30fdc8d8SChris Lattner uint64_t mask = ~sign_bit + 1; 289*30fdc8d8SChris Lattner addressValue |= mask; 290*30fdc8d8SChris Lattner } 291*30fdc8d8SChris Lattner } 292*30fdc8d8SChris Lattner return baseAddress + addressValue; 293*30fdc8d8SChris Lattner } 294*30fdc8d8SChris Lattner */ 295*30fdc8d8SChris Lattner 296*30fdc8d8SChris Lattner 297*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 298*30fdc8d8SChris Lattner // GetCStr 299*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 300*30fdc8d8SChris Lattner const char * 301*30fdc8d8SChris Lattner DNBDataRef::GetCStr(offset_t *offset_ptr, uint32_t fixed_length) const 302*30fdc8d8SChris Lattner { 303*30fdc8d8SChris Lattner const char *s = NULL; 304*30fdc8d8SChris Lattner if ( m_start < m_end ) 305*30fdc8d8SChris Lattner { 306*30fdc8d8SChris Lattner s = (char*)m_start + *offset_ptr; 307*30fdc8d8SChris Lattner 308*30fdc8d8SChris Lattner // Advance the offset 309*30fdc8d8SChris Lattner if (fixed_length) 310*30fdc8d8SChris Lattner *offset_ptr += fixed_length; 311*30fdc8d8SChris Lattner else 312*30fdc8d8SChris Lattner *offset_ptr += strlen(s) + 1; 313*30fdc8d8SChris Lattner } 314*30fdc8d8SChris Lattner return s; 315*30fdc8d8SChris Lattner } 316*30fdc8d8SChris Lattner 317*30fdc8d8SChris Lattner 318*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 319*30fdc8d8SChris Lattner // GetData 320*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 321*30fdc8d8SChris Lattner const uint8_t * 322*30fdc8d8SChris Lattner DNBDataRef::GetData(offset_t *offset_ptr, uint32_t length) const 323*30fdc8d8SChris Lattner { 324*30fdc8d8SChris Lattner const uint8_t *data = NULL; 325*30fdc8d8SChris Lattner if ( length > 0 && ValidOffsetForDataOfSize(*offset_ptr, length) ) 326*30fdc8d8SChris Lattner { 327*30fdc8d8SChris Lattner data = m_start + *offset_ptr; 328*30fdc8d8SChris Lattner *offset_ptr += length; 329*30fdc8d8SChris Lattner } 330*30fdc8d8SChris Lattner return data; 331*30fdc8d8SChris Lattner } 332*30fdc8d8SChris Lattner 333*30fdc8d8SChris Lattner 334*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 335*30fdc8d8SChris Lattner // Get_ULEB128 336*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 337*30fdc8d8SChris Lattner uint64_t 338*30fdc8d8SChris Lattner DNBDataRef::Get_ULEB128 (offset_t *offset_ptr) const 339*30fdc8d8SChris Lattner { 340*30fdc8d8SChris Lattner uint64_t result = 0; 341*30fdc8d8SChris Lattner if ( m_start < m_end ) 342*30fdc8d8SChris Lattner { 343*30fdc8d8SChris Lattner int shift = 0; 344*30fdc8d8SChris Lattner const uint8_t *src = m_start + *offset_ptr; 345*30fdc8d8SChris Lattner uint8_t byte; 346*30fdc8d8SChris Lattner int bytecount = 0; 347*30fdc8d8SChris Lattner 348*30fdc8d8SChris Lattner while (src < m_end) 349*30fdc8d8SChris Lattner { 350*30fdc8d8SChris Lattner bytecount++; 351*30fdc8d8SChris Lattner byte = *src++; 352*30fdc8d8SChris Lattner result |= (byte & 0x7f) << shift; 353*30fdc8d8SChris Lattner shift += 7; 354*30fdc8d8SChris Lattner if ((byte & 0x80) == 0) 355*30fdc8d8SChris Lattner break; 356*30fdc8d8SChris Lattner } 357*30fdc8d8SChris Lattner 358*30fdc8d8SChris Lattner *offset_ptr += bytecount; 359*30fdc8d8SChris Lattner } 360*30fdc8d8SChris Lattner return result; 361*30fdc8d8SChris Lattner } 362*30fdc8d8SChris Lattner 363*30fdc8d8SChris Lattner 364*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 365*30fdc8d8SChris Lattner // Get_SLEB128 366*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 367*30fdc8d8SChris Lattner int64_t 368*30fdc8d8SChris Lattner DNBDataRef::Get_SLEB128 (offset_t *offset_ptr) const 369*30fdc8d8SChris Lattner { 370*30fdc8d8SChris Lattner int64_t result = 0; 371*30fdc8d8SChris Lattner 372*30fdc8d8SChris Lattner if ( m_start < m_end ) 373*30fdc8d8SChris Lattner { 374*30fdc8d8SChris Lattner int shift = 0; 375*30fdc8d8SChris Lattner int size = sizeof (uint32_t) * 8; 376*30fdc8d8SChris Lattner const uint8_t *src = m_start + *offset_ptr; 377*30fdc8d8SChris Lattner 378*30fdc8d8SChris Lattner uint8_t byte; 379*30fdc8d8SChris Lattner int bytecount = 0; 380*30fdc8d8SChris Lattner 381*30fdc8d8SChris Lattner while (src < m_end) 382*30fdc8d8SChris Lattner { 383*30fdc8d8SChris Lattner bytecount++; 384*30fdc8d8SChris Lattner byte = *src++; 385*30fdc8d8SChris Lattner result |= (byte & 0x7f) << shift; 386*30fdc8d8SChris Lattner shift += 7; 387*30fdc8d8SChris Lattner if ((byte & 0x80) == 0) 388*30fdc8d8SChris Lattner break; 389*30fdc8d8SChris Lattner } 390*30fdc8d8SChris Lattner 391*30fdc8d8SChris Lattner // Sign bit of byte is 2nd high order bit (0x40) 392*30fdc8d8SChris Lattner if (shift < size && (byte & 0x40)) 393*30fdc8d8SChris Lattner result |= - (1ll << shift); 394*30fdc8d8SChris Lattner 395*30fdc8d8SChris Lattner *offset_ptr += bytecount; 396*30fdc8d8SChris Lattner } 397*30fdc8d8SChris Lattner return result; 398*30fdc8d8SChris Lattner } 399*30fdc8d8SChris Lattner 400*30fdc8d8SChris Lattner 401*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 402*30fdc8d8SChris Lattner // Skip_LEB128 403*30fdc8d8SChris Lattner // 404*30fdc8d8SChris Lattner // Skips past ULEB128 and SLEB128 numbers (just updates the offset) 405*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 406*30fdc8d8SChris Lattner void 407*30fdc8d8SChris Lattner DNBDataRef::Skip_LEB128 (offset_t *offset_ptr) const 408*30fdc8d8SChris Lattner { 409*30fdc8d8SChris Lattner if ( m_start < m_end ) 410*30fdc8d8SChris Lattner { 411*30fdc8d8SChris Lattner const uint8_t *start = m_start + *offset_ptr; 412*30fdc8d8SChris Lattner const uint8_t *src = start; 413*30fdc8d8SChris Lattner 414*30fdc8d8SChris Lattner while ((src < m_end) && (*src++ & 0x80)) 415*30fdc8d8SChris Lattner /* Do nothing */; 416*30fdc8d8SChris Lattner 417*30fdc8d8SChris Lattner *offset_ptr += src - start; 418*30fdc8d8SChris Lattner } 419*30fdc8d8SChris Lattner } 420*30fdc8d8SChris Lattner 421*30fdc8d8SChris Lattner uint32_t 422*30fdc8d8SChris Lattner DNBDataRef::Dump 423*30fdc8d8SChris Lattner ( 424*30fdc8d8SChris Lattner uint32_t startOffset, 425*30fdc8d8SChris Lattner uint32_t endOffset, 426*30fdc8d8SChris Lattner uint64_t offsetBase, 427*30fdc8d8SChris Lattner DNBDataRef::Type type, 428*30fdc8d8SChris Lattner uint32_t numPerLine, 429*30fdc8d8SChris Lattner const char *format 430*30fdc8d8SChris Lattner ) 431*30fdc8d8SChris Lattner { 432*30fdc8d8SChris Lattner uint32_t offset; 433*30fdc8d8SChris Lattner uint32_t count; 434*30fdc8d8SChris Lattner char str[1024]; 435*30fdc8d8SChris Lattner str[0] = '\0'; 436*30fdc8d8SChris Lattner int str_offset = 0; 437*30fdc8d8SChris Lattner 438*30fdc8d8SChris Lattner for (offset = startOffset, count = 0; ValidOffset(offset) && offset < endOffset; ++count) 439*30fdc8d8SChris Lattner { 440*30fdc8d8SChris Lattner if ((count % numPerLine) == 0) 441*30fdc8d8SChris Lattner { 442*30fdc8d8SChris Lattner // Print out any previous string 443*30fdc8d8SChris Lattner if (str[0] != '\0') 444*30fdc8d8SChris Lattner DNBLog("%s", str); 445*30fdc8d8SChris Lattner // Reset string offset and fill the current line string with address: 446*30fdc8d8SChris Lattner str_offset = 0; 447*30fdc8d8SChris Lattner str_offset += snprintf(str, sizeof(str), "0x%8.8llx:", (uint64_t)(offsetBase + (offset - startOffset))); 448*30fdc8d8SChris Lattner } 449*30fdc8d8SChris Lattner 450*30fdc8d8SChris Lattner // Make sure we don't pass the bounds of our current string buffer on each iteration through this loop 451*30fdc8d8SChris Lattner if (str_offset >= sizeof(str)) 452*30fdc8d8SChris Lattner { 453*30fdc8d8SChris Lattner // The last snprintf consumed our string buffer, we will need to dump this out 454*30fdc8d8SChris Lattner // and reset the string with no address 455*30fdc8d8SChris Lattner DNBLog("%s", str); 456*30fdc8d8SChris Lattner str_offset = 0; 457*30fdc8d8SChris Lattner str[0] = '\0'; 458*30fdc8d8SChris Lattner } 459*30fdc8d8SChris Lattner 460*30fdc8d8SChris Lattner // We already checked that there is at least some room in the string str above, so it is safe to make 461*30fdc8d8SChris Lattner // the snprintf call each time through this loop 462*30fdc8d8SChris Lattner switch (type) 463*30fdc8d8SChris Lattner { 464*30fdc8d8SChris Lattner default: 465*30fdc8d8SChris Lattner case TypeUInt8: str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " %2.2x", Get8(&offset)); break; 466*30fdc8d8SChris Lattner case TypeChar: 467*30fdc8d8SChris Lattner { 468*30fdc8d8SChris Lattner char ch = Get8(&offset); 469*30fdc8d8SChris Lattner str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " %c", isprint(ch) ? ch : ' '); 470*30fdc8d8SChris Lattner } 471*30fdc8d8SChris Lattner break; 472*30fdc8d8SChris Lattner case TypeUInt16: str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " %4.4x", Get16(&offset)); break; 473*30fdc8d8SChris Lattner case TypeUInt32: str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " %8.8x", Get32(&offset)); break; 474*30fdc8d8SChris Lattner case TypeUInt64: str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " %16.16llx", Get64(&offset)); break; 475*30fdc8d8SChris Lattner case TypePointer: str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " 0x%llx", GetPointer(&offset)); break; 476*30fdc8d8SChris Lattner case TypeULEB128: str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " 0x%llx", Get_ULEB128(&offset)); break; 477*30fdc8d8SChris Lattner case TypeSLEB128: str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " %lld", Get_SLEB128(&offset)); break; 478*30fdc8d8SChris Lattner } 479*30fdc8d8SChris Lattner } 480*30fdc8d8SChris Lattner 481*30fdc8d8SChris Lattner if (str[0] != '\0') 482*30fdc8d8SChris Lattner DNBLog("%s", str); 483*30fdc8d8SChris Lattner 484*30fdc8d8SChris Lattner return offset; // Return the offset at which we ended up 485*30fdc8d8SChris Lattner } 486