diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp index ec0fdf0b67b38..d87a4d8d1ae79 100644 --- a/lld/COFF/Chunks.cpp +++ b/lld/COFF/Chunks.cpp @@ -564,6 +564,22 @@ void SectionChunk::getBaserels(std::vector *res) { continue; res->emplace_back(rva + rel.VirtualAddress, ty); } + + // Insert a 64-bit relocation for CHPEMetadataPointer in the native load + // config of a hybrid ARM64X image. Its value will be set in prepareLoadConfig + // to match the value in the EC load config, which is expected to be + // a relocatable pointer to the __chpe_metadata symbol. + COFFLinkerContext &ctx = file->symtab.ctx; + if (ctx.hybridSymtab && ctx.symtab.loadConfigSym && + ctx.symtab.loadConfigSym->getChunk() == this && + ctx.hybridSymtab->loadConfigSym && + ctx.symtab.loadConfigSize >= + offsetof(coff_load_configuration64, CHPEMetadataPointer) + + sizeof(coff_load_configuration64::CHPEMetadataPointer)) + res->emplace_back( + ctx.symtab.loadConfigSym->getRVA() + + offsetof(coff_load_configuration64, CHPEMetadataPointer), + IMAGE_REL_BASED_DIR64); } // MinGW specific. diff --git a/lld/test/COFF/arm64x-loadconfig.s b/lld/test/COFF/arm64x-loadconfig.s index d21f4bfe95b84..3b53d32a9b549 100644 --- a/lld/test/COFF/arm64x-loadconfig.s +++ b/lld/test/COFF/arm64x-loadconfig.s @@ -118,10 +118,14 @@ // BASERELOC: BaseReloc [ // BASERELOC-NEXT: Entry { // BASERELOC-NEXT: Type: DIR64 +// BASERELOC-NEXT: Address: 0x10C8 +// BASERELOC-NEXT: } +// BASERELOC-NEXT: Entry { +// BASERELOC-NEXT: Type: DIR64 // BASERELOC-NEXT: Address: 0x1208 // BASERELOC-NEXT: } // BASERELOC-NEXT: Entry { -// BASERELOC: Type: DIR64 +// BASERELOC-NEXT: Type: DIR64 // BASERELOC-NEXT: Address: 0x2074 // BASERELOC-NEXT: }