DWARFDataExtractor.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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/BinaryFormat/Dwarf.h"
  10. #include "llvm/DebugInfo/DWARF/DWARFContext.h"
  11. using namespace llvm;
  12. uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off,
  13. uint64_t *SecNdx,
  14. Error *Err) const {
  15. if (SecNdx)
  16. *SecNdx = object::SectionedAddress::UndefSection;
  17. if (!Section)
  18. return getUnsigned(Off, Size, Err);
  19. Optional<RelocAddrEntry> E = Obj->find(*Section, *Off);
  20. uint64_t A = getUnsigned(Off, Size, Err);
  21. if (!E)
  22. return A;
  23. if (SecNdx)
  24. *SecNdx = E->SectionIndex;
  25. uint64_t R = E->Resolver(E->Reloc, E->SymbolValue, A);
  26. if (E->Reloc2)
  27. R = E->Resolver(*E->Reloc2, E->SymbolValue2, R);
  28. return R;
  29. }
  30. Optional<uint64_t>
  31. DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding,
  32. uint64_t PCRelOffset) const {
  33. if (Encoding == dwarf::DW_EH_PE_omit)
  34. return None;
  35. uint64_t Result = 0;
  36. uint64_t OldOffset = *Offset;
  37. // First get value
  38. switch (Encoding & 0x0F) {
  39. case dwarf::DW_EH_PE_absptr:
  40. switch (getAddressSize()) {
  41. case 2:
  42. case 4:
  43. case 8:
  44. Result = getUnsigned(Offset, getAddressSize());
  45. break;
  46. default:
  47. return None;
  48. }
  49. break;
  50. case dwarf::DW_EH_PE_uleb128:
  51. Result = getULEB128(Offset);
  52. break;
  53. case dwarf::DW_EH_PE_sleb128:
  54. Result = getSLEB128(Offset);
  55. break;
  56. case dwarf::DW_EH_PE_udata2:
  57. Result = getUnsigned(Offset, 2);
  58. break;
  59. case dwarf::DW_EH_PE_udata4:
  60. Result = getUnsigned(Offset, 4);
  61. break;
  62. case dwarf::DW_EH_PE_udata8:
  63. Result = getUnsigned(Offset, 8);
  64. break;
  65. case dwarf::DW_EH_PE_sdata2:
  66. Result = getSigned(Offset, 2);
  67. break;
  68. case dwarf::DW_EH_PE_sdata4:
  69. Result = getSigned(Offset, 4);
  70. break;
  71. case dwarf::DW_EH_PE_sdata8:
  72. Result = getSigned(Offset, 8);
  73. break;
  74. default:
  75. return None;
  76. }
  77. // Then add relative offset, if required
  78. switch (Encoding & 0x70) {
  79. case dwarf::DW_EH_PE_absptr:
  80. // do nothing
  81. break;
  82. case dwarf::DW_EH_PE_pcrel:
  83. Result += PCRelOffset;
  84. break;
  85. case dwarf::DW_EH_PE_datarel:
  86. case dwarf::DW_EH_PE_textrel:
  87. case dwarf::DW_EH_PE_funcrel:
  88. case dwarf::DW_EH_PE_aligned:
  89. default:
  90. *Offset = OldOffset;
  91. return None;
  92. }
  93. return Result;
  94. }