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 
19 namespace 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  */
34 class SourceFile
35 {
36 public:
37           // \brief Factory function that creates the correct subclass of SourceFile.
38           static SourceFile * openFile(const std::string & path);
39 
40 public:
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.
setOptions(OptionContext * context)51           inline void setOptions(OptionContext * context) { m_options = context; }
52 
53           //! \brief Return the option context.
getOptions()54           inline const OptionContext * getOptions() const { return m_options; }
55 
56           //! \brief Returns the path to the file.
getPath()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.
isOpen()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.
createDataSource(StringMatcher & matcher)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.
getEntryPointAddress()102           virtual uint32_t getEntryPointAddress() { return 0; }
103           //@}
104 
105           //! \name Data target creation
106           //@{
createDataTargetForSection(const std::string & section)107           virtual DataTarget * createDataTargetForSection(const std::string & section) { return NULL; }
createDataTargetForSymbol(const std::string & symbol)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.
hasSymbol(const std::string & name)115           virtual bool hasSymbol(const std::string & name) { return false; }
116 
117           //! \brief Returns the value of a symbol.
getSymbolValue(const std::string & name)118           virtual uint32_t getSymbolValue(const std::string & name) { return 0; }
119 
120           //! \brief Returns the size of a symbol.
getSymbolSize(const std::string & name)121           virtual unsigned getSymbolSize(const std::string & name) { return 0; }
122           //@}
123 
124 protected:
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.
getStream()130           inline std::ifstream * getStream() { return m_stream; }
131 };
132 
133 /*!
134  * \brief Binary data file.
135  */
136 class BinarySourceFile : public SourceFile
137 {
138 public:
139           //! \brief Default constructor.
BinarySourceFile(const std::string & path)140           BinarySourceFile(const std::string & path) : SourceFile(path) {}
141 
142           //! \name Format capabilities
143           //@{
supportsNamedSections()144           virtual bool supportsNamedSections() const { return false; }
supportsNamedSymbols()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 
hasEntryPoint()151           virtual bool hasEntryPoint() { return false; }
152 };
153 
154 }; // namespace elftosb
155 
156 #endif // _SourceFile_h_
157