[clang] Fix implicit integer conversion for opaque enums declared in class templates...
[llvm-project.git] / lldb / tools / debugserver / source / DNBDataRef.cpp
blob13ffd25e1bf2cec5ad42f70139076e1d5e2c5b9c
1 //===-- DNBDataRef.cpp ------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Created by Greg Clayton on 1/11/06.
11 //===----------------------------------------------------------------------===//
13 #include "DNBDataRef.h"
14 #include "DNBLog.h"
15 #include <cassert>
16 #include <cctype>
17 #include <libkern/OSByteOrder.h>
19 // Constructor
21 DNBDataRef::DNBDataRef()
22 : m_start(NULL), m_end(NULL), m_swap(false), m_ptrSize(0),
23 m_addrPCRelative(INVALID_NUB_ADDRESS), m_addrTEXT(INVALID_NUB_ADDRESS),
24 m_addrDATA(INVALID_NUB_ADDRESS) {}
26 // Constructor
28 DNBDataRef::DNBDataRef(const uint8_t *start, size_t size, bool swap)
29 : m_start(start), m_end(start + size), m_swap(swap), m_ptrSize(0),
30 m_addrPCRelative(INVALID_NUB_ADDRESS), m_addrTEXT(INVALID_NUB_ADDRESS),
31 m_addrDATA(INVALID_NUB_ADDRESS) {}
33 // Destructor
35 DNBDataRef::~DNBDataRef() = default;
37 // Get8
38 uint8_t DNBDataRef::Get8(offset_t *offset_ptr) const {
39 uint8_t val = 0;
40 if (ValidOffsetForDataOfSize(*offset_ptr, sizeof(val))) {
41 val = *(m_start + *offset_ptr);
42 *offset_ptr += sizeof(val);
44 return val;
47 // Get16
48 uint16_t DNBDataRef::Get16(offset_t *offset_ptr) const {
49 uint16_t val = 0;
50 if (ValidOffsetForDataOfSize(*offset_ptr, sizeof(val))) {
51 const uint8_t *p = m_start + *offset_ptr;
52 memcpy(&val, p, sizeof(uint16_t));
54 if (m_swap)
55 val = OSSwapInt16(val);
57 // Advance the offset
58 *offset_ptr += sizeof(val);
60 return val;
63 // Get32
64 uint32_t DNBDataRef::Get32(offset_t *offset_ptr) const {
65 uint32_t val = 0;
66 if (ValidOffsetForDataOfSize(*offset_ptr, sizeof(val))) {
67 const uint8_t *p = m_start + *offset_ptr;
68 memcpy(&val, p, sizeof(uint32_t));
69 if (m_swap)
70 val = OSSwapInt32(val);
72 // Advance the offset
73 *offset_ptr += sizeof(val);
75 return val;
78 // Get64
79 uint64_t DNBDataRef::Get64(offset_t *offset_ptr) const {
80 uint64_t val = 0;
81 if (ValidOffsetForDataOfSize(*offset_ptr, sizeof(val))) {
82 const uint8_t *p = m_start + *offset_ptr;
83 memcpy(&val, p, sizeof(uint64_t));
84 if (m_swap)
85 val = OSSwapInt64(val);
87 // Advance the offset
88 *offset_ptr += sizeof(val);
90 return val;
93 // GetMax32
95 // Used for calls when the size can vary. Fill in extra cases if they
96 // are ever needed.
97 uint32_t DNBDataRef::GetMax32(offset_t *offset_ptr, uint32_t byte_size) const {
98 switch (byte_size) {
99 case 1:
100 return Get8(offset_ptr);
101 break;
102 case 2:
103 return Get16(offset_ptr);
104 break;
105 case 4:
106 return Get32(offset_ptr);
107 break;
108 default:
109 assert(false && "GetMax32 unhandled case!");
110 break;
112 return 0;
115 // GetMax64
117 // Used for calls when the size can vary. Fill in extra cases if they
118 // are ever needed.
119 uint64_t DNBDataRef::GetMax64(offset_t *offset_ptr, uint32_t size) const {
120 switch (size) {
121 case 1:
122 return Get8(offset_ptr);
123 break;
124 case 2:
125 return Get16(offset_ptr);
126 break;
127 case 4:
128 return Get32(offset_ptr);
129 break;
130 case 8:
131 return Get64(offset_ptr);
132 break;
133 default:
134 assert(false && "GetMax64 unhandled case!");
135 break;
137 return 0;
140 // GetPointer
142 // Extract a pointer value from the buffer. The pointer size must be
143 // set prior to using this using one of the SetPointerSize functions.
144 uint64_t DNBDataRef::GetPointer(offset_t *offset_ptr) const {
145 // Must set pointer size prior to using this call
146 assert(m_ptrSize != 0);
147 return GetMax64(offset_ptr, m_ptrSize);
149 // GetCStr
150 const char *DNBDataRef::GetCStr(offset_t *offset_ptr,
151 uint32_t fixed_length) const {
152 const char *s = NULL;
153 if (m_start < m_end) {
154 s = (const char *)m_start + *offset_ptr;
156 // Advance the offset
157 if (fixed_length)
158 *offset_ptr += fixed_length;
159 else
160 *offset_ptr += strlen(s) + 1;
162 return s;
165 // GetData
166 const uint8_t *DNBDataRef::GetData(offset_t *offset_ptr,
167 uint32_t length) const {
168 const uint8_t *data = NULL;
169 if (length > 0 && ValidOffsetForDataOfSize(*offset_ptr, length)) {
170 data = m_start + *offset_ptr;
171 *offset_ptr += length;
173 return data;
176 // Get_ULEB128
177 uint64_t DNBDataRef::Get_ULEB128(offset_t *offset_ptr) const {
178 uint64_t result = 0;
179 if (m_start < m_end) {
180 int shift = 0;
181 const uint8_t *src = m_start + *offset_ptr;
182 uint8_t byte;
183 int bytecount = 0;
185 while (src < m_end) {
186 bytecount++;
187 byte = *src++;
188 result |= (uint64_t)(byte & 0x7f) << shift;
189 shift += 7;
190 if ((byte & 0x80) == 0)
191 break;
194 *offset_ptr += bytecount;
196 return result;
199 // Get_SLEB128
200 int64_t DNBDataRef::Get_SLEB128(offset_t *offset_ptr) const {
201 int64_t result = 0;
203 if (m_start < m_end) {
204 int shift = 0;
205 int size = sizeof(uint32_t) * 8;
206 const uint8_t *src = m_start + *offset_ptr;
208 uint8_t byte = 0;
209 int bytecount = 0;
211 while (src < m_end) {
212 bytecount++;
213 byte = *src++;
214 result |= (int64_t)(byte & 0x7f) << shift;
215 shift += 7;
216 if ((byte & 0x80) == 0)
217 break;
220 // Sign bit of byte is 2nd high order bit (0x40)
221 if (shift < size && (byte & 0x40))
222 result |= -(1ll << shift);
224 *offset_ptr += bytecount;
226 return result;
229 // Skip_LEB128
231 // Skips past ULEB128 and SLEB128 numbers (just updates the offset)
232 void DNBDataRef::Skip_LEB128(offset_t *offset_ptr) const {
233 if (m_start < m_end) {
234 const uint8_t *start = m_start + *offset_ptr;
235 const uint8_t *src = start;
237 while ((src < m_end) && (*src++ & 0x80))
238 /* Do nothing */;
240 *offset_ptr += src - start;
244 uint32_t DNBDataRef::Dump(uint32_t startOffset, uint32_t endOffset,
245 uint64_t offsetBase, DNBDataRef::Type type,
246 uint32_t numPerLine, const char *format) {
247 uint32_t offset;
248 uint32_t count;
249 char str[1024];
250 str[0] = '\0';
251 size_t str_offset = 0;
253 for (offset = startOffset, count = 0;
254 ValidOffset(offset) && offset < endOffset; ++count) {
255 if ((count % numPerLine) == 0) {
256 // Print out any previous string
257 if (str[0] != '\0')
258 DNBLog("%s", str);
259 // Reset string offset and fill the current line string with address:
260 str_offset = 0;
261 str_offset += snprintf(str, sizeof(str), "0x%8.8llx:",
262 (uint64_t)(offsetBase + (offset - startOffset)));
265 // Make sure we don't pass the bounds of our current string buffer on each
266 // iteration through this loop
267 if (str_offset >= sizeof(str)) {
268 // The last snprintf consumed our string buffer, we will need to dump this
269 // out
270 // and reset the string with no address
271 DNBLog("%s", str);
272 str_offset = 0;
273 str[0] = '\0';
276 // We already checked that there is at least some room in the string str
277 // above, so it is safe to make
278 // the snprintf call each time through this loop
279 switch (type) {
280 case TypeUInt8:
281 str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
282 format ? format : " %2.2x", Get8(&offset));
283 break;
284 case TypeChar: {
285 char ch = Get8(&offset);
286 str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
287 format ? format : " %c", isprint(ch) ? ch : ' ');
288 } break;
289 case TypeUInt16:
290 str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
291 format ? format : " %4.4x", Get16(&offset));
292 break;
293 case TypeUInt32:
294 str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
295 format ? format : " %8.8x", Get32(&offset));
296 break;
297 case TypeUInt64:
298 str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
299 format ? format : " %16.16llx", Get64(&offset));
300 break;
301 case TypePointer:
302 str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
303 format ? format : " 0x%llx", GetPointer(&offset));
304 break;
305 case TypeULEB128:
306 str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
307 format ? format : " 0x%llx", Get_ULEB128(&offset));
308 break;
309 case TypeSLEB128:
310 str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
311 format ? format : " %lld", Get_SLEB128(&offset));
312 break;
316 if (str[0] != '\0')
317 DNBLog("%s", str);
319 return offset; // Return the offset at which we ended up