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 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 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 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