You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
2.9 KiB
114 lines
2.9 KiB
//===- LEB128.h -----------------------------------------------------------===//
|
|
//
|
|
// The MCLinker Project
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#ifndef MCLD_SUPPORT_LEB128_H_
|
|
#define MCLD_SUPPORT_LEB128_H_
|
|
|
|
#include <stdint.h>
|
|
#include <sys/types.h>
|
|
|
|
namespace mcld {
|
|
|
|
namespace leb128 {
|
|
|
|
typedef unsigned char ByteType;
|
|
|
|
/* Forward declarations */
|
|
template <typename IntType>
|
|
size_t encode(ByteType*& pBuf, IntType pValue);
|
|
|
|
template <typename IntType>
|
|
IntType decode(const ByteType* pBuf, size_t& pSize);
|
|
|
|
template <typename IntType>
|
|
IntType decode(const ByteType*& pBuf);
|
|
|
|
/*
|
|
* Given an integer, this function returns the number of bytes required to
|
|
* encode it in ULEB128 format.
|
|
*/
|
|
template <typename IntType>
|
|
size_t size(IntType pValue) {
|
|
size_t size = 1;
|
|
while (pValue > 0x80) {
|
|
pValue >>= 7;
|
|
++size;
|
|
}
|
|
return size;
|
|
}
|
|
|
|
/*
|
|
* Write an unsigned integer in ULEB128 to the given buffer. The client should
|
|
* ensure there's enough space in the buffer to hold the result. Update the
|
|
* given buffer pointer to the point just past the end of the write value and
|
|
* return the number of bytes being written.
|
|
*/
|
|
template <>
|
|
size_t encode<uint64_t>(ByteType*& pBuf, uint64_t pValue);
|
|
|
|
template <>
|
|
size_t encode<uint32_t>(ByteType*& pBuf, uint32_t pValue);
|
|
|
|
/*
|
|
* Encoding functions for signed LEB128.
|
|
*/
|
|
template <>
|
|
size_t encode<int64_t>(ByteType*& pBuf, int64_t pValue);
|
|
|
|
template <>
|
|
size_t encode<int32_t>(ByteType*& pBuf, int32_t pValue);
|
|
|
|
/*
|
|
* Read an integer encoded in ULEB128 format from the given buffer. pSize will
|
|
* contain the number of bytes used in the buffer to encode the returned
|
|
* integer.
|
|
*/
|
|
template <>
|
|
uint64_t decode<uint64_t>(const ByteType* pBuf, size_t& pSize);
|
|
|
|
/*
|
|
* Read an integer encoded in ULEB128 format from the given buffer. Update the
|
|
* given buffer pointer to the point just past the end of the read value.
|
|
*/
|
|
template <>
|
|
uint64_t decode<uint64_t>(const ByteType*& pBuf);
|
|
|
|
/*
|
|
* Decoding functions for signed LEB128.
|
|
*/
|
|
template <>
|
|
int64_t decode<int64_t>(const ByteType* pBuf, size_t& pSize);
|
|
|
|
template <>
|
|
int64_t decode<int64_t>(const ByteType*& pBuf);
|
|
|
|
/*
|
|
* The functions below handle the signed byte stream. This helps the user to get
|
|
* rid of annoying type conversions when using the LEB128 encoding/decoding APIs
|
|
* defined above.
|
|
*/
|
|
template <typename IntType>
|
|
size_t encode(char*& pBuf, IntType pValue) {
|
|
return encode<IntType>(reinterpret_cast<ByteType*&>(pBuf), pValue);
|
|
}
|
|
|
|
template <typename IntType>
|
|
IntType decode(const char* pBuf, size_t& pSize) {
|
|
return decode<IntType>(reinterpret_cast<const ByteType*>(pBuf), pSize);
|
|
}
|
|
|
|
template <typename IntType>
|
|
IntType decode(const char*& pBuf) {
|
|
return decode<IntType>(reinterpret_cast<const ByteType*&>(pBuf));
|
|
}
|
|
|
|
} // namespace leb128
|
|
} // namespace mcld
|
|
|
|
#endif // MCLD_SUPPORT_LEB128_H_
|