ELFAttributeData.cpp revision 87f34658dec9097d987d254a990ea7f311bfc95f
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
16using namespace mcld;
17
18bool ELFAttributeData::ReadTag(TagType& pTag, const char* &pBuf,
19                               size_t &pBufSize)
20{
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, const char* &pBuf,
36                                 size_t &pBufSize)
37{
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{
68  // Write the attribute tag.
69  leb128::encode<uint32_t>(pBuf, pTag);
70
71  // Write the attribute value.
72  if (pValue.isIntValue())
73    leb128::encode<uint32_t>(pBuf, pValue.getIntValue());
74
75  if (pValue.isStringValue()) {
76    // Write string data.
77    size_t str_val_len = pValue.getStringValue().length();
78
79    if (str_val_len > 0)
80      ::memcpy(pBuf, pValue.getStringValue().c_str(), str_val_len);
81    pBuf += str_val_len;
82
83    // Write NULL-terminator.
84    *pBuf++ = '\0';
85  }
86
87  return true;
88}
89