DWARFDataExtractor.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. //===- DWARFDataExtractor.cpp ---------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
  9. #include "llvm/DebugInfo/DWARF/DWARFContext.h"
  10. using namespace llvm;
  11. std::pair<uint64_t, dwarf::DwarfFormat>
  12. DWARFDataExtractor::getInitialLength(uint64_t *Off, Error *Err) const {
  13. ErrorAsOutParameter ErrAsOut(Err);
  14. if (Err && *Err)
  15. return {0, dwarf::DWARF32};
  16. Cursor C(*Off);
  17. uint64_t Length = getRelocatedValue(C, 4);
  18. dwarf::DwarfFormat Format = dwarf::DWARF32;
  19. if (Length == dwarf::DW_LENGTH_DWARF64) {
  20. Length = getRelocatedValue(C, 8);
  21. Format = dwarf::DWARF64;
  22. } else if (Length >= dwarf::DW_LENGTH_lo_reserved) {
  23. cantFail(C.takeError());
  24. if (Err)
  25. *Err = createStringError(
  26. errc::invalid_argument,
  27. "unsupported reserved unit length of value 0x%8.8" PRIx64, Length);
  28. return {0, dwarf::DWARF32};
  29. }
  30. if (C) {
  31. *Off = C.tell();
  32. return {Length, Format};
  33. }
  34. if (Err)
  35. *Err = C.takeError();
  36. else
  37. consumeError(C.takeError());
  38. return {0, dwarf::DWARF32};
  39. }
  40. uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off,
  41. uint64_t *SecNdx,
  42. Error *Err) const {
  43. if (SecNdx)
  44. *SecNdx = object::SectionedAddress::UndefSection;
  45. if (!Section)
  46. return getUnsigned(Off, Size, Err);
  47. ErrorAsOutParameter ErrAsOut(Err);
  48. Optional<RelocAddrEntry> E = Obj->find(*Section, *Off);
  49. uint64_t LocData = getUnsigned(Off, Size, Err);
  50. if (!E || (Err && *Err))
  51. return LocData;
  52. if (SecNdx)
  53. *SecNdx = E->SectionIndex;
  54. uint64_t R =
  55. object::resolveRelocation(E->Resolver, E->Reloc, E->SymbolValue, LocData);
  56. if (E->Reloc2)
  57. R = object::resolveRelocation(E->Resolver, *E->Reloc2, E->SymbolValue2, R);
  58. return R;
  59. }
  60. Optional<uint64_t>
  61. DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding,
  62. uint64_t PCRelOffset) const {
  63. if (Encoding == dwarf::DW_EH_PE_omit)
  64. return None;
  65. uint64_t Result = 0;
  66. uint64_t OldOffset = *Offset;
  67. // First get value
  68. switch (Encoding & 0x0F) {
  69. case dwarf::DW_EH_PE_absptr:
  70. switch (getAddressSize()) {
  71. case 2:
  72. case 4:
  73. case 8:
  74. Result = getUnsigned(Offset, getAddressSize());
  75. break;
  76. default:
  77. return None;
  78. }
  79. break;
  80. case dwarf::DW_EH_PE_uleb128:
  81. Result = getULEB128(Offset);
  82. break;
  83. case dwarf::DW_EH_PE_sleb128:
  84. Result = getSLEB128(Offset);
  85. break;
  86. case dwarf::DW_EH_PE_udata2:
  87. Result = getUnsigned(Offset, 2);
  88. break;
  89. case dwarf::DW_EH_PE_udata4:
  90. Result = getUnsigned(Offset, 4);
  91. break;
  92. case dwarf::DW_EH_PE_udata8:
  93. Result = getUnsigned(Offset, 8);
  94. break;
  95. case dwarf::DW_EH_PE_sdata2:
  96. Result = getSigned(Offset, 2);
  97. break;
  98. case dwarf::DW_EH_PE_sdata4:
  99. Result = SignExtend64<32>(getRelocatedValue(4, Offset));
  100. break;
  101. case dwarf::DW_EH_PE_sdata8:
  102. Result = getRelocatedValue(8, Offset);
  103. break;
  104. default:
  105. return None;
  106. }
  107. // Then add relative offset, if required
  108. switch (Encoding & 0x70) {
  109. case dwarf::DW_EH_PE_absptr:
  110. // do nothing
  111. break;
  112. case dwarf::DW_EH_PE_pcrel:
  113. Result += PCRelOffset;
  114. break;
  115. case dwarf::DW_EH_PE_datarel:
  116. case dwarf::DW_EH_PE_textrel:
  117. case dwarf::DW_EH_PE_funcrel:
  118. case dwarf::DW_EH_PE_aligned:
  119. default:
  120. *Offset = OldOffset;
  121. return None;
  122. }
  123. return Result;
  124. }