diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 73a11c1aedd716db787ab2c71369bc3e540fa233..a8edcb5688755bbf348f351adc7f1a6a4e34196d 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -4060,11 +4060,6 @@ static_assert( "adlt_dt_needed_index_t have to be an offset with intrused flags" ); -static_assert( - sizeof(adlt_relocations_segment_t) == 16, - "adlt_relocations_segment_t size is 16 bytes" -); - static_assert( sizeof(adlt_cross_section_ref_t) == 16, "adlt_cross_section_ref_t size is 16 bytes" @@ -4085,11 +4080,11 @@ static_assert( "blob array reference occupies 16 bytes in PSOD" ); -static_assert(sizeof(adltBlobStartMark) == 4, +static_assert(sizeof(adltBlobStartMark) == 4, "0xad17 consist of 4 bytes" ); -static_assert(sizeof(adlt_section_header_t) == 72, +static_assert(sizeof(adlt_section_header_t) == 40, "please update version if header has been changed" ); @@ -4110,12 +4105,12 @@ template void AdltSection::finalizeContents() { soInputs.clear(); soInputs.reserve(ctx->sharedFilesExtended.size()); - for (InputFile* file : ctx->sharedFilesExtended) { + for (InputFile* file : ctx->sharedFilesExtended) { auto* soext = cast>(file); soInputs.push_back(makeSoData(soext)); } - assert((soInputs.size() < 1<<16) && + assert((soInputs.size() < 1<<16) && "the number of input libs exeeds ELF limit on number of sections"); const Elf64_Half soNum = soInputs.size(); @@ -4131,8 +4126,6 @@ void AdltSection::finalizeContents() { getBlobStartOffset(), // .blobStart estimateBlobSize(), // .blobSize 0, // .overallMappedSize, known on writeTo - {0, 0}, // .relaDynSegs, filled in writeTo - {0, 0}, // .relaPltSegs, filled in writeTo }; buildSonameIndex(); @@ -4203,12 +4196,7 @@ size_t AdltSection::estimateOverallMappedSize() { template typename AdltSection::CommonData AdltSection::makeCommonData() { - // TODO: fill relaDynSegs - // TODO: fill relaPltSegs - return CommonData { - {}, // .relaDynSegs - {}, // .relaPltSegs UINT32_MAX, // .symtabSecIndex, filled in writeTo }; } @@ -4231,8 +4219,8 @@ AdltSection::makeSoData(const SharedFileExtended* soext) { data.initArrayName = soext->addAdltPostfix(".init_array"); data.finiArrayName = soext->addAdltPostfix(".fini_array"); - // TODO: fill data.relaDynSegs - // TODO: fill data.relaPltSegs + // TODO: fill data.relaDynIndx + // TODO: fill data.relaPltIndx std::copy(soext->programHeaderIndexes.begin(), soext->programHeaderIndexes.end(), @@ -4282,8 +4270,8 @@ adlt_psod_t AdltSection::serialize(const SoData& soData) const { soData.sharedGlobalIndex.value_or(0), }, // .sharedGlobalSymbolIndex adlt_blob_u16_array_t {}, // .phIndexes, filled in writeTo - adlt_blob_array_t {}, // .relaDynSegs, filled in writeTo - adlt_blob_array_t {}, // .relaPltSegs, filled in writeTo + adlt_blob_u32_array_t {}, // .relaDynIndx, filled in writeTo + adlt_blob_u32_array_t {}, // .relaPltIndx, filled in writeTo }; } @@ -4299,13 +4287,10 @@ 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(); - blobSize += sizeof(adlt_relocations_segment_t) * soData.relaDynSegs.size(); - blobSize += sizeof(adlt_relocations_segment_t) * soData.relaPltSegs.size(); + blobSize += sizeof(uint32_t) * soData.relaDynIndx.size(); + blobSize += sizeof(uint32_t) * soData.relaPltIndx.size(); }; - blobSize += sizeof(adlt_relocations_segment_t) * common.relaDynSegs.size(); - blobSize += sizeof(adlt_relocations_segment_t) * common.relaPltSegs.size(); - return blobSize; } @@ -4321,6 +4306,19 @@ adlt_blob_array_t AdltSection::writeArray( return {offset, to_write}; } +template +template +adlt_blob_array_t AdltSection::writeArray( + uint8_t* buff, size_t offset, const ArrayRef& data) { + if (data.empty()) return {0x0, 0}; + + const size_t to_write = data.size() * sizeof(T); + memcpy(buff + offset, data.data(), to_write); + + return {offset, to_write}; +} + + template adlt_blob_array_t AdltSection::writeDtNeeded( uint8_t* buff, size_t offset, const DtNeededsVec& neededVec) { @@ -4332,7 +4330,7 @@ adlt_blob_array_t AdltSection::writeDtNeeded( 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 + need_data.str.strtabOff, // .sonameOffset }); } @@ -4380,7 +4378,7 @@ void AdltSection::writeTo(uint8_t* buf) { size_t blobOff = 0; memcpy(blobBuf + blobOff, &adltBlobStartMark, sizeof(adltBlobStartMark)); blobOff += sizeof(adltBlobStartMark); - + // psod-related data for(const auto& it : llvm::enumerate(soInputs)) { const auto& soData = it.value(); @@ -4391,21 +4389,18 @@ void AdltSection::writeTo(uint8_t* buf) { psod.phIndexes = writeArray(blobBuf, blobOff, soData.phIndexes); blobOff += psod.phIndexes.size; - - psod.relaDynSegs = writeArray(blobBuf, blobOff, soData.relaDynSegs); - blobOff += psod.relaDynSegs.size; - - psod.relaPltSegs = writeArray(blobBuf, blobOff, soData.relaPltSegs); - blobOff += psod.relaPltSegs.size; } - // common data - { - header.relaDynSegs = writeArray(blobBuf, blobOff, common.relaDynSegs); - blobOff += header.relaDynSegs.size; + // group up relaDyn and relaPlt idxs, it tends to be size-consuming + for(const auto& it : llvm::enumerate(soInputs)) { + const auto& soData = it.value(); + auto& psod = psods[it.index()]; + + psod.relaDynIndx = writeArray(blobBuf, blobOff, soData.relaDynIndx); + blobOff += psod.relaDynIndx.size; - header.relaPltSegs = writeArray(blobBuf, blobOff, common.relaPltSegs); - blobOff += header.relaPltSegs.size; + psod.relaPltIndx = writeArray(blobBuf, blobOff, soData.relaPltIndx); + blobOff += psod.relaPltIndx.size; } // finalize header.blobSize diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 09189e39f1d6e98e1563a7c28760525eb75dae8b..c16389cb31ecd200f67e6c2144c500ab1207ff8e 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -1241,7 +1241,7 @@ public: SectionString str; llvm::Optional psodIndex; }; - + using SectionStringVector = SmallVector; using DtNeededsVec = SmallVector; @@ -1260,14 +1260,12 @@ public: llvm::Optional sharedGlobalIndex; SmallVector phIndexes; - SmallVector relaDynSegs; // TODO - SmallVector relaPltSegs; // TODO + ArrayRef relaDynIndx; // TODO + ArrayRef relaPltIndx; // TODO }; // will be used to form some header data struct CommonData { - SmallVector relaDynSegs; // TODO - SmallVector relaPltSegs; // TODO uint32_t symtabSecIndex = UINT32_MAX; }; @@ -1301,6 +1299,10 @@ private: adlt_blob_array_t writeArray(uint8_t* buff, size_t offset, const SmallVector& data); + template + adlt_blob_array_t writeArray(uint8_t* buff, size_t offset, + const ArrayRef& data); + adlt_blob_array_t writeDtNeeded(uint8_t* buff, size_t offset, const DtNeededsVec& neededVec); diff --git a/llvm/include/llvm/BinaryFormat/ADLTSection.h b/llvm/include/llvm/BinaryFormat/ADLTSection.h index 37656b486b776c211db893ca14ab53ee549966b6..ac883cb30da8d92c5aed462eb15905d75c32b689 100644 --- a/llvm/include/llvm/BinaryFormat/ADLTSection.h +++ b/llvm/include/llvm/BinaryFormat/ADLTSection.h @@ -74,12 +74,6 @@ typedef struct { Elf64_Off sonameOffset : 47; // string start in bound .adlt.strtab } adlt_dt_needed_index_t; -typedef struct { - Elf64_Word relType; // relocation type - Elf64_Word count; // segment length - Elf64_Off startOffset; // segment start offset in .rela.dyn -} adlt_relocations_segment_t; - typedef enum { ADLT_HASH_TYPE_NONE = 0, ADLT_HASH_TYPE_GNU_HASH = 1, @@ -100,8 +94,8 @@ typedef struct { adlt_cross_section_ref_t sharedLocalSymbolIndex; adlt_cross_section_ref_t sharedGlobalSymbolIndex; adlt_blob_u16_array_t phIndexes; // program header indexes, typeof(e_phnum) - adlt_blob_array_t relaDynSegs; // lib's adlt_relocations_segment_t[] - adlt_blob_array_t relaPltSegs; // lib's adlt_relocations_segment_t[] + adlt_blob_u32_array_t relaDynIndx; // .rela.dyn dependent indexes, raw list + adlt_blob_u32_array_t relaPltIndx; // .rela.plt dependent indexes, raw list } adlt_psod_t; typedef struct { @@ -113,8 +107,6 @@ typedef struct { Elf64_Off blobStart; // offset of binary blob start relative to .adlt Elf64_Xword blobSize; Elf64_Xword overallMappedSize; // bytes, required to map the whole ADLT image - adlt_blob_array_t relaDynSegs; // common adlt_relocations_segment_t[] - adlt_blob_array_t relaPltSegs; // common adlt_relocations_segment_t[] } adlt_section_header_t; static const char adltBlobStartMark[4] = { 0xA, 0xD, 0x1, 0x7 }; diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 26d30094f28bc0e883ed273616fc9d5b599af539..48e9ec0d2c2513bcc0c4d25fd67f1471bb8a984e 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -7022,6 +7022,7 @@ template void LLVMELFDumper::printHashHistograms() { template void LLVMELFDumper::printAdltSection() { using namespace llvm::adlt; + constexpr size_t kBinDumpLimit = sizeof(Elf64_Xword) * 0x80; Expected> ContentsOrErr = this->findAdlt(); if (!ContentsOrErr) { @@ -7050,21 +7051,6 @@ template void LLVMELFDumper::printAdltSection() { W.printHex("blob-start", header->blobStart); W.printHex("blob-size", header->blobSize); W.printHex("overall-mapped-size", header->overallMappedSize); - - if (ver.minor < 1) break; - - { - DictScope RDEntry(W, "rela-dyn-segs"); - const auto& arr = header->relaDynSegs; - W.printHex("offset", arr.offset); - W.printHex("size", arr.size); - } - { - DictScope RPEntry(W, "rela-plt-segs"); - const auto& arr = header->relaPltSegs; - W.printHex("offset", arr.offset); - W.printHex("size", arr.size); - } } while(0); ArrayRef psodsRaw = adltRaw.slice( @@ -7077,7 +7063,7 @@ template void LLVMELFDumper::printAdltSection() { "PSOD and blob entries are overlapped"); if (blob.data() + blob.size() > adltRaw.data() + adltRaw.size()) return this->reportUniqueWarning("invalid .adlt section: " - "blob is out section range"); + "blob is out of section range"); { ListScope LPsods(W, "PSODs"); @@ -7103,10 +7089,11 @@ template void LLVMELFDumper::printAdltSection() { } { DictScope DNEntry(W, "dt-needed"); - W.printHex("size", psod.dtNeeded.size); - W.printHex("offset", psod.dtNeeded.offset); + const auto& arr = psod.dtNeeded; + W.printHex("size", arr.size); + W.printHex("offset", arr.offset); - const auto chunk = blob.slice(psod.dtNeeded.offset, psod.dtNeeded.size); + const auto chunk = blob.slice(arr.offset, arr.size); if (!chunk.empty()) { W.printBinary("raw", chunk); @@ -7140,47 +7127,56 @@ template void LLVMELFDumper::printAdltSection() { const auto& arr = psod.phIndexes; W.printHex("size", arr.size); W.printHex("offset", arr.offset); - + const auto chunk = blob.slice(arr.offset, arr.size); if (!chunk.empty()) { + W.printBinary("raw", chunk); ArrayRef phIdxs( reinterpret_cast(chunk.data()), chunk.size() / sizeof(uint16_t)); - W.printBinary("raw", chunk); W.printList("values", phIdxs); } } - - if (ver.minor < 1) continue; - { - DictScope RDSEntry(W, "rela-dyn-segs"); - const auto& arr = psod.relaDynSegs; + DictScope RDEntry(W, "rela-dyn-idxs"); + const auto& arr = psod.relaDynIndx; W.printHex("size", arr.size); W.printHex("offset", arr.offset); const auto chunk = blob.slice(arr.offset, arr.size); - if (!chunk.empty()) - W.printBinary("raw", chunk); + if (!chunk.empty()) { + if (chunk.size() > kBinDumpLimit) + W.printString("raw", ""); + else + W.printBinary("raw", chunk); + } } { - DictScope RPSEntry(W, "rela-plt-segs"); - const auto& arr = psod.relaPltSegs; + DictScope RPEntry(W, "rela-plt-idsx"); + const auto& arr = psod.relaPltIndx; W.printHex("size", arr.size); W.printHex("offset", arr.offset); const auto chunk = blob.slice(arr.offset, arr.size); - if (!chunk.empty()) - W.printBinary("raw", chunk); + if (!chunk.empty()) { + if (chunk.size() > kBinDumpLimit) + W.printString("raw", ""); + else + W.printBinary("raw", chunk); + } } } } { - DictScope DBlob (W, "Blob"); + DictScope DBlob(W, "Blob"); W.printHex("start", header->blobStart); W.printHex("size", header->blobSize); - W.printBinaryBlock("raw", blob); + + if (blob.size() > kBinDumpLimit * 50) + W.printString("raw", ""); + else + W.printBinaryBlock("raw", blob); } }