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
16namespace mcld {
17
18class ELFAttributeValue;
19class Input;
20class LinkerConfig;
21
22/** \class ELFAttributeData
23 *  \brief ELFAttributeData handles data in vendor attribute subsection.
24 */
25class ELFAttributeData
26{
27public:
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
38public:
39  ELFAttributeData(const char* pVendor) : m_Vendor(pVendor) { }
40
41  virtual ~ELFAttributeData() { }
42
43public:
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.
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.
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
79public:
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
105private:
106  const std::string m_Vendor;
107};
108
109} // namespace of mcld
110
111#endif
112