1 //===- ELFAttributeData.h -------------------------------------------------===//
2 //
3 //                     The MCLinker Project
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #ifndef MCLD_TARGET_ELFATTRIBUTEDATA_H
10 #define MCLD_TARGET_ELFATTRIBUTEDATA_H
11 
12 #include <stdint.h>
13 #include <string>
14 #include <utility>
15 
16 namespace mcld {
17 
18 class ELFAttributeValue;
19 class Input;
20 class LinkerConfig;
21 
22 /** \class ELFAttributeData
23  *  \brief ELFAttributeData handles data in vendor attribute subsection.
24  */
25 class ELFAttributeData
26 {
27 public:
28   typedef uint32_t TagType;
29 
30   // Generic attribute tags shared between all vendors
31   enum {
32     Tag_NULL          = 0,
33     Tag_File          = 1,
34     Tag_Section       = 2,
35     Tag_Symbol        = 3,
36   };
37 
38 public:
ELFAttributeData(const char * pVendor)39   ELFAttributeData(const char* pVendor) : m_Vendor(pVendor) { }
40 
~ELFAttributeData()41   virtual ~ELFAttributeData() { }
42 
43 public:
getVendorName()44   inline const std::string &getVendorName() const { return m_Vendor; }
45 
46   /// getAttributeValue - query the data store for the attribute value of the
47   /// given tag.
48   virtual const ELFAttributeValue *getAttributeValue(TagType pTag) const = 0;
49 
50   /// getOrCreateAttributeValue - obtain attribute value for the given tag and
51   /// create if it does not exist.
52   ///
53   /// It returns a pair containing the attribute value instance (guaranteed to
54   /// be non-NULL) and a boolean value indicating whether the instance is newly
55   /// created (true) or not (false.)
56   virtual std::pair<ELFAttributeValue*, bool>
57       getOrCreateAttributeValue(TagType pTag) = 0;
58 
59   /// preMerge - hooks to call before starting merge the attribute data in an
60   /// input.
preMerge(const Input & pInput)61   virtual bool preMerge(const Input &pInput) { return true; }
62 
63   /// merge - implement logics to merge input attribute to the output.
64   virtual bool merge(const LinkerConfig& pConfig, const Input &pInput,
65                      TagType pTag, const ELFAttributeValue& pInAttr) = 0;
66 
67   /// postMerge - hooks to call after finishing merge the attribute data from an
68   /// input.
postMerge(const LinkerConfig & pConfig,const Input & pInput)69   virtual bool postMerge(const LinkerConfig& pConfig, const Input &pInput)
70   { return true; }
71 
72   /// sizeOutput - obtain number of bytes required to encode the attribute data.
73   virtual size_t sizeOutput() const = 0;
74 
75   /// emit - write out attribute data to the buffer and return the number of
76   /// bytes written
77   virtual size_t emit(char *pBuf) const = 0;
78 
79 public:
80   /// ReadTag - read an attribute tag from input buffer.
81   ///
82   /// If the read succeeds, pBuf moves to the new position just pass the end of
83   /// the tag in the buffer and pBufSize decreases the size of tag in the
84   /// buffer. Otherwise, this function will return false and change nothing
85   /// except leaving undefined value in pTag.
86   static bool ReadTag(TagType& pTag, const char* &pBuf, size_t &pBufSize);
87 
88   /// ReadValue - read an attribute value from input buffer
89   ///
90   /// Similar with ReadTag() while this reads attribute value from the input
91   /// buffer. Note that the value type of the attribute must be properly set in
92   /// pValue prior the call.
93   static bool ReadValue(ELFAttributeValue& pValue, const char* &pBuf,
94                         size_t &pBufSize);
95 
96   /// WriteAttribute - write an attribute tag plus value to buffer.
97   ///
98   /// On success, the pBuf moves to the new position just pass the end of the
99   /// attribute data just written. Otherwise, it returns false and leaves pBuf
100   /// in an undefined position. Note that buffer is guaranteed to be able to
101   /// contain the attribute data.
102   static bool WriteAttribute(TagType pTag, const ELFAttributeValue& pValue,
103                              char* &pBuf);
104 
105 private:
106   const std::string m_Vendor;
107 };
108 
109 } // namespace of mcld
110 
111 #endif
112