@@ -227,6 +227,9 @@ class Writer {
227227 void markSymbolsForRVATable (ObjFile *file,
228228 ArrayRef<SectionChunk *> symIdxChunks,
229229 SymbolRVASet &tableSymbols);
230+ void getSymbolsFromSections (ObjFile *file,
231+ ArrayRef<SectionChunk *> symIdxChunks,
232+ std::vector<Symbol *> &symbols);
230233 void maybeAddRVATable (SymbolRVASet tableSymbols, StringRef tableSym,
231234 StringRef countSym);
232235 void setSectionPermissions ();
@@ -605,8 +608,9 @@ void Writer::run() {
605608
606609 createImportTables ();
607610 createSections ();
608- createMiscChunks ();
609611 appendImportThunks ();
612+ // Import thunks must be added before the Control Flow Guard tables are added.
613+ createMiscChunks ();
610614 createExportTable ();
611615 mergeSections ();
612616 removeUnusedSections ();
@@ -1618,6 +1622,8 @@ static void markSymbolsWithRelocations(ObjFile *file,
16181622// table.
16191623void Writer::createGuardCFTables () {
16201624 SymbolRVASet addressTakenSyms;
1625+ SymbolRVASet giatsRVASet;
1626+ std::vector<Symbol *> giatsSymbols;
16211627 SymbolRVASet longJmpTargets;
16221628 for (ObjFile *file : ObjFile::instances) {
16231629 // If the object was compiled with /guard:cf, the address taken symbols
@@ -1627,6 +1633,8 @@ void Writer::createGuardCFTables() {
16271633 // possibly address-taken.
16281634 if (file->hasGuardCF ()) {
16291635 markSymbolsForRVATable (file, file->getGuardFidChunks (), addressTakenSyms);
1636+ markSymbolsForRVATable (file, file->getGuardIATChunks (), giatsRVASet);
1637+ getSymbolsFromSections (file, file->getGuardIATChunks (), giatsSymbols);
16301638 markSymbolsForRVATable (file, file->getGuardLJmpChunks (), longJmpTargets);
16311639 } else {
16321640 markSymbolsWithRelocations (file, addressTakenSyms);
@@ -1641,6 +1649,16 @@ void Writer::createGuardCFTables() {
16411649 for (Export &e : config->exports )
16421650 maybeAddAddressTakenFunction (addressTakenSyms, e.sym );
16431651
1652+ // For each entry in the .giats table, check if it has a corresponding load
1653+ // thunk (e.g. because the DLL that defines it will be delay-loaded) and, if
1654+ // so, add the load thunk to the address taken (.gfids) table.
1655+ for (Symbol *s : giatsSymbols) {
1656+ if (auto *di = dyn_cast<DefinedImportData>(s)) {
1657+ if (di->loadThunkSym )
1658+ addSymbolToRVASet (addressTakenSyms, di->loadThunkSym );
1659+ }
1660+ }
1661+
16441662 // Ensure sections referenced in the gfid table are 16-byte aligned.
16451663 for (const ChunkAndOffset &c : addressTakenSyms)
16461664 if (c.inputChunk ->getAlignment () < 16 )
@@ -1649,6 +1667,10 @@ void Writer::createGuardCFTables() {
16491667 maybeAddRVATable (std::move (addressTakenSyms), " __guard_fids_table" ,
16501668 " __guard_fids_count" );
16511669
1670+ // Add the Guard Address Taken IAT Entry Table (.giats).
1671+ maybeAddRVATable (std::move (giatsRVASet), " __guard_iat_table" ,
1672+ " __guard_iat_count" );
1673+
16521674 // Add the longjmp target table unless the user told us not to.
16531675 if (config->guardCF == GuardCFLevel::Full)
16541676 maybeAddRVATable (std::move (longJmpTargets), " __guard_longjmp_table" ,
@@ -1665,11 +1687,11 @@ void Writer::createGuardCFTables() {
16651687}
16661688
16671689// Take a list of input sections containing symbol table indices and add those
1668- // symbols to an RVA table . The challenge is that symbol RVAs are not known and
1690+ // symbols to a vector . The challenge is that symbol RVAs are not known and
16691691// depend on the table size, so we can't directly build a set of integers.
1670- void Writer::markSymbolsForRVATable (ObjFile *file,
1692+ void Writer::getSymbolsFromSections (ObjFile *file,
16711693 ArrayRef<SectionChunk *> symIdxChunks,
1672- SymbolRVASet &tableSymbols ) {
1694+ std::vector<Symbol *> &symbols ) {
16731695 for (SectionChunk *c : symIdxChunks) {
16741696 // Skip sections discarded by linker GC. This comes up when a .gfids section
16751697 // is associated with something like a vtable and the vtable is discarded.
@@ -1687,7 +1709,7 @@ void Writer::markSymbolsForRVATable(ObjFile *file,
16871709 }
16881710
16891711 // Read each symbol table index and check if that symbol was included in the
1690- // final link. If so, add it to the table symbol set .
1712+ // final link. If so, add it to the vector of symbols .
16911713 ArrayRef<ulittle32_t > symIndices (
16921714 reinterpret_cast <const ulittle32_t *>(data.data ()), data.size () / 4 );
16931715 ArrayRef<Symbol *> objSymbols = file->getSymbols ();
@@ -1699,12 +1721,24 @@ void Writer::markSymbolsForRVATable(ObjFile *file,
16991721 }
17001722 if (Symbol *s = objSymbols[symIndex]) {
17011723 if (s->isLive ())
1702- addSymbolToRVASet (tableSymbols, cast<Defined >(s));
1724+ symbols. push_back ( cast<Symbol >(s));
17031725 }
17041726 }
17051727 }
17061728}
17071729
1730+ // Take a list of input sections containing symbol table indices and add those
1731+ // symbols to an RVA table.
1732+ void Writer::markSymbolsForRVATable (ObjFile *file,
1733+ ArrayRef<SectionChunk *> symIdxChunks,
1734+ SymbolRVASet &tableSymbols) {
1735+ std::vector<Symbol *> syms;
1736+ getSymbolsFromSections (file, symIdxChunks, syms);
1737+
1738+ for (Symbol *s : syms)
1739+ addSymbolToRVASet (tableSymbols, cast<Defined>(s));
1740+ }
1741+
17081742// Replace the absolute table symbol with a synthetic symbol pointing to
17091743// tableChunk so that we can emit base relocations for it and resolve section
17101744// relative relocations.
0 commit comments