/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Target/ProcessStructReader.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===---------------------ProcessStructReader.h ------------------*- 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 | | #ifndef LLDB_TARGET_PROCESSSTRUCTREADER_H |
10 | | #define LLDB_TARGET_PROCESSSTRUCTREADER_H |
11 | | |
12 | | #include "lldb/lldb-defines.h" |
13 | | #include "lldb/lldb-types.h" |
14 | | |
15 | | #include "lldb/Symbol/CompilerType.h" |
16 | | #include "lldb/Target/Process.h" |
17 | | #include "lldb/Utility/DataBufferHeap.h" |
18 | | #include "lldb/Utility/DataExtractor.h" |
19 | | #include "lldb/Utility/Status.h" |
20 | | |
21 | | #include "llvm/ADT/StringMap.h" |
22 | | |
23 | | #include <initializer_list> |
24 | | #include <map> |
25 | | #include <string> |
26 | | |
27 | | namespace lldb_private { |
28 | | class ProcessStructReader { |
29 | | protected: |
30 | | struct FieldImpl { |
31 | | CompilerType type; |
32 | | size_t offset; |
33 | | size_t size; |
34 | | }; |
35 | | |
36 | | llvm::StringMap<FieldImpl> m_fields; |
37 | | DataExtractor m_data; |
38 | | lldb::ByteOrder m_byte_order; |
39 | | size_t m_addr_byte_size; |
40 | | |
41 | | public: |
42 | | ProcessStructReader(Process *process, lldb::addr_t base_addr, |
43 | | CompilerType struct_type) |
44 | 894 | : m_byte_order(lldb::eByteOrderInvalid), m_addr_byte_size(0) { |
45 | 894 | if (!process) |
46 | 0 | return; |
47 | 894 | if (base_addr == 0 || base_addr == LLDB_INVALID_ADDRESS) |
48 | 0 | return; |
49 | 894 | m_byte_order = process->GetByteOrder(); |
50 | 894 | m_addr_byte_size = process->GetAddressByteSize(); |
51 | | |
52 | 4.47k | for (size_t idx = 0; idx < struct_type.GetNumFields(); idx++3.57k ) { |
53 | 3.57k | std::string name; |
54 | 3.57k | uint64_t bit_offset; |
55 | 3.57k | uint32_t bitfield_bit_size; |
56 | 3.57k | bool is_bitfield; |
57 | 3.57k | CompilerType field_type = struct_type.GetFieldAtIndex( |
58 | 3.57k | idx, name, &bit_offset, &bitfield_bit_size, &is_bitfield); |
59 | | // no support for bitfields in here (yet) |
60 | 3.57k | if (is_bitfield) |
61 | 0 | return; |
62 | 3.57k | auto size = field_type.GetByteSize(nullptr); |
63 | | // no support for things larger than a uint64_t (yet) |
64 | 3.57k | if (!size || *size > 8) |
65 | 0 | return; |
66 | 3.57k | size_t byte_index = static_cast<size_t>(bit_offset / 8); |
67 | 3.57k | m_fields.insert({name, FieldImpl{field_type, byte_index, |
68 | 3.57k | static_cast<size_t>(*size)}}); |
69 | 3.57k | } |
70 | 894 | auto total_size = struct_type.GetByteSize(nullptr); |
71 | 894 | if (!total_size) |
72 | 0 | return; |
73 | 894 | lldb::WritableDataBufferSP buffer_sp(new DataBufferHeap(*total_size, 0)); |
74 | 894 | Status error; |
75 | 894 | process->ReadMemoryFromInferior(base_addr, buffer_sp->GetBytes(), |
76 | 894 | *total_size, error); |
77 | 894 | if (error.Fail()) |
78 | 0 | return; |
79 | 894 | m_data = DataExtractor(buffer_sp, m_byte_order, m_addr_byte_size); |
80 | 894 | } |
81 | | |
82 | | template <typename RetType> |
83 | 3.57k | RetType GetField(llvm::StringRef name, RetType fail_value = RetType()) { |
84 | 3.57k | auto iter = m_fields.find(name), end = m_fields.end(); |
85 | 3.57k | if (iter == end) |
86 | 0 | return fail_value; |
87 | 3.57k | auto size = iter->second.size; |
88 | 3.57k | if (sizeof(RetType) < size) |
89 | 0 | return fail_value; |
90 | 3.57k | lldb::offset_t offset = iter->second.offset; |
91 | 3.57k | if (offset + size > m_data.GetByteSize()) |
92 | 0 | return fail_value; |
93 | 3.57k | return (RetType)(m_data.GetMaxU64(&offset, size)); |
94 | 3.57k | } |
95 | | }; |
96 | | } |
97 | | |
98 | | #endif // LLDB_TARGET_PROCESSSTRUCTREADER_H |