1/*
2 * File:	SourceFile.h
3 *
4 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5 * See included license file for license details.
6 */
7#if !defined(_SourceFile_h_)
8#define _SourceFile_h_
9
10#include <string>
11#include <iostream>
12#include <fstream>
13#include "smart_ptr.h"
14#include "DataSource.h"
15#include "DataTarget.h"
16#include "StringMatcher.h"
17#include "OptionContext.h"
18
19namespace elftosb
20{
21
22/*!
23 * \brief Abstract base class for a source file containing executable code.
24 *
25 * The purpose of this class cluster is to provide a common interface for
26 * accessing the contents of different file formats. This is accomplished
27 * through several small sets of methods along with the DataSource and
28 * DataTarget classes.
29 *
30 * The primary interface for creating instances of SourceFile is the static
31 * SourceFile::openFile() function. It will create the correct subclass of
32 * SourceFile by inspecting the file to determine its type.
33 */
34class SourceFile
35{
36public:
37	// \brief Factory function that creates the correct subclass of SourceFile.
38	static SourceFile * openFile(const std::string & path);
39
40public:
41	//! \brief Default constructor.
42	SourceFile(const std::string & path);
43
44	//! \brief Destructor.
45	virtual ~SourceFile();
46
47	//! \brief Set the option context.
48	//!
49	//! The source file will take ownership of the @a context and delete it
50	//! when the source file is itself deleted.
51	inline void setOptions(OptionContext * context) { m_options = context; }
52
53	//! \brief Return the option context.
54	inline const OptionContext * getOptions() const { return m_options; }
55
56	//! \brief Returns the path to the file.
57	inline const std::string & getPath() const { return m_path; }
58
59	//! \brief Get the size in bytes of the file.
60	unsigned getSize();
61
62	//! \name Opening and closing
63	//@{
64	//! \brief Opens the file.
65	virtual void open();
66
67	//! \brief Closes the file.
68	virtual void close();
69
70	//! \brief Returns whether the file is already open.
71	virtual bool isOpen() const { return (bool)m_stream && const_cast<std::ifstream*>(m_stream.get())->is_open(); }
72	//@}
73
74	//! \name Format capabilities
75	//@{
76	virtual bool supportsNamedSections() const=0;
77	virtual bool supportsNamedSymbols() const=0;
78	//@}
79
80	//! \name Data source creation
81	//@{
82	//! \brief Creates a data source from the entire file.
83	virtual DataSource * createDataSource()=0;
84
85	//! \brief Creates a data source out of one or more sections of the file.
86	//!
87	//! The \a selector object is used to perform the section name comparison.
88	//! If the file does not support named sections, or if there is not a
89	//! section with the given name, this method may return NULL.
90	virtual DataSource * createDataSource(StringMatcher & matcher) { return NULL; }
91
92	//! \brief Creates a data source out of one section of the file.
93	virtual DataSource * createDataSource(const std::string & section);
94	//@}
95
96	//! \name Entry point
97	//@{
98	//! \brief Returns true if an entry point was set in the file.
99	virtual bool hasEntryPoint()=0;
100
101	//! \brief Returns the entry point address.
102	virtual uint32_t getEntryPointAddress() { return 0; }
103	//@}
104
105	//! \name Data target creation
106	//@{
107	virtual DataTarget * createDataTargetForSection(const std::string & section) { return NULL; }
108	virtual DataTarget * createDataTargetForSymbol(const std::string & symbol) { return NULL; }
109	virtual DataTarget * createDataTargetForEntryPoint();
110	//@}
111
112	//! \name Symbols
113	//@{
114	//! \brief Returns whether a symbol exists in the source file.
115	virtual bool hasSymbol(const std::string & name) { return false; }
116
117	//! \brief Returns the value of a symbol.
118	virtual uint32_t getSymbolValue(const std::string & name) { return 0; }
119
120	//! \brief Returns the size of a symbol.
121	virtual unsigned getSymbolSize(const std::string & name) { return 0; }
122	//@}
123
124protected:
125	std::string m_path;	//!< Path to the file.
126	smart_ptr<std::ifstream> m_stream;	//!< File stream, or NULL if file is closed.
127	smart_ptr<OptionContext> m_options;	//!< Table of option values.
128
129	//! \brief Internal access to the input stream object.
130	inline std::ifstream * getStream() { return m_stream; }
131};
132
133/*!
134 * \brief Binary data file.
135 */
136class BinarySourceFile : public SourceFile
137{
138public:
139	//! \brief Default constructor.
140	BinarySourceFile(const std::string & path) : SourceFile(path) {}
141
142	//! \name Format capabilities
143	//@{
144	virtual bool supportsNamedSections() const { return false; }
145	virtual bool supportsNamedSymbols() const { return false; }
146	//@}
147
148	//! \brief Creates an unmapped data source from the entire file.
149	virtual DataSource * createDataSource();
150
151	virtual bool hasEntryPoint() { return false; }
152};
153
154}; // namespace elftosb
155
156#endif // _SourceFile_h_
157