From 5d7adce6107f92cb42805bb0014cfc5957e92305 Mon Sep 17 00:00:00 2001 From: Khomutov Nikita Date: Sun, 7 Apr 2024 11:36:27 +0300 Subject: [PATCH 1/4] [ADLT] refactor types in section generation Signed-off-by: Khomutov Nikita Change-Id: I2e9b2836abbbfdbd38d4de014b277ccf920eef5f --- lld/ELF/SyntheticSections.cpp | 76 +++++++++++++++++------------------ lld/ELF/SyntheticSections.h | 22 +++------- 2 files changed, 43 insertions(+), 55 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 28d699a13f3b..81a4d94977df 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -4002,13 +4002,13 @@ size_t PackageMetadataNote::getSize() const { namespace lld { namespace elf { namespace adlt { static_assert( - sizeof(SemanticVersion) == sizeof(Elf64_Half), + sizeof(adlt_semver_t) == sizeof(Elf64_Half), ".adlt semantic version is designed to occupy uint16_t" ); static_assert( - sizeof(DtNeededIndex) == sizeof(Elf64_Off), - "DtNeededIndex have to be an offset with intrused flags" + sizeof(adlt_dt_needed_index_t) == sizeof(Elf64_Off), + "adlt_dt_needed_index_t have to be an offset with intrused flags" ); static_assert( @@ -4020,12 +4020,12 @@ static_assert(sizeof(adltBlobStartMark) == 4, "0xad17 consist of 4 bytes" ); -static_assert(sizeof(AdltSectionHeader) == 32, +static_assert(sizeof(adlt_section_header_t) == 32, "please udpate major version if header has been changed" ); -static_assert(sizeof(PSOD) == 112, - "please udpate version if PSOD layout or content changed" +static_assert(sizeof(adlt_psod_t) == 112, + "please udpate version if adlt_psod_t layout or content changed" ); @@ -4050,14 +4050,14 @@ void AdltSection::finalizeContents() { "the number of input libs exeeds ELF limit on number of sections"); const Elf64_Half soNum = soInputs.size(); - header = AdltSectionHeader{ - adltSchemaVersion, // .schemaVersion - sizeof(AdltSectionHeader), // .schemaHeaderSize - sizeof(PSOD), // .schemaPSODSize - soNum, // .sharedObjectsNum - ADLT_HASH_TYPE_GNU_HASH, // .stringHashType - getBlobStartOffset(), // .blobStart - estimateBlobSize(), // .blobSize + header = adlt_section_header_t{ + adltSchemaVersion, // .schemaVersion + sizeof(adlt_section_header_t), // .schemaHeaderSize + sizeof(adlt_psod_t), // .schemaPSODSize + soNum, // .sharedObjectsNum + ADLT_HASH_TYPE_GNU_HASH, // .stringHashType + getBlobStartOffset(), // .blobStart + estimateBlobSize(), // .blobSize }; buildSonameIndex(); @@ -4127,17 +4127,13 @@ AdltSection::makeSoData(const SharedFileExtended* soext) { for (const auto& neededName: soext->dtNeeded) { data.dtNeededs.push_back({ SectionString{neededName, strTabSec.addString(neededName)}, - {}, // internal PSOD index is uknown by the moment, will be linked + {}, // unknown now, filled by linkInternalDtNeeded }); } data.initArrayName = soext->addAdltPostfix(".init_array"); data.finiArrayName = soext->addAdltPostfix(".fini_array"); - // TODO: - // sharedLocalIndex - // sharedGlobalIndex - // TODO: get section index for sharedLocalIndex // TODO: get section index for sharedGlobalIndex @@ -4146,7 +4142,7 @@ AdltSection::makeSoData(const SharedFileExtended* soext) { template Elf64_Xword AdltSection::calculateHash(StringRef str) const { - switch(static_cast(header.stringHashType)) { + switch(static_cast(header.stringHashType)) { case ADLT_HASH_TYPE_NONE: return 0x0; case ADLT_HASH_TYPE_GNU_HASH: @@ -4159,27 +4155,27 @@ Elf64_Xword AdltSection::calculateHash(StringRef str) const { } template -PSOD AdltSection::serialize(const SoData& soData) const { - return PSOD { +adlt_psod_t AdltSection::serialize(const SoData& soData) const { + return adlt_psod_t { soData.soName.strtabOff, // .soName calculateHash(soData.soName.ref), // .soNameHash - soData.initArraySec ? CrossSectionVec{ // .initArray + soData.initArraySec ? adlt_cross_section_vec_t{ // .initArray soData.initArraySec->sectionIndex, soData.initArraySec->size / sizeof(Elf64_Addr), // size soData.initArraySec->addr, - } : CrossSectionVec{0, 0, 0}, - soData.finiArraySec ? CrossSectionVec{ // .finiArray + } : adlt_cross_section_vec_t{0, 0, 0}, + soData.finiArraySec ? adlt_cross_section_vec_t{ // .finiArray soData.finiArraySec->sectionIndex, soData.finiArraySec->size / sizeof(Elf64_Addr), // size soData.finiArraySec->addr, - } : CrossSectionVec{0, 0, 0}, + } : adlt_cross_section_vec_t{0, 0, 0}, 0x0, // .dtNeeded // filled by blob serialization soData.dtNeededs.size(), // .dtNeededSz - CrossSectionRef { + adlt_cross_section_ref_t { 0, // .secIndex soData.sharedLocalIndex, // .offset }, // .sharedLocalSymbolIndex - CrossSectionRef { + adlt_cross_section_ref_t { 0, // .secIndex soData.sharedGlobalIndex, // .offset }, // .sharedGlobalSymbolIndex @@ -4188,7 +4184,7 @@ PSOD AdltSection::serialize(const SoData& soData) const { template Elf64_Off AdltSection::getBlobStartOffset() const { - return sizeof(header) + sizeof(PSOD) * soInputs.size(); + return sizeof(adlt_section_header_t) + sizeof(adlt_psod_t) * soInputs.size(); } template @@ -4196,7 +4192,7 @@ size_t AdltSection::estimateBlobSize() const { size_t blobSize = sizeof(adltBlobStartMark); for (const auto& soData: soInputs) { - blobSize += sizeof(DtNeededIndex) * soData.dtNeededs.size(); + blobSize += sizeof(adlt_dt_needed_index_t) * soData.dtNeededs.size(); }; return blobSize; @@ -4207,10 +4203,10 @@ size_t AdltSection::writeDtNeededVec( uint8_t* buff, const DtNeededsVec& neededVec) const { if (neededVec.empty()) return 0; - SmallVector needIndexes; + SmallVector needIndexes; needIndexes.reserve(neededVec.size()); for (const auto& need_data : neededVec) { - needIndexes.push_back(DtNeededIndex{ + needIndexes.push_back(adlt_dt_needed_index_t{ need_data.psodIndex.has_value(), // .hasInternalPSOD need_data.psodIndex.value_or(0), // .PSODindex need_data.str.strtabOff, // .sonameOffset @@ -4225,11 +4221,11 @@ template void AdltSection::writeTo(uint8_t* buf) { // TODO: take care of endianness, use write32 / write64 etc. // pre-serialized SoData, enriched with offsets during blob writing - SmallVector psods; + SmallVector psods; for (const auto& it: llvm::enumerate(soInputs)) { const SoData& soData = it.value(); - PSOD psod = serialize(soData); + adlt_psod_t psod = serialize(soData); psods.push_back(psod); } @@ -4243,7 +4239,7 @@ void AdltSection::writeTo(uint8_t* buf) { // dt-needed for(const auto& it : llvm::enumerate(soInputs)) { const auto& soData = it.value(); - PSOD& psod = psods[it.index()]; + adlt_psod_t& psod = psods[it.index()]; psod.dtNeededSz = soData.dtNeededs.size(); psod.dtNeeded = blob_off; @@ -4266,16 +4262,18 @@ void AdltSection::writeTo(uint8_t* buf) { uint8_t* const psods_buf = buf + sizeof(header); size_t psods_off = 0; for (const auto& it: llvm::enumerate(soInputs)) { - PSOD& psod = psods[it.index()]; - memcpy(psods_buf + psods_off, &psod, sizeof(PSOD)); - psods_off += sizeof(PSOD); + adlt_psod_t& psod = psods[it.index()]; + memcpy(psods_buf + psods_off, &psod, sizeof(adlt_psod_t)); + psods_off += sizeof(adlt_psod_t); } } } template size_t AdltSection::getSize() const { - assert(sizeof(header) + sizeof(PSOD) * soInputs.size() <= header.blobStart); + assert(sizeof(adlt_section_header_t) + + sizeof(adlt_psod_t) * soInputs.size() + <= header.blobStart); return header.blobStart + header.blobSize; } diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index ebf03b332d4b..f325ca02759a 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -1225,15 +1225,6 @@ public: namespace adlt { -using CrossSectionRef = adlt_cross_section_ref_t; -using CrossSectionVec = adlt_cross_section_vec_t; -using SemanticVersion = adlt_semver_t; -using DtNeededIndex = adlt_dt_needed_index_t; -using PSOD = adlt_psod_t; -using AdltSectionHeader = adlt_section_header_t; -using HashType = adlt_hash_type_enum_t; - - template class AdltSection final : public SyntheticSection { public: @@ -1242,16 +1233,16 @@ public: Elf64_Off strtabOff; // offset in strTabSec }; - // will be serialized to DtNeededIndex + // will be serialized to adlt_dt_needed_index_t struct DtNeededData { SectionString str; llvm::Optional psodIndex; }; - using SectionStringVector = SmallVector; - using DtNeededsVec = SmallVector; + using SectionStringVector = SmallVector; + using DtNeededsVec = SmallVector; - // will be serialized to PSOD + // will be serialized to adlt_psod_t struct SoData { SectionString soName; DtNeededsVec dtNeededs; @@ -1266,7 +1257,6 @@ public: Elf64_Off sharedGlobalIndex; // TODO }; - public: AdltSection(StringTableSection& strTabSec); @@ -1285,7 +1275,7 @@ private: Elf64_Xword calculateHash(StringRef str) const; SoData makeSoData(const SharedFileExtended*); - PSOD serialize(const SoData&) const; + adlt_psod_t serialize(const SoData&) const; size_t estimateBlobSize() const; size_t writeDtNeededVec(uint8_t* buff, const DtNeededsVec& neededVec) const; @@ -1293,7 +1283,7 @@ private: private: StringTableSection& strTabSec; - AdltSectionHeader header = {}; + adlt_section_header_t header = {}; SmallVector soInputs; llvm::DenseMap sonameToIndexMap; }; -- Gitee From 6023e2273d53f49786d0de735b31b181a3f77995 Mon Sep 17 00:00:00 2001 From: Khomutov Nikita Date: Sun, 7 Apr 2024 12:53:32 +0300 Subject: [PATCH 2/4] [ADLT] refactor .adlt types - add array type - replace add in cs-adday to relocatable offset - union dtNeeded Signed-off-by: Khomutov Nikita Change-Id: I88bd48e32ad562b151a955a74b073b0596870c93 --- lld/ELF/ADLTSection.h | 27 +++++++++++++++-------- lld/ELF/SyntheticSections.cpp | 41 +++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/lld/ELF/ADLTSection.h b/lld/ELF/ADLTSection.h index 74fc48600554..6b029c4dd0f1 100644 --- a/lld/ELF/ADLTSection.h +++ b/lld/ELF/ADLTSection.h @@ -39,14 +39,24 @@ typedef uint8_t Elf64_Byte; typedef struct { Elf64_Word secIndex; - Elf64_Off offset; // in-section offset from start + Elf64_Off offset; // from section start } adlt_cross_section_ref_t; typedef struct { - Elf64_Xword secIndex; - Elf64_Xword numElem; - Elf64_Addr addr; -} adlt_cross_section_vec_t; + Elf64_Word secIndex; + Elf64_Off offset; // from section start + Elf64_Xword size; // size in bytes +} adlt_cross_section_array_t; + +typedef struct { + Elf64_Off offset; // relative to header.blobStart + Elf64_Xword size; // size in bytes, make convertions for data type +} adlt_blob_array_t; + +typedef adlt_blob_array_t adlt_blob_u8_array_t; +typedef adlt_blob_array_t adlt_blob_u16_array_t; +typedef adlt_blob_array_t adlt_blob_u32_array_t; +typedef adlt_blob_array_t adlt_blob_u64_array_t; typedef struct { Elf64_Half major: 6; @@ -75,10 +85,9 @@ typedef uint8_t adlt_hash_type_t; typedef struct { Elf64_Off soName; // offset in .adlt.strtab Elf64_Xword soNameHash; // algorith according to header.stringHashType value - adlt_cross_section_vec_t initArray; - adlt_cross_section_vec_t finiArray; - Elf64_Off dtNeeded; // offset to adlt_dt_needed_index_t[] array in blob - Elf64_Xword dtNeededSz; + adlt_cross_section_array_t initArray; + adlt_cross_section_array_t finiArray; + adlt_blob_array_t dtNeeded; // array of adlt_dt_needed_index_t[] elems adlt_cross_section_ref_t sharedLocalSymbolIndex; adlt_cross_section_ref_t sharedGlobalSymbolIndex; } adlt_psod_t; diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 81a4d94977df..5a3b997ccbdc 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -4159,26 +4159,28 @@ adlt_psod_t AdltSection::serialize(const SoData& soData) const { return adlt_psod_t { soData.soName.strtabOff, // .soName calculateHash(soData.soName.ref), // .soNameHash - soData.initArraySec ? adlt_cross_section_vec_t{ // .initArray + soData.initArraySec ? adlt_cross_section_array_t{ // .initArray soData.initArraySec->sectionIndex, - soData.initArraySec->size / sizeof(Elf64_Addr), // size - soData.initArraySec->addr, - } : adlt_cross_section_vec_t{0, 0, 0}, - soData.finiArraySec ? adlt_cross_section_vec_t{ // .finiArray + 0x0, // .init_array function addresses are located at the start + soData.initArraySec->size, // size + } : adlt_cross_section_array_t{0, 0, 0}, + soData.finiArraySec ? adlt_cross_section_array_t{ // .finiArray soData.finiArraySec->sectionIndex, - soData.finiArraySec->size / sizeof(Elf64_Addr), // size - soData.finiArraySec->addr, - } : adlt_cross_section_vec_t{0, 0, 0}, - 0x0, // .dtNeeded // filled by blob serialization - soData.dtNeededs.size(), // .dtNeededSz - adlt_cross_section_ref_t { - 0, // .secIndex + 0x0, // .fini_array function addresses are located at the start + soData.finiArraySec->size, // size + } : adlt_cross_section_array_t{0, 0, 0}, + adlt_blob_array_t { // .dtNeeded + 0x0, // offset, filled array write in blob + soData.dtNeededs.size() * sizeof(adlt_dt_needed_index_t) + }, + adlt_cross_section_ref_t { // .sharedLocalSymbolIndex + 0, // .secIndex // TODO: dynsym? soData.sharedLocalIndex, // .offset - }, // .sharedLocalSymbolIndex - adlt_cross_section_ref_t { - 0, // .secIndex + }, + adlt_cross_section_ref_t { // .sharedGlobalSymbolIndex + 0, // .secIndex // TODO: dynsym? soData.sharedGlobalIndex, // .offset - }, // .sharedGlobalSymbolIndex + }, }; } @@ -4241,9 +4243,10 @@ void AdltSection::writeTo(uint8_t* buf) { const auto& soData = it.value(); adlt_psod_t& psod = psods[it.index()]; - psod.dtNeededSz = soData.dtNeededs.size(); - psod.dtNeeded = blob_off; - blob_off += writeDtNeededVec(blob_buf + blob_off, soData.dtNeededs); + size_t written = writeDtNeededVec(blob_buf + blob_off, soData.dtNeededs); + psod.dtNeeded.offset = blob_off; + psod.dtNeeded.size = written; + blob_off += written; } // finalize header.blobSize -- Gitee From 67542acfd52d83363fadda0b73e7c681ad8f14f9 Mon Sep 17 00:00:00 2001 From: Khomutov Nikita Date: Sun, 7 Apr 2024 13:21:52 +0300 Subject: [PATCH 3/4] [ADLT] add ph indexes to .adlt Signed-off-by: Khomutov Nikita Change-Id: Ia72cb2e0aac44f7b27061f35de1f79fc9132218c --- lld/ELF/ADLTSection.h | 5 +++-- lld/ELF/SyntheticSections.cpp | 30 ++++++++++++++++++++++++------ lld/ELF/SyntheticSections.h | 2 ++ 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/lld/ELF/ADLTSection.h b/lld/ELF/ADLTSection.h index 6b029c4dd0f1..e8513a9d50f2 100644 --- a/lld/ELF/ADLTSection.h +++ b/lld/ELF/ADLTSection.h @@ -83,13 +83,14 @@ typedef uint8_t adlt_hash_type_t; // Serializable representation per-shared-object-data in .adlt section typedef struct { - Elf64_Off soName; // offset in .adlt.strtab - Elf64_Xword soNameHash; // algorith according to header.stringHashType value + Elf64_Off soName; // offset in .adlt.strtab + Elf64_Xword soNameHash; // algorithm according to header.stringHashType value adlt_cross_section_array_t initArray; adlt_cross_section_array_t finiArray; adlt_blob_array_t dtNeeded; // array of adlt_dt_needed_index_t[] elems adlt_cross_section_ref_t sharedLocalSymbolIndex; adlt_cross_section_ref_t sharedGlobalSymbolIndex; + adlt_blob_u16_array_t phIndexes; // program header index array, typeof(e_phnum) } adlt_psod_t; typedef struct { diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 5a3b997ccbdc..6ac5296c1530 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -4024,7 +4024,7 @@ static_assert(sizeof(adlt_section_header_t) == 32, "please udpate major version if header has been changed" ); -static_assert(sizeof(adlt_psod_t) == 112, +static_assert(sizeof(adlt_psod_t) == 128, "please udpate version if adlt_psod_t layout or content changed" ); @@ -4134,8 +4134,9 @@ AdltSection::makeSoData(const SharedFileExtended* soext) { data.initArrayName = soext->addAdltPostfix(".init_array"); data.finiArrayName = soext->addAdltPostfix(".fini_array"); - // TODO: get section index for sharedLocalIndex - // TODO: get section index for sharedGlobalIndex + // TODO: fill data.sharedLocalIndex + // TODO: fill data.sharedGlobalIndex + // TODO: fill data.phIndexes return data; } @@ -4169,7 +4170,7 @@ adlt_psod_t AdltSection::serialize(const SoData& soData) const { 0x0, // .fini_array function addresses are located at the start soData.finiArraySec->size, // size } : adlt_cross_section_array_t{0, 0, 0}, - adlt_blob_array_t { // .dtNeeded + adlt_blob_array_t { // .dtNeeded 0x0, // offset, filled array write in blob soData.dtNeededs.size() * sizeof(adlt_dt_needed_index_t) }, @@ -4181,6 +4182,9 @@ adlt_psod_t AdltSection::serialize(const SoData& soData) const { 0, // .secIndex // TODO: dynsym? soData.sharedGlobalIndex, // .offset }, + adlt_blob_u16_array_t { // .phIndexes + 0x0, 0 + } }; } @@ -4195,6 +4199,7 @@ size_t AdltSection::estimateBlobSize() const { for (const auto& soData: soInputs) { blobSize += sizeof(adlt_dt_needed_index_t) * soData.dtNeededs.size(); + blobSize += sizeof(uint16_t) * soData.phIndexes.size(); }; return blobSize; @@ -4240,15 +4245,28 @@ void AdltSection::writeTo(uint8_t* buf) { // dt-needed for(const auto& it : llvm::enumerate(soInputs)) { - const auto& soData = it.value(); + const SoData& soData = it.value(); adlt_psod_t& psod = psods[it.index()]; - size_t written = writeDtNeededVec(blob_buf + blob_off, soData.dtNeededs); + const size_t written = writeDtNeededVec(blob_buf + blob_off, soData.dtNeededs); psod.dtNeeded.offset = blob_off; psod.dtNeeded.size = written; blob_off += written; } + // phIndexes + for (const auto& it : llvm::enumerate(soInputs)) { + const SoData& soData = it.value(); + adlt_psod_t& psod = psods[it.index()]; + + const size_t written = soData.phIndexes.size_in_bytes();; + memcpy(blob_buf + blob_off, + soData.phIndexes.data(), soData.phIndexes.size_in_bytes()); + psod.phIndexes.offset = blob_off; + psod.phIndexes.size = written; + blob_off += written; + } + // finalize header.blobSize assert((blob_off <= header.blobSize) && ".adlt-section: blob output exeeds its initial estimation"); diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index f325ca02759a..8292495940fa 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -1255,6 +1255,8 @@ public: Elf64_Off sharedLocalIndex; // TODO Elf64_Off sharedGlobalIndex; // TODO + + SmallVector phIndexes; // TODO }; public: -- Gitee From 9c20ab43ddd264f17a43b07c26941ffd027f0ba9 Mon Sep 17 00:00:00 2001 From: Khomutov Nikita Date: Mon, 8 Apr 2024 12:38:09 +0300 Subject: [PATCH 4/4] [ADLT] added .adlt typedef reasoning Signed-off-by: Khomutov Nikita Change-Id: I1e4711a60ae8f641a63288763ec47acde4eef051 Signed-off-by: Khomutov Nikita --- lld/ELF/ADLTSection.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lld/ELF/ADLTSection.h b/lld/ELF/ADLTSection.h index e8513a9d50f2..b4ba5966741d 100644 --- a/lld/ELF/ADLTSection.h +++ b/lld/ELF/ADLTSection.h @@ -53,10 +53,11 @@ typedef struct { Elf64_Xword size; // size in bytes, make convertions for data type } adlt_blob_array_t; -typedef adlt_blob_array_t adlt_blob_u8_array_t; -typedef adlt_blob_array_t adlt_blob_u16_array_t; -typedef adlt_blob_array_t adlt_blob_u32_array_t; -typedef adlt_blob_array_t adlt_blob_u64_array_t; +// plain-C has no strict typedefs, but aliases used to interpred underlying data +typedef adlt_blob_array_t adlt_blob_u8_array_t; // uint8_t[] +typedef adlt_blob_array_t adlt_blob_u16_array_t; // uint16_t[] +typedef adlt_blob_array_t adlt_blob_u32_array_t; // uint32_t[] +typedef adlt_blob_array_t adlt_blob_u64_array_t; // uint64_t[] typedef struct { Elf64_Half major: 6; -- Gitee