gendef: Detect jumping of stdcall function to imported ordinal-only symbol

Currently gendef does not recognize information about stdcall functions
which jumps to function from external library imported by ordinal number.
It prints just:

  Check!!! Couldn't determine function argument count. Function doesn't return.

With this change gendef recognize also such jumps and prints better info:

  Check!!! return value is from ord 1 in lib.dll

First thing which is fixed in this change is mixing of ordinal numbers and
hint numbers. Those are two different things which in most cases are not
same numbers for exported functions in DLL export table.

Imported function in PE import table is either by name + hint number or by
the ordinal number. Never both. Currently the imp32_add() is taking
argument named "ord", but do_import_read32() calls that function with
parsed hint number. And then dump_def() function is printing line
"from <name> in <dll> (ordinal <%u>)" but for %u it prints hint number.
This is misleading for reader as it makes hard to understand it.

Extend do_import_read32() to properly read ordinal or hint number (what is
available) and adjust dump_def() to print ordinal number or export name,
based on what is present. Printing the hint number from import table is
useless as in most cases it does not match the hint number from DLL export
table.

Signed-off-by: Martin Storsjö <martin@martin.st>
diff --git a/mingw-w64-tools/gendef/src/gendef.c b/mingw-w64-tools/gendef/src/gendef.c
index a1c9795..c66b28e 100644
--- a/mingw-w64-tools/gendef/src/gendef.c
+++ b/mingw-w64-tools/gendef/src/gendef.c
@@ -49,7 +49,7 @@
 static int disassembleRet (uint32_t func,uint32_t *retpop,const char *name, sImportname **ppimpname, int *seen_ret);
 static size_t getMemonic (int *aCode,uint32_t pc,volatile uint32_t *jmp_pc,const char *name, sImportname **ppimpname);
 
-static sImportname *imp32_add (const char *dll, const char *name, uint32_t addr, uint16_t ord);
+static sImportname *imp32_add (const char *dll, const char *name, uint32_t addr, uint16_t hint, uint16_t ord);
 static void imp32_free (void);
 static sImportname *imp32_findbyaddress (uint32_t addr);
 
@@ -574,19 +574,28 @@
 
       for (;;) {
 	char *fctname;
+	uint16_t hint;
+	uint16_t ord;
 	pIAT = (PIMAGE_THUNK_DATA32) map_va (pid->OriginalFirstThunk + index);
 	pFT = (PIMAGE_THUNK_DATA32) map_va (pid->FirstThunk + index);
 	if (pIAT->u1.Ordinal == 0 || pFT->u1.Ordinal == 0)
 	  break;
 	if (IMAGE_SNAP_BY_ORDINAL32 (pIAT->u1.Ordinal))
+	{
 	  fctname = NULL;
+	  hint = 0;
+	  ord = IMAGE_ORDINAL32 (pIAT->u1.Ordinal);
+	}
 	else
+	{
 	  fctname = (char *) map_va (pIAT->u1.Function + 2);
-	if (fctname)
-	  imp32_add (imp_name, fctname,
+	  hint = *((uint16_t *) map_va (pIAT->u1.Function));
+	  ord = 0;
+	}
+	imp32_add (imp_name, fctname,
 	  //pid->OriginalFirstThunk + index + gPEDta->OptionalHeader.ImageBase,
 	  pid->FirstThunk + index + gPEDta->OptionalHeader.ImageBase,
-	    *((uint16_t *) map_va (pIAT->u1.Function)));
+	  hint, ord);
 	index += 4;
       }
       sz_imp -= 20;
@@ -621,12 +630,13 @@
 }
 
 static sImportname *
-imp32_add (const char *dll, const char *name, uint32_t addr, uint16_t ord)
+imp32_add (const char *dll, const char *name, uint32_t addr, uint16_t hint, uint16_t ord)
 {
   sImportname *n = (sImportname *) malloc (sizeof (sImportname));
   memset (n, 0, sizeof (sImportname));
   n->dll = strdup (dll);
-  n->name = strdup (name);
+  n->name = name ? strdup (name) : NULL;
+  n->hint = hint;
   n->ord = ord;
   n->addr_iat = addr;
   n->next = theImports;
@@ -834,8 +844,12 @@
 	}
       else if (pimpname)
         {
-	  fprintf (fp, " ; Check!!! return value is from %s in %s (ordinal %u)",
-	    pimpname->name, pimpname->dll, pimpname->ord);
+          if (pimpname->name)
+            fprintf (fp, " ; Check!!! return value is from %s in %s",
+              pimpname->name, pimpname->dll);
+          else
+            fprintf (fp, " ; Check!!! return value is from ord %u in %s",
+              (unsigned int )pimpname->ord, pimpname->dll);
         }
       else if (exp->func == 0 && !exp->beData)
 	{
diff --git a/mingw-w64-tools/gendef/src/gendef.h b/mingw-w64-tools/gendef/src/gendef.h
index c6acac7..68b168d 100644
--- a/mingw-w64-tools/gendef/src/gendef.h
+++ b/mingw-w64-tools/gendef/src/gendef.h
@@ -350,6 +350,7 @@
   uint32_t addr_iat;
   char *dll;
   char *name;
+  uint16_t hint;
   uint16_t ord;
 } sImportname;