10b57cec5SDimitry Andric //===- EhFrame.cpp -------------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // .eh_frame section contains information on how to unwind the stack when 100b57cec5SDimitry Andric // an exception is thrown. The section consists of sequence of CIE and FDE 110b57cec5SDimitry Andric // records. The linker needs to merge CIEs and associate FDEs to CIEs. 120b57cec5SDimitry Andric // That means the linker has to understand the format of the section. 130b57cec5SDimitry Andric // 140b57cec5SDimitry Andric // This file contains a few utility functions to read .eh_frame contents. 150b57cec5SDimitry Andric // 160b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include "EhFrame.h" 190b57cec5SDimitry Andric #include "Config.h" 200b57cec5SDimitry Andric #include "InputSection.h" 210b57cec5SDimitry Andric #include "Relocations.h" 220b57cec5SDimitry Andric #include "Target.h" 230b57cec5SDimitry Andric #include "lld/Common/ErrorHandler.h" 240b57cec5SDimitry Andric #include "lld/Common/Strings.h" 250b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 260b57cec5SDimitry Andric #include "llvm/Object/ELF.h" 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric using namespace llvm; 290b57cec5SDimitry Andric using namespace llvm::ELF; 300b57cec5SDimitry Andric using namespace llvm::dwarf; 310b57cec5SDimitry Andric using namespace llvm::object; 325ffd83dbSDimitry Andric using namespace lld; 335ffd83dbSDimitry Andric using namespace lld::elf; 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric namespace { 360b57cec5SDimitry Andric class EhReader { 370b57cec5SDimitry Andric public: 380b57cec5SDimitry Andric EhReader(InputSectionBase *s, ArrayRef<uint8_t> d) : isec(s), d(d) {} 390b57cec5SDimitry Andric size_t readEhRecordSize(); 400b57cec5SDimitry Andric uint8_t getFdeEncoding(); 41*e8d8bef9SDimitry Andric bool hasLSDA(); 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric private: 440b57cec5SDimitry Andric template <class P> void failOn(const P *loc, const Twine &msg) { 450b57cec5SDimitry Andric fatal("corrupted .eh_frame: " + msg + "\n>>> defined in " + 460b57cec5SDimitry Andric isec->getObjMsg((const uint8_t *)loc - isec->data().data())); 470b57cec5SDimitry Andric } 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric uint8_t readByte(); 500b57cec5SDimitry Andric void skipBytes(size_t count); 510b57cec5SDimitry Andric StringRef readString(); 520b57cec5SDimitry Andric void skipLeb128(); 530b57cec5SDimitry Andric void skipAugP(); 54*e8d8bef9SDimitry Andric StringRef getAugmentation(); 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric InputSectionBase *isec; 570b57cec5SDimitry Andric ArrayRef<uint8_t> d; 580b57cec5SDimitry Andric }; 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric 615ffd83dbSDimitry Andric size_t elf::readEhRecordSize(InputSectionBase *s, size_t off) { 620b57cec5SDimitry Andric return EhReader(s, s->data().slice(off)).readEhRecordSize(); 630b57cec5SDimitry Andric } 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric // .eh_frame section is a sequence of records. Each record starts with 660b57cec5SDimitry Andric // a 4 byte length field. This function reads the length. 670b57cec5SDimitry Andric size_t EhReader::readEhRecordSize() { 680b57cec5SDimitry Andric if (d.size() < 4) 690b57cec5SDimitry Andric failOn(d.data(), "CIE/FDE too small"); 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric // First 4 bytes of CIE/FDE is the size of the record. 720b57cec5SDimitry Andric // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead, 730b57cec5SDimitry Andric // but we do not support that format yet. 740b57cec5SDimitry Andric uint64_t v = read32(d.data()); 750b57cec5SDimitry Andric if (v == UINT32_MAX) 760b57cec5SDimitry Andric failOn(d.data(), "CIE/FDE too large"); 770b57cec5SDimitry Andric uint64_t size = v + 4; 780b57cec5SDimitry Andric if (size > d.size()) 790b57cec5SDimitry Andric failOn(d.data(), "CIE/FDE ends past the end of the section"); 800b57cec5SDimitry Andric return size; 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric // Read a byte and advance D by one byte. 840b57cec5SDimitry Andric uint8_t EhReader::readByte() { 850b57cec5SDimitry Andric if (d.empty()) 860b57cec5SDimitry Andric failOn(d.data(), "unexpected end of CIE"); 870b57cec5SDimitry Andric uint8_t b = d.front(); 880b57cec5SDimitry Andric d = d.slice(1); 890b57cec5SDimitry Andric return b; 900b57cec5SDimitry Andric } 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric void EhReader::skipBytes(size_t count) { 930b57cec5SDimitry Andric if (d.size() < count) 940b57cec5SDimitry Andric failOn(d.data(), "CIE is too small"); 950b57cec5SDimitry Andric d = d.slice(count); 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric // Read a null-terminated string. 990b57cec5SDimitry Andric StringRef EhReader::readString() { 1000b57cec5SDimitry Andric const uint8_t *end = llvm::find(d, '\0'); 1010b57cec5SDimitry Andric if (end == d.end()) 1020b57cec5SDimitry Andric failOn(d.data(), "corrupted CIE (failed to read string)"); 1030b57cec5SDimitry Andric StringRef s = toStringRef(d.slice(0, end - d.begin())); 1040b57cec5SDimitry Andric d = d.slice(s.size() + 1); 1050b57cec5SDimitry Andric return s; 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric // Skip an integer encoded in the LEB128 format. 1090b57cec5SDimitry Andric // Actual number is not of interest because only the runtime needs it. 1100b57cec5SDimitry Andric // But we need to be at least able to skip it so that we can read 1110b57cec5SDimitry Andric // the field that follows a LEB128 number. 1120b57cec5SDimitry Andric void EhReader::skipLeb128() { 1130b57cec5SDimitry Andric const uint8_t *errPos = d.data(); 1140b57cec5SDimitry Andric while (!d.empty()) { 1150b57cec5SDimitry Andric uint8_t val = d.front(); 1160b57cec5SDimitry Andric d = d.slice(1); 1170b57cec5SDimitry Andric if ((val & 0x80) == 0) 1180b57cec5SDimitry Andric return; 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric failOn(errPos, "corrupted CIE (failed to read LEB128)"); 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric static size_t getAugPSize(unsigned enc) { 1240b57cec5SDimitry Andric switch (enc & 0x0f) { 1250b57cec5SDimitry Andric case DW_EH_PE_absptr: 1260b57cec5SDimitry Andric case DW_EH_PE_signed: 1270b57cec5SDimitry Andric return config->wordsize; 1280b57cec5SDimitry Andric case DW_EH_PE_udata2: 1290b57cec5SDimitry Andric case DW_EH_PE_sdata2: 1300b57cec5SDimitry Andric return 2; 1310b57cec5SDimitry Andric case DW_EH_PE_udata4: 1320b57cec5SDimitry Andric case DW_EH_PE_sdata4: 1330b57cec5SDimitry Andric return 4; 1340b57cec5SDimitry Andric case DW_EH_PE_udata8: 1350b57cec5SDimitry Andric case DW_EH_PE_sdata8: 1360b57cec5SDimitry Andric return 8; 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric return 0; 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric void EhReader::skipAugP() { 1420b57cec5SDimitry Andric uint8_t enc = readByte(); 1430b57cec5SDimitry Andric if ((enc & 0xf0) == DW_EH_PE_aligned) 1440b57cec5SDimitry Andric failOn(d.data() - 1, "DW_EH_PE_aligned encoding is not supported"); 1450b57cec5SDimitry Andric size_t size = getAugPSize(enc); 1460b57cec5SDimitry Andric if (size == 0) 1470b57cec5SDimitry Andric failOn(d.data() - 1, "unknown FDE encoding"); 1480b57cec5SDimitry Andric if (size >= d.size()) 1490b57cec5SDimitry Andric failOn(d.data() - 1, "corrupted CIE"); 1500b57cec5SDimitry Andric d = d.slice(size); 1510b57cec5SDimitry Andric } 1520b57cec5SDimitry Andric 1535ffd83dbSDimitry Andric uint8_t elf::getFdeEncoding(EhSectionPiece *p) { 1540b57cec5SDimitry Andric return EhReader(p->sec, p->data()).getFdeEncoding(); 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric 157*e8d8bef9SDimitry Andric bool elf::hasLSDA(const EhSectionPiece &p) { 158*e8d8bef9SDimitry Andric return EhReader(p.sec, p.data()).hasLSDA(); 159*e8d8bef9SDimitry Andric } 160*e8d8bef9SDimitry Andric 161*e8d8bef9SDimitry Andric StringRef EhReader::getAugmentation() { 1620b57cec5SDimitry Andric skipBytes(8); 1630b57cec5SDimitry Andric int version = readByte(); 1640b57cec5SDimitry Andric if (version != 1 && version != 3) 1650b57cec5SDimitry Andric failOn(d.data() - 1, 1660b57cec5SDimitry Andric "FDE version 1 or 3 expected, but got " + Twine(version)); 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric StringRef aug = readString(); 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric // Skip code and data alignment factors. 1710b57cec5SDimitry Andric skipLeb128(); 1720b57cec5SDimitry Andric skipLeb128(); 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric // Skip the return address register. In CIE version 1 this is a single 1750b57cec5SDimitry Andric // byte. In CIE version 3 this is an unsigned LEB128. 1760b57cec5SDimitry Andric if (version == 1) 1770b57cec5SDimitry Andric readByte(); 1780b57cec5SDimitry Andric else 1790b57cec5SDimitry Andric skipLeb128(); 180*e8d8bef9SDimitry Andric return aug; 181*e8d8bef9SDimitry Andric } 1820b57cec5SDimitry Andric 183*e8d8bef9SDimitry Andric uint8_t EhReader::getFdeEncoding() { 1840b57cec5SDimitry Andric // We only care about an 'R' value, but other records may precede an 'R' 1850b57cec5SDimitry Andric // record. Unfortunately records are not in TLV (type-length-value) format, 1860b57cec5SDimitry Andric // so we need to teach the linker how to skip records for each type. 187*e8d8bef9SDimitry Andric StringRef aug = getAugmentation(); 1880b57cec5SDimitry Andric for (char c : aug) { 1890b57cec5SDimitry Andric if (c == 'R') 1900b57cec5SDimitry Andric return readByte(); 191*e8d8bef9SDimitry Andric if (c == 'z') 1920b57cec5SDimitry Andric skipLeb128(); 193*e8d8bef9SDimitry Andric else if (c == 'L') 1940b57cec5SDimitry Andric readByte(); 195*e8d8bef9SDimitry Andric else if (c == 'P') 196*e8d8bef9SDimitry Andric skipAugP(); 197*e8d8bef9SDimitry Andric else if (c != 'B' && c != 'S') 1980b57cec5SDimitry Andric failOn(aug.data(), "unknown .eh_frame augmentation string: " + aug); 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric return DW_EH_PE_absptr; 2010b57cec5SDimitry Andric } 202*e8d8bef9SDimitry Andric 203*e8d8bef9SDimitry Andric bool EhReader::hasLSDA() { 204*e8d8bef9SDimitry Andric StringRef aug = getAugmentation(); 205*e8d8bef9SDimitry Andric for (char c : aug) { 206*e8d8bef9SDimitry Andric if (c == 'L') 207*e8d8bef9SDimitry Andric return true; 208*e8d8bef9SDimitry Andric if (c == 'z') 209*e8d8bef9SDimitry Andric skipLeb128(); 210*e8d8bef9SDimitry Andric else if (c == 'P') 211*e8d8bef9SDimitry Andric skipAugP(); 212*e8d8bef9SDimitry Andric else if (c == 'R') 213*e8d8bef9SDimitry Andric readByte(); 214*e8d8bef9SDimitry Andric else if (c != 'B' && c != 'S') 215*e8d8bef9SDimitry Andric failOn(aug.data(), "unknown .eh_frame augmentation string: " + aug); 216*e8d8bef9SDimitry Andric } 217*e8d8bef9SDimitry Andric return false; 218*e8d8bef9SDimitry Andric } 219