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