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