michael@0: // Copyright 2006 Google Inc. All Rights Reserved. michael@0: // michael@0: // Redistribution and use in source and binary forms, with or without michael@0: // modification, are permitted provided that the following conditions are michael@0: // met: michael@0: // michael@0: // * Redistributions of source code must retain the above copyright michael@0: // notice, this list of conditions and the following disclaimer. michael@0: // * Redistributions in binary form must reproduce the above michael@0: // copyright notice, this list of conditions and the following disclaimer michael@0: // in the documentation and/or other materials provided with the michael@0: // distribution. michael@0: // * Neither the name of Google Inc. nor the names of its michael@0: // contributors may be used to endorse or promote products derived from michael@0: // this software without specific prior written permission. michael@0: // michael@0: // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR michael@0: // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT michael@0: // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@0: // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@0: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, michael@0: // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY michael@0: // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE michael@0: // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: michael@0: #ifndef UTIL_DEBUGINFO_BYTEREADER_INL_H__ michael@0: #define UTIL_DEBUGINFO_BYTEREADER_INL_H__ michael@0: michael@0: #include "common/dwarf/bytereader.h" michael@0: michael@0: #include michael@0: michael@0: namespace dwarf2reader { michael@0: michael@0: inline uint8 ByteReader::ReadOneByte(const char* buffer) const { michael@0: return buffer[0]; michael@0: } michael@0: michael@0: inline uint16 ByteReader::ReadTwoBytes(const char* signed_buffer) const { michael@0: const unsigned char *buffer michael@0: = reinterpret_cast(signed_buffer); michael@0: const uint16 buffer0 = buffer[0]; michael@0: const uint16 buffer1 = buffer[1]; michael@0: if (endian_ == ENDIANNESS_LITTLE) { michael@0: return buffer0 | buffer1 << 8; michael@0: } else { michael@0: return buffer1 | buffer0 << 8; michael@0: } michael@0: } michael@0: michael@0: inline uint64 ByteReader::ReadFourBytes(const char* signed_buffer) const { michael@0: const unsigned char *buffer michael@0: = reinterpret_cast(signed_buffer); michael@0: const uint32 buffer0 = buffer[0]; michael@0: const uint32 buffer1 = buffer[1]; michael@0: const uint32 buffer2 = buffer[2]; michael@0: const uint32 buffer3 = buffer[3]; michael@0: if (endian_ == ENDIANNESS_LITTLE) { michael@0: return buffer0 | buffer1 << 8 | buffer2 << 16 | buffer3 << 24; michael@0: } else { michael@0: return buffer3 | buffer2 << 8 | buffer1 << 16 | buffer0 << 24; michael@0: } michael@0: } michael@0: michael@0: inline uint64 ByteReader::ReadEightBytes(const char* signed_buffer) const { michael@0: const unsigned char *buffer michael@0: = reinterpret_cast(signed_buffer); michael@0: const uint64 buffer0 = buffer[0]; michael@0: const uint64 buffer1 = buffer[1]; michael@0: const uint64 buffer2 = buffer[2]; michael@0: const uint64 buffer3 = buffer[3]; michael@0: const uint64 buffer4 = buffer[4]; michael@0: const uint64 buffer5 = buffer[5]; michael@0: const uint64 buffer6 = buffer[6]; michael@0: const uint64 buffer7 = buffer[7]; michael@0: if (endian_ == ENDIANNESS_LITTLE) { michael@0: return buffer0 | buffer1 << 8 | buffer2 << 16 | buffer3 << 24 | michael@0: buffer4 << 32 | buffer5 << 40 | buffer6 << 48 | buffer7 << 56; michael@0: } else { michael@0: return buffer7 | buffer6 << 8 | buffer5 << 16 | buffer4 << 24 | michael@0: buffer3 << 32 | buffer2 << 40 | buffer1 << 48 | buffer0 << 56; michael@0: } michael@0: } michael@0: michael@0: // Read an unsigned LEB128 number. Each byte contains 7 bits of michael@0: // information, plus one bit saying whether the number continues or michael@0: // not. michael@0: michael@0: inline uint64 ByteReader::ReadUnsignedLEB128(const char* buffer, michael@0: size_t* len) const { michael@0: uint64 result = 0; michael@0: size_t num_read = 0; michael@0: unsigned int shift = 0; michael@0: unsigned char byte; michael@0: michael@0: do { michael@0: byte = *buffer++; michael@0: num_read++; michael@0: michael@0: result |= (static_cast(byte & 0x7f)) << shift; michael@0: michael@0: shift += 7; michael@0: michael@0: } while (byte & 0x80); michael@0: michael@0: *len = num_read; michael@0: michael@0: return result; michael@0: } michael@0: michael@0: // Read a signed LEB128 number. These are like regular LEB128 michael@0: // numbers, except the last byte may have a sign bit set. michael@0: michael@0: inline int64 ByteReader::ReadSignedLEB128(const char* buffer, michael@0: size_t* len) const { michael@0: int64 result = 0; michael@0: unsigned int shift = 0; michael@0: size_t num_read = 0; michael@0: unsigned char byte; michael@0: michael@0: do { michael@0: byte = *buffer++; michael@0: num_read++; michael@0: result |= (static_cast(byte & 0x7f) << shift); michael@0: shift += 7; michael@0: } while (byte & 0x80); michael@0: michael@0: if ((shift < 8 * sizeof (result)) && (byte & 0x40)) michael@0: result |= -((static_cast(1)) << shift); michael@0: *len = num_read; michael@0: return result; michael@0: } michael@0: michael@0: inline uint64 ByteReader::ReadOffset(const char* buffer) const { michael@0: assert(this->offset_reader_); michael@0: return (this->*offset_reader_)(buffer); michael@0: } michael@0: michael@0: inline uint64 ByteReader::ReadAddress(const char* buffer) const { michael@0: assert(this->address_reader_); michael@0: return (this->*address_reader_)(buffer); michael@0: } michael@0: michael@0: inline void ByteReader::SetCFIDataBase(uint64 section_base, michael@0: const char *buffer_base) { michael@0: section_base_ = section_base; michael@0: buffer_base_ = buffer_base; michael@0: have_section_base_ = true; michael@0: } michael@0: michael@0: inline void ByteReader::SetTextBase(uint64 text_base) { michael@0: text_base_ = text_base; michael@0: have_text_base_ = true; michael@0: } michael@0: michael@0: inline void ByteReader::SetDataBase(uint64 data_base) { michael@0: data_base_ = data_base; michael@0: have_data_base_ = true; michael@0: } michael@0: michael@0: inline void ByteReader::SetFunctionBase(uint64 function_base) { michael@0: function_base_ = function_base; michael@0: have_function_base_ = true; michael@0: } michael@0: michael@0: inline void ByteReader::ClearFunctionBase() { michael@0: have_function_base_ = false; michael@0: } michael@0: michael@0: } // namespace dwarf2reader michael@0: michael@0: #endif // UTIL_DEBUGINFO_BYTEREADER_INL_H__