/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
/*-------------------------------------------------------------------------
  Portions of this source have been derived from the 'bindexplib' tool
  provided by the CERN ROOT Data Analysis Framework project (root.cern.ch).
  Permission has been granted by Pere Mato <pere.mato@cern.ch> to distribute
  this derived work under the CMake license.
-------------------------------------------------------------------------*/

/*
*----------------------------------------------------------------------
* Program:  dumpexts.exe
* Author:   Gordon Chaffee
*
* History:  The real functionality of this file was written by
*           Matt Pietrek in 1993 in his pedump utility.  I've
*           modified it to dump the externals in a bunch of object
*           files to create a .def file.
*
* Notes:    Visual C++ puts an underscore before each exported symbol.
*           This file removes them.  I don't know if this is a problem
*           this other compilers.  If _MSC_VER is defined,
*           the underscore is removed.  If not, it isn't.  To get a
*           full dump of an object file, use the -f option.  This can
*           help determine the something that may be different with a
*           compiler other than Visual C++.
*   ======================================
* Corrections (Axel 2006-04-04):
*   Conversion to C++. Mostly.
*
 * Extension (Axel 2006-03-15)
 *    As soon as an object file contains an /EXPORT directive (which
 *    is generated by the compiler when a symbol is declared as
 *    __declspec(dllexport) no to-be-exported symbols are printed,
 *    as the linker will see these directives, and if those directives
 *    are present we only export selectively (i.e. we trust the
 *    programmer).
 *
 *   ======================================
*   ======================================
* Corrections (Valery Fine 23/02/98):
*
*           The "(vector) deleting destructor" MUST not be exported
*           To recognize it the following test are introduced:
*  "@@UAEPAXI@Z"  scalar deleting dtor
*  "@@QAEPAXI@Z"  vector deleting dtor
*  "AEPAXI@Z"     vector deleting dtor with thunk adjustor
*   ======================================
* Corrections (Valery Fine 12/02/97):
*
*    It created a wrong EXPORTS for the global pointers and constants.
*    The Section Header has been involved to discover the missing information
*    Now the pointers are correctly supplied with "DATA" descriptor
*        the constants  with no extra descriptor.
*
* Corrections (Valery Fine 16/09/96):
*
*     It didn't work for C++ code with global variables and class definitions
*     The DumpExternalObject function has been introduced to generate .DEF file
*
* Author:   Valery Fine 16/09/96  (E-mail: fine@vxcern.cern.ch)
*----------------------------------------------------------------------
*/
#include "bindexplib.h"

#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx"
#include <iostream>
#include <windows.h>

#ifndef IMAGE_FILE_MACHINE_ARM
#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
#endif

#ifndef IMAGE_FILE_MACHINE_THUMB
#define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian
#endif

#ifndef IMAGE_FILE_MACHINE_ARMNT
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
#endif

#ifndef IMAGE_FILE_MACHINE_ARM64
#define IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64 Little-Endian
#endif

typedef struct cmANON_OBJECT_HEADER_BIGOBJ
{
  /* same as ANON_OBJECT_HEADER_V2 */
  WORD Sig1;    // Must be IMAGE_FILE_MACHINE_UNKNOWN
  WORD Sig2;    // Must be 0xffff
  WORD Version; // >= 2 (implies the Flags field is present)
  WORD Machine; // Actual machine - IMAGE_FILE_MACHINE_xxx
  DWORD TimeDateStamp;
  CLSID ClassID;        // {D1BAA1C7-BAEE-4ba9-AF20-FAF66AA4DCB8}
  DWORD SizeOfData;     // Size of data that follows the header
  DWORD Flags;          // 0x1 -> contains metadata
  DWORD MetaDataSize;   // Size of CLR metadata
  DWORD MetaDataOffset; // Offset of CLR metadata

  /* bigobj specifics */
  DWORD NumberOfSections; // extended from WORD
  DWORD PointerToSymbolTable;
  DWORD NumberOfSymbols;
} cmANON_OBJECT_HEADER_BIGOBJ;

typedef struct _cmIMAGE_SYMBOL_EX
{
  union
  {
    BYTE ShortName[8];
    struct
    {
      DWORD Short; // if 0, use LongName
      DWORD Long;  // offset into string table
    } Name;
    DWORD LongName[2]; // PBYTE  [2]
  } N;
  DWORD Value;
  LONG SectionNumber;
  WORD Type;
  BYTE StorageClass;
  BYTE NumberOfAuxSymbols;
} cmIMAGE_SYMBOL_EX;
typedef cmIMAGE_SYMBOL_EX UNALIGNED* cmPIMAGE_SYMBOL_EX;

PIMAGE_SECTION_HEADER GetSectionHeaderOffset(
  PIMAGE_FILE_HEADER pImageFileHeader)
{
  return (PIMAGE_SECTION_HEADER)((DWORD_PTR)pImageFileHeader +
                                 IMAGE_SIZEOF_FILE_HEADER +
                                 pImageFileHeader->SizeOfOptionalHeader);
}

PIMAGE_SECTION_HEADER GetSectionHeaderOffset(
  cmANON_OBJECT_HEADER_BIGOBJ* pImageFileHeader)
{
  return (PIMAGE_SECTION_HEADER)((DWORD_PTR)pImageFileHeader +
                                 sizeof(cmANON_OBJECT_HEADER_BIGOBJ));
}

/*
+ * Utility func, strstr with size
+ */
const char* StrNStr(const char* start, const char* find, size_t& size)
{
  size_t len;
  const char* hint;

  if (!start || !find || !size) {
    size = 0;
    return 0;
  }
  len = strlen(find);

  while ((hint = (const char*)memchr(start, find[0], size - len + 1))) {
    size -= (hint - start);
    if (!strncmp(hint, find, len))
      return hint;
    start = hint + 1;
  }

  size = 0;
  return 0;
}

template <
  // cmANON_OBJECT_HEADER_BIGOBJ or IMAGE_FILE_HEADER
  class ObjectHeaderType,
  // cmPIMAGE_SYMBOL_EX or PIMAGE_SYMBOL
  class SymbolTableType>
class DumpSymbols
{
public:
  /*
   *----------------------------------------------------------------------
   * Constructor --
   *
   *     Initialize variables from pointer to object header.
   *
   *----------------------------------------------------------------------
   */

  DumpSymbols(ObjectHeaderType* ih, std::set<std::string>& symbols,
              std::set<std::string>& dataSymbols, bool isI386)
    : Symbols(symbols)
    , DataSymbols(dataSymbols)
  {
    this->ObjectImageHeader = ih;
    this->SymbolTable =
      (SymbolTableType*)((DWORD_PTR) this->ObjectImageHeader +
                         this->ObjectImageHeader->PointerToSymbolTable);
    this->SectionHeaders = GetSectionHeaderOffset(this->ObjectImageHeader);
    this->SymbolCount = this->ObjectImageHeader->NumberOfSymbols;
    this->IsI386 = isI386;
  }

  /*
   *----------------------------------------------------------------------
   * DumpObjFile --
   *
   *      Dump an object file's exported symbols.
   *----------------------------------------------------------------------
   */
  void DumpObjFile() { this->DumpExternalsObjects(); }

  /*
   *----------------------------------------------------------------------
   * DumpExternalsObjects --
   *
   *      Dumps a COFF symbol table from an OBJ.
   *----------------------------------------------------------------------
   */
  void DumpExternalsObjects()
  {
    unsigned i;
    PSTR stringTable;
    std::string symbol;
    DWORD SectChar;
    /*
     * The string table apparently starts right after the symbol table
     */
    stringTable = (PSTR) & this->SymbolTable[this->SymbolCount];
    SymbolTableType* pSymbolTable = this->SymbolTable;
    for (i = 0; i < this->SymbolCount; i++) {
      if (pSymbolTable->SectionNumber > 0 &&
          (pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
        if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
          /*
          *    The name of the Function entry points
          */
          if (pSymbolTable->N.Name.Short != 0) {
            symbol.clear();
            symbol.insert(0, (const char*)pSymbolTable->N.ShortName, 8);
          } else {
            symbol = stringTable + pSymbolTable->N.Name.Long;
          }

          // clear out any leading spaces
          while (isspace(symbol[0]))
            symbol.erase(0, 1);
          // if it starts with _ and has an @ then it is a __cdecl
          // so remove the @ stuff for the export
          if (symbol[0] == '_') {
            std::string::size_type posAt = symbol.find('@');
            if (posAt != std::string::npos) {
              symbol.erase(posAt);
            }
          }
          // For i386 builds we need to remove _
          if (this->IsI386 && symbol[0] == '_') {
            symbol.erase(0, 1);
          }

          // Check whether it is "Scalar deleting destructor" and "Vector
          // deleting destructor"
          // if scalarPrefix and vectorPrefix are not found then print
          // the symbol
          const char* scalarPrefix = "??_G";
          const char* vectorPrefix = "??_E";
          // The original code had a check for
          //     symbol.find("real@") == std::string::npos)
          // but this disallows member functions with the name "real".
          if (symbol.compare(0, 4, scalarPrefix) &&
              symbol.compare(0, 4, vectorPrefix)) {
            SectChar = this->SectionHeaders[pSymbolTable->SectionNumber - 1]
                         .Characteristics;
            // skip symbols containing a dot
            if (symbol.find('.') == std::string::npos) {
              if (!pSymbolTable->Type && (SectChar & IMAGE_SCN_MEM_WRITE)) {
                // Read only (i.e. constants) must be excluded
                this->DataSymbols.insert(symbol);
              } else {
                if (pSymbolTable->Type || !(SectChar & IMAGE_SCN_MEM_READ) ||
                    (SectChar & IMAGE_SCN_MEM_EXECUTE)) {
                  this->Symbols.insert(symbol);
                }
              }
            }
          }
        }
      }

      /*
      * Take into account any aux symbols
      */
      i += pSymbolTable->NumberOfAuxSymbols;
      pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
      pSymbolTable++;
    }
  }

private:
  std::set<std::string>& Symbols;
  std::set<std::string>& DataSymbols;
  DWORD_PTR SymbolCount;
  PIMAGE_SECTION_HEADER SectionHeaders;
  ObjectHeaderType* ObjectImageHeader;
  SymbolTableType* SymbolTable;
  bool IsI386;
};

bool DumpFile(const char* filename, std::set<std::string>& symbols,
              std::set<std::string>& dataSymbols)
{
  HANDLE hFile;
  HANDLE hFileMapping;
  LPVOID lpFileBase;

  hFile = CreateFileW(cmsys::Encoding::ToWide(filename).c_str(), GENERIC_READ,
                      FILE_SHARE_READ, NULL, OPEN_EXISTING,
                      FILE_ATTRIBUTE_NORMAL, 0);

  if (hFile == INVALID_HANDLE_VALUE) {
    fprintf(stderr, "Couldn't open file '%s' with CreateFile()\n", filename);
    return false;
  }

  hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
  if (hFileMapping == 0) {
    CloseHandle(hFile);
    fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
    return false;
  }

  lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
  if (lpFileBase == 0) {
    CloseHandle(hFileMapping);
    CloseHandle(hFile);
    fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
    return false;
  }

  const PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
  if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
    fprintf(stderr, "File is an executable.  I don't dump those.\n");
    return false;
  } else {
    const PIMAGE_FILE_HEADER imageHeader = (PIMAGE_FILE_HEADER)lpFileBase;
    /* Does it look like a COFF OBJ file??? */
    if (((imageHeader->Machine == IMAGE_FILE_MACHINE_I386) ||
         (imageHeader->Machine == IMAGE_FILE_MACHINE_AMD64) ||
         (imageHeader->Machine == IMAGE_FILE_MACHINE_ARM) ||
         (imageHeader->Machine == IMAGE_FILE_MACHINE_ARMNT) ||
         (imageHeader->Machine == IMAGE_FILE_MACHINE_ARM64)) &&
        (imageHeader->Characteristics == 0)) {
      /*
      * The tests above are checking for IMAGE_FILE_HEADER.Machine
      * if it contains supported machine formats (currently ARM and x86)
      * and IMAGE_FILE_HEADER.Characteristics == 0 indicating that
      * this is not linked COFF OBJ file;
      */
      DumpSymbols<IMAGE_FILE_HEADER, IMAGE_SYMBOL> symbolDumper(
        (PIMAGE_FILE_HEADER)lpFileBase, symbols, dataSymbols,
        (imageHeader->Machine == IMAGE_FILE_MACHINE_I386));
      symbolDumper.DumpObjFile();
    } else {
      // check for /bigobj format
      cmANON_OBJECT_HEADER_BIGOBJ* h =
        (cmANON_OBJECT_HEADER_BIGOBJ*)lpFileBase;
      if (h->Sig1 == 0x0 && h->Sig2 == 0xffff) {
        DumpSymbols<cmANON_OBJECT_HEADER_BIGOBJ, cmIMAGE_SYMBOL_EX>
        symbolDumper((cmANON_OBJECT_HEADER_BIGOBJ*)lpFileBase, symbols,
                     dataSymbols, (h->Machine == IMAGE_FILE_MACHINE_I386));
        symbolDumper.DumpObjFile();
      } else {
        printf("unrecognized file format in '%s'\n", filename);
        return false;
      }
    }
  }
  UnmapViewOfFile(lpFileBase);
  CloseHandle(hFileMapping);
  CloseHandle(hFile);
  return true;
}

bool bindexplib::AddObjectFile(const char* filename)
{
  return DumpFile(filename, this->Symbols, this->DataSymbols);
}

bool bindexplib::AddDefinitionFile(const char* filename)
{
  cmsys::ifstream infile(filename);
  if (!infile) {
    fprintf(stderr, "Couldn't open definition file '%s'\n", filename);
    return false;
  }
  std::string str;
  while (std::getline(infile, str)) {
    // skip the LIBRAY and EXPORTS lines (if any)
    if ((str.compare(0, 7, "LIBRARY") == 0) ||
        (str.compare(0, 7, "EXPORTS") == 0)) {
      continue;
    }
    // remove leading tabs & spaces
    str.erase(0, str.find_first_not_of(" \t"));
    std::size_t found = str.find(" \t DATA");
    if (found != std::string::npos) {
      str.erase(found, std::string::npos);
      this->DataSymbols.insert(str);
    } else {
      this->Symbols.insert(str);
    }
  }
  infile.close();
  return true;
}

void bindexplib::WriteFile(FILE* file)
{
  fprintf(file, "EXPORTS \n");
  for (std::string const& ds : this->DataSymbols) {
    fprintf(file, "\t%s \t DATA\n", ds.c_str());
  }
  for (std::string const& s : this->Symbols) {
    fprintf(file, "\t%s\n", s.c_str());
  }
}
