1/*
2 * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2013, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef VALUE_LOCATION_H
7#define VALUE_LOCATION_H
8
9#include <vector>
10
11#include <stdlib.h>
12#include <string.h>
13
14#include <Referenceable.h>
15
16#include "Types.h"
17
18
19enum value_piece_location_type {
20	VALUE_PIECE_LOCATION_INVALID,	// structure is invalid
21	VALUE_PIECE_LOCATION_UNKNOWN,	// location unknown, but size is valid
22	VALUE_PIECE_LOCATION_MEMORY,	// piece is in memory
23	VALUE_PIECE_LOCATION_REGISTER,	// piece is in a register
24	VALUE_PIECE_LOCATION_IMPLICIT	// value isn't stored anywhere in memory but is known
25};
26
27
28struct ValuePieceLocation {
29	union {
30		target_addr_t			address;	// memory address
31		uint32					reg;		// register number
32	};
33	target_size_t				size;		// size in bytes (including
34											// incomplete ones)
35	uint64						bitSize;	// total size in bits
36	uint64						bitOffset;	// bit offset (to the most
37											// significant bit)
38	value_piece_location_type	type;
39	void*						value;		// used for storing implicit values
40	bool						writable;	// indicates if the piece is in a
41											// location in the target team
42											// where it can be modified
43
44
45	ValuePieceLocation()
46		:
47		type(VALUE_PIECE_LOCATION_INVALID),
48		value(NULL),
49		writable(false)
50	{
51	}
52
53	ValuePieceLocation(const ValuePieceLocation& other)
54	{
55		if (!Copy(other))
56			throw std::bad_alloc();
57	}
58
59	~ValuePieceLocation()
60	{
61		if (value != NULL)
62			free(value);
63	}
64
65	ValuePieceLocation& operator=(const ValuePieceLocation& other)
66	{
67		if (!Copy(other))
68			throw std::bad_alloc();
69
70		return *this;
71	}
72
73	bool Copy(const ValuePieceLocation& other)
74	{
75		memcpy((void*)this, (void*)&other, sizeof(ValuePieceLocation));
76		if (type == VALUE_PIECE_LOCATION_IMPLICIT) {
77			void* tempValue = malloc(size);
78			if (tempValue == NULL) {
79				type = VALUE_PIECE_LOCATION_INVALID;
80				return false;
81			}
82
83			memcpy(tempValue, value, other.size);
84			value = tempValue;
85		}
86
87		return true;
88	}
89
90	bool IsValid() const
91	{
92		return type != VALUE_PIECE_LOCATION_INVALID;
93	}
94
95	void SetToUnknown()
96	{
97		type = VALUE_PIECE_LOCATION_UNKNOWN;
98	}
99
100	void SetToMemory(target_addr_t address)
101	{
102		type = VALUE_PIECE_LOCATION_MEMORY;
103		this->address = address;
104		this->writable = true;
105	}
106
107	void SetToRegister(uint32 reg)
108	{
109		type = VALUE_PIECE_LOCATION_REGISTER;
110		this->reg = reg;
111		this->writable = true;
112	}
113
114	void SetSize(target_size_t size)
115	{
116		this->size = size;
117		this->bitSize = size * 8;
118		this->bitOffset = 0;
119	}
120
121	void SetSize(uint64 bitSize, uint64 bitOffset)
122	{
123		this->size = (bitOffset + bitSize + 7) / 8;
124		this->bitSize = bitSize;
125		this->bitOffset = bitOffset;
126	}
127
128	bool SetToValue(const void* data, target_size_t size)
129	{
130		char* valueData = (char*)malloc(size);
131		if (valueData == NULL)
132			return false;
133		memcpy(valueData, data, size);
134		SetSize(size);
135		type = VALUE_PIECE_LOCATION_IMPLICIT;
136		value = valueData;
137		writable = false;
138		return true;
139	}
140
141	ValuePieceLocation& Normalize(bool bigEndian);
142};
143
144
145class ValueLocation : public BReferenceable {
146public:
147								ValueLocation();
148								ValueLocation(bool bigEndian);
149								ValueLocation(bool bigEndian,
150									const ValuePieceLocation& piece);
151
152								ValueLocation(const ValueLocation& other);
153
154			bool				SetToByteOffset(const ValueLocation& other,
155									uint64 byteffset, uint64 Size);
156
157			bool				SetTo(const ValueLocation& other,
158									uint64 bitOffset, uint64 bitSize);
159
160			void				Clear();
161
162			bool				IsBigEndian() const	{ return fBigEndian; }
163			bool				IsWritable() const { return fWritable; }
164
165			bool				AddPiece(const ValuePieceLocation& piece);
166
167			int32				CountPieces() const;
168			ValuePieceLocation	PieceAt(int32 index) const;
169			bool				SetPieceAt(int32 index,
170									const ValuePieceLocation& piece);
171			ValueLocation&		operator=(const ValueLocation& other);
172
173			void				Dump() const;
174
175private:
176	typedef std::vector<ValuePieceLocation> PieceVector;
177
178private:
179			PieceVector			fPieces;
180			bool				fBigEndian;
181			bool				fWritable;
182};
183
184
185#endif	// VALUE_LOCATION_H
186