DwarfMemory.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*
  2. * Copyright (C) 2017 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <stdint.h>
  17. #include <string>
  18. #include <unwindstack/DwarfMemory.h>
  19. #include <unwindstack/Memory.h>
  20. #include "Check.h"
  21. #include "DwarfEncoding.h"
  22. namespace unwindstack {
  23. bool DwarfMemory::ReadBytes(void* dst, size_t num_bytes) {
  24. if (!memory_->ReadFully(cur_offset_, dst, num_bytes)) {
  25. return false;
  26. }
  27. cur_offset_ += num_bytes;
  28. return true;
  29. }
  30. template <typename SignedType>
  31. bool DwarfMemory::ReadSigned(uint64_t* value) {
  32. SignedType signed_value;
  33. if (!ReadBytes(&signed_value, sizeof(SignedType))) {
  34. return false;
  35. }
  36. *value = static_cast<int64_t>(signed_value);
  37. return true;
  38. }
  39. bool DwarfMemory::ReadULEB128(uint64_t* value) {
  40. uint64_t cur_value = 0;
  41. uint64_t shift = 0;
  42. uint8_t byte;
  43. do {
  44. if (!ReadBytes(&byte, 1)) {
  45. return false;
  46. }
  47. cur_value += static_cast<uint64_t>(byte & 0x7f) << shift;
  48. shift += 7;
  49. } while (byte & 0x80);
  50. *value = cur_value;
  51. return true;
  52. }
  53. bool DwarfMemory::ReadSLEB128(int64_t* value) {
  54. uint64_t cur_value = 0;
  55. uint64_t shift = 0;
  56. uint8_t byte;
  57. do {
  58. if (!ReadBytes(&byte, 1)) {
  59. return false;
  60. }
  61. cur_value += static_cast<uint64_t>(byte & 0x7f) << shift;
  62. shift += 7;
  63. } while (byte & 0x80);
  64. if (byte & 0x40) {
  65. // Negative value, need to sign extend.
  66. cur_value |= static_cast<uint64_t>(-1) << shift;
  67. }
  68. *value = static_cast<int64_t>(cur_value);
  69. return true;
  70. }
  71. template <typename AddressType>
  72. size_t DwarfMemory::GetEncodedSize(uint8_t encoding) {
  73. switch (encoding & 0x0f) {
  74. case DW_EH_PE_absptr:
  75. return sizeof(AddressType);
  76. case DW_EH_PE_udata1:
  77. case DW_EH_PE_sdata1:
  78. return 1;
  79. case DW_EH_PE_udata2:
  80. case DW_EH_PE_sdata2:
  81. return 2;
  82. case DW_EH_PE_udata4:
  83. case DW_EH_PE_sdata4:
  84. return 4;
  85. case DW_EH_PE_udata8:
  86. case DW_EH_PE_sdata8:
  87. return 8;
  88. case DW_EH_PE_uleb128:
  89. case DW_EH_PE_sleb128:
  90. default:
  91. return 0;
  92. }
  93. }
  94. bool DwarfMemory::AdjustEncodedValue(uint8_t encoding, uint64_t* value) {
  95. CHECK((encoding & 0x0f) == 0);
  96. // Handle the encoding.
  97. switch (encoding) {
  98. case DW_EH_PE_absptr:
  99. // Nothing to do.
  100. break;
  101. case DW_EH_PE_pcrel:
  102. if (pc_offset_ == static_cast<uint64_t>(-1)) {
  103. // Unsupported encoding.
  104. return false;
  105. }
  106. *value += pc_offset_;
  107. break;
  108. case DW_EH_PE_textrel:
  109. if (text_offset_ == static_cast<uint64_t>(-1)) {
  110. // Unsupported encoding.
  111. return false;
  112. }
  113. *value += text_offset_;
  114. break;
  115. case DW_EH_PE_datarel:
  116. if (data_offset_ == static_cast<uint64_t>(-1)) {
  117. // Unsupported encoding.
  118. return false;
  119. }
  120. *value += data_offset_;
  121. break;
  122. case DW_EH_PE_funcrel:
  123. if (func_offset_ == static_cast<uint64_t>(-1)) {
  124. // Unsupported encoding.
  125. return false;
  126. }
  127. *value += func_offset_;
  128. break;
  129. default:
  130. return false;
  131. }
  132. return true;
  133. }
  134. template <typename AddressType>
  135. bool DwarfMemory::ReadEncodedValue(uint8_t encoding, uint64_t* value) {
  136. if (encoding == DW_EH_PE_omit) {
  137. *value = 0;
  138. return true;
  139. } else if (encoding == DW_EH_PE_aligned) {
  140. if (__builtin_add_overflow(cur_offset_, sizeof(AddressType) - 1, &cur_offset_)) {
  141. return false;
  142. }
  143. cur_offset_ &= -sizeof(AddressType);
  144. if (sizeof(AddressType) != sizeof(uint64_t)) {
  145. *value = 0;
  146. }
  147. return ReadBytes(value, sizeof(AddressType));
  148. }
  149. // Get the data.
  150. switch (encoding & 0x0f) {
  151. case DW_EH_PE_absptr:
  152. if (sizeof(AddressType) != sizeof(uint64_t)) {
  153. *value = 0;
  154. }
  155. if (!ReadBytes(value, sizeof(AddressType))) {
  156. return false;
  157. }
  158. break;
  159. case DW_EH_PE_uleb128:
  160. if (!ReadULEB128(value)) {
  161. return false;
  162. }
  163. break;
  164. case DW_EH_PE_sleb128:
  165. int64_t signed_value;
  166. if (!ReadSLEB128(&signed_value)) {
  167. return false;
  168. }
  169. *value = static_cast<uint64_t>(signed_value);
  170. break;
  171. case DW_EH_PE_udata1: {
  172. uint8_t value8;
  173. if (!ReadBytes(&value8, 1)) {
  174. return false;
  175. }
  176. *value = value8;
  177. } break;
  178. case DW_EH_PE_sdata1:
  179. if (!ReadSigned<int8_t>(value)) {
  180. return false;
  181. }
  182. break;
  183. case DW_EH_PE_udata2: {
  184. uint16_t value16;
  185. if (!ReadBytes(&value16, 2)) {
  186. return false;
  187. }
  188. *value = value16;
  189. } break;
  190. case DW_EH_PE_sdata2:
  191. if (!ReadSigned<int16_t>(value)) {
  192. return false;
  193. }
  194. break;
  195. case DW_EH_PE_udata4: {
  196. uint32_t value32;
  197. if (!ReadBytes(&value32, 4)) {
  198. return false;
  199. }
  200. *value = value32;
  201. } break;
  202. case DW_EH_PE_sdata4:
  203. if (!ReadSigned<int32_t>(value)) {
  204. return false;
  205. }
  206. break;
  207. case DW_EH_PE_udata8:
  208. if (!ReadBytes(value, sizeof(uint64_t))) {
  209. return false;
  210. }
  211. break;
  212. case DW_EH_PE_sdata8:
  213. if (!ReadSigned<int64_t>(value)) {
  214. return false;
  215. }
  216. break;
  217. default:
  218. return false;
  219. }
  220. return AdjustEncodedValue(encoding & 0x70, value);
  221. }
  222. // Instantiate all of the needed template functions.
  223. template bool DwarfMemory::ReadSigned<int8_t>(uint64_t*);
  224. template bool DwarfMemory::ReadSigned<int16_t>(uint64_t*);
  225. template bool DwarfMemory::ReadSigned<int32_t>(uint64_t*);
  226. template bool DwarfMemory::ReadSigned<int64_t>(uint64_t*);
  227. template size_t DwarfMemory::GetEncodedSize<uint32_t>(uint8_t);
  228. template size_t DwarfMemory::GetEncodedSize<uint64_t>(uint8_t);
  229. template bool DwarfMemory::ReadEncodedValue<uint32_t>(uint8_t, uint64_t*);
  230. template bool DwarfMemory::ReadEncodedValue<uint64_t>(uint8_t, uint64_t*);
  231. } // namespace unwindstack