| OLD | NEW |
| 1 // Copyright (c) 2010 Google Inc. All Rights Reserved. | 1 // Copyright (c) 2010 Google Inc. All Rights Reserved. |
| 2 // | 2 // |
| 3 // Redistribution and use in source and binary forms, with or without | 3 // Redistribution and use in source and binary forms, with or without |
| 4 // modification, are permitted provided that the following conditions are | 4 // modification, are permitted provided that the following conditions are |
| 5 // met: | 5 // met: |
| 6 // | 6 // |
| 7 // * Redistributions of source code must retain the above copyright | 7 // * Redistributions of source code must retain the above copyright |
| 8 // notice, this list of conditions and the following disclaimer. | 8 // notice, this list of conditions and the following disclaimer. |
| 9 // * Redistributions in binary form must reproduce the above | 9 // * Redistributions in binary form must reproduce the above |
| 10 // copyright notice, this list of conditions and the following disclaimer | 10 // copyright notice, this list of conditions and the following disclaimer |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 void ByteReader::SetAddressSize(uint8 size) { | 55 void ByteReader::SetAddressSize(uint8 size) { |
| 56 address_size_ = size; | 56 address_size_ = size; |
| 57 assert(size == 4 || size == 8); | 57 assert(size == 4 || size == 8); |
| 58 if (size == 4) { | 58 if (size == 4) { |
| 59 this->address_reader_ = &ByteReader::ReadFourBytes; | 59 this->address_reader_ = &ByteReader::ReadFourBytes; |
| 60 } else { | 60 } else { |
| 61 this->address_reader_ = &ByteReader::ReadEightBytes; | 61 this->address_reader_ = &ByteReader::ReadEightBytes; |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 | 64 |
| 65 uint64 ByteReader::ReadInitialLength(const char* start, size_t* len) { | 65 uint64 ByteReader::ReadInitialLength(const uint8_t *start, size_t* len) { |
| 66 const uint64 initial_length = ReadFourBytes(start); | 66 const uint64 initial_length = ReadFourBytes(start); |
| 67 start += 4; | 67 start += 4; |
| 68 | 68 |
| 69 // In DWARF2/3, if the initial length is all 1 bits, then the offset | 69 // In DWARF2/3, if the initial length is all 1 bits, then the offset |
| 70 // size is 8 and we need to read the next 8 bytes for the real length. | 70 // size is 8 and we need to read the next 8 bytes for the real length. |
| 71 if (initial_length == 0xffffffff) { | 71 if (initial_length == 0xffffffff) { |
| 72 SetOffsetSize(8); | 72 SetOffsetSize(8); |
| 73 *len = 12; | 73 *len = 12; |
| 74 return ReadOffset(start); | 74 return ReadOffset(start); |
| 75 } else { | 75 } else { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 93 switch (encoding & 0x70) { | 93 switch (encoding & 0x70) { |
| 94 case DW_EH_PE_absptr: return true; | 94 case DW_EH_PE_absptr: return true; |
| 95 case DW_EH_PE_pcrel: return have_section_base_; | 95 case DW_EH_PE_pcrel: return have_section_base_; |
| 96 case DW_EH_PE_textrel: return have_text_base_; | 96 case DW_EH_PE_textrel: return have_text_base_; |
| 97 case DW_EH_PE_datarel: return have_data_base_; | 97 case DW_EH_PE_datarel: return have_data_base_; |
| 98 case DW_EH_PE_funcrel: return have_function_base_; | 98 case DW_EH_PE_funcrel: return have_function_base_; |
| 99 default: return false; | 99 default: return false; |
| 100 } | 100 } |
| 101 } | 101 } |
| 102 | 102 |
| 103 uint64 ByteReader::ReadEncodedPointer(const char *buffer, | 103 uint64 ByteReader::ReadEncodedPointer(const uint8_t *buffer, |
| 104 DwarfPointerEncoding encoding, | 104 DwarfPointerEncoding encoding, |
| 105 size_t *len) const { | 105 size_t *len) const { |
| 106 // UsableEncoding doesn't approve of DW_EH_PE_omit, so we shouldn't | 106 // UsableEncoding doesn't approve of DW_EH_PE_omit, so we shouldn't |
| 107 // see it here. | 107 // see it here. |
| 108 assert(encoding != DW_EH_PE_omit); | 108 assert(encoding != DW_EH_PE_omit); |
| 109 | 109 |
| 110 // The Linux Standards Base 4.0 does not make this clear, but the | 110 // The Linux Standards Base 4.0 does not make this clear, but the |
| 111 // GNU tools (gcc/unwind-pe.h; readelf/dwarf.c; gdb/dwarf2-frame.c) | 111 // GNU tools (gcc/unwind-pe.h; readelf/dwarf.c; gdb/dwarf2-frame.c) |
| 112 // agree that aligned pointers are always absolute, machine-sized, | 112 // agree that aligned pointers are always absolute, machine-sized, |
| 113 // machine-signed pointers. | 113 // machine-signed pointers. |
| 114 if (encoding == DW_EH_PE_aligned) { | 114 if (encoding == DW_EH_PE_aligned) { |
| 115 assert(have_section_base_); | 115 assert(have_section_base_); |
| 116 | 116 |
| 117 // We don't need to align BUFFER in *our* address space. Rather, we | 117 // We don't need to align BUFFER in *our* address space. Rather, we |
| 118 // need to find the next position in our buffer that would be aligned | 118 // need to find the next position in our buffer that would be aligned |
| 119 // when the .eh_frame section the buffer contains is loaded into the | 119 // when the .eh_frame section the buffer contains is loaded into the |
| 120 // program's memory. So align assuming that buffer_base_ gets loaded at | 120 // program's memory. So align assuming that buffer_base_ gets loaded at |
| 121 // address section_base_, where section_base_ itself may or may not be | 121 // address section_base_, where section_base_ itself may or may not be |
| 122 // aligned. | 122 // aligned. |
| 123 | 123 |
| 124 // First, find the offset to START from the closest prior aligned | 124 // First, find the offset to START from the closest prior aligned |
| 125 // address. | 125 // address. |
| 126 uint64 skew = section_base_ & (AddressSize() - 1); | 126 uint64 skew = section_base_ & (AddressSize() - 1); |
| 127 // Now find the offset from that aligned address to buffer. | 127 // Now find the offset from that aligned address to buffer. |
| 128 uint64 offset = skew + (buffer - buffer_base_); | 128 uint64 offset = skew + (buffer - buffer_base_); |
| 129 // Round up to the next boundary. | 129 // Round up to the next boundary. |
| 130 uint64 aligned = (offset + AddressSize() - 1) & -AddressSize(); | 130 uint64 aligned = (offset + AddressSize() - 1) & -AddressSize(); |
| 131 // Convert back to a pointer. | 131 // Convert back to a pointer. |
| 132 const char *aligned_buffer = buffer_base_ + (aligned - skew); | 132 const uint8_t *aligned_buffer = buffer_base_ + (aligned - skew); |
| 133 // Finally, store the length and actually fetch the pointer. | 133 // Finally, store the length and actually fetch the pointer. |
| 134 *len = aligned_buffer - buffer + AddressSize(); | 134 *len = aligned_buffer - buffer + AddressSize(); |
| 135 return ReadAddress(aligned_buffer); | 135 return ReadAddress(aligned_buffer); |
| 136 } | 136 } |
| 137 | 137 |
| 138 // Extract the value first, ignoring whether it's a pointer or an | 138 // Extract the value first, ignoring whether it's a pointer or an |
| 139 // offset relative to some base. | 139 // offset relative to some base. |
| 140 uint64 offset; | 140 uint64 offset; |
| 141 switch (encoding & 0x0f) { | 141 switch (encoding & 0x0f) { |
| 142 case DW_EH_PE_absptr: | 142 case DW_EH_PE_absptr: |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 // Remove inappropriate upper bits. | 236 // Remove inappropriate upper bits. |
| 237 if (AddressSize() == 4) | 237 if (AddressSize() == 4) |
| 238 pointer = pointer & 0xffffffff; | 238 pointer = pointer & 0xffffffff; |
| 239 else | 239 else |
| 240 assert(AddressSize() == sizeof(uint64)); | 240 assert(AddressSize() == sizeof(uint64)); |
| 241 | 241 |
| 242 return pointer; | 242 return pointer; |
| 243 } | 243 } |
| 244 | 244 |
| 245 } // namespace dwarf2reader | 245 } // namespace dwarf2reader |
| OLD | NEW |