1f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===- ELFAttributeData.cpp -----------------------------------------------===// 2f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 3f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// The MCLinker Project 4f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 5f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// This file is distributed under the University of Illinois Open Source 6f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// License. See LICENSE.TXT for details. 7f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 8f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/ELFAttributeData.h" 10f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/LEB128.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/ELFAttributeValue.h" 13f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <cstring> 14f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <cassert> 15f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 17f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFAttributeData::ReadTag(TagType& pTag, 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines const char*& pBuf, 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t& pBufSize) { 21f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines size_t size = 0; 22f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 23f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pTag = static_cast<ELFAttributeData::TagType>( 2437b74a387bb3993387029859c2d9d051c41c724eStephen Hines leb128::decode<uint64_t>(pBuf, size)); 25f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 26f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (size > pBufSize) 27f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 28f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 29f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pBuf += size; 30f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pBufSize -= size; 31f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 32f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return true; 33f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 34f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 3537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFAttributeData::ReadValue(ELFAttributeValue& pValue, 3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines const char*& pBuf, 3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t& pBufSize) { 38f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // An ULEB128-encoded value 39f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (pValue.isIntValue()) { 40f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines size_t size = 0; 41f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint64_t int_value = leb128::decode<uint64_t>(pBuf, size); 42f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pValue.setIntValue(static_cast<unsigned int>(int_value)); 43f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 44f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (size > pBufSize) 45f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 46f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 47f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pBuf += size; 48f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pBufSize -= size; 49f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 50f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 51f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // A null-terminated byte string 52f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (pValue.isStringValue()) { 53f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pValue.setStringValue(pBuf); 54f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 55f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines size_t size = pValue.getStringValue().length() + 1 /* '\0' */; 56f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines assert(size <= pBufSize); 57f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pBuf += size; 58f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pBufSize -= size; 59f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 60f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 61f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return true; 62f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 63f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 64f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool ELFAttributeData::WriteAttribute(TagType pTag, 65f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const ELFAttributeValue& pValue, 6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines char*& pBuf) { 67f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Write the attribute tag. 68f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines leb128::encode<uint32_t>(pBuf, pTag); 69f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 70f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Write the attribute value. 71f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (pValue.isIntValue()) 72f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines leb128::encode<uint32_t>(pBuf, pValue.getIntValue()); 73f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 74f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (pValue.isStringValue()) { 75f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Write string data. 76f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines size_t str_val_len = pValue.getStringValue().length(); 77f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 78f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (str_val_len > 0) 79f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ::memcpy(pBuf, pValue.getStringValue().c_str(), str_val_len); 80f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pBuf += str_val_len; 81f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 82f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Write NULL-terminator. 83f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *pBuf++ = '\0'; 84f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 85f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 86f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return true; 87f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 90