Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:54

0001 //===---------------------ProcessStructReader.h ------------------*- C++-*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_TARGET_PROCESSSTRUCTREADER_H
0010 #define LLDB_TARGET_PROCESSSTRUCTREADER_H
0011 
0012 #include "lldb/lldb-defines.h"
0013 #include "lldb/lldb-types.h"
0014 
0015 #include "lldb/Symbol/CompilerType.h"
0016 #include "lldb/Target/Process.h"
0017 #include "lldb/Utility/DataBufferHeap.h"
0018 #include "lldb/Utility/DataExtractor.h"
0019 #include "lldb/Utility/Status.h"
0020 
0021 #include "llvm/ADT/StringMap.h"
0022 
0023 #include <initializer_list>
0024 #include <map>
0025 #include <string>
0026 
0027 namespace lldb_private {
0028 class ProcessStructReader {
0029 protected:
0030   struct FieldImpl {
0031     CompilerType type;
0032     size_t offset;
0033     size_t size;
0034   };
0035 
0036   llvm::StringMap<FieldImpl> m_fields;
0037   DataExtractor m_data;
0038   lldb::ByteOrder m_byte_order;
0039   size_t m_addr_byte_size;
0040 
0041 public:
0042   ProcessStructReader(Process *process, lldb::addr_t base_addr,
0043                       CompilerType struct_type)
0044       : m_byte_order(lldb::eByteOrderInvalid), m_addr_byte_size(0) {
0045     if (!process)
0046       return;
0047     if (base_addr == 0 || base_addr == LLDB_INVALID_ADDRESS)
0048       return;
0049     m_byte_order = process->GetByteOrder();
0050     m_addr_byte_size = process->GetAddressByteSize();
0051 
0052     for (size_t idx = 0; idx < struct_type.GetNumFields(); idx++) {
0053       std::string name;
0054       uint64_t bit_offset;
0055       uint32_t bitfield_bit_size;
0056       bool is_bitfield;
0057       CompilerType field_type = struct_type.GetFieldAtIndex(
0058           idx, name, &bit_offset, &bitfield_bit_size, &is_bitfield);
0059       // no support for bitfields in here (yet)
0060       if (is_bitfield)
0061         return;
0062       auto size = field_type.GetByteSize(nullptr);
0063       // no support for things larger than a uint64_t (yet)
0064       if (!size || *size > 8)
0065         return;
0066       size_t byte_index = static_cast<size_t>(bit_offset / 8);
0067       m_fields.insert({name, FieldImpl{field_type, byte_index,
0068                                        static_cast<size_t>(*size)}});
0069     }
0070     auto total_size = struct_type.GetByteSize(nullptr);
0071     if (!total_size)
0072       return;
0073     lldb::WritableDataBufferSP buffer_sp(new DataBufferHeap(*total_size, 0));
0074     Status error;
0075     process->ReadMemoryFromInferior(base_addr, buffer_sp->GetBytes(),
0076                                     *total_size, error);
0077     if (error.Fail())
0078       return;
0079     m_data = DataExtractor(buffer_sp, m_byte_order, m_addr_byte_size);
0080   }
0081 
0082   template <typename RetType>
0083   RetType GetField(llvm::StringRef name, RetType fail_value = RetType()) {
0084     auto iter = m_fields.find(name), end = m_fields.end();
0085     if (iter == end)
0086       return fail_value;
0087     auto size = iter->second.size;
0088     if (sizeof(RetType) < size)
0089       return fail_value;
0090     lldb::offset_t offset = iter->second.offset;
0091     if (offset + size > m_data.GetByteSize())
0092       return fail_value;
0093     return (RetType)(m_data.GetMaxU64(&offset, size));
0094   }
0095 };
0096 }
0097 
0098 #endif // LLDB_TARGET_PROCESSSTRUCTREADER_H