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