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