Skip to content

Commit ae1a032

Browse files
committed
move functions back to original location in file, add forward declaration instead
1 parent d802fcc commit ae1a032

File tree

1 file changed

+104
-95
lines changed

1 file changed

+104
-95
lines changed

lld/ELF/InputFiles.cpp

Lines changed: 104 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -540,102 +540,14 @@ uint32_t ObjFile<ELFT>::getSectionIndex(const Elf_Sym &sym) const {
540540
this);
541541
}
542542

543+
// Forward declarations:
543544
template <typename ELFT>
544-
static void parseGnuPropertyNote(Ctx &ctx, ELFFileBase &f,
545-
uint32_t featureAndType,
546-
ArrayRef<uint8_t> &desc, const uint8_t *base,
547-
ArrayRef<uint8_t> *data = nullptr) {
548-
auto err = [&](const uint8_t *place) -> ELFSyncStream {
549-
auto diag = Err(ctx);
550-
diag << &f << ":(" << ".note.gnu.property+0x"
551-
<< Twine::utohexstr(place - base) << "): ";
552-
return diag;
553-
};
554-
555-
while (!desc.empty()) {
556-
const uint8_t *place = desc.data();
557-
if (desc.size() < 8)
558-
return void(err(place) << "program property is too short");
559-
uint32_t type = read32<ELFT::Endianness>(desc.data());
560-
uint32_t size = read32<ELFT::Endianness>(desc.data() + 4);
561-
desc = desc.slice(8);
562-
if (desc.size() < size)
563-
return void(err(place) << "program property is too short");
564-
565-
if (type == featureAndType) {
566-
// We found a FEATURE_1_AND field. There may be more than one of these
567-
// in a .note.gnu.property section, for a relocatable object we
568-
// accumulate the bits set.
569-
if (size < 4)
570-
return void(err(place) << "FEATURE_1_AND entry is too short");
571-
f.andFeatures |= read32<ELFT::Endianness>(desc.data());
572-
} else if (ctx.arg.emachine == EM_AARCH64 &&
573-
type == GNU_PROPERTY_AARCH64_FEATURE_PAUTH) {
574-
ArrayRef<uint8_t> contents = data ? *data : desc;
575-
if (!f.aarch64PauthAbiCoreInfo.empty()) {
576-
return void(
577-
err(contents.data())
578-
<< "multiple GNU_PROPERTY_AARCH64_FEATURE_PAUTH entries are "
579-
"not supported");
580-
} else if (size != 16) {
581-
return void(err(contents.data())
582-
<< "GNU_PROPERTY_AARCH64_FEATURE_PAUTH entry "
583-
"is invalid: expected 16 bytes, but got "
584-
<< size);
585-
}
586-
f.aarch64PauthAbiCoreInfo = desc;
587-
}
588-
589-
// Padding is present in the note descriptor, if necessary.
590-
desc = desc.slice(alignTo<(ELFT::Is64Bits ? 8 : 4)>(size));
591-
}
592-
}
593-
594-
// Read the following info from the .note.gnu.property section and write it to
595-
// the corresponding fields in `ObjFile`:
596-
// - Feature flags (32 bits) representing x86 or AArch64 features for
597-
// hardware-assisted call flow control;
598-
// - AArch64 PAuth ABI core info (16 bytes).
599-
template <class ELFT>
600-
static gnuPropertiesInfo readGnuProperty(Ctx &ctx, const InputSection &sec,
601-
ObjFile<ELFT> &f) {
602-
using Elf_Nhdr = typename ELFT::Nhdr;
603-
using Elf_Note = typename ELFT::Note;
604-
605-
ArrayRef<uint8_t> data = sec.content();
606-
auto err = [&](const uint8_t *place) -> ELFSyncStream {
607-
auto diag = Err(ctx);
608-
diag << sec.file << ":(" << sec.name << "+0x"
609-
<< Twine::utohexstr(place - sec.content().data()) << "): ";
610-
return diag;
611-
};
612-
while (!data.empty()) {
613-
// Read one NOTE record.
614-
auto *nhdr = reinterpret_cast<const Elf_Nhdr *>(data.data());
615-
if (data.size() < sizeof(Elf_Nhdr) ||
616-
data.size() < nhdr->getSize(sec.addralign))
617-
return (err(data.data()) << "data is too short", gnuPropertiesInfo{});
618-
619-
Elf_Note note(*nhdr);
620-
if (nhdr->n_type != NT_GNU_PROPERTY_TYPE_0 || note.getName() != "GNU") {
621-
data = data.slice(nhdr->getSize(sec.addralign));
622-
continue;
623-
}
624-
625-
uint32_t featureAndType = ctx.arg.emachine == EM_AARCH64
626-
? GNU_PROPERTY_AARCH64_FEATURE_1_AND
627-
: GNU_PROPERTY_X86_FEATURE_1_AND;
628-
629-
// Read a body of a NOTE record, which consists of type-length-value fields.
630-
ArrayRef<uint8_t> desc = note.getDesc(sec.addralign);
631-
const uint8_t *base = sec.content().data();
632-
parseGnuPropertyNote<ELFT>(ctx, f, featureAndType, desc, base, &data);
633-
634-
// Go to next NOTE record to look for more FEATURE_1_AND descriptions.
635-
data = data.slice(nhdr->getSize(sec.addralign));
636-
}
637-
return gnuPropertiesInfo{f.andFeatures, f.aarch64PauthAbiCoreInfo};
638-
}
545+
static void parseGnuPropertyNote(Ctx &, ELFFileBase &, uint32_t,
546+
ArrayRef<uint8_t> &, const uint8_t *,
547+
ArrayRef<uint8_t> * = nullptr);
548+
template <typename ELFT>
549+
static gnuPropertiesInfo readGnuProperty(Ctx &, const InputSection &,
550+
ObjFile<ELFT> &);
639551

640552
template <class ELFT>
641553
static void
@@ -1526,6 +1438,103 @@ std::vector<uint32_t> SharedFile::parseVerneed(const ELFFile<ELFT> &obj,
15261438
return verneeds;
15271439
}
15281440

1441+
template <typename ELFT>
1442+
static void parseGnuPropertyNote(Ctx &ctx, ELFFileBase &f,
1443+
uint32_t featureAndType,
1444+
ArrayRef<uint8_t> &desc, const uint8_t *base,
1445+
ArrayRef<uint8_t> *data) {
1446+
auto err = [&](const uint8_t *place) -> ELFSyncStream {
1447+
auto diag = Err(ctx);
1448+
diag << &f << ":(" << ".note.gnu.property+0x"
1449+
<< Twine::utohexstr(place - base) << "): ";
1450+
return diag;
1451+
};
1452+
1453+
while (!desc.empty()) {
1454+
const uint8_t *place = desc.data();
1455+
if (desc.size() < 8)
1456+
return void(err(place) << "program property is too short");
1457+
uint32_t type = read32<ELFT::Endianness>(desc.data());
1458+
uint32_t size = read32<ELFT::Endianness>(desc.data() + 4);
1459+
desc = desc.slice(8);
1460+
if (desc.size() < size)
1461+
return void(err(place) << "program property is too short");
1462+
1463+
if (type == featureAndType) {
1464+
// We found a FEATURE_1_AND field. There may be more than one of these
1465+
// in a .note.gnu.property section, for a relocatable object we
1466+
// accumulate the bits set.
1467+
if (size < 4)
1468+
return void(err(place) << "FEATURE_1_AND entry is too short");
1469+
f.andFeatures |= read32<ELFT::Endianness>(desc.data());
1470+
} else if (ctx.arg.emachine == EM_AARCH64 &&
1471+
type == GNU_PROPERTY_AARCH64_FEATURE_PAUTH) {
1472+
ArrayRef<uint8_t> contents = data ? *data : desc;
1473+
if (!f.aarch64PauthAbiCoreInfo.empty()) {
1474+
return void(
1475+
err(contents.data())
1476+
<< "multiple GNU_PROPERTY_AARCH64_FEATURE_PAUTH entries are "
1477+
"not supported");
1478+
} else if (size != 16) {
1479+
return void(err(contents.data())
1480+
<< "GNU_PROPERTY_AARCH64_FEATURE_PAUTH entry "
1481+
"is invalid: expected 16 bytes, but got "
1482+
<< size);
1483+
}
1484+
f.aarch64PauthAbiCoreInfo = desc;
1485+
}
1486+
1487+
// Padding is present in the note descriptor, if necessary.
1488+
desc = desc.slice(alignTo<(ELFT::Is64Bits ? 8 : 4)>(size));
1489+
}
1490+
}
1491+
1492+
// Read the following info from the .note.gnu.property section and write it to
1493+
// the corresponding fields in `ObjFile`:
1494+
// - Feature flags (32 bits) representing x86 or AArch64 features for
1495+
// hardware-assisted call flow control;
1496+
// - AArch64 PAuth ABI core info (16 bytes).
1497+
template <class ELFT>
1498+
static gnuPropertiesInfo readGnuProperty(Ctx &ctx, const InputSection &sec,
1499+
ObjFile<ELFT> &f) {
1500+
using Elf_Nhdr = typename ELFT::Nhdr;
1501+
using Elf_Note = typename ELFT::Note;
1502+
1503+
ArrayRef<uint8_t> data = sec.content();
1504+
auto err = [&](const uint8_t *place) -> ELFSyncStream {
1505+
auto diag = Err(ctx);
1506+
diag << sec.file << ":(" << sec.name << "+0x"
1507+
<< Twine::utohexstr(place - sec.content().data()) << "): ";
1508+
return diag;
1509+
};
1510+
while (!data.empty()) {
1511+
// Read one NOTE record.
1512+
auto *nhdr = reinterpret_cast<const Elf_Nhdr *>(data.data());
1513+
if (data.size() < sizeof(Elf_Nhdr) ||
1514+
data.size() < nhdr->getSize(sec.addralign))
1515+
return (err(data.data()) << "data is too short", gnuPropertiesInfo{});
1516+
1517+
Elf_Note note(*nhdr);
1518+
if (nhdr->n_type != NT_GNU_PROPERTY_TYPE_0 || note.getName() != "GNU") {
1519+
data = data.slice(nhdr->getSize(sec.addralign));
1520+
continue;
1521+
}
1522+
1523+
uint32_t featureAndType = ctx.arg.emachine == EM_AARCH64
1524+
? GNU_PROPERTY_AARCH64_FEATURE_1_AND
1525+
: GNU_PROPERTY_X86_FEATURE_1_AND;
1526+
1527+
// Read a body of a NOTE record, which consists of type-length-value fields.
1528+
ArrayRef<uint8_t> desc = note.getDesc(sec.addralign);
1529+
const uint8_t *base = sec.content().data();
1530+
parseGnuPropertyNote<ELFT>(ctx, f, featureAndType, desc, base, &data);
1531+
1532+
// Go to next NOTE record to look for more FEATURE_1_AND descriptions.
1533+
data = data.slice(nhdr->getSize(sec.addralign));
1534+
}
1535+
return gnuPropertiesInfo{f.andFeatures, f.aarch64PauthAbiCoreInfo};
1536+
}
1537+
15291538
// Parse PT_GNU_PROPERTY segments in DSO. The process is similar to
15301539
// readGnuProperty, but we don't have the InputSection information.
15311540
template <typename ELFT>

0 commit comments

Comments
 (0)