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 |