1//===-- DNBDataRef.h --------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  Created by Greg Clayton on 1/11/06.
11//
12//===----------------------------------------------------------------------===//
13//
14//  DNBDataRef is a class that can extract data in normal or byte
15//  swapped order from a data buffer that someone else owns. The data
16//  buffer needs to remain intact as long as the DNBDataRef object
17//  needs the data. Strings returned are pointers into the data buffer
18//  and will need to be copied if they are needed after the data buffer
19//  is no longer around.
20//
21//===----------------------------------------------------------------------===//
22
23#ifndef __DNBDataRef_h__
24#define __DNBDataRef_h__
25
26#include "DNBDefs.h"
27#include <stdint.h>
28#include <stdio.h>
29#include <string.h>
30#include <limits.h>
31
32class DNBDataRef
33{
34public:
35    // For use with Dump
36    typedef enum
37    {
38        TypeUInt8 = 0,
39        TypeChar,
40        TypeUInt16,
41        TypeUInt32,
42        TypeUInt64,
43        TypePointer,
44        TypeULEB128,
45        TypeSLEB128
46    }   Type;
47    typedef uint32_t offset_t;
48    typedef nub_addr_t addr_t;
49
50                    DNBDataRef();
51                    DNBDataRef(const uint8_t *start, size_t size, bool swap);
52                    ~DNBDataRef();
53        void        Clear()
54                    {
55                        DNBDataRef::SetData(NULL, 0);
56                        m_swap = false;
57                    }
58
59    offset_t        BytesLeft (offset_t offset) const
60                    {
61                        const offset_t size = GetSize();
62                        if (size > offset)
63                            return size - offset;
64                        return 0;
65                    }
66
67    bool            ValidOffset(offset_t offset) const
68                    {
69                        return BytesLeft(offset) > 0;
70                    }
71    bool            ValidOffsetForDataOfSize(offset_t offset, uint32_t num_bytes) const
72                    {
73                        return num_bytes <= BytesLeft (offset);
74                    }
75    size_t          GetSize() const { return m_end - m_start; }
76    const uint8_t * GetDataStart() const { return m_start; }
77    const uint8_t * GetDataEnd() const { return m_end; }
78    bool            GetSwap() const { return m_swap; }
79    void            SetSwap(bool swap) { m_swap = swap; }
80    void            SetData(const uint8_t *start, size_t size)
81                    {
82                        m_start = start;
83                        if (m_start != NULL)
84                            m_end = start + size;
85                        else
86                            m_end = NULL;
87                    }
88    uint8_t         GetPointerSize() const { return m_ptrSize; }
89    void            SetPointerSize(uint8_t size) { m_ptrSize = size; }
90    void            SetEHPtrBaseAddrPCRelative(addr_t addr = INVALID_NUB_ADDRESS) { m_addrPCRelative = addr; }
91    void            SetEHPtrBaseAddrTEXT(addr_t addr = INVALID_NUB_ADDRESS)  { m_addrTEXT = addr; }
92    void            SetEHPtrBaseAddrDATA(addr_t addr = INVALID_NUB_ADDRESS)  { m_addrDATA = addr; }
93    uint8_t         Get8(offset_t *offset_ptr) const;
94    uint16_t        Get16(offset_t *offset_ptr) const;
95    uint32_t        Get32(offset_t *offset_ptr) const;
96    uint64_t        Get64(offset_t *offset_ptr) const;
97    uint32_t        GetMax32(offset_t *offset_ptr, uint32_t byte_size) const;
98    uint64_t        GetMax64(offset_t *offset_ptr, uint32_t byte_size) const;
99    uint64_t        GetPointer(offset_t *offset_ptr) const;
100//  uint64_t        GetDwarfEHPtr(offset_t *offset_ptr, uint32_t eh_ptr_enc) const;
101    const char *    GetCStr(offset_t *offset_ptr, uint32_t fixed_length = 0) const;
102    const char *    PeekCStr(offset_t offset) const
103                    {
104                        if (ValidOffset(offset))
105                            return (const char*)m_start + offset;
106                        return NULL;
107                    }
108
109    const uint8_t * GetData( offset_t *offset_ptr, uint32_t length) const;
110    uint64_t        Get_ULEB128 (offset_t *offset_ptr) const;
111    int64_t         Get_SLEB128 (offset_t *offset_ptr) const;
112    void            Skip_LEB128 (offset_t *offset_ptr) const;
113
114    uint32_t        Dump(offset_t startOffset, offset_t endOffset, uint64_t offsetBase, DNBDataRef::Type type, uint32_t numPerLine, const char *typeFormat = NULL);
115protected:
116    const uint8_t * m_start;
117    const uint8_t * m_end;
118    bool            m_swap;
119    uint8_t         m_ptrSize;
120    addr_t          m_addrPCRelative;
121    addr_t          m_addrTEXT;
122    addr_t          m_addrDATA;
123};
124
125#endif // #ifndef __DNBDataRef_h__
126