ELFAttributeData.cpp revision 37b74a387bb3993387029859c2d9d051c41c724e
1//===- ELFAttributeData.cpp -----------------------------------------------===//
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#include "mcld/Target/ELFAttributeData.h"
10
11#include "mcld/Support/LEB128.h"
12#include "mcld/Target/ELFAttributeValue.h"
13#include <cstring>
14#include <cassert>
15
16namespace mcld {
17
18bool ELFAttributeData::ReadTag(TagType& pTag,
19                               const char*& pBuf,
20                               size_t& pBufSize) {
21  size_t size = 0;
22
23  pTag = static_cast<ELFAttributeData::TagType>(
24      leb128::decode<uint64_t>(pBuf, size));
25
26  if (size > pBufSize)
27    return false;
28
29  pBuf += size;
30  pBufSize -= size;
31
32  return true;
33}
34
35bool ELFAttributeData::ReadValue(ELFAttributeValue& pValue,
36                                 const char*& pBuf,
37                                 size_t& pBufSize) {
38  // An ULEB128-encoded value
39  if (pValue.isIntValue()) {
40    size_t size = 0;
41    uint64_t int_value = leb128::decode<uint64_t>(pBuf, size);
42    pValue.setIntValue(static_cast<unsigned int>(int_value));
43
44    if (size > pBufSize)
45      return false;
46
47    pBuf += size;
48    pBufSize -= size;
49  }
50
51  // A null-terminated byte string
52  if (pValue.isStringValue()) {
53    pValue.setStringValue(pBuf);
54
55    size_t size = pValue.getStringValue().length() + 1 /* '\0' */;
56    assert(size <= pBufSize);
57    pBuf += size;
58    pBufSize -= size;
59  }
60
61  return true;
62}
63
64bool ELFAttributeData::WriteAttribute(TagType pTag,
65                                      const ELFAttributeValue& pValue,
66                                      char*& pBuf) {
67  // Write the attribute tag.
68  leb128::encode<uint32_t>(pBuf, pTag);
69
70  // Write the attribute value.
71  if (pValue.isIntValue())
72    leb128::encode<uint32_t>(pBuf, pValue.getIntValue());
73
74  if (pValue.isStringValue()) {
75    // Write string data.
76    size_t str_val_len = pValue.getStringValue().length();
77
78    if (str_val_len > 0)
79      ::memcpy(pBuf, pValue.getStringValue().c_str(), str_val_len);
80    pBuf += str_val_len;
81
82    // Write NULL-terminator.
83    *pBuf++ = '\0';
84  }
85
86  return true;
87}
88
89}  // namespace mcld
90