@@ -272,12 +272,12 @@ class Writer {
272272 OutputSection *findSection (StringRef name);
273273 void addBaserels ();
274274 void addBaserelBlocks (std::vector<Baserel> &v);
275+ void createDynamicRelocs ();
275276
276277 uint32_t getSizeOfInitializedData ();
277278
278279 void prepareLoadConfig ();
279280 template <typename T> void prepareLoadConfig (T *loadConfig);
280- template <typename T> void checkLoadConfigGuardData (const T *loadConfig);
281281
282282 std::unique_ptr<FileOutputBuffer> &buffer;
283283 std::map<PartialSectionKey, PartialSection *> partialSections;
@@ -754,6 +754,8 @@ void Writer::run() {
754754 llvm::TimeTraceScope timeScope (" Write PE" );
755755 ScopedTimer t1 (ctx.codeLayoutTimer );
756756
757+ if (ctx.config .machine == ARM64X)
758+ ctx.dynamicRelocs = make<DynamicRelocsChunk>();
757759 createImportTables ();
758760 createSections ();
759761 appendImportThunks ();
@@ -764,6 +766,7 @@ void Writer::run() {
764766 mergeSections ();
765767 sortECChunks ();
766768 appendECImportTables ();
769+ createDynamicRelocs ();
767770 removeUnusedSections ();
768771 finalizeAddresses ();
769772 removeEmptySections ();
@@ -1596,8 +1599,13 @@ void Writer::assignAddresses() {
15961599
15971600 for (OutputSection *sec : ctx.outputSections ) {
15981601 llvm::TimeTraceScope timeScope (" Section: " , sec->name );
1599- if (sec == relocSec)
1602+ if (sec == relocSec) {
16001603 addBaserels ();
1604+ if (ctx.dynamicRelocs ) {
1605+ ctx.dynamicRelocs ->finalize ();
1606+ relocSec->addChunk (ctx.dynamicRelocs );
1607+ }
1608+ }
16011609 uint64_t rawSize = 0 , virtualSize = 0 ;
16021610 sec->header .VirtualAddress = rva;
16031611
@@ -1798,9 +1806,12 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
17981806 exceptionTable.last ->getSize () -
17991807 exceptionTable.first ->getRVA ();
18001808 }
1801- if (relocSec->getVirtualSize ()) {
1809+ size_t relocSize = relocSec->getVirtualSize ();
1810+ if (ctx.dynamicRelocs )
1811+ relocSize -= ctx.dynamicRelocs ->getSize ();
1812+ if (relocSize) {
18021813 dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = relocSec->getRVA ();
1803- dir[BASE_RELOCATION_TABLE].Size = relocSec-> getVirtualSize () ;
1814+ dir[BASE_RELOCATION_TABLE].Size = relocSize ;
18041815 }
18051816 if (Symbol *sym = ctx.symtab .findUnderscore (" _tls_used" )) {
18061817 if (Defined *b = dyn_cast<Defined>(sym)) {
@@ -2555,6 +2566,33 @@ void Writer::addBaserelBlocks(std::vector<Baserel> &v) {
25552566 relocSec->addChunk (make<BaserelChunk>(page, &v[i], &v[0 ] + j));
25562567}
25572568
2569+ void Writer::createDynamicRelocs () {
2570+ if (!ctx.dynamicRelocs )
2571+ return ;
2572+
2573+ const uint32_t coffHeaderOffset = dosStubSize + sizeof (PEMagic);
2574+ const uint32_t peHeaderOffset = coffHeaderOffset + sizeof (coff_file_header);
2575+ const uint32_t dataDirOffset = peHeaderOffset + sizeof (pe32plus_header);
2576+
2577+ // Adjust the Machine field in the COFF header to AMD64.
2578+ ctx.dynamicRelocs ->add (IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint16_t ),
2579+ coffHeaderOffset + offsetof (coff_file_header, Machine),
2580+ AMD64);
2581+
2582+ // Adjust the load config directory.
2583+ // FIXME: Use the hybrid load config value instead.
2584+ ctx.dynamicRelocs ->add (IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint32_t ),
2585+ dataDirOffset +
2586+ LOAD_CONFIG_TABLE * sizeof (data_directory) +
2587+ offsetof (data_directory, RelativeVirtualAddress),
2588+ 0 );
2589+ ctx.dynamicRelocs ->add (IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint32_t ),
2590+ dataDirOffset +
2591+ LOAD_CONFIG_TABLE * sizeof (data_directory) +
2592+ offsetof (data_directory, Size),
2593+ 0 );
2594+ }
2595+
25582596PartialSection *Writer::createPartialSection (StringRef name,
25592597 uint32_t outChars) {
25602598 PartialSection *&pSec = partialSections[{name, outChars}];
@@ -2634,11 +2672,6 @@ template <typename T> void Writer::prepareLoadConfig(T *loadConfig) {
26342672 if (ctx.config .dependentLoadFlags )
26352673 loadConfig->DependentLoadFlags = ctx.config .dependentLoadFlags ;
26362674
2637- checkLoadConfigGuardData (loadConfig);
2638- }
2639-
2640- template <typename T>
2641- void Writer::checkLoadConfigGuardData (const T *loadConfig) {
26422675 size_t loadConfigSize = loadConfig->Size ;
26432676
26442677#define RETURN_IF_NOT_CONTAINS (field ) \
@@ -2660,6 +2693,18 @@ void Writer::checkLoadConfigGuardData(const T *loadConfig) {
26602693 if (loadConfig->field != s->getVA ()) \
26612694 warn (#field " not set correctly in '_load_config_used'" );
26622695
2696+ if (ctx.dynamicRelocs ) {
2697+ IF_CONTAINS (DynamicValueRelocTableSection) {
2698+ loadConfig->DynamicValueRelocTableSection = relocSec->sectionIndex ;
2699+ loadConfig->DynamicValueRelocTableOffset =
2700+ ctx.dynamicRelocs ->getRVA () - relocSec->getRVA ();
2701+ }
2702+ else {
2703+ warn (" '_load_config_used' structure too small to include dynamic "
2704+ " relocations" );
2705+ }
2706+ }
2707+
26632708 if (ctx.config .guardCF == GuardCFLevel::Off)
26642709 return ;
26652710 RETURN_IF_NOT_CONTAINS (GuardFlags)
0 commit comments