From 33966cb4d0a0f54aa9bbe0b827c7f27c2eca32de Mon Sep 17 00:00:00 2001 From: Khomutov Nikita Date: Wed, 3 Apr 2024 13:07:03 +0300 Subject: [PATCH 1/5] [ADLT] .adlt section C-style header - move serializable types to plain c header - move size static asserts to impl Signed-off-by: Khomutov Nikita Change-Id: I4c88ec19dbeae66e42d8c52b43d24cdec9554ac2 --- lld/ELF/ADLTSection.h | 93 +++++++++++++++++++++++++++++++++++ lld/ELF/SyntheticSections.cpp | 56 +++++++++++++++------ lld/ELF/SyntheticSections.h | 79 ++++------------------------- 3 files changed, 144 insertions(+), 84 deletions(-) create mode 100644 lld/ELF/ADLTSection.h diff --git a/lld/ELF/ADLTSection.h b/lld/ELF/ADLTSection.h new file mode 100644 index 000000000000..5b3079c36635 --- /dev/null +++ b/lld/ELF/ADLTSection.h @@ -0,0 +1,93 @@ +//===- ADLTSection.h - ADLT Section data types --------------------*- C -*-===// +// +// Copyright (C) 2024 Huawei Device Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_ELF_ADLT_SECTION_H +#define LLD_ELF_ADLT_SECTION_H + +#include + +// part of #include +typedef uint16_t Elf64_Half; +typedef uint64_t Elf64_Off; +typedef uint64_t Elf64_Addr; +typedef uint32_t Elf64_Word; +typedef uint64_t Elf64_Xword; +typedef uint8_t Elf64_Byte; + + +typedef struct { + Elf64_Word secIndex; + Elf64_Off offset; // in-section offset from start +} adlt_cross_section_ref_t; + +typedef struct { + Elf64_Xword secIndex; + Elf64_Xword numElem; + Elf64_Addr addr; +} adlt_cross_section_vec_t; + +typedef struct { + Elf64_Half major: 6; + Elf64_Half minor: 6; + Elf64_Half patch: 4; +} adlt_semver_t; + + +// DT_NEEDED string index with embedded PSOD index if available +typedef struct { + Elf64_Off hasInternalPSOD : 1; // true if soname + Elf64_Off PSODindex : 16; // PSOD in the current ADLT image + Elf64_Off sonameOffset : 47; // string start in bound .adlt.strtab +} adlt_dt_needed_index_t; + + +typedef enum { + ADLT_HASH_TYPE_NONE = 0, + ADLT_HASH_TYPE_GNU_HASH = 1, + ADLT_HASH_TYPE_SYSV_HASH = 2, + ADLT_HASH_TYPE_DEBUG_CONST = 0xfe, + ADLT_HASH_TYPE_MAX = 0xff, +} adlt_hash_type_enum_t; +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 + 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_ref_t sharedLocalSymbolIndex; + adlt_cross_section_ref_t sharedGlobalSymbolIndex; +} adlt_psod_t; + +typedef struct { + adlt_semver_t schemaVersion; // {major, minor, patch} + Elf64_Half schemaPSODSize; // >= sizeof(adlt_psod_t) if compatible + Elf64_Half sharedObjectsNum; // number of PSOD entries + adlt_hash_type_t stringHashType; // contains adlt_hash_type_enum_t value + Elf64_Off blobStart; // offset of binary blob start relative to .adlt + Elf64_Xword blobSize; +} adlt_section_header_t; + +static const char adltBlobStartMark[4] = { 0xA, 0xD, 0x1, 0x7 }; + + +#endif // LLD_ELF_ADLT_SECTION_H diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 35f163c5d2ba..d53b64b36800 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -4001,6 +4001,35 @@ size_t PackageMetadataNote::getSize() const { // OHOS_LOCAL begin namespace lld { namespace elf { namespace adlt { +static_assert( + sizeof(SemanticVersion) == 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" +); + +static_assert( + sizeof(adlt_hash_type_t) == sizeof(Elf64_Byte), + "String hash type enum should occupy only one byte" +); + + +static_assert(sizeof(adltBlobStartMark) == 4, + "0xad17 consist of 4 bytes" +); + +static_assert(sizeof(AdltSectionHeader) == 24, + "please udpate major version if header has been changed" +); + +static_assert(sizeof(PSOD) == 112, + "please udpate version if PSOD layout or content changed" +); + + template AdltSection::AdltSection(StringTableSection& strTabSec) : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 4, ".adlt") @@ -4026,7 +4055,7 @@ void AdltSection::finalizeContents() { {1, 0, 0}, // .schemaVersion sizeof(PSOD), // .schemaPSODSize soNum, // .sharedObjectsNum - HashType::MUSL_GNU_HASH, // .stringHashType + ADLT_HASH_TYPE_GNU_HASH, // .stringHashType getBlobStartOffset(), // .blobStart estimateBlobSize(), // .blobSize }; @@ -4117,12 +4146,12 @@ AdltSection::makeSoData(const SharedFileExtended* soext) { template Elf64_Xword AdltSection::calculateHash(StringRef str) const { - switch(header.stringHashType) { - case HashType::NONE: + switch(static_cast(header.stringHashType)) { + case ADLT_HASH_TYPE_NONE: return 0x0; - case HashType::MUSL_GNU_HASH: + case ADLT_HASH_TYPE_GNU_HASH: return hashGnu(str); - case HashType::DEBUG_CONST: + case ADLT_HASH_TYPE_DEBUG_CONST: return 0xdeadbeef1337c0de; default: llvm_unreachable(".adlt hash type not implemented"); @@ -4147,12 +4176,12 @@ PSOD AdltSection::serialize(const SoData& soData) const { 0x0, // .dtNeeded // filled by blob serialization soData.dtNeededs.size(), // .dtNeededSz CrossSectionRef { - 0, // .sectionIndex - soData.sharedLocalIndex, // .offsetFromStart + 0, // .secIndex + soData.sharedLocalIndex, // .offset }, // .sharedLocalSymbolIndex CrossSectionRef { - 0, // .sectionIndex - soData.sharedGlobalIndex, // .offsetFromStart + 0, // .secIndex + soData.sharedGlobalIndex, // .offset }, // .sharedGlobalSymbolIndex }; } @@ -4164,7 +4193,7 @@ Elf64_Off AdltSection::getBlobStartOffset() const { template size_t AdltSection::estimateBlobSize() const { - size_t blobSize = sizeof(BlobStartMark); + size_t blobSize = sizeof(adltBlobStartMark); for (const auto& soData: soInputs) { blobSize += sizeof(DtNeededIndex) * soData.dtNeededs.size(); @@ -4208,8 +4237,8 @@ void AdltSection::writeTo(uint8_t* buf) { { uint8_t* const blob_buf = buf + header.blobStart; size_t blob_off = 0; - memcpy(blob_buf + blob_off, &BlobStartMark, sizeof(BlobStartMark)); - blob_off += sizeof(BlobStartMark); + memcpy(blob_buf + blob_off, &adltBlobStartMark, sizeof(adltBlobStartMark)); + blob_off += sizeof(adltBlobStartMark); // dt-needed for(const auto& it : llvm::enumerate(soInputs)) { @@ -4246,8 +4275,7 @@ void AdltSection::writeTo(uint8_t* buf) { template size_t AdltSection::getSize() const { - const size_t pre_blob_size = sizeof(header) + sizeof(PSOD) * soInputs.size(); - assert(pre_blob_size <= header.blobStart); + assert(sizeof(header) + sizeof(PSOD) * soInputs.size() <= header.blobStart); return header.blobStart + header.blobSize; } diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 48edc79a718d..79eaf0ed3ca3 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -1224,76 +1224,15 @@ public: namespace adlt { -using llvm::ELF::Elf64_Half; -using llvm::ELF::Elf64_Off; -using llvm::ELF::Elf64_Addr; -using llvm::ELF::Elf64_Word; -using llvm::ELF::Elf64_Xword; -using Elf64_Byte = uint8_t; - -struct CrossSectionRef { - Elf64_Word sectionIndex; - Elf64_Off offsetFromStart; -}; - -struct SemanticVersion { - Elf64_Half major: 6; - Elf64_Half minor: 6; - Elf64_Half patch: 4; -}; - -static_assert( - sizeof(SemanticVersion) == sizeof(Elf64_Half), - ".adlt semantic version is designed to occupy uint16_t" -); - -enum HashType : Elf64_Byte { - NONE = 0, - MUSL_GNU_HASH = 1, - MUSL_SYSV_HASH = 2, - MUSL_KEYHASH = 3, - DEBUG_CONST = 0xff, -}; - -struct DtNeededIndex { - bool hasInternalPSOD : 1; // true if soname - Elf64_Off PSODindex : 16; // PSOD in the current ADLT image - Elf64_Off sonameOffset : 47; // string start in bound strTabSec -}; - -static_assert( - sizeof(DtNeededIndex) == sizeof(Elf64_Off), - "DtNeededIndex have to be an offset with intrused flags" -); - -struct CrossSectionVec { - Elf64_Xword secIndex; - Elf64_Xword numElem; - Elf64_Addr addr; -}; - -// Serializable representation per-shared-object-data in .adlt section -struct PSOD { - Elf64_Off soName; // offset in strTabSec - Elf64_Xword soNameHash; - CrossSectionVec initArray; - CrossSectionVec finiArray; - Elf64_Off dtNeeded; // offset to DtNeededIndex[] in blob - Elf64_Xword dtNeededSz; - CrossSectionRef sharedLocalSymbolIndex; - CrossSectionRef sharedGlobalSymbolIndex; -}; - -struct AdltSectionHeader { - SemanticVersion schemaVersion = {1, 0, 0}; - Elf64_Half schemaPSODSize = sizeof(PSOD); - Elf64_Half sharedObjectsNum; - HashType stringHashType = HashType::NONE; - Elf64_Off blobStart; // binary blob start offset from the .adlt start - Elf64_Xword blobSize; -}; - -constexpr char BlobStartMark[4] = {0xA, 0xD, 0x1, 0x7}; +#include "ADLTSection.h" + +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 -- Gitee From daf3aecb97f265448a33459f80b8910127004594 Mon Sep 17 00:00:00 2001 From: Khomutov Nikita Date: Wed, 3 Apr 2024 15:39:58 +0300 Subject: [PATCH 2/5] lint and add namespace under C++ macro Signed-off-by: Khomutov Nikita Change-Id: Icbd3c6d311beb852ff3182f2ac24f6e18b542db3 --- lld/ELF/ADLTSection.h | 18 ++++++++++++++---- lld/ELF/SyntheticSections.h | 3 +-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lld/ELF/ADLTSection.h b/lld/ELF/ADLTSection.h index 5b3079c36635..a8ff84786dd9 100644 --- a/lld/ELF/ADLTSection.h +++ b/lld/ELF/ADLTSection.h @@ -21,6 +21,12 @@ #include +#ifdef __cplusplus +namespace lld { +namespace elf { +namespace adlt { +#endif // __cplusplus + // part of #include typedef uint16_t Elf64_Half; typedef uint64_t Elf64_Off; @@ -29,7 +35,6 @@ typedef uint32_t Elf64_Word; typedef uint64_t Elf64_Xword; typedef uint8_t Elf64_Byte; - typedef struct { Elf64_Word secIndex; Elf64_Off offset; // in-section offset from start @@ -47,7 +52,6 @@ typedef struct { Elf64_Half patch: 4; } adlt_semver_t; - // DT_NEEDED string index with embedded PSOD index if available typedef struct { Elf64_Off hasInternalPSOD : 1; // true if soname @@ -55,7 +59,6 @@ typedef struct { Elf64_Off sonameOffset : 47; // string start in bound .adlt.strtab } adlt_dt_needed_index_t; - typedef enum { ADLT_HASH_TYPE_NONE = 0, ADLT_HASH_TYPE_GNU_HASH = 1, @@ -63,8 +66,8 @@ typedef enum { ADLT_HASH_TYPE_DEBUG_CONST = 0xfe, ADLT_HASH_TYPE_MAX = 0xff, } adlt_hash_type_enum_t; -typedef uint8_t adlt_hash_type_t; +typedef uint8_t adlt_hash_type_t; // Serializable representation per-shared-object-data in .adlt section typedef struct { @@ -90,4 +93,11 @@ typedef struct { static const char adltBlobStartMark[4] = { 0xA, 0xD, 0x1, 0x7 }; +#ifndef __cplusplus +#else // __cplusplus +} // namespace adlt +} // namespace elf +} // namespace lld +#endif // __cplusplus + #endif // LLD_ELF_ADLT_SECTION_H diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 79eaf0ed3ca3..ebf03b332d4b 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -22,6 +22,7 @@ #include "Config.h" #include "EhFrame.h" // OHOS_LOCAL +#include "ADLTSection.h" // OHOS_LOCAL #include "InputSection.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/MapVector.h" @@ -1224,8 +1225,6 @@ public: namespace adlt { -#include "ADLTSection.h" - using CrossSectionRef = adlt_cross_section_ref_t; using CrossSectionVec = adlt_cross_section_vec_t; using SemanticVersion = adlt_semver_t; -- Gitee From f9aafaabd5bbf3f8ebfefa17013b26f5c32121d3 Mon Sep 17 00:00:00 2001 From: Khomutov Nikita Date: Thu, 4 Apr 2024 10:57:08 +0300 Subject: [PATCH 3/5] [ADLT] add header size to .adlt header Signed-off-by: Khomutov Nikita Change-Id: I52cc794367e6e6bb08acc9b113c2785763583ddd --- lld/ELF/ADLTSection.h | 6 ++++-- lld/ELF/SyntheticSections.cpp | 16 ++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/lld/ELF/ADLTSection.h b/lld/ELF/ADLTSection.h index a8ff84786dd9..9e7dffb3257c 100644 --- a/lld/ELF/ADLTSection.h +++ b/lld/ELF/ADLTSection.h @@ -82,8 +82,9 @@ typedef struct { } adlt_psod_t; typedef struct { - adlt_semver_t schemaVersion; // {major, minor, patch} - Elf64_Half schemaPSODSize; // >= sizeof(adlt_psod_t) if compatible + adlt_semver_t schemaVersion; // {major, minor, patch} + Elf64_Half schemaHeaderSize; // >= sizeof(adlt_section_header_t) if comp + Elf64_Half schemaPSODSize; // >= sizeof(adlt_psod_t) if compatible Elf64_Half sharedObjectsNum; // number of PSOD entries adlt_hash_type_t stringHashType; // contains adlt_hash_type_enum_t value Elf64_Off blobStart; // offset of binary blob start relative to .adlt @@ -92,6 +93,7 @@ typedef struct { static const char adltBlobStartMark[4] = { 0xA, 0xD, 0x1, 0x7 }; +static const adlt_semver_t adltSchemaVersion = {1, 0, 0}; #ifndef __cplusplus #else // __cplusplus diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index d53b64b36800..28d699a13f3b 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -4016,12 +4016,11 @@ static_assert( "String hash type enum should occupy only one byte" ); - static_assert(sizeof(adltBlobStartMark) == 4, "0xad17 consist of 4 bytes" ); -static_assert(sizeof(AdltSectionHeader) == 24, +static_assert(sizeof(AdltSectionHeader) == 32, "please udpate major version if header has been changed" ); @@ -4052,12 +4051,13 @@ void AdltSection::finalizeContents() { const Elf64_Half soNum = soInputs.size(); header = AdltSectionHeader{ - {1, 0, 0}, // .schemaVersion - sizeof(PSOD), // .schemaPSODSize - soNum, // .sharedObjectsNum - ADLT_HASH_TYPE_GNU_HASH, // .stringHashType - getBlobStartOffset(), // .blobStart - estimateBlobSize(), // .blobSize + adltSchemaVersion, // .schemaVersion + sizeof(AdltSectionHeader), // .schemaHeaderSize + sizeof(PSOD), // .schemaPSODSize + soNum, // .sharedObjectsNum + ADLT_HASH_TYPE_GNU_HASH, // .stringHashType + getBlobStartOffset(), // .blobStart + estimateBlobSize(), // .blobSize }; buildSonameIndex(); -- Gitee From 636725e1b5f86de14f69a0afc3fa4d6c03f231b3 Mon Sep 17 00:00:00 2001 From: Khomutov Nikita Date: Thu, 4 Apr 2024 11:07:54 +0300 Subject: [PATCH 4/5] .adlt sec header: use proper includes for C/C++ Signed-off-by: Khomutov Nikita Change-Id: I3bf21fd81353c356c5804031ecb6ccde4c6999fc Signed-off-by: Khomutov Nikita --- lld/ELF/ADLTSection.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lld/ELF/ADLTSection.h b/lld/ELF/ADLTSection.h index 9e7dffb3257c..6ca2bf90cd36 100644 --- a/lld/ELF/ADLTSection.h +++ b/lld/ELF/ADLTSection.h @@ -19,12 +19,14 @@ #ifndef LLD_ELF_ADLT_SECTION_H #define LLD_ELF_ADLT_SECTION_H -#include - #ifdef __cplusplus +#include namespace lld { namespace elf { namespace adlt { + +#else // __cplusplus +#include #endif // __cplusplus // part of #include -- Gitee From cf4e9a015793751c7b64b30e44358492d1ddbe3d Mon Sep 17 00:00:00 2001 From: Khomutov Nikita Date: Thu, 4 Apr 2024 12:26:23 +0300 Subject: [PATCH 5/5] simplify ifdef Signed-off-by: Khomutov Nikita Change-Id: I0a5a85affdb3d6ab4dfd39fc2fc4a639fabc03c1 --- lld/ELF/ADLTSection.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lld/ELF/ADLTSection.h b/lld/ELF/ADLTSection.h index 6ca2bf90cd36..74fc48600554 100644 --- a/lld/ELF/ADLTSection.h +++ b/lld/ELF/ADLTSection.h @@ -97,8 +97,7 @@ static const char adltBlobStartMark[4] = { 0xA, 0xD, 0x1, 0x7 }; static const adlt_semver_t adltSchemaVersion = {1, 0, 0}; -#ifndef __cplusplus -#else // __cplusplus +#ifdef __cplusplus } // namespace adlt } // namespace elf } // namespace lld -- Gitee