⛏️ index : haiku.git

/*
 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
 * Distributed under the terms of the MIT License.
 */
#ifndef DWARF_EXPRESSION_EVALUATOR_H
#define DWARF_EXPRESSION_EVALUATOR_H


#include "DataReader.h"
#include "Types.h"


class DwarfTargetInterface;
class ValueLocation;
struct ValuePieceLocation;


class DwarfExpressionEvaluationContext {
public:
								DwarfExpressionEvaluationContext(
									const DwarfTargetInterface* targetInterface,
									uint8 addressSize,
									bool isBigEndian,
									target_addr_t relocationDelta);
	virtual						~DwarfExpressionEvaluationContext();

			const DwarfTargetInterface* TargetInterface() const
									{ return fTargetInterface; }
			uint8				AddressSize() const	{ return fAddressSize; }
			bool				IsBigEndian() const { return fIsBigEndian; }

			target_addr_t			RelocationDelta() const
									{ return fRelocationDelta; }

	virtual	bool				GetObjectAddress(target_addr_t& _address) = 0;
	virtual	bool				GetFrameAddress(target_addr_t& _address) = 0;
	virtual	bool				GetFrameBaseAddress(target_addr_t& _address)
									= 0;
	virtual	bool				GetTLSAddress(target_addr_t localAddress,
									target_addr_t& _address) = 0;

	virtual	status_t			GetCallTarget(uint64 offset,
									uint8 refType, const void*& _block,
									off_t& _size) = 0;
									// returns error, when an error resolving
									// the entry occurs; returns B_OK and a NULL
									// block, when the entry doesn't have a
									// location attribute

protected:
			const DwarfTargetInterface* fTargetInterface;
			uint8				fAddressSize;
			bool				fIsBigEndian;
			target_addr_t		fRelocationDelta;
};


class DwarfExpressionEvaluator {
public:
								DwarfExpressionEvaluator(
									DwarfExpressionEvaluationContext* context);
								~DwarfExpressionEvaluator();

			status_t			Push(target_addr_t value);

			status_t			Evaluate(const void* expression, size_t size,
									target_addr_t& _result);
			status_t			EvaluateLocation(const void* expression,
									size_t size, ValueLocation& _location);
									// The returned location will have DWARF
									// semantics regarding register numbers and
									// bit offsets/sizes (cf. bit pieces).

private:
			struct EvaluationException;

private:
	inline	void				_AssertMinStackSize(size_t size) const;

	inline	void				_Push(target_addr_t value);
	inline	target_addr_t		_Pop();

			status_t			_Evaluate(ValuePieceLocation* _piece);
			void				_DereferenceAddress(uint8 addressSize);
			void				_DereferenceAddressSpaceAddress(
									uint8 addressSize);
			void				_PushRegister(uint32 reg, target_addr_t offset);
			void				_Call(uint64 offset, uint8 refType);

private:
			DwarfExpressionEvaluationContext* fContext;
			target_addr_t*		fStack;
			size_t				fStackSize;
			size_t				fStackCapacity;
			DataReader			fDataReader;
			target_addr_t		fObjectAddress;
			target_addr_t		fFrameAddress;
			bool				fObjectAddressValid;
			bool				fFrameAddressValid;
};


#endif	// DWARF_EXPRESSION_EVALUATOR_H