183e085b7a331c96237cf8e814f97b3ef4c36a70fjimblandy// Copyright (c) 2010 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 29760d66430e41ea9b817492b2137268e41430035bmmentovai#include <assert.h> 300de9f43b879cc4e31766d4607e895641bdda1c21jimblandy#include <stdlib.h> 31cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid 324969cfc6477c56afb2d4f2f6c1733c3120690b6djimblandy@gmail.com#include "common/dwarf/bytereader-inl.h" 334969cfc6477c56afb2d4f2f6c1733c3120690b6djimblandy@gmail.com#include "common/dwarf/bytereader.h" 34cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid 35cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidnamespace dwarf2reader { 36cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid 37cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidByteReader::ByteReader(enum Endianness endian) 38cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid :offset_reader_(NULL), address_reader_(NULL), endian_(endian), 390de9f43b879cc4e31766d4607e895641bdda1c21jimblandy address_size_(0), offset_size_(0), 400de9f43b879cc4e31766d4607e895641bdda1c21jimblandy have_section_base_(), have_text_base_(), have_data_base_(), 410de9f43b879cc4e31766d4607e895641bdda1c21jimblandy have_function_base_() { } 42cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid 43cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidByteReader::~ByteReader() { } 44cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid 45cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidvoid ByteReader::SetOffsetSize(uint8 size) { 46cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid offset_size_ = size; 47cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid assert(size == 4 || size == 8); 48cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid if (size == 4) { 49cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid this->offset_reader_ = &ByteReader::ReadFourBytes; 50cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid } else { 51cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid this->offset_reader_ = &ByteReader::ReadEightBytes; 52cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid } 53cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid} 54cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid 55cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidvoid ByteReader::SetAddressSize(uint8 size) { 56cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid address_size_ = size; 57cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid assert(size == 4 || size == 8); 58cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid if (size == 4) { 59cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid this->address_reader_ = &ByteReader::ReadFourBytes; 60cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid } else { 61cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid this->address_reader_ = &ByteReader::ReadEightBytes; 62cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid } 63cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid} 64cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid 651ac84da26d72cc3fb85af124d91b17cdecb17499jimblandyuint64 ByteReader::ReadInitialLength(const char* start, size_t* len) { 661ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy const uint64 initial_length = ReadFourBytes(start); 671ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy start += 4; 681ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy 691ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy // In DWARF2/3, if the initial length is all 1 bits, then the offset 701ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy // size is 8 and we need to read the next 8 bytes for the real length. 711ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy if (initial_length == 0xffffffff) { 721ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy SetOffsetSize(8); 731ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy *len = 12; 741ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy return ReadOffset(start); 751ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy } else { 761ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy SetOffsetSize(4); 771ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy *len = 4; 781ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy } 791ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy return initial_length; 801ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy} 811ac84da26d72cc3fb85af124d91b17cdecb17499jimblandy 820de9f43b879cc4e31766d4607e895641bdda1c21jimblandybool ByteReader::ValidEncoding(DwarfPointerEncoding encoding) const { 830de9f43b879cc4e31766d4607e895641bdda1c21jimblandy if (encoding == DW_EH_PE_omit) return true; 840de9f43b879cc4e31766d4607e895641bdda1c21jimblandy if (encoding == DW_EH_PE_aligned) return true; 85a76aaa1442d765410da36d743ef92748ea1b815ejimblandy if ((encoding & 0x7) > DW_EH_PE_udata8) 86a76aaa1442d765410da36d743ef92748ea1b815ejimblandy return false; 87a76aaa1442d765410da36d743ef92748ea1b815ejimblandy if ((encoding & 0x70) > DW_EH_PE_funcrel) 88a76aaa1442d765410da36d743ef92748ea1b815ejimblandy return false; 890de9f43b879cc4e31766d4607e895641bdda1c21jimblandy return true; 900de9f43b879cc4e31766d4607e895641bdda1c21jimblandy} 910de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 920de9f43b879cc4e31766d4607e895641bdda1c21jimblandybool ByteReader::UsableEncoding(DwarfPointerEncoding encoding) const { 93a76aaa1442d765410da36d743ef92748ea1b815ejimblandy switch (encoding & 0x70) { 940de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_absptr: return true; 950de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_pcrel: return have_section_base_; 960de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_textrel: return have_text_base_; 970de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_datarel: return have_data_base_; 980de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_funcrel: return have_function_base_; 990de9f43b879cc4e31766d4607e895641bdda1c21jimblandy default: return false; 1000de9f43b879cc4e31766d4607e895641bdda1c21jimblandy } 1010de9f43b879cc4e31766d4607e895641bdda1c21jimblandy} 1020de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 1030de9f43b879cc4e31766d4607e895641bdda1c21jimblandyuint64 ByteReader::ReadEncodedPointer(const char *buffer, 1040de9f43b879cc4e31766d4607e895641bdda1c21jimblandy DwarfPointerEncoding encoding, 1050de9f43b879cc4e31766d4607e895641bdda1c21jimblandy size_t *len) const { 106a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // UsableEncoding doesn't approve of DW_EH_PE_omit, so we shouldn't 107a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // see it here. 108a76aaa1442d765410da36d743ef92748ea1b815ejimblandy assert(encoding != DW_EH_PE_omit); 109a76aaa1442d765410da36d743ef92748ea1b815ejimblandy 110a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // The Linux Standards Base 4.0 does not make this clear, but the 111a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // GNU tools (gcc/unwind-pe.h; readelf/dwarf.c; gdb/dwarf2-frame.c) 112a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // agree that aligned pointers are always absolute, machine-sized, 113a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // machine-signed pointers. 1140de9f43b879cc4e31766d4607e895641bdda1c21jimblandy if (encoding == DW_EH_PE_aligned) { 1150de9f43b879cc4e31766d4607e895641bdda1c21jimblandy assert(have_section_base_); 1160de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 1170de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // We don't need to align BUFFER in *our* address space. Rather, we 1180de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // need to find the next position in our buffer that would be aligned 1190de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // when the .eh_frame section the buffer contains is loaded into the 1200de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // program's memory. So align assuming that buffer_base_ gets loaded at 1210de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // address section_base_, where section_base_ itself may or may not be 1220de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // aligned. 1230de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 1240de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // First, find the offset to START from the closest prior aligned 1250de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // address. 12616f2f376823fc6511157c12e7127a796c8ae0564jimblandy uint64 skew = section_base_ & (AddressSize() - 1); 1270de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // Now find the offset from that aligned address to buffer. 12816f2f376823fc6511157c12e7127a796c8ae0564jimblandy uint64 offset = skew + (buffer - buffer_base_); 1290de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // Round up to the next boundary. 13016f2f376823fc6511157c12e7127a796c8ae0564jimblandy uint64 aligned = (offset + AddressSize() - 1) & -AddressSize(); 1310de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // Convert back to a pointer. 1320de9f43b879cc4e31766d4607e895641bdda1c21jimblandy const char *aligned_buffer = buffer_base_ + (aligned - skew); 1330de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // Finally, store the length and actually fetch the pointer. 1340de9f43b879cc4e31766d4607e895641bdda1c21jimblandy *len = aligned_buffer - buffer + AddressSize(); 1350de9f43b879cc4e31766d4607e895641bdda1c21jimblandy return ReadAddress(aligned_buffer); 1360de9f43b879cc4e31766d4607e895641bdda1c21jimblandy } 1370de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 1380de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // Extract the value first, ignoring whether it's a pointer or an 1390de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // offset relative to some base. 1400de9f43b879cc4e31766d4607e895641bdda1c21jimblandy uint64 offset; 141a76aaa1442d765410da36d743ef92748ea1b815ejimblandy switch (encoding & 0x0f) { 1420de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_absptr: 143a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // DW_EH_PE_absptr is weird, as it is used as a meaningful value for 144a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // both the high and low nybble of encoding bytes. When it appears in 145a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // the high nybble, it means that the pointer is absolute, not an 146a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // offset from some base address. When it appears in the low nybble, 147a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // as here, it means that the pointer is stored as a normal 148a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // machine-sized and machine-signed address. A low nybble of 149a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // DW_EH_PE_absptr does not imply that the pointer is absolute; it is 150a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // correct for us to treat the value as an offset from a base address 151a76aaa1442d765410da36d743ef92748ea1b815ejimblandy // if the upper nybble is not DW_EH_PE_absptr. 1520de9f43b879cc4e31766d4607e895641bdda1c21jimblandy offset = ReadAddress(buffer); 1530de9f43b879cc4e31766d4607e895641bdda1c21jimblandy *len = AddressSize(); 1540de9f43b879cc4e31766d4607e895641bdda1c21jimblandy break; 1550de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 1560de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_uleb128: 1570de9f43b879cc4e31766d4607e895641bdda1c21jimblandy offset = ReadUnsignedLEB128(buffer, len); 1580de9f43b879cc4e31766d4607e895641bdda1c21jimblandy break; 159a453cc24f431a3323fee6799c6d8e8bef653a8e4jimblandy 1600de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_udata2: 1610de9f43b879cc4e31766d4607e895641bdda1c21jimblandy offset = ReadTwoBytes(buffer); 1620de9f43b879cc4e31766d4607e895641bdda1c21jimblandy *len = 2; 1630de9f43b879cc4e31766d4607e895641bdda1c21jimblandy break; 1640de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 1650de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_udata4: 1660de9f43b879cc4e31766d4607e895641bdda1c21jimblandy offset = ReadFourBytes(buffer); 1670de9f43b879cc4e31766d4607e895641bdda1c21jimblandy *len = 4; 1680de9f43b879cc4e31766d4607e895641bdda1c21jimblandy break; 1690de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 1700de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_udata8: 1710de9f43b879cc4e31766d4607e895641bdda1c21jimblandy offset = ReadEightBytes(buffer); 1720de9f43b879cc4e31766d4607e895641bdda1c21jimblandy *len = 8; 1730de9f43b879cc4e31766d4607e895641bdda1c21jimblandy break; 1740de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 1750de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_sleb128: 1760de9f43b879cc4e31766d4607e895641bdda1c21jimblandy offset = ReadSignedLEB128(buffer, len); 1770de9f43b879cc4e31766d4607e895641bdda1c21jimblandy break; 1780de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 1790de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_sdata2: 1800de9f43b879cc4e31766d4607e895641bdda1c21jimblandy offset = ReadTwoBytes(buffer); 1810de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // Sign-extend from 16 bits. 1820de9f43b879cc4e31766d4607e895641bdda1c21jimblandy offset = (offset ^ 0x8000) - 0x8000; 1830de9f43b879cc4e31766d4607e895641bdda1c21jimblandy *len = 2; 1840de9f43b879cc4e31766d4607e895641bdda1c21jimblandy break; 1850de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 1860de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_sdata4: 1870de9f43b879cc4e31766d4607e895641bdda1c21jimblandy offset = ReadFourBytes(buffer); 1880de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // Sign-extend from 32 bits. 1890de9f43b879cc4e31766d4607e895641bdda1c21jimblandy offset = (offset ^ 0x80000000ULL) - 0x80000000ULL; 1900de9f43b879cc4e31766d4607e895641bdda1c21jimblandy *len = 4; 1910de9f43b879cc4e31766d4607e895641bdda1c21jimblandy break; 1920de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 1930de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_sdata8: 1940de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // No need to sign-extend; this is the full width of our type. 1950de9f43b879cc4e31766d4607e895641bdda1c21jimblandy offset = ReadEightBytes(buffer); 1960de9f43b879cc4e31766d4607e895641bdda1c21jimblandy *len = 8; 1970de9f43b879cc4e31766d4607e895641bdda1c21jimblandy break; 1980de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 1990de9f43b879cc4e31766d4607e895641bdda1c21jimblandy default: 2000de9f43b879cc4e31766d4607e895641bdda1c21jimblandy abort(); 2010de9f43b879cc4e31766d4607e895641bdda1c21jimblandy } 2020de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 2030de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // Find the appropriate base address. 2040de9f43b879cc4e31766d4607e895641bdda1c21jimblandy uint64 base; 205a76aaa1442d765410da36d743ef92748ea1b815ejimblandy switch (encoding & 0x70) { 2060de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_absptr: 2070de9f43b879cc4e31766d4607e895641bdda1c21jimblandy base = 0; 2080de9f43b879cc4e31766d4607e895641bdda1c21jimblandy break; 2090de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 2100de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_pcrel: 2110de9f43b879cc4e31766d4607e895641bdda1c21jimblandy assert(have_section_base_); 2120de9f43b879cc4e31766d4607e895641bdda1c21jimblandy base = section_base_ + (buffer - buffer_base_); 2130de9f43b879cc4e31766d4607e895641bdda1c21jimblandy break; 2140de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 2150de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_textrel: 2160de9f43b879cc4e31766d4607e895641bdda1c21jimblandy assert(have_text_base_); 2170de9f43b879cc4e31766d4607e895641bdda1c21jimblandy base = text_base_; 2180de9f43b879cc4e31766d4607e895641bdda1c21jimblandy break; 2190de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 2200de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_datarel: 2210de9f43b879cc4e31766d4607e895641bdda1c21jimblandy assert(have_data_base_); 2220de9f43b879cc4e31766d4607e895641bdda1c21jimblandy base = data_base_; 2230de9f43b879cc4e31766d4607e895641bdda1c21jimblandy break; 2240de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 2250de9f43b879cc4e31766d4607e895641bdda1c21jimblandy case DW_EH_PE_funcrel: 2260de9f43b879cc4e31766d4607e895641bdda1c21jimblandy assert(have_function_base_); 2270de9f43b879cc4e31766d4607e895641bdda1c21jimblandy base = function_base_; 2280de9f43b879cc4e31766d4607e895641bdda1c21jimblandy break; 2290de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 2300de9f43b879cc4e31766d4607e895641bdda1c21jimblandy default: 2310de9f43b879cc4e31766d4607e895641bdda1c21jimblandy abort(); 2320de9f43b879cc4e31766d4607e895641bdda1c21jimblandy } 2330de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 2340de9f43b879cc4e31766d4607e895641bdda1c21jimblandy uint64 pointer = base + offset; 2350de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 2360de9f43b879cc4e31766d4607e895641bdda1c21jimblandy // Remove inappropriate upper bits. 2370de9f43b879cc4e31766d4607e895641bdda1c21jimblandy if (AddressSize() == 4) 2380de9f43b879cc4e31766d4607e895641bdda1c21jimblandy pointer = pointer & 0xffffffff; 2390de9f43b879cc4e31766d4607e895641bdda1c21jimblandy else 2400de9f43b879cc4e31766d4607e895641bdda1c21jimblandy assert(AddressSize() == sizeof(uint64)); 2410de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 2420de9f43b879cc4e31766d4607e895641bdda1c21jimblandy return pointer; 2430de9f43b879cc4e31766d4607e895641bdda1c21jimblandy} 2440de9f43b879cc4e31766d4607e895641bdda1c21jimblandy 245cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid} // namespace dwarf2reader 246