[ELF] Simplify EhInputSection::split. NFC

* Inline getReloc
* Fold the UINT32_MAX length check into the section size check.
  This transformation is valid because we don't support .eh_frame input sections
  larger than 32-bit (unrealistic even for large code models).
This commit is contained in:
Fangrui Song 2022-07-31 16:59:57 -07:00
parent 3e9adff456
commit af1328ef45
1 changed files with 15 additions and 29 deletions

View File

@ -1260,25 +1260,6 @@ SyntheticSection *EhInputSection::getParent() const {
return cast_or_null<SyntheticSection>(parent);
}
// Returns the index of the first relocation that points to a region between
// Begin and Begin+Size.
template <class IntTy, class RelTy>
static unsigned getReloc(IntTy begin, IntTy size, const ArrayRef<RelTy> &rels,
unsigned &relocI) {
// Start search from RelocI for fast access. That works because the
// relocations are sorted in .eh_frame.
for (unsigned n = rels.size(); relocI < n; ++relocI) {
const RelTy &rel = rels[relocI];
if (rel.r_offset < begin)
continue;
if (rel.r_offset < begin + size)
return relocI;
return -1;
}
return -1;
}
// .eh_frame is a sequence of CIE or FDE records.
// This function splits an input section into records and returns them.
template <class ELFT> void EhInputSection::split() {
@ -1308,20 +1289,25 @@ void EhInputSection::split(ArrayRef<RelTy> rels) {
if (size == 0) // ZERO terminator
break;
uint32_t id = endian::read32<ELFT::TargetEndianness>(d.data() + 4);
// If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
// but we do not support that format yet.
if (size == UINT32_MAX) {
msg = "CIE/FDE too large";
break;
}
size += 4;
if (size > d.size()) {
msg = "CIE/FDE ends past the end of the section";
if (LLVM_UNLIKELY(size > d.size())) {
// If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
// but we do not support that format yet.
msg = size == UINT32_MAX + uint64_t(4)
? "CIE/FDE too large"
: "CIE/FDE ends past the end of the section";
break;
}
uint64_t off = d.data() - rawData.data();
(id == 0 ? cies : fdes).emplace_back(off, this, size, getReloc(off, size, rels, relI));
// Find the first relocation that points to [off,off+size). Relocations
// have been sorted by r_offset.
const uint64_t off = d.data() - rawData.data();
while (relI != rels.size() && rels[relI].r_offset < off)
++relI;
unsigned firstRel = -1;
if (relI != rels.size() && rels[relI].r_offset < off + size)
firstRel = relI;
(id == 0 ? cies : fdes).emplace_back(off, this, size, firstRel);
d = d.slice(size);
}
if (msg)