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
16 namespace mcld {
17
ReadTag(TagType & pTag,const char * & pBuf,size_t & pBufSize)18 bool 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
ReadValue(ELFAttributeValue & pValue,const char * & pBuf,size_t & pBufSize)35 bool 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
WriteAttribute(TagType pTag,const ELFAttributeValue & pValue,char * & pBuf)64 bool 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