COFF: Support import-by-ordinal DLL imports.

Symbols exported by DLLs can be imported not by name but by
small number or ordinal. Usually, symbols have both ordinals
and names, and in that case ordinals are called "hints" and
used by the loader as hints.

However, symbols can have only ordinals. They are called
import-by-ordinal symbols. You need to manage ordinals by hand
so that they will never change if you choose to use the feature.
But it's supposed to make dynamic linking faster because
it needs no string comparison. Not sure if that claim still
stands in year 2015, though. Anyways, the feature exists,
and this patch implements that.

llvm-svn: 238780
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index 3a64a78..5a151ea 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -186,6 +186,12 @@
   write32le(Buf + FileOff, HintName->getRVA());
 }
 
+void OrdinalOnlyChunk::writeTo(uint8_t *Buf) {
+  // An import-by-ordinal slot has MSB 1 to indicate that
+  // this is import-by-ordinal (and not import-by-name).
+  write64le(Buf + FileOff, (uint64_t(1) << 63) | Ordinal);
+}
+
 void DirectoryChunk::applyRelocations(uint8_t *Buf) {
   auto *E = (coff_import_directory_table_entry *)(Buf + FileOff);
   E->ImportLookupTableRVA = LookupTab->getRVA();
@@ -195,20 +201,27 @@
 
 ImportTable::ImportTable(StringRef N,
                          std::vector<DefinedImportData *> &Symbols) {
+  // Create the import table hader.
   DLLName = new StringChunk(N);
   DirTab = new DirectoryChunk(DLLName);
-  for (DefinedImportData *S : Symbols)
-    HintNameTables.push_back(
-        new HintNameChunk(S->getExportName(), S->getOrdinal()));
 
-  for (Chunk *H : HintNameTables) {
-    LookupTables.push_back(new LookupChunk(H));
-    AddressTables.push_back(new LookupChunk(H));
+  // Create lookup and address tables. If they have external names,
+  // we need to create HintName chunks to store the names.
+  // If they don't (if they are import-by-ordinals), we store only
+  // ordinal values to the table.
+  for (DefinedImportData *S : Symbols) {
+    if (S->getExternalName().empty()) {
+      LookupTables.push_back(new OrdinalOnlyChunk(S->getOrdinal()));
+      AddressTables.push_back(new OrdinalOnlyChunk(S->getOrdinal()));
+      continue;
+    }
+    Chunk *C = new HintNameChunk(S->getExternalName(), S->getOrdinal());
+    HintNameTables.push_back(C);
+    LookupTables.push_back(new LookupChunk(C));
+    AddressTables.push_back(new LookupChunk(C));
   }
-
   for (int I = 0, E = Symbols.size(); I < E; ++I)
     Symbols[I]->setLocation(AddressTables[I]);
-
   DirTab->LookupTab = LookupTables[0];
   DirTab->AddressTab = AddressTables[0];
 }