Coverage Report

Created: 2017-09-21 03:39

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/ELF/EhFrame.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- EhFrame.cpp -------------------------------------------------------===//
2
//
3
//                             The LLVM Linker
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// .eh_frame section contains information on how to unwind the stack when
11
// an exception is thrown. The section consists of sequence of CIE and FDE
12
// records. The linker needs to merge CIEs and associate FDEs to CIEs.
13
// That means the linker has to understand the format of the section.
14
//
15
// This file contains a few utility functions to read .eh_frame contents.
16
//
17
//===----------------------------------------------------------------------===//
18
19
#include "EhFrame.h"
20
#include "Error.h"
21
#include "InputSection.h"
22
#include "Relocations.h"
23
#include "Strings.h"
24
25
#include "llvm/BinaryFormat/Dwarf.h"
26
#include "llvm/Object/ELF.h"
27
#include "llvm/Support/Endian.h"
28
29
using namespace llvm;
30
using namespace llvm::ELF;
31
using namespace llvm::dwarf;
32
using namespace llvm::object;
33
using namespace llvm::support::endian;
34
35
using namespace lld;
36
using namespace lld::elf;
37
38
namespace {
39
template <class ELFT> class EhReader {
40
public:
41
217
  EhReader(InputSectionBase *S, ArrayRef<uint8_t> D) : IS(S), D(D) {}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, true> >::EhReader(lld::elf::InputSectionBase*, llvm::ArrayRef<unsigned char>)
Line
Count
Source
41
8
  EhReader(InputSectionBase *S, ArrayRef<uint8_t> D) : IS(S), D(D) {}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, true> >::EhReader(lld::elf::InputSectionBase*, llvm::ArrayRef<unsigned char>)
Line
Count
Source
41
198
  EhReader(InputSectionBase *S, ArrayRef<uint8_t> D) : IS(S), D(D) {}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, false> >::EhReader(lld::elf::InputSectionBase*, llvm::ArrayRef<unsigned char>)
Line
Count
Source
41
3
  EhReader(InputSectionBase *S, ArrayRef<uint8_t> D) : IS(S), D(D) {}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, false> >::EhReader(lld::elf::InputSectionBase*, llvm::ArrayRef<unsigned char>)
Line
Count
Source
41
8
  EhReader(InputSectionBase *S, ArrayRef<uint8_t> D) : IS(S), D(D) {}
42
  size_t readEhRecordSize();
43
  uint8_t getFdeEncoding();
44
45
private:
46
0
  template <class P> void failOn(const P *Loc, const Twine &Msg) {
47
0
    fatal("corrupted .eh_frame: " + Msg + "\n>>> defined in " +
48
0
          IS->getObjMsg<ELFT>((const uint8_t *)Loc - IS->Data.data()));
49
0
  }
Unexecuted instantiation: EhFrame.cpp:void (anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, false> >::failOn<unsigned char>(unsigned char const*, llvm::Twine const&)
Unexecuted instantiation: EhFrame.cpp:void (anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, false> >::failOn<char>(char const*, llvm::Twine const&)
Unexecuted instantiation: EhFrame.cpp:void (anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, false> >::failOn<unsigned char>(unsigned char const*, llvm::Twine const&)
Unexecuted instantiation: EhFrame.cpp:void (anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, true> >::failOn<unsigned char>(unsigned char const*, llvm::Twine const&)
Unexecuted instantiation: EhFrame.cpp:void (anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, true> >::failOn<unsigned char>(unsigned char const*, llvm::Twine const&)
Unexecuted instantiation: EhFrame.cpp:void (anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, true> >::failOn<char>(char const*, llvm::Twine const&)
Unexecuted instantiation: EhFrame.cpp:void (anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, false> >::failOn<char>(char const*, llvm::Twine const&)
Unexecuted instantiation: EhFrame.cpp:void (anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, true> >::failOn<char>(char const*, llvm::Twine const&)
50
51
  uint8_t readByte();
52
  void skipBytes(size_t Count);
53
  StringRef readString();
54
  void skipLeb128();
55
  void skipAugP();
56
57
  InputSectionBase *IS;
58
  ArrayRef<uint8_t> D;
59
};
60
}
61
62
template <class ELFT>
63
203
size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off) {
64
203
  return EhReader<ELFT>(S, S->Data.slice(Off)).readEhRecordSize();
65
203
}
unsigned long lld::elf::readEhRecordSize<llvm::object::ELFType<(llvm::support::endianness)1, false> >(lld::elf::InputSectionBase*, unsigned long)
Line
Count
Source
63
8
size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off) {
64
8
  return EhReader<ELFT>(S, S->Data.slice(Off)).readEhRecordSize();
65
8
}
unsigned long lld::elf::readEhRecordSize<llvm::object::ELFType<(llvm::support::endianness)1, true> >(lld::elf::InputSectionBase*, unsigned long)
Line
Count
Source
63
188
size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off) {
64
188
  return EhReader<ELFT>(S, S->Data.slice(Off)).readEhRecordSize();
65
188
}
unsigned long lld::elf::readEhRecordSize<llvm::object::ELFType<(llvm::support::endianness)0, false> >(lld::elf::InputSectionBase*, unsigned long)
Line
Count
Source
63
2
size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off) {
64
2
  return EhReader<ELFT>(S, S->Data.slice(Off)).readEhRecordSize();
65
2
}
unsigned long lld::elf::readEhRecordSize<llvm::object::ELFType<(llvm::support::endianness)0, true> >(lld::elf::InputSectionBase*, unsigned long)
Line
Count
Source
63
5
size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off) {
64
5
  return EhReader<ELFT>(S, S->Data.slice(Off)).readEhRecordSize();
65
5
}
66
67
// .eh_frame section is a sequence of records. Each record starts with
68
// a 4 byte length field. This function reads the length.
69
203
template <class ELFT> size_t EhReader<ELFT>::readEhRecordSize() {
70
203
  const endianness E = ELFT::TargetEndianness;
71
203
  if (D.size() < 4)
72
0
    failOn(D.data(), "CIE/FDE too small");
73
203
74
203
  // First 4 bytes of CIE/FDE is the size of the record.
75
203
  // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
76
203
  // but we do not support that format yet.
77
203
  uint64_t V = read32<E>(D.data());
78
203
  if (V == UINT32_MAX)
79
0
    failOn(D.data(), "CIE/FDE too large");
80
203
  uint64_t Size = V + 4;
81
203
  if (Size > D.size())
82
0
    failOn(D.data(), "CIE/FDE ends past the end of the section");
83
203
  return Size;
84
203
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, false> >::readEhRecordSize()
Line
Count
Source
69
8
template <class ELFT> size_t EhReader<ELFT>::readEhRecordSize() {
70
8
  const endianness E = ELFT::TargetEndianness;
71
8
  if (D.size() < 4)
72
0
    failOn(D.data(), "CIE/FDE too small");
73
8
74
8
  // First 4 bytes of CIE/FDE is the size of the record.
75
8
  // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
76
8
  // but we do not support that format yet.
77
8
  uint64_t V = read32<E>(D.data());
78
8
  if (V == UINT32_MAX)
79
0
    failOn(D.data(), "CIE/FDE too large");
80
8
  uint64_t Size = V + 4;
81
8
  if (Size > D.size())
82
0
    failOn(D.data(), "CIE/FDE ends past the end of the section");
83
8
  return Size;
84
8
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, false> >::readEhRecordSize()
Line
Count
Source
69
2
template <class ELFT> size_t EhReader<ELFT>::readEhRecordSize() {
70
2
  const endianness E = ELFT::TargetEndianness;
71
2
  if (D.size() < 4)
72
0
    failOn(D.data(), "CIE/FDE too small");
73
2
74
2
  // First 4 bytes of CIE/FDE is the size of the record.
75
2
  // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
76
2
  // but we do not support that format yet.
77
2
  uint64_t V = read32<E>(D.data());
78
2
  if (V == UINT32_MAX)
79
0
    failOn(D.data(), "CIE/FDE too large");
80
2
  uint64_t Size = V + 4;
81
2
  if (Size > D.size())
82
0
    failOn(D.data(), "CIE/FDE ends past the end of the section");
83
2
  return Size;
84
2
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, true> >::readEhRecordSize()
Line
Count
Source
69
5
template <class ELFT> size_t EhReader<ELFT>::readEhRecordSize() {
70
5
  const endianness E = ELFT::TargetEndianness;
71
5
  if (D.size() < 4)
72
0
    failOn(D.data(), "CIE/FDE too small");
73
5
74
5
  // First 4 bytes of CIE/FDE is the size of the record.
75
5
  // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
76
5
  // but we do not support that format yet.
77
5
  uint64_t V = read32<E>(D.data());
78
5
  if (V == UINT32_MAX)
79
0
    failOn(D.data(), "CIE/FDE too large");
80
5
  uint64_t Size = V + 4;
81
5
  if (Size > D.size())
82
0
    failOn(D.data(), "CIE/FDE ends past the end of the section");
83
5
  return Size;
84
5
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, true> >::readEhRecordSize()
Line
Count
Source
69
188
template <class ELFT> size_t EhReader<ELFT>::readEhRecordSize() {
70
188
  const endianness E = ELFT::TargetEndianness;
71
188
  if (D.size() < 4)
72
0
    failOn(D.data(), "CIE/FDE too small");
73
188
74
188
  // First 4 bytes of CIE/FDE is the size of the record.
75
188
  // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
76
188
  // but we do not support that format yet.
77
188
  uint64_t V = read32<E>(D.data());
78
188
  if (V == UINT32_MAX)
79
0
    failOn(D.data(), "CIE/FDE too large");
80
188
  uint64_t Size = V + 4;
81
188
  if (Size > D.size())
82
0
    failOn(D.data(), "CIE/FDE ends past the end of the section");
83
188
  return Size;
84
188
}
85
86
// Read a byte and advance D by one byte.
87
45
template <class ELFT> uint8_t EhReader<ELFT>::readByte() {
88
45
  if (D.empty())
89
0
    failOn(D.data(), "unexpected end of CIE");
90
45
  uint8_t B = D.front();
91
45
  D = D.slice(1);
92
45
  return B;
93
45
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, false> >::readByte()
Line
Count
Source
87
4
template <class ELFT> uint8_t EhReader<ELFT>::readByte() {
88
4
  if (D.empty())
89
0
    failOn(D.data(), "unexpected end of CIE");
90
4
  uint8_t B = D.front();
91
4
  D = D.slice(1);
92
4
  return B;
93
4
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, true> >::readByte()
Line
Count
Source
87
33
template <class ELFT> uint8_t EhReader<ELFT>::readByte() {
88
33
  if (D.empty())
89
0
    failOn(D.data(), "unexpected end of CIE");
90
33
  uint8_t B = D.front();
91
33
  D = D.slice(1);
92
33
  return B;
93
33
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, true> >::readByte()
Line
Count
Source
87
8
template <class ELFT> uint8_t EhReader<ELFT>::readByte() {
88
8
  if (D.empty())
89
0
    failOn(D.data(), "unexpected end of CIE");
90
8
  uint8_t B = D.front();
91
8
  D = D.slice(1);
92
8
  return B;
93
8
}
Unexecuted instantiation: EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, false> >::readByte()
94
95
14
template <class ELFT> void EhReader<ELFT>::skipBytes(size_t Count) {
96
14
  if (D.size() < Count)
97
0
    failOn(D.data(), "CIE is too small");
98
14
  D = D.slice(Count);
99
14
}
Unexecuted instantiation: EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, false> >::skipBytes(unsigned long)
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, false> >::skipBytes(unsigned long)
Line
Count
Source
95
1
template <class ELFT> void EhReader<ELFT>::skipBytes(size_t Count) {
96
1
  if (D.size() < Count)
97
0
    failOn(D.data(), "CIE is too small");
98
1
  D = D.slice(Count);
99
1
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, true> >::skipBytes(unsigned long)
Line
Count
Source
95
10
template <class ELFT> void EhReader<ELFT>::skipBytes(size_t Count) {
96
10
  if (D.size() < Count)
97
0
    failOn(D.data(), "CIE is too small");
98
10
  D = D.slice(Count);
99
10
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, true> >::skipBytes(unsigned long)
Line
Count
Source
95
3
template <class ELFT> void EhReader<ELFT>::skipBytes(size_t Count) {
96
3
  if (D.size() < Count)
97
0
    failOn(D.data(), "CIE is too small");
98
3
  D = D.slice(Count);
99
3
}
100
101
// Read a null-terminated string.
102
14
template <class ELFT> StringRef EhReader<ELFT>::readString() {
103
14
  const uint8_t *End = std::find(D.begin(), D.end(), '\0');
104
14
  if (End == D.end())
105
0
    failOn(D.data(), "corrupted CIE (failed to read string)");
106
14
  StringRef S = toStringRef(D.slice(0, End - D.begin()));
107
14
  D = D.slice(S.size() + 1);
108
14
  return S;
109
14
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, true> >::readString()
Line
Count
Source
102
3
template <class ELFT> StringRef EhReader<ELFT>::readString() {
103
3
  const uint8_t *End = std::find(D.begin(), D.end(), '\0');
104
3
  if (End == D.end())
105
0
    failOn(D.data(), "corrupted CIE (failed to read string)");
106
3
  StringRef S = toStringRef(D.slice(0, End - D.begin()));
107
3
  D = D.slice(S.size() + 1);
108
3
  return S;
109
3
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, true> >::readString()
Line
Count
Source
102
10
template <class ELFT> StringRef EhReader<ELFT>::readString() {
103
10
  const uint8_t *End = std::find(D.begin(), D.end(), '\0');
104
10
  if (End == D.end())
105
0
    failOn(D.data(), "corrupted CIE (failed to read string)");
106
10
  StringRef S = toStringRef(D.slice(0, End - D.begin()));
107
10
  D = D.slice(S.size() + 1);
108
10
  return S;
109
10
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, false> >::readString()
Line
Count
Source
102
1
template <class ELFT> StringRef EhReader<ELFT>::readString() {
103
1
  const uint8_t *End = std::find(D.begin(), D.end(), '\0');
104
1
  if (End == D.end())
105
0
    failOn(D.data(), "corrupted CIE (failed to read string)");
106
1
  StringRef S = toStringRef(D.slice(0, End - D.begin()));
107
1
  D = D.slice(S.size() + 1);
108
1
  return S;
109
1
}
Unexecuted instantiation: EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, false> >::readString()
110
111
// Skip an integer encoded in the LEB128 format.
112
// Actual number is not of interest because only the runtime needs it.
113
// But we need to be at least able to skip it so that we can read
114
// the field that follows a LEB128 number.
115
41
template <class ELFT> void EhReader<ELFT>::skipLeb128() {
116
41
  const uint8_t *ErrPos = D.data();
117
41
  while (
!D.empty()41
) {
118
41
    uint8_t Val = D.front();
119
41
    D = D.slice(1);
120
41
    if ((Val & 0x80) == 0)
121
41
      return;
122
41
  }
123
0
  failOn(ErrPos, "corrupted CIE (failed to read LEB128)");
124
0
}
Unexecuted instantiation: EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, false> >::skipLeb128()
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, true> >::skipLeb128()
Line
Count
Source
115
8
template <class ELFT> void EhReader<ELFT>::skipLeb128() {
116
8
  const uint8_t *ErrPos = D.data();
117
8
  while (
!D.empty()8
) {
118
8
    uint8_t Val = D.front();
119
8
    D = D.slice(1);
120
8
    if ((Val & 0x80) == 0)
121
8
      return;
122
8
  }
123
0
  failOn(ErrPos, "corrupted CIE (failed to read LEB128)");
124
0
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, true> >::skipLeb128()
Line
Count
Source
115
30
template <class ELFT> void EhReader<ELFT>::skipLeb128() {
116
30
  const uint8_t *ErrPos = D.data();
117
30
  while (
!D.empty()30
) {
118
30
    uint8_t Val = D.front();
119
30
    D = D.slice(1);
120
30
    if ((Val & 0x80) == 0)
121
30
      return;
122
30
  }
123
0
  failOn(ErrPos, "corrupted CIE (failed to read LEB128)");
124
0
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, false> >::skipLeb128()
Line
Count
Source
115
3
template <class ELFT> void EhReader<ELFT>::skipLeb128() {
116
3
  const uint8_t *ErrPos = D.data();
117
3
  while (
!D.empty()3
) {
118
3
    uint8_t Val = D.front();
119
3
    D = D.slice(1);
120
3
    if ((Val & 0x80) == 0)
121
3
      return;
122
3
  }
123
0
  failOn(ErrPos, "corrupted CIE (failed to read LEB128)");
124
0
}
125
126
2
static size_t getAugPSize(unsigned Enc) {
127
2
  switch (Enc & 0x0f) {
128
0
  case DW_EH_PE_absptr:
129
0
  case DW_EH_PE_signed:
130
0
    return Config->Wordsize;
131
0
  case DW_EH_PE_udata2:
132
0
  case DW_EH_PE_sdata2:
133
0
    return 2;
134
2
  case DW_EH_PE_udata4:
135
2
  case DW_EH_PE_sdata4:
136
2
    return 4;
137
0
  case DW_EH_PE_udata8:
138
0
  case DW_EH_PE_sdata8:
139
0
    return 8;
140
0
  }
141
0
  return 0;
142
0
}
143
144
2
template <class ELFT> void EhReader<ELFT>::skipAugP() {
145
2
  uint8_t Enc = readByte();
146
2
  if ((Enc & 0xf0) == DW_EH_PE_aligned)
147
0
    failOn(D.data() - 1, "DW_EH_PE_aligned encoding is not supported");
148
2
  size_t Size = getAugPSize(Enc);
149
2
  if (Size == 0)
150
0
    failOn(D.data() - 1, "unknown FDE encoding");
151
2
  if (Size >= D.size())
152
0
    failOn(D.data() - 1, "corrupted CIE");
153
2
  D = D.slice(Size);
154
2
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, true> >::skipAugP()
Line
Count
Source
144
2
template <class ELFT> void EhReader<ELFT>::skipAugP() {
145
2
  uint8_t Enc = readByte();
146
2
  if ((Enc & 0xf0) == DW_EH_PE_aligned)
147
0
    failOn(D.data() - 1, "DW_EH_PE_aligned encoding is not supported");
148
2
  size_t Size = getAugPSize(Enc);
149
2
  if (Size == 0)
150
0
    failOn(D.data() - 1, "unknown FDE encoding");
151
2
  if (Size >= D.size())
152
0
    failOn(D.data() - 1, "corrupted CIE");
153
2
  D = D.slice(Size);
154
2
}
Unexecuted instantiation: EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, false> >::skipAugP()
Unexecuted instantiation: EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, false> >::skipAugP()
Unexecuted instantiation: EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, true> >::skipAugP()
155
156
14
template <class ELFT> uint8_t elf::getFdeEncoding(EhSectionPiece *P) {
157
14
  return EhReader<ELFT>(P->Sec, P->data()).getFdeEncoding();
158
14
}
unsigned char lld::elf::getFdeEncoding<llvm::object::ELFType<(llvm::support::endianness)0, true> >(lld::elf::EhSectionPiece*)
Line
Count
Source
156
3
template <class ELFT> uint8_t elf::getFdeEncoding(EhSectionPiece *P) {
157
3
  return EhReader<ELFT>(P->Sec, P->data()).getFdeEncoding();
158
3
}
unsigned char lld::elf::getFdeEncoding<llvm::object::ELFType<(llvm::support::endianness)1, true> >(lld::elf::EhSectionPiece*)
Line
Count
Source
156
10
template <class ELFT> uint8_t elf::getFdeEncoding(EhSectionPiece *P) {
157
10
  return EhReader<ELFT>(P->Sec, P->data()).getFdeEncoding();
158
10
}
unsigned char lld::elf::getFdeEncoding<llvm::object::ELFType<(llvm::support::endianness)0, false> >(lld::elf::EhSectionPiece*)
Line
Count
Source
156
1
template <class ELFT> uint8_t elf::getFdeEncoding(EhSectionPiece *P) {
157
1
  return EhReader<ELFT>(P->Sec, P->data()).getFdeEncoding();
158
1
}
Unexecuted instantiation: unsigned char lld::elf::getFdeEncoding<llvm::object::ELFType<(llvm::support::endianness)1, false> >(lld::elf::EhSectionPiece*)
159
160
14
template <class ELFT> uint8_t EhReader<ELFT>::getFdeEncoding() {
161
14
  skipBytes(8);
162
14
  int Version = readByte();
163
14
  if (
Version != 1 && 14
Version != 30
)
164
0
    failOn(D.data() - 1,
165
0
           "FDE version 1 or 3 expected, but got " + Twine(Version));
166
14
167
14
  StringRef Aug = readString();
168
14
169
14
  // Skip code and data alignment factors.
170
14
  skipLeb128();
171
14
  skipLeb128();
172
14
173
14
  // Skip the return address register. In CIE version 1 this is a single
174
14
  // byte. In CIE version 3 this is an unsigned LEB128.
175
14
  if (Version == 1)
176
14
    readByte();
177
14
  else
178
0
    skipLeb128();
179
14
180
14
  // We only care about an 'R' value, but other records may precede an 'R'
181
14
  // record. Unfortunately records are not in TLV (type-length-value) format,
182
14
  // so we need to teach the linker how to skip records for each type.
183
30
  for (char C : Aug) {
184
30
    if (C == 'R')
185
13
      return readByte();
186
17
    
if (17
C == 'z'17
) {
187
13
      skipLeb128();
188
13
      continue;
189
13
    }
190
4
    
if (4
C == 'P'4
) {
191
2
      skipAugP();
192
2
      continue;
193
2
    }
194
2
    
if (2
C == 'L'2
) {
195
2
      readByte();
196
2
      continue;
197
2
    }
198
0
    failOn(Aug.data(), "unknown .eh_frame augmentation string: " + Aug);
199
0
  }
200
1
  return DW_EH_PE_absptr;
201
14
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getFdeEncoding()
Line
Count
Source
160
3
template <class ELFT> uint8_t EhReader<ELFT>::getFdeEncoding() {
161
3
  skipBytes(8);
162
3
  int Version = readByte();
163
3
  if (
Version != 1 && 3
Version != 30
)
164
0
    failOn(D.data() - 1,
165
0
           "FDE version 1 or 3 expected, but got " + Twine(Version));
166
3
167
3
  StringRef Aug = readString();
168
3
169
3
  // Skip code and data alignment factors.
170
3
  skipLeb128();
171
3
  skipLeb128();
172
3
173
3
  // Skip the return address register. In CIE version 1 this is a single
174
3
  // byte. In CIE version 3 this is an unsigned LEB128.
175
3
  if (Version == 1)
176
3
    readByte();
177
3
  else
178
0
    skipLeb128();
179
3
180
3
  // We only care about an 'R' value, but other records may precede an 'R'
181
3
  // record. Unfortunately records are not in TLV (type-length-value) format,
182
3
  // so we need to teach the linker how to skip records for each type.
183
4
  for (char C : Aug) {
184
4
    if (C == 'R')
185
2
      return readByte();
186
2
    
if (2
C == 'z'2
) {
187
2
      skipLeb128();
188
2
      continue;
189
2
    }
190
0
    
if (0
C == 'P'0
) {
191
0
      skipAugP();
192
0
      continue;
193
0
    }
194
0
    
if (0
C == 'L'0
) {
195
0
      readByte();
196
0
      continue;
197
0
    }
198
0
    failOn(Aug.data(), "unknown .eh_frame augmentation string: " + Aug);
199
0
  }
200
1
  return DW_EH_PE_absptr;
201
3
}
Unexecuted instantiation: EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getFdeEncoding()
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getFdeEncoding()
Line
Count
Source
160
1
template <class ELFT> uint8_t EhReader<ELFT>::getFdeEncoding() {
161
1
  skipBytes(8);
162
1
  int Version = readByte();
163
1
  if (
Version != 1 && 1
Version != 30
)
164
0
    failOn(D.data() - 1,
165
0
           "FDE version 1 or 3 expected, but got " + Twine(Version));
166
1
167
1
  StringRef Aug = readString();
168
1
169
1
  // Skip code and data alignment factors.
170
1
  skipLeb128();
171
1
  skipLeb128();
172
1
173
1
  // Skip the return address register. In CIE version 1 this is a single
174
1
  // byte. In CIE version 3 this is an unsigned LEB128.
175
1
  if (Version == 1)
176
1
    readByte();
177
1
  else
178
0
    skipLeb128();
179
1
180
1
  // We only care about an 'R' value, but other records may precede an 'R'
181
1
  // record. Unfortunately records are not in TLV (type-length-value) format,
182
1
  // so we need to teach the linker how to skip records for each type.
183
3
  for (char C : Aug) {
184
3
    if (C == 'R')
185
1
      return readByte();
186
2
    
if (2
C == 'z'2
) {
187
1
      skipLeb128();
188
1
      continue;
189
1
    }
190
1
    
if (1
C == 'P'1
) {
191
0
      skipAugP();
192
0
      continue;
193
0
    }
194
1
    
if (1
C == 'L'1
) {
195
1
      readByte();
196
1
      continue;
197
1
    }
198
0
    failOn(Aug.data(), "unknown .eh_frame augmentation string: " + Aug);
199
0
  }
200
0
  return DW_EH_PE_absptr;
201
1
}
EhFrame.cpp:(anonymous namespace)::EhReader<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getFdeEncoding()
Line
Count
Source
160
10
template <class ELFT> uint8_t EhReader<ELFT>::getFdeEncoding() {
161
10
  skipBytes(8);
162
10
  int Version = readByte();
163
10
  if (
Version != 1 && 10
Version != 30
)
164
0
    failOn(D.data() - 1,
165
0
           "FDE version 1 or 3 expected, but got " + Twine(Version));
166
10
167
10
  StringRef Aug = readString();
168
10
169
10
  // Skip code and data alignment factors.
170
10
  skipLeb128();
171
10
  skipLeb128();
172
10
173
10
  // Skip the return address register. In CIE version 1 this is a single
174
10
  // byte. In CIE version 3 this is an unsigned LEB128.
175
10
  if (Version == 1)
176
10
    readByte();
177
10
  else
178
0
    skipLeb128();
179
10
180
10
  // We only care about an 'R' value, but other records may precede an 'R'
181
10
  // record. Unfortunately records are not in TLV (type-length-value) format,
182
10
  // so we need to teach the linker how to skip records for each type.
183
23
  for (char C : Aug) {
184
23
    if (C == 'R')
185
10
      return readByte();
186
13
    
if (13
C == 'z'13
) {
187
10
      skipLeb128();
188
10
      continue;
189
10
    }
190
3
    
if (3
C == 'P'3
) {
191
2
      skipAugP();
192
2
      continue;
193
2
    }
194
1
    
if (1
C == 'L'1
) {
195
1
      readByte();
196
1
      continue;
197
1
    }
198
0
    failOn(Aug.data(), "unknown .eh_frame augmentation string: " + Aug);
199
0
  }
200
0
  return DW_EH_PE_absptr;
201
10
}
202
203
template size_t elf::readEhRecordSize<ELF32LE>(InputSectionBase *S, size_t Off);
204
template size_t elf::readEhRecordSize<ELF32BE>(InputSectionBase *S, size_t Off);
205
template size_t elf::readEhRecordSize<ELF64LE>(InputSectionBase *S, size_t Off);
206
template size_t elf::readEhRecordSize<ELF64BE>(InputSectionBase *S, size_t Off);
207
208
template uint8_t elf::getFdeEncoding<ELF32LE>(EhSectionPiece *P);
209
template uint8_t elf::getFdeEncoding<ELF32BE>(EhSectionPiece *P);
210
template uint8_t elf::getFdeEncoding<ELF64LE>(EhSectionPiece *P);
211
template uint8_t elf::getFdeEncoding<ELF64BE>(EhSectionPiece *P);