@@ -272,12 +272,12 @@ class Writer {
272
272
OutputSection *findSection (StringRef name);
273
273
void addBaserels ();
274
274
void addBaserelBlocks (std::vector<Baserel> &v);
275
+ void createDynamicRelocs ();
275
276
276
277
uint32_t getSizeOfInitializedData ();
277
278
278
279
void prepareLoadConfig ();
279
280
template <typename T> void prepareLoadConfig (T *loadConfig);
280
- template <typename T> void checkLoadConfigGuardData (const T *loadConfig);
281
281
282
282
std::unique_ptr<FileOutputBuffer> &buffer;
283
283
std::map<PartialSectionKey, PartialSection *> partialSections;
@@ -754,6 +754,8 @@ void Writer::run() {
754
754
llvm::TimeTraceScope timeScope (" Write PE" );
755
755
ScopedTimer t1 (ctx.codeLayoutTimer );
756
756
757
+ if (ctx.config .machine == ARM64X)
758
+ ctx.dynamicRelocs = make<DynamicRelocsChunk>();
757
759
createImportTables ();
758
760
createSections ();
759
761
appendImportThunks ();
@@ -764,6 +766,7 @@ void Writer::run() {
764
766
mergeSections ();
765
767
sortECChunks ();
766
768
appendECImportTables ();
769
+ createDynamicRelocs ();
767
770
removeUnusedSections ();
768
771
finalizeAddresses ();
769
772
removeEmptySections ();
@@ -1596,8 +1599,13 @@ void Writer::assignAddresses() {
1596
1599
1597
1600
for (OutputSection *sec : ctx.outputSections ) {
1598
1601
llvm::TimeTraceScope timeScope (" Section: " , sec->name );
1599
- if (sec == relocSec)
1602
+ if (sec == relocSec) {
1600
1603
addBaserels ();
1604
+ if (ctx.dynamicRelocs ) {
1605
+ ctx.dynamicRelocs ->finalize ();
1606
+ relocSec->addChunk (ctx.dynamicRelocs );
1607
+ }
1608
+ }
1601
1609
uint64_t rawSize = 0 , virtualSize = 0 ;
1602
1610
sec->header .VirtualAddress = rva;
1603
1611
@@ -1798,9 +1806,12 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
1798
1806
exceptionTable.last ->getSize () -
1799
1807
exceptionTable.first ->getRVA ();
1800
1808
}
1801
- if (relocSec->getVirtualSize ()) {
1809
+ size_t relocSize = relocSec->getVirtualSize ();
1810
+ if (ctx.dynamicRelocs )
1811
+ relocSize -= ctx.dynamicRelocs ->getSize ();
1812
+ if (relocSize) {
1802
1813
dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = relocSec->getRVA ();
1803
- dir[BASE_RELOCATION_TABLE].Size = relocSec-> getVirtualSize () ;
1814
+ dir[BASE_RELOCATION_TABLE].Size = relocSize ;
1804
1815
}
1805
1816
if (Symbol *sym = ctx.symtab .findUnderscore (" _tls_used" )) {
1806
1817
if (Defined *b = dyn_cast<Defined>(sym)) {
@@ -2555,6 +2566,33 @@ void Writer::addBaserelBlocks(std::vector<Baserel> &v) {
2555
2566
relocSec->addChunk (make<BaserelChunk>(page, &v[i], &v[0 ] + j));
2556
2567
}
2557
2568
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
+
2558
2596
PartialSection *Writer::createPartialSection (StringRef name,
2559
2597
uint32_t outChars) {
2560
2598
PartialSection *&pSec = partialSections[{name, outChars}];
@@ -2634,11 +2672,6 @@ template <typename T> void Writer::prepareLoadConfig(T *loadConfig) {
2634
2672
if (ctx.config .dependentLoadFlags )
2635
2673
loadConfig->DependentLoadFlags = ctx.config .dependentLoadFlags ;
2636
2674
2637
- checkLoadConfigGuardData (loadConfig);
2638
- }
2639
-
2640
- template <typename T>
2641
- void Writer::checkLoadConfigGuardData (const T *loadConfig) {
2642
2675
size_t loadConfigSize = loadConfig->Size ;
2643
2676
2644
2677
#define RETURN_IF_NOT_CONTAINS (field ) \
@@ -2660,6 +2693,18 @@ void Writer::checkLoadConfigGuardData(const T *loadConfig) {
2660
2693
if (loadConfig->field != s->getVA ()) \
2661
2694
warn (#field " not set correctly in '_load_config_used'" );
2662
2695
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
+
2663
2708
if (ctx.config .guardCF == GuardCFLevel::Off)
2664
2709
return ;
2665
2710
RETURN_IF_NOT_CONTAINS (GuardFlags)
0 commit comments