Skip to content

Commit eafd345

Browse files
committed
[ELF] Simplify/optimize EhInputSection::split
and change some `fatal` to `errorOrWarn`. EhFrame.cpp is a helper file. We don't place all .eh_frame implementation there, so the code move is fine.
1 parent b6a9396 commit eafd345

File tree

3 files changed

+34
-36
lines changed

3 files changed

+34
-36
lines changed

lld/ELF/EhFrame.cpp

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ namespace {
3636
class EhReader {
3737
public:
3838
EhReader(InputSectionBase *s, ArrayRef<uint8_t> d) : isec(s), d(d) {}
39-
size_t readEhRecordSize();
4039
uint8_t getFdeEncoding();
4140
bool hasLSDA();
4241

@@ -58,28 +57,6 @@ class EhReader {
5857
};
5958
}
6059

61-
size_t elf::readEhRecordSize(InputSectionBase *s, size_t off) {
62-
return EhReader(s, s->data().slice(off)).readEhRecordSize();
63-
}
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.
67-
size_t EhReader::readEhRecordSize() {
68-
if (d.size() < 4)
69-
failOn(d.data(), "CIE/FDE too small");
70-
71-
// First 4 bytes of CIE/FDE is the size of the record.
72-
// If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
73-
// but we do not support that format yet.
74-
uint64_t v = read32(d.data());
75-
if (v == UINT32_MAX)
76-
failOn(d.data(), "CIE/FDE too large");
77-
uint64_t size = v + 4;
78-
if (size > d.size())
79-
failOn(d.data(), "CIE/FDE ends past the end of the section");
80-
return size;
81-
}
82-
8360
// Read a byte and advance D by one byte.
8461
uint8_t EhReader::readByte() {
8562
if (d.empty())

lld/ELF/EhFrame.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ namespace elf {
1616
class InputSectionBase;
1717
struct EhSectionPiece;
1818

19-
size_t readEhRecordSize(InputSectionBase *s, size_t off);
2019
uint8_t getFdeEncoding(EhSectionPiece *p);
2120
bool hasLSDA(const EhSectionPiece &p);
2221
} // namespace elf

lld/ELF/InputSection.cpp

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,25 +1323,47 @@ static unsigned getReloc(IntTy begin, IntTy size, const ArrayRef<RelTy> &rels,
13231323
// This function splits an input section into records and returns them.
13241324
template <class ELFT> void EhInputSection::split() {
13251325
const RelsOrRelas<ELFT> rels = relsOrRelas<ELFT>();
1326-
if (rels.areRelocsRel())
1327-
split<ELFT>(rels.rels);
1328-
else
1329-
split<ELFT>(rels.relas);
1326+
// getReloc expects the relocations to be sorted by r_offset. See the comment
1327+
// in scanRelocs.
1328+
if (rels.areRelocsRel()) {
1329+
SmallVector<typename ELFT::Rel, 0> storage;
1330+
split<ELFT>(sortRels(rels.rels, storage));
1331+
} else {
1332+
SmallVector<typename ELFT::Rela, 0> storage;
1333+
split<ELFT>(sortRels(rels.relas, storage));
1334+
}
13301335
}
13311336

13321337
template <class ELFT, class RelTy>
13331338
void EhInputSection::split(ArrayRef<RelTy> rels) {
1334-
// getReloc expects the relocations to be sorted by r_offset. See the comment
1335-
// in scanRelocs.
1336-
SmallVector<RelTy, 0> storage;
1337-
rels = sortRels(rels, storage);
1338-
1339+
ArrayRef<uint8_t> d = rawData;
1340+
const char *msg = nullptr;
13391341
unsigned relI = 0;
1340-
for (size_t off = 0, end = data().size(); off != end;) {
1341-
size_t size = readEhRecordSize(this, off);
1342+
while (!d.empty()) {
1343+
if (d.size() < 4) {
1344+
msg = "CIE/FDE too small";
1345+
break;
1346+
}
1347+
uint64_t size = endian::read32<ELFT::TargetEndianness>(d.data());
1348+
// If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
1349+
// but we do not support that format yet.
1350+
if (size == UINT32_MAX) {
1351+
msg = "CIE/FDE too large";
1352+
break;
1353+
}
1354+
size += 4;
1355+
if (size > d.size()) {
1356+
msg = "CIE/FDE ends past the end of the section";
1357+
break;
1358+
}
1359+
1360+
uint64_t off = d.data() - rawData.data();
13421361
pieces.emplace_back(off, this, size, getReloc(off, size, rels, relI));
1343-
off += size;
1362+
d = d.slice(size);
13441363
}
1364+
if (msg)
1365+
errorOrWarn("corrupted .eh_frame: " + Twine(msg) + "\n>>> defined in " +
1366+
getObjMsg(d.data() - rawData.data()));
13451367
}
13461368

13471369
static size_t findNull(StringRef s, size_t entSize) {

0 commit comments

Comments
 (0)