Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
bindexplib.cxx
Go to the documentation of this file.
1/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3/*-------------------------------------------------------------------------
4 Portions of this source have been derived from the 'bindexplib' tool
5 provided by the CERN ROOT Data Analysis Framework project (root.cern.ch).
6 Permission has been granted by Pere Mato <pere.mato@cern.ch> to distribute
7 this derived work under the CMake license.
8-------------------------------------------------------------------------*/
9
10/*
11 *----------------------------------------------------------------------
12 * Program: dumpexts.exe
13 * Author: Gordon Chaffee
14 *
15 * History: The real functionality of this file was written by
16 * Matt Pietrek in 1993 in his pedump utility. I've
17 * modified it to dump the externals in a bunch of object
18 * files to create a .def file.
19 *
20 * Notes: Visual C++ puts an underscore before each exported symbol.
21 * This file removes them. I don't know if this is a problem
22 * this other compilers. If _MSC_VER is defined,
23 * the underscore is removed. If not, it isn't. To get a
24 * full dump of an object file, use the -f option. This can
25 * help determine the something that may be different with a
26 * compiler other than Visual C++.
27 * ======================================
28 * Corrections (Axel 2006-04-04):
29 * Conversion to C++. Mostly.
30 *
31 * Extension (Axel 2006-03-15)
32 * As soon as an object file contains an /EXPORT directive (which
33 * is generated by the compiler when a symbol is declared as
34 * __declspec(dllexport) no to-be-exported symbols are printed,
35 * as the linker will see these directives, and if those directives
36 * are present we only export selectively (i.e. we trust the
37 * programmer).
38 *
39 * ======================================
40 * ======================================
41 * Corrections (Valery Fine 23/02/98):
42 *
43 * The "(vector) deleting destructor" MUST not be exported
44 * To recognize it the following test are introduced:
45 * "@@UAEPAXI@Z" scalar deleting dtor
46 * "@@QAEPAXI@Z" vector deleting dtor
47 * "AEPAXI@Z" vector deleting dtor with thunk adjustor
48 * ======================================
49 * Corrections (Valery Fine 12/02/97):
50 *
51 * It created a wrong EXPORTS for the global pointers and constants.
52 * The Section Header has been involved to discover the missing information
53 * Now the pointers are correctly supplied with "DATA" descriptor
54 * the constants with no extra descriptor.
55 *
56 * Corrections (Valery Fine 16/09/96):
57 *
58 * It didn't work for C++ code with global variables and class definitions
59 * The DumpExternalObject function has been introduced to generate .DEF
60 *file
61 *
62 * Author: Valery Fine 16/09/96 (E-mail: fine@vxcern.cern.ch)
63 *----------------------------------------------------------------------
64 */
65#include <iostream>
66#include <windows.h>
67
68#include <set>
69#include <cstdio>
70#include <string>
71#include <fstream>
72
74public:
76 bool AddObjectFile(const char *filename);
77 void WriteFile(FILE *file);
78
79private:
80 std::set<std::string> Symbols;
81 std::set<std::string> DataSymbols;
82};
83
84#ifndef IMAGE_FILE_MACHINE_ARM
85# define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
86#endif
87
88#ifndef IMAGE_FILE_MACHINE_THUMB
89# define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian
90#endif
91
92#ifndef IMAGE_FILE_MACHINE_ARMNT
93# define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
94#endif
95
96#ifndef IMAGE_FILE_MACHINE_ARM64
97# define IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64 Little-Endian
98#endif
99
101 /* same as ANON_OBJECT_HEADER_V2 */
102 WORD Sig1; // Must be IMAGE_FILE_MACHINE_UNKNOWN
103 WORD Sig2; // Must be 0xffff
104 WORD Version; // >= 2 (implies the Flags field is present)
105 WORD Machine; // Actual machine - IMAGE_FILE_MACHINE_xxx
107 CLSID ClassID; // {D1BAA1C7-BAEE-4ba9-AF20-FAF66AA4DCB8}
108 DWORD SizeOfData; // Size of data that follows the header
109 DWORD Flags; // 0x1 -> contains metadata
110 DWORD MetaDataSize; // Size of CLR metadata
111 DWORD MetaDataOffset; // Offset of CLR metadata
112
113 /* bigobj specifics */
114 DWORD NumberOfSections; // extended from WORD
118
119typedef struct _cmIMAGE_SYMBOL_EX {
120 union {
121 BYTE ShortName[8];
122 struct {
123 DWORD Short; // if 0, use LongName
124 DWORD Long; // offset into string table
126 DWORD LongName[2]; // PBYTE [2]
127 } N;
128 DWORD Value;
130 WORD Type;
135
136PIMAGE_SECTION_HEADER GetSectionHeaderOffset(
137 PIMAGE_FILE_HEADER pImageFileHeader)
138{
139 return (PIMAGE_SECTION_HEADER)((DWORD_PTR)pImageFileHeader +
140 IMAGE_SIZEOF_FILE_HEADER +
141 pImageFileHeader->SizeOfOptionalHeader);
142}
143
144PIMAGE_SECTION_HEADER GetSectionHeaderOffset(
145 cmANON_OBJECT_HEADER_BIGOBJ *pImageFileHeader)
146{
147 return (PIMAGE_SECTION_HEADER)((DWORD_PTR)pImageFileHeader +
149}
150
151
152std::wstring ToWide(const std::string &str)
153{
154 std::wstring wstr;
155 const int wlength = MultiByteToWideChar(
156 CP_UTF8, 0, str.data(), int(str.size()), NULL, 0);
157 if (wlength > 0) {
158 wchar_t *wdata = new wchar_t[wlength];
159 int r = MultiByteToWideChar(CP_UTF8, 0, str.data(),
160 int(str.size()), wdata, wlength);
161 if (r > 0) {
162 wstr = std::wstring(wdata, wlength);
163 }
164 delete[] wdata;
165 }
166 return wstr;
167}
168
169/*
170*----------------------------------------------------------------------
171* GetArgcArgv --
172*
173* Break up a line into argc argv
174*----------------------------------------------------------------------
175*/
176int
177GetArgcArgv(std::string &s, char **argv)
178{
179 int quote = 0;
180 int argc = 0;
181 std::string::iterator bp = s.begin();
182
183 while (1) {
184 while (isspace(*bp)) {
185 ++bp;
186 }
187 if (*bp == '\n' || *bp == '\0') {
188 *bp = '\0';
189 return argc;
190 }
191 if (*bp == '\"') {
192 quote = 1;
193 ++bp;
194 }
195 argv[argc++] = &(*bp);
196
197 while (*bp != '\0') {
198 if (quote) {
199 if (*bp == '\"') {
200 quote = 0;
201 *bp = '\0';
202 ++bp;
203 break;
204 }
205 ++bp;
206 continue;
207 }
208 if (isspace(*bp)) {
209 *bp = '\0';
210 ++bp;
211 break;
212 }
213 ++bp;
214 }
215 }
216}
217
218/*
219 * Utility func, strstr with size
220 */
221const char *StrNStr(const char *start, const char *find, size_t &size)
222{
223 size_t len;
224 const char *hint;
225
226 if (!start || !find || !size) {
227 size = 0;
228 return 0;
229 }
230 len = strlen(find);
231
232 while ((hint = (const char *)memchr(start, find[0], size - len + 1))) {
233 size -= (hint - start);
234 if (!strncmp(hint, find, len))
235 return hint;
236 start = hint + 1;
237 }
238
239 size = 0;
240 return 0;
241}
242
243template <
244 // cmANON_OBJECT_HEADER_BIGOBJ or IMAGE_FILE_HEADER
245 class ObjectHeaderType,
246 // cmPIMAGE_SYMBOL_EX or PIMAGE_SYMBOL
247 class SymbolTableType >
249public:
250 /*
251 *----------------------------------------------------------------------
252 * Constructor --
253 *
254 * Initialize variables from pointer to object header.
255 *
256 *----------------------------------------------------------------------
257 */
258
259 DumpSymbols(ObjectHeaderType *ih, std::set<std::string> &symbols,
260 std::set<std::string> &dataSymbols, bool isI386)
261 : Symbols(symbols)
262 , DataSymbols(dataSymbols)
263 {
264 this->ObjectImageHeader = ih;
265 this->SymbolTable =
266 (SymbolTableType *)((DWORD_PTR)this->ObjectImageHeader +
267 this->ObjectImageHeader->PointerToSymbolTable);
268 this->SectionHeaders = GetSectionHeaderOffset(this->ObjectImageHeader);
269 this->SymbolCount = this->ObjectImageHeader->NumberOfSymbols;
270 this->IsI386 = isI386;
271 }
272
273 /*
274 *----------------------------------------------------------------------
275 * DumpObjFile --
276 *
277 * Dump an object file's exported symbols.
278 *----------------------------------------------------------------------
279 */
281 {
282 this->DumpExternalsObjects();
283 }
284
285 /*
286 *----------------------------------------------------------------------
287 * DumpExternalsObjects --
288 *
289 * Dumps a COFF symbol table from an OBJ.
290 *----------------------------------------------------------------------
291 */
293 {
294 unsigned i;
295 PSTR stringTable;
296 std::string symbol;
297 DWORD SectChar;
298 /*
299 * The string table apparently starts right after the symbol table
300 */
301 stringTable = (PSTR) & this->SymbolTable[this->SymbolCount];
302 SymbolTableType *pSymbolTable = this->SymbolTable;
303 for (i = 0; i < this->SymbolCount; i++) {
304 if (pSymbolTable->SectionNumber > 0 &&
305 (pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
306 if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
307 /*
308 * The name of the Function entry points
309 */
310 if (pSymbolTable->N.Name.Short != 0) {
311 symbol.clear();
312 symbol.insert(0, (const char *)pSymbolTable->N.ShortName, 8);
313 } else {
314 symbol = stringTable + pSymbolTable->N.Name.Long;
315 }
316
317 // clear out any leading spaces
318 while (isspace(symbol[0]))
319 symbol.erase(0, 1);
320 // if it starts with _ and has an @ then it is a __cdecl
321 // so remove the @ stuff for the export
322 if (symbol[0] == '_') {
323 std::string::size_type posAt = symbol.find('@');
324 if (posAt != std::string::npos) {
325 symbol.erase(posAt);
326 }
327 }
328 // For i386 builds we need to remove _
329 if (this->IsI386 && symbol[0] == '_') {
330 symbol.erase(0, 1);
331 }
332
333 // Check whether it is "Scalar deleting destructor" and "Vector
334 // deleting destructor"
335 // if scalarPrefix and vectorPrefix are not found then print
336 // the symbol
337 const char *scalarPrefix = "??_G";
338 const char *vectorPrefix = "??_E";
339 // The original code had a check for
340 // symbol.find("real@") == std::string::npos)
341 // but this disallows member functions with the name "real".
342 if (symbol.compare(0, 4, scalarPrefix) &&
343 symbol.compare(0, 4, vectorPrefix)) {
344 SectChar = this->SectionHeaders[pSymbolTable->SectionNumber - 1]
345 .Characteristics;
346 // skip symbols containing a dot
347 if (symbol.find('.') == std::string::npos) {
348 if (!pSymbolTable->Type && (SectChar & IMAGE_SCN_MEM_WRITE)) {
349 // Read only (i.e. constants) must be excluded
350 this->DataSymbols.insert(symbol);
351 } else {
352 if (pSymbolTable->Type || !(SectChar & IMAGE_SCN_MEM_READ) ||
353 (SectChar & IMAGE_SCN_MEM_EXECUTE)) {
354 this->Symbols.insert(symbol);
355 }
356 }
357 }
358 }
359 }
360 }
361
362 /*
363 * Take into account any aux symbols
364 */
365 i += pSymbolTable->NumberOfAuxSymbols;
366 pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
367 pSymbolTable++;
368 }
369 }
370
371private:
372 std::set<std::string> &Symbols;
373 std::set<std::string> &DataSymbols;
374 DWORD_PTR SymbolCount;
375 PIMAGE_SECTION_HEADER SectionHeaders;
376 ObjectHeaderType *ObjectImageHeader;
377 SymbolTableType *SymbolTable;
378 bool IsI386;
379};
380
381bool DumpFile(const char *filename, std::set<std::string> &symbols,
382 std::set<std::string> &dataSymbols)
383{
384 HANDLE hFile;
385 HANDLE hFileMapping;
386 LPVOID lpFileBase;
387
388 hFile = CreateFileW(ToWide(filename).c_str(), GENERIC_READ,
389 FILE_SHARE_READ, NULL, OPEN_EXISTING,
390 FILE_ATTRIBUTE_NORMAL, 0);
391
392 if (hFile == INVALID_HANDLE_VALUE) {
393 fprintf(stderr, "Couldn't open file '%s' with CreateFile()\n", filename);
394 return false;
395 }
396
397 hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
398 if (hFileMapping == 0) {
399 CloseHandle(hFile);
400 fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
401 return false;
402 }
403
404 lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
405 if (lpFileBase == 0) {
406 CloseHandle(hFileMapping);
407 CloseHandle(hFile);
408 fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
409 return false;
410 }
411
412 const PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
413 if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
414 fprintf(stderr, "File is an executable. I don't dump those.\n");
415 return false;
416 } else {
417 const PIMAGE_FILE_HEADER imageHeader = (PIMAGE_FILE_HEADER)lpFileBase;
418 /* Does it look like a COFF OBJ file??? */
419 if (((imageHeader->Machine == IMAGE_FILE_MACHINE_I386) ||
420 (imageHeader->Machine == IMAGE_FILE_MACHINE_AMD64) ||
421 (imageHeader->Machine == IMAGE_FILE_MACHINE_ARM) ||
422 (imageHeader->Machine == IMAGE_FILE_MACHINE_ARMNT) ||
423 (imageHeader->Machine == IMAGE_FILE_MACHINE_ARM64)) &&
424 (imageHeader->Characteristics == 0)) {
425 /*
426 * The tests above are checking for IMAGE_FILE_HEADER.Machine
427 * if it contains supported machine formats (currently ARM and x86)
428 * and IMAGE_FILE_HEADER.Characteristics == 0 indicating that
429 * this is not linked COFF OBJ file;
430 */
432 (PIMAGE_FILE_HEADER)lpFileBase, symbols, dataSymbols,
433 (imageHeader->Machine == IMAGE_FILE_MACHINE_I386));
434 symbolDumper.DumpObjFile();
435 } else {
436 // check for /bigobj format
438 (cmANON_OBJECT_HEADER_BIGOBJ *)lpFileBase;
439 if (h->Sig1 == 0x0 && h->Sig2 == 0xffff) {
441 symbolDumper((cmANON_OBJECT_HEADER_BIGOBJ *)lpFileBase, symbols,
442 dataSymbols, (h->Machine == IMAGE_FILE_MACHINE_I386));
443 symbolDumper.DumpObjFile();
444 } else {
445 printf("unrecognized file format in '%s'\n", filename);
446 return false;
447 }
448 }
449 }
450 UnmapViewOfFile(lpFileBase);
451 CloseHandle(hFileMapping);
452 CloseHandle(hFile);
453 return true;
454}
455
457{
458 return DumpFile(filename, this->Symbols, this->DataSymbols);
459}
460
462{
463 fprintf(file, "EXPORTS \n");
464 for (std::string const &ds : this->DataSymbols) {
465 fprintf(file, "\t%s \t DATA\n", ds.c_str());
466 }
467 for (std::string const &s : this->Symbols) {
468 fprintf(file, "\t%s\n", s.c_str());
469 }
470}
471
472
473int
474main(int argc, char **argv)
475{
476 std::string cmdline;
477 int i, arg;
478 FILE *fout;
479 int full = 0;
480 int fort = 0;
481 const char *dllname;
482 char *outfile = NULL;
483
484 if (argc < 3) {
485Usage:
486 fprintf(stderr, "Usage: %s ?-o outfile? ?-f(ull)? <dllname> <object filenames> ..\n", argv[0]);
487 return EXIT_FAILURE;
488 }
489
490 arg = 1;
491 while (argv[arg][0] == '-') {
492 if (strcmp(argv[arg], "--") == 0) {
493 arg++;
494 break;
495 } else if (strcmp(argv[arg], "-f") == 0) {
496 full = 1;
497 } else if (strcmp(argv[arg], "-x") == 0) {
498 fort = 1;
499 } else if (strcmp(argv[arg], "-o") == 0) {
500 arg++;
501 if (arg == argc) {
502 goto Usage;
503 }
504 outfile = argv[arg];
505 }
506 arg++;
507 }
508 if (arg == argc) {
509 goto Usage;
510 }
511
512 if (outfile) {
513 fout = fopen(outfile, "w+");
514 if (fout == NULL) {
515 fprintf(stderr, "Unable to open \'%s\' for writing:\n",
516 argv[arg]);
517 perror("");
518 return EXIT_FAILURE;
519 }
520 } else {
521 fout = stdout;
522 }
523
524 if (! full) {
525 dllname = argv[arg];
526 arg++;
527 if (arg == argc) {
528 goto Usage;
529 }
530 fprintf(fout, "LIBRARY %s\n", dllname);
531#if 0 //ndef _X86_
532 fprintf(fout, "CODE PRELOAD MOVEABLE DISCARDABLE\n");
533 fprintf(fout, "DATA PRELOAD MOVEABLE MULTIPLE\n\n");
534#endif
535 }
536
537 for (; arg < argc; arg++) {
538 WIN32_FIND_DATA FindFileData;
539 HANDLE SearchFile;
540 if (argv[arg][0] == '@') {
541 std::ifstream fargs(&argv[arg][1]);
542 if (!fargs) {
543 fprintf(stderr, "Unable to open \'%s\' for reading:\n",
544 argv[arg]);
545 perror("");
546 return EXIT_FAILURE;
547 }
548 char *fargv[1000];
549 for (i = 0; i < arg; i++) {
550 cmdline += argv[i];
551 fargv[i] = argv[i];
552 }
553 std::string line;
554 std::getline(fargs, line);
555 cmdline += line;
556 fprintf(stderr, "%s\n", line.c_str());
557 i += GetArgcArgv(line, &fargv[i]);
558 argc = i;
559 argv = fargv;
560 }
561 /*
562 * Argument can contain the wildcard names
563 */
564 bindexplib deffile;
565 SearchFile = FindFirstFile(argv[arg], &FindFileData);
566 if (SearchFile == INVALID_HANDLE_VALUE) {
567 fprintf(stderr, "Unable to find \'%s\' for reading:\n",
568 argv[arg]);
569 return EXIT_FAILURE;
570 } else {
571 /*
572 * Since WIN32_FIND_DATA has no path information one has to extract it oneself.
573 */
574 TCHAR *filename = argv[arg];
575 TCHAR path[2048];
576 int i = strlen(filename);
577 i--;
578 while (filename[i] != '\\' && filename[i] != '/' && i >= 0) i--;
579 do {
580 if (i >= 0) strncpy(path, filename, i + 1); /* Generate the 'path' info */
581 path[i + 1] = '\0';
582 if (!deffile.AddObjectFile(strcat(path, FindFileData.cFileName))) {
583 break;
584 }
585 } while (FindNextFile(SearchFile, &FindFileData));
586
587 FindClose(SearchFile);
588 deffile.WriteFile(fout);
589 }
590 }
591 return EXIT_SUCCESS;
592}
ROOT::R::TRInterface & r
Definition Object.C:4
#define h(i)
Definition RSha256.hxx:106
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
start
Definition Rotated.cxx:223
#define N
#define INVALID_HANDLE_VALUE
Definition TMapFile.cxx:84
#define NULL
Definition ZInflate.c:15
bool DumpFile(const char *filename, std::set< std::string > &symbols, std::set< std::string > &dataSymbols)
#define IMAGE_FILE_MACHINE_ARMNT
const char * StrNStr(const char *start, const char *find, size_t &size)
#define IMAGE_FILE_MACHINE_ARM
struct _cmIMAGE_SYMBOL_EX cmIMAGE_SYMBOL_EX
#define IMAGE_FILE_MACHINE_ARM64
PIMAGE_SECTION_HEADER GetSectionHeaderOffset(PIMAGE_FILE_HEADER pImageFileHeader)
int GetArgcArgv(std::string &s, char **argv)
std::wstring ToWide(const std::string &str)
cmIMAGE_SYMBOL_EX UNALIGNED * cmPIMAGE_SYMBOL_EX
SymbolTableType * SymbolTable
DumpSymbols(ObjectHeaderType *ih, std::set< std::string > &symbols, std::set< std::string > &dataSymbols, bool isI386)
DWORD_PTR SymbolCount
ObjectHeaderType * ObjectImageHeader
void DumpObjFile()
std::set< std::string > & Symbols
void DumpExternalsObjects()
std::set< std::string > & DataSymbols
PIMAGE_SECTION_HEADER SectionHeaders
std::set< std::string > Symbols
std::set< std::string > DataSymbols
bool AddObjectFile(const char *filename)
void WriteFile(FILE *file)
auto filename
TLine * line
void file()
Definition file.C:11
int main()
printf("Client 0: bytes recv = %d, bytes sent = %d\n", s0->GetBytesRecv(), s0->GetBytesSent())
TSpectrum2 * s
Definition peaks2.C:33
struct _cmIMAGE_SYMBOL_EX::@057136276216350343327256316142167222203321244034::@247246144036221236273071310077012231114347052377 Name