1cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// Copyright 2006 Google Inc. All Rights Reserved.
2cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid//
3cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// Redistribution and use in source and binary forms, with or without
4cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// modification, are permitted provided that the following conditions are
5cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// met:
6cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid//
7cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid//     * Redistributions of source code must retain the above copyright
8cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// notice, this list of conditions and the following disclaimer.
9cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid//     * Redistributions in binary form must reproduce the above
10cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// copyright notice, this list of conditions and the following disclaimer
11cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// in the documentation and/or other materials provided with the
12cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// distribution.
13cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid//     * Neither the name of Google Inc. nor the names of its
14cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// contributors may be used to endorse or promote products derived from
15cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// this software without specific prior written permission.
16cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid//
17cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
29cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid#ifndef UTIL_DEBUGINFO_BYTEREADER_INL_H__
30cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid#define UTIL_DEBUGINFO_BYTEREADER_INL_H__
31cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
324969cfc6477c56afb2d4f2f6c1733c3120690b6djimblandy@gmail.com#include "common/dwarf/bytereader.h"
33cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
34e1930985430ce289f4fe8525f51050e5d78cc44eted.mielczarek#include <assert.h>
35e1930985430ce289f4fe8525f51050e5d78cc44eted.mielczarek
36cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidnamespace dwarf2reader {
37cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
38cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidinline uint8 ByteReader::ReadOneByte(const char* buffer) const {
39cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  return buffer[0];
40cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid}
41cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
42e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.cominline uint16 ByteReader::ReadTwoBytes(const char* signed_buffer) const {
43e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const unsigned char *buffer
44e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com    = reinterpret_cast<const unsigned char *>(signed_buffer);
45e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const uint16 buffer0 = buffer[0];
46e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const uint16 buffer1 = buffer[1];
47cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  if (endian_ == ENDIANNESS_LITTLE) {
48cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid    return buffer0 | buffer1 << 8;
49cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  } else {
50cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid    return buffer1 | buffer0 << 8;
51cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  }
52cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid}
53cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
54e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.cominline uint64 ByteReader::ReadFourBytes(const char* signed_buffer) const {
55e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const unsigned char *buffer
56e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com    = reinterpret_cast<const unsigned char *>(signed_buffer);
57e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const uint32 buffer0 = buffer[0];
58e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const uint32 buffer1 = buffer[1];
59e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const uint32 buffer2 = buffer[2];
60e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const uint32 buffer3 = buffer[3];
61cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  if (endian_ == ENDIANNESS_LITTLE) {
62cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid    return buffer0 | buffer1 << 8 | buffer2 << 16 | buffer3 << 24;
63cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  } else {
64cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid    return buffer3 | buffer2 << 8 | buffer1 << 16 | buffer0 << 24;
65cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  }
66cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid}
67cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
68e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.cominline uint64 ByteReader::ReadEightBytes(const char* signed_buffer) const {
69e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const unsigned char *buffer
70e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com    = reinterpret_cast<const unsigned char *>(signed_buffer);
71e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const uint64 buffer0 = buffer[0];
72e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const uint64 buffer1 = buffer[1];
73e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const uint64 buffer2 = buffer[2];
74e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const uint64 buffer3 = buffer[3];
75e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const uint64 buffer4 = buffer[4];
76e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const uint64 buffer5 = buffer[5];
77e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const uint64 buffer6 = buffer[6];
78e4be54eb3e343cbf920a0a9ac6347b6aecc8c13cjimblandy@gmail.com  const uint64 buffer7 = buffer[7];
79cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  if (endian_ == ENDIANNESS_LITTLE) {
80cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid    return buffer0 | buffer1 << 8 | buffer2 << 16 | buffer3 << 24 |
81cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid      buffer4 << 32 | buffer5 << 40 | buffer6 << 48 | buffer7 << 56;
82cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  } else {
83cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid    return buffer7 | buffer6 << 8 | buffer5 << 16 | buffer4 << 24 |
84cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid      buffer3 << 32 | buffer2 << 40 | buffer1 << 48 | buffer0 << 56;
85cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  }
86cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid}
87cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
88cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// Read an unsigned LEB128 number.  Each byte contains 7 bits of
89cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// information, plus one bit saying whether the number continues or
90cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// not.
91cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
92cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidinline uint64 ByteReader::ReadUnsignedLEB128(const char* buffer,
93cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                                             size_t* len) const {
94cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  uint64 result = 0;
95cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  size_t num_read = 0;
96cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  unsigned int shift = 0;
97cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  unsigned char byte;
98cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
99cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  do {
100cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid    byte = *buffer++;
101cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid    num_read++;
102cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
103cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid    result |= (static_cast<uint64>(byte & 0x7f)) << shift;
104cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
105cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid    shift += 7;
106cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
107cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  } while (byte & 0x80);
108cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
109cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  *len = num_read;
110cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
111cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  return result;
112cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid}
113cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
114cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// Read a signed LEB128 number.  These are like regular LEB128
115cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// numbers, except the last byte may have a sign bit set.
116cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
117cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidinline int64 ByteReader::ReadSignedLEB128(const char* buffer,
118cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                                          size_t* len) const {
119cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  int64 result = 0;
120cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  unsigned int shift = 0;
121cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  size_t num_read = 0;
122cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  unsigned char byte;
123cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
124cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  do {
125cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid      byte = *buffer++;
126cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid      num_read++;
127cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid      result |= (static_cast<uint64>(byte & 0x7f) << shift);
128cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid      shift += 7;
129cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  } while (byte & 0x80);
130cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
131cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  if ((shift < 8 * sizeof (result)) && (byte & 0x40))
132cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid    result |= -((static_cast<int64>(1)) << shift);
133cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  *len = num_read;
134cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  return result;
135cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid}
136cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
137cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidinline uint64 ByteReader::ReadOffset(const char* buffer) const {
138cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  assert(this->offset_reader_);
139cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  return (this->*offset_reader_)(buffer);
140cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid}
141cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
142cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidinline uint64 ByteReader::ReadAddress(const char* buffer) const {
143cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  assert(this->address_reader_);
144cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  return (this->*address_reader_)(buffer);
145cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid}
146cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
1470de9f43b879cc4e31766d4607e895641bdda1c21jimblandyinline void ByteReader::SetCFIDataBase(uint64 section_base,
1480de9f43b879cc4e31766d4607e895641bdda1c21jimblandy                                       const char *buffer_base) {
1490de9f43b879cc4e31766d4607e895641bdda1c21jimblandy  section_base_ = section_base;
1500de9f43b879cc4e31766d4607e895641bdda1c21jimblandy  buffer_base_ = buffer_base;
1510de9f43b879cc4e31766d4607e895641bdda1c21jimblandy  have_section_base_ = true;
1520de9f43b879cc4e31766d4607e895641bdda1c21jimblandy}
1530de9f43b879cc4e31766d4607e895641bdda1c21jimblandy
1540de9f43b879cc4e31766d4607e895641bdda1c21jimblandyinline void ByteReader::SetTextBase(uint64 text_base) {
1550de9f43b879cc4e31766d4607e895641bdda1c21jimblandy  text_base_ = text_base;
1560de9f43b879cc4e31766d4607e895641bdda1c21jimblandy  have_text_base_ = true;
1570de9f43b879cc4e31766d4607e895641bdda1c21jimblandy}
1580de9f43b879cc4e31766d4607e895641bdda1c21jimblandy
1590de9f43b879cc4e31766d4607e895641bdda1c21jimblandyinline void ByteReader::SetDataBase(uint64 data_base) {
1600de9f43b879cc4e31766d4607e895641bdda1c21jimblandy  data_base_ = data_base;
1610de9f43b879cc4e31766d4607e895641bdda1c21jimblandy  have_data_base_ = true;
1620de9f43b879cc4e31766d4607e895641bdda1c21jimblandy}
1630de9f43b879cc4e31766d4607e895641bdda1c21jimblandy
1640de9f43b879cc4e31766d4607e895641bdda1c21jimblandyinline void ByteReader::SetFunctionBase(uint64 function_base) {
1650de9f43b879cc4e31766d4607e895641bdda1c21jimblandy  function_base_ = function_base;
1660de9f43b879cc4e31766d4607e895641bdda1c21jimblandy  have_function_base_ = true;
1670de9f43b879cc4e31766d4607e895641bdda1c21jimblandy}
1680de9f43b879cc4e31766d4607e895641bdda1c21jimblandy
1690de9f43b879cc4e31766d4607e895641bdda1c21jimblandyinline void ByteReader::ClearFunctionBase() {
1700de9f43b879cc4e31766d4607e895641bdda1c21jimblandy  have_function_base_ = false;
1710de9f43b879cc4e31766d4607e895641bdda1c21jimblandy}
1720de9f43b879cc4e31766d4607e895641bdda1c21jimblandy
173cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid}  // namespace dwarf2reader
174cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
175cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid#endif  // UTIL_DEBUGINFO_BYTEREADER_INL_H__
176