Skip to content

Commit 54fe275

Browse files
committed
move code back to prev lcation
1 parent b5c882e commit 54fe275

File tree

1 file changed

+97
-97
lines changed

1 file changed

+97
-97
lines changed

lld/ELF/InputFiles.cpp

Lines changed: 97 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,103 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
10301030
handleSectionGroup<ELFT>(this->sections, entries);
10311031
}
10321032

1033+
template <typename ELFT>
1034+
static void parseGnuPropertyNote(Ctx &ctx, ELFFileBase &f,
1035+
uint32_t featureAndType,
1036+
ArrayRef<uint8_t> &desc, const uint8_t *base,
1037+
ArrayRef<uint8_t> *data) {
1038+
auto err = [&](const uint8_t *place) -> ELFSyncStream {
1039+
auto diag = Err(ctx);
1040+
diag << &f << ":(" << ".note.gnu.property+0x"
1041+
<< Twine::utohexstr(place - base) << "): ";
1042+
return diag;
1043+
};
1044+
1045+
while (!desc.empty()) {
1046+
const uint8_t *place = desc.data();
1047+
if (desc.size() < 8)
1048+
return void(err(place) << "program property is too short");
1049+
uint32_t type = read32<ELFT::Endianness>(desc.data());
1050+
uint32_t size = read32<ELFT::Endianness>(desc.data() + 4);
1051+
desc = desc.slice(8);
1052+
if (desc.size() < size)
1053+
return void(err(place) << "program property is too short");
1054+
1055+
if (type == featureAndType) {
1056+
// We found a FEATURE_1_AND field. There may be more than one of these
1057+
// in a .note.gnu.property section, for a relocatable object we
1058+
// accumulate the bits set.
1059+
if (size < 4)
1060+
return void(err(place) << "FEATURE_1_AND entry is too short");
1061+
f.andFeatures |= read32<ELFT::Endianness>(desc.data());
1062+
} else if (ctx.arg.emachine == EM_AARCH64 &&
1063+
type == GNU_PROPERTY_AARCH64_FEATURE_PAUTH) {
1064+
ArrayRef<uint8_t> contents = data ? *data : desc;
1065+
if (!f.aarch64PauthAbiCoreInfo.empty()) {
1066+
return void(
1067+
err(contents.data())
1068+
<< "multiple GNU_PROPERTY_AARCH64_FEATURE_PAUTH entries are "
1069+
"not supported");
1070+
} else if (size != 16) {
1071+
return void(err(contents.data())
1072+
<< "GNU_PROPERTY_AARCH64_FEATURE_PAUTH entry "
1073+
"is invalid: expected 16 bytes, but got "
1074+
<< size);
1075+
}
1076+
f.aarch64PauthAbiCoreInfo = desc;
1077+
}
1078+
1079+
// Padding is present in the note descriptor, if necessary.
1080+
desc = desc.slice(alignTo<(ELFT::Is64Bits ? 8 : 4)>(size));
1081+
}
1082+
}
1083+
1084+
// Read the following info from the .note.gnu.property section and write it to
1085+
// the corresponding fields in `ObjFile`:
1086+
// - Feature flags (32 bits) representing x86 or AArch64 features for
1087+
// hardware-assisted call flow control;
1088+
// - AArch64 PAuth ABI core info (16 bytes).
1089+
template <class ELFT>
1090+
static gnuPropertiesInfo readGnuProperty(Ctx &ctx, const InputSection &sec,
1091+
ObjFile<ELFT> &f) {
1092+
using Elf_Nhdr = typename ELFT::Nhdr;
1093+
using Elf_Note = typename ELFT::Note;
1094+
1095+
ArrayRef<uint8_t> data = sec.content();
1096+
auto err = [&](const uint8_t *place) -> ELFSyncStream {
1097+
auto diag = Err(ctx);
1098+
diag << sec.file << ":(" << sec.name << "+0x"
1099+
<< Twine::utohexstr(place - sec.content().data()) << "): ";
1100+
return diag;
1101+
};
1102+
while (!data.empty()) {
1103+
// Read one NOTE record.
1104+
auto *nhdr = reinterpret_cast<const Elf_Nhdr *>(data.data());
1105+
if (data.size() < sizeof(Elf_Nhdr) ||
1106+
data.size() < nhdr->getSize(sec.addralign))
1107+
return (err(data.data()) << "data is too short", gnuPropertiesInfo{});
1108+
1109+
Elf_Note note(*nhdr);
1110+
if (nhdr->n_type != NT_GNU_PROPERTY_TYPE_0 || note.getName() != "GNU") {
1111+
data = data.slice(nhdr->getSize(sec.addralign));
1112+
continue;
1113+
}
1114+
1115+
uint32_t featureAndType = ctx.arg.emachine == EM_AARCH64
1116+
? GNU_PROPERTY_AARCH64_FEATURE_1_AND
1117+
: GNU_PROPERTY_X86_FEATURE_1_AND;
1118+
1119+
// Read a body of a NOTE record, which consists of type-length-value fields.
1120+
ArrayRef<uint8_t> desc = note.getDesc(sec.addralign);
1121+
const uint8_t *base = sec.content().data();
1122+
parseGnuPropertyNote<ELFT>(ctx, f, featureAndType, desc, base, &data);
1123+
1124+
// Go to next NOTE record to look for more FEATURE_1_AND descriptions.
1125+
data = data.slice(nhdr->getSize(sec.addralign));
1126+
}
1127+
return gnuPropertiesInfo{f.andFeatures, f.aarch64PauthAbiCoreInfo};
1128+
}
1129+
10331130
template <class ELFT>
10341131
InputSectionBase *ObjFile<ELFT>::getRelocTarget(uint32_t idx, uint32_t info) {
10351132
if (info < this->sections.size()) {
@@ -1438,103 +1535,6 @@ std::vector<uint32_t> SharedFile::parseVerneed(const ELFFile<ELFT> &obj,
14381535
return verneeds;
14391536
}
14401537

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-
15381538
// Parse PT_GNU_PROPERTY segments in DSO. The process is similar to
15391539
// readGnuProperty, but we don't have the InputSection information.
15401540
template <typename ELFT>

0 commit comments

Comments
 (0)