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