xref: /netbsd-src/external/bsd/elftosb/dist/common/StExecutableImage.h (revision 93f5e2c30272859d294e5c9c68ed3d0473b9c75d)
1 /*
2  * File:	StExecutableImage.h
3  *
4  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5  * See included license file for license details.
6  */
7 #if !defined(_StExecutableImage_h_)
8 #define _StExecutableImage_h_
9 
10 #include "stdafx.h"
11 #include <list>
12 
13 /*!
14  * \brief Used to build a representation of memory regions.
15  *
16  * An intermediate representation of the memory regions and segments loaded
17  * from an executable file. Also used to find contiguous segments that are
18  * specified separately in the source file.
19  *
20  * When regions are added, an attempt is made to coalesce contiguous regions.
21  * In order for this to succeed, the touching regions must be of the same
22  * type and have the same permissions. Regions are also kept sorted by their
23  * address range as they are added.
24  *
25  * \todo Implement alignment support.
26  */
27 class StExecutableImage
28 {
29 public:
30 	//! Possible types of memory regions.
31 	typedef enum {
32 		TEXT_REGION,	//!< A region containing data or instructions.
33 		FILL_REGION		//!< Region to be initialized with zero bytes.
34 	} MemoryRegionType;
35 
36 	//! Memory region flag constants.
37 	enum {
38 		REGION_READ_FLAG = 1,	//!< Region is readable.
39 		REGION_WRITE_FLAG = 2,	//!< Region is writable.
40 		REGION_EXEC_FLAG = 4,	//!< Region may contain executable code.
41 
42 		REGION_RW_FLAG = REGION_READ_FLAG | REGION_WRITE_FLAG,	//!< Region is read-write.
43 
44 		//! Mask to access only permissions flags for a region.
45 		REGION_PERM_FLAG_MASK = 0x7
46 	};
47 
48 	/*!
49 	 * Representation of a contiguous region of memory.
50      *
51      * \todo Add comparison operators so we can use the STL sort algorithm.
52 	 */
53 	struct MemoryRegion
54 	{
55 		MemoryRegionType m_type;	//!< Memory region type.
56 		uint32_t m_address;	//!< The 32-bit start address of this region.
57 		uint32_t m_length;	//!< Number of bytes in this region.
58 		uint8_t * m_data;	//!< Pointer to data. Will be NULL for FILL_REGION type.
59 		unsigned m_flags;	//!< Flags for the region.
60 
61         //! \brief Calculates the address of the last byte occupied by this region.
endAddressMemoryRegion62         inline uint32_t endAddress() const { return m_address + m_length - 1; }
63 
64         //! \brief Equality operator.
65         bool operator == (const MemoryRegion & other) const;
66 	};
67 
68 	//! A list of #StExecutableImage::MemoryRegion objects.
69 	typedef std::list<MemoryRegion> MemoryRegionList;
70 
71     //! The iterator type used to access #StExecutableImage::MemoryRegion objects. This type
72     //! is used by the methods #getRegionBegin() and #getRegionEnd().
73 	typedef MemoryRegionList::const_iterator const_iterator;
74 
75     //! The possible actions for regions matching an address filter range.
76     typedef enum {
77         ADDR_FILTER_NONE,       //!< Do nothing.
78         ADDR_FILTER_ERROR,      //!< Raise an error exception.
79         ADDR_FILTER_WARNING,    //!< Raise a warning exception.
80         ADDR_FILTER_CROP        //!< Don't include the matching address range in the executable image.
81     } AddressFilterAction;
82 
83     /*!
84      * An address filter consists of a single address range and an action. If a
85      * memory region overlaps the filter's range then the action will be performed.
86      * The possible filter actions are defined by the #AddressFilterAction enumeration.
87      */
88     struct AddressFilter
89     {
90         AddressFilterAction m_action;   //!< Action to be performed when the filter is matched.
91         uint32_t m_fromAddress; //!< Start address of the filter. Should be lower than or equal to #m_toAddress.
92         uint32_t m_toAddress;   //!< End address of the filter. Should be higher than or equal to #m_fromAddress.
93         unsigned m_priority;     //!< Priority for this filter. Zero is the lowest priority.
94 
95         //! \brief Constructor.
96         AddressFilter(AddressFilterAction action, uint32_t from, uint32_t to, unsigned priority=0)
m_actionAddressFilter97         :   m_action(action), m_fromAddress(from), m_toAddress(to), m_priority(priority)
98         {
99         }
100 
101         //! \brief Test routine.
102         bool matchesMemoryRegion(const MemoryRegion & region) const;
103 
104         //! \brief Compares two address filter objects.
105         int compare(const AddressFilter & other) const;
106 
107         //! \name Comparison operators
108         //@{
109         inline bool operator < (const AddressFilter & other) const { return compare(other) == -1; }
110         inline bool operator > (const AddressFilter & other) const { return compare(other) == 1; }
111         inline bool operator == (const AddressFilter & other) const { return compare(other) == 0; }
112         inline bool operator <= (const AddressFilter & other) const { return compare(other) != 1; }
113         inline bool operator >= (const AddressFilter & other) const { return compare(other) != -1; }
114         //@}
115     };
116 
117     //! List of #StExecutableImage::AddressFilter objects.
118     typedef std::list<AddressFilter> AddressFilterList;
119 
120     //! The exception class raised for the #ADDR_FILTER_ERROR and #ADDR_FILTER_WARNING
121     //! filter actions.
122     class address_filter_exception
123     {
124     public:
125         //! \brief Constructor.
126         //!
127         //! A local copy of \a matchingFilter is made, in case the image and/or filter
128         //! are on the stack and would be disposed of when the exception is raised.
address_filter_exception(bool isError,std::string & imageName,const AddressFilter & matchingFilter)129         address_filter_exception(bool isError, std::string & imageName, const AddressFilter & matchingFilter)
130         : m_isError(isError), m_imageName(imageName), m_filter(matchingFilter)
131         {
132         }
133 
134         //! \brief Returns true if the exception is an error. Otherwise the exception
135         //!     is for a warning.
isError()136         inline bool isError() const { return m_isError; }
137 
138         //! \brief
getImageName()139         inline std::string getImageName() const { return m_imageName; }
140 
141         //! \brief
getMatchingFilter()142         inline const AddressFilter & getMatchingFilter() const { return m_filter; }
143 
144     protected:
145         bool m_isError;
146         std::string m_imageName;
147         AddressFilter m_filter;
148     };
149 
150 public:
151 	//! \brief Constructor.
152 	StExecutableImage(int inAlignment=256);
153 
154 	//! \brief Copy constructor.
155 	StExecutableImage(const StExecutableImage & inOther);
156 
157 	//! \brief Destructor.
158 	virtual ~StExecutableImage();
159 
160 	//! \name Image name
161 	//! Methods for getting and setting the image name.
162 	//@{
163 	//! \brief Sets the image's name to \a inName.
164 	virtual void setName(const std::string & inName);
165 
166 	//! \brief Returns a copy of the image's name.
167 	virtual std::string getName() const;
168 	//@}
169 
170 	//! \name Regions
171 	//! Methods to add and access memory regions.
172 	//@{
173 	//! \brief Add a region to be filled with zeroes.
174 	virtual void addFillRegion(uint32_t inAddress, unsigned inLength);
175 
176 	//! \brief Add a region containing data to be loaded.
177 	virtual void addTextRegion(uint32_t inAddress, const uint8_t * inData, unsigned inLength);
178 
179 	//! \brief Returns the total number of regions.
180 	//!
181 	//! Note that this count may not be the same as the number of calls to
182 	//! addFillRegion() and addTextRegion() due to region coalescing.
getRegionCount()183 	inline unsigned getRegionCount() const { return static_cast<unsigned>(m_image.size()); }
184 
185 	//! \brief Returns a reference to the region specified by \a inIndex.
186 	const MemoryRegion & getRegionAtIndex(unsigned inIndex) const;
187 
188     //! \brief Return an iterator to the first region.
getRegionBegin()189 	inline const_iterator getRegionBegin() const { return m_image.begin(); }
190 
191     //! \brief Return an iterator to the next-after-last region.
getRegionEnd()192 	inline const_iterator getRegionEnd() const { return m_image.end(); }
193 	//@}
194 
195 	//! \name Entry point
196 	//@{
197 	//! \brief Sets the entry point address.
setEntryPoint(uint32_t inEntryAddress)198 	inline void setEntryPoint(uint32_t inEntryAddress) { m_entry = inEntryAddress; m_hasEntry = true; }
199 
200 	//! \brief Returns true if an entry point has been set.
hasEntryPoint()201 	inline bool hasEntryPoint() const { return m_hasEntry; }
202 
203 	//! \brief Returns the entry point address.
getEntryPoint()204 	inline uint32_t getEntryPoint() const { return hasEntryPoint() ? m_entry : 0; }
205 	//@}
206 
207     //! \name Address filter
208     //@{
209     //! \brief Add a new address filter.
210     virtual void addAddressFilter(const AddressFilter & filter);
211 
212     //! \brief Add multiple address filters at once.
213     //!
214     //! The template argument \a _T must be an iterator or const iterator that
215     //! dereferences to an StExecutableImage::AddressFilter reference. All filters
216     //! from \a from to \a to will be added to the address filter list.
addAddressFilters(_T from,_T to)217     template<typename _T> void addAddressFilters(_T from, _T to)
218     {
219         _T it = from;
220         for (; it != to; ++it)
221         {
222             addAddressFilter(*it);
223         }
224     }
225 
226     //! \brief Remove all active filters.
227     virtual void clearAddressFilters();
228 
229     //! \brief Process all active filters and perform associated actions.
230     virtual void applyAddressFilters();
231     //@}
232 
233 protected:
234 	std::string m_name;	//!< The name of the image (can be a file name, for instance).
235 	int m_alignment;	//!< The required address alignment for each memory region.
236 	bool m_hasEntry;	//!< True if an entry point has been set.
237 	uint32_t m_entry;	//!< Entry point address.
238 	MemoryRegionList m_image;	//!< The memory regions.
239     AddressFilterList m_filters;    //!< List of active address filters.
240 
241     //! \brief Deletes the portion \a region that overlaps \a filter.
242     void cropRegionToFilter(MemoryRegion & region, const AddressFilter & filter);
243 
244 	//! \brief Inserts the region in sorted order or merges with one already in the image.
245 	void insertOrMergeRegion(MemoryRegion & inRegion);
246 
247 	//! \brief Merges two memory regions into one.
248 	void mergeRegions(MemoryRegion & inOldRegion, MemoryRegion & inNewRegion);
249 };
250 
251 #endif // _StExecutableImage_h_
252