Load dependent dlls.
[ghc.git] / rts / linker / PEi386.c
1 /* --------------------------------------------------------------------------
2 * PEi386(+) specifics (Win32 targets)
3 * ------------------------------------------------------------------------*/
4
5 /* The information for this linker comes from
6 Microsoft Portable Executable
7 and Common Object File Format Specification
8 revision 8.3 February 2013
9
10 It can be found online at:
11
12 https://msdn.microsoft.com/en-us/windows/hardware/gg463119.aspx
13
14 Things move, so if that fails, try searching for it via
15
16 http://www.google.com/search?q=PE+COFF+specification
17
18 The ultimate reference for the PE format is the Winnt.h
19 header file that comes with the Platform SDKs; as always,
20 implementations will drift wrt their documentation.
21
22 A good background article on the PE format is Matt Pietrek's
23 March 1994 article in Microsoft System Journal (MSJ)
24 (Vol.9, No. 3): "Peering Inside the PE: A Tour of the
25 Win32 Portable Executable File Format." The info in there
26 has recently been updated in a two part article in
27 MSDN magazine, issues Feb and March 2002,
28 "Inside Windows: An In-Depth Look into the Win32 Portable
29 Executable File Format"
30
31 John Levine's book "Linkers and Loaders" contains useful
32 info on PE too.
33
34 The PE specification doesn't specify how to do the actual
35 relocations. For this reason, and because both PE and ELF are
36 based on COFF, the relocations for the PEi386+ code is based on
37 the ELF relocations for the equivalent relocation type.
38
39 The ELF ABI can be found at
40
41 http://www.x86-64.org/documentation/abi.pdf
42
43 The current code is based on version 0.99.6 - October 2013
44 */
45
46 #include "Rts.h"
47
48 #if defined(x86_64_HOST_ARCH)
49 #define USED_IF_x86_64_HOST_ARCH /* Nothing */
50 #else
51 #define USED_IF_x86_64_HOST_ARCH STG_UNUSED
52 #endif
53
54 #ifdef mingw32_HOST_OS
55
56 #include "RtsUtils.h"
57 #include "RtsSymbolInfo.h"
58 #include "GetEnv.h"
59 #include "linker/PEi386.h"
60 #include "LinkerInternals.h"
61
62 #include <windows.h>
63 #include <shfolder.h> /* SHGetFolderPathW */
64 #include <math.h>
65 #include <wchar.h>
66 #include <stdbool.h>
67 #include <stdint.h>
68
69 static uint8_t* cstring_from_COFF_symbol_name(
70 uint8_t* name,
71 uint8_t* strtab);
72
73 #if defined(x86_64_HOST_ARCH)
74 static size_t makeSymbolExtra_PEi386(
75 ObjectCode* oc,
76 uint64_t index,
77 size_t s,
78 SymbolName* symbol);
79 #endif
80
81 static void addDLLHandle(
82 pathchar* dll_name,
83 HINSTANCE instance);
84
85 static bool verifyCOFFHeader(
86 COFF_header *hdr,
87 pathchar *filename);
88
89 static bool checkIfDllLoaded(
90 HINSTANCE instance);
91
92 /* Add ld symbol for PE image base. */
93 #if defined(__GNUC__)
94 #define __ImageBase __MINGW_LSYMBOL(_image_base__)
95 #endif
96
97 /* Get the base of the module. */
98 /* This symbol is defined by ld. */
99 extern IMAGE_DOS_HEADER __ImageBase;
100 #define __image_base (void*)((HINSTANCE)&__ImageBase)
101
102 void initLinker_PEi386()
103 {
104 if (!ghciInsertSymbolTable(WSTR("(GHCi/Ld special symbols)"),
105 symhash, "__image_base__", __image_base, HS_BOOL_TRUE, NULL)) {
106 barf("ghciInsertSymbolTable failed");
107 }
108
109 #if defined(mingw32_HOST_OS)
110 addDLLHandle(WSTR("*.exe"), GetModuleHandle(NULL));
111 /*
112 * Most of these are included by base, but GCC always includes them
113 * So lets make sure we always have them too.
114 *
115 * In most cases they would have been loaded by the
116 * addDLLHandle above.
117 */
118 addDLL(WSTR("msvcrt"));
119 addDLL(WSTR("kernel32"));
120 addDLL(WSTR("advapi32"));
121 addDLL(WSTR("shell32"));
122 addDLL(WSTR("user32"));
123 #endif
124 }
125
126 /* A list thereof. */
127 static OpenedDLL* opened_dlls = NULL;
128
129 /* A list thereof. */
130 static IndirectAddr* indirects = NULL;
131
132 /* Adds a DLL instance to the list of DLLs in which to search for symbols. */
133 static void addDLLHandle(pathchar* dll_name, HINSTANCE instance) {
134
135 /* At this point, we actually know what was loaded.
136 So bail out if it's already been loaded. */
137 if (checkIfDllLoaded(instance))
138 {
139 return;
140 }
141
142 OpenedDLL* o_dll;
143 o_dll = stgMallocBytes( sizeof(OpenedDLL), "addDLLHandle" );
144 o_dll->name = dll_name ? pathdup(dll_name) : NULL;
145 o_dll->instance = instance;
146 o_dll->next = opened_dlls;
147 opened_dlls = o_dll;
148
149 /* Now discover the dependencies of dll_name that were
150 just loaded in our process space. The reason is we have access to them
151 without the user having to explicitly specify them. */
152 PIMAGE_NT_HEADERS header =
153 (PIMAGE_NT_HEADERS)((BYTE *)instance +
154 ((PIMAGE_DOS_HEADER)instance)->e_lfanew);
155 PIMAGE_IMPORT_DESCRIPTOR imports =
156 (PIMAGE_IMPORT_DESCRIPTOR)((BYTE *)instance + header->
157 OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
158
159 /* Ignore these compatibility shims. */
160 const pathchar* ms_dll = WSTR("api-ms-win-");
161 const int len = wcslen(ms_dll);
162
163 do {
164 pathchar* module = mkPath((char*)(BYTE *)instance + imports->Name);
165 HINSTANCE module_instance = GetModuleHandleW(module);
166 if (0 != wcsncmp(module, ms_dll, len)
167 && module_instance
168 && !checkIfDllLoaded(module_instance))
169 {
170 IF_DEBUG(linker, debugBelch("Loading dependency %" PATH_FMT " -> %" PATH_FMT ".\n", dll_name, module));
171 /* Now recursively load dependencies too. */
172 addDLLHandle(module, module_instance);
173 }
174 stgFree(module);
175 imports++;
176 } while (imports->Name);
177 }
178
179 static bool checkIfDllLoaded(HINSTANCE instance)
180 {
181 for (OpenedDLL* o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
182 if (o_dll->instance == instance)
183 {
184 return true;
185 }
186 }
187
188 return false;
189 }
190
191 void freePreloadObjectFile_PEi386(ObjectCode *oc)
192 {
193 VirtualFree(oc->image - PEi386_IMAGE_OFFSET, 0, MEM_RELEASE);
194
195 IndirectAddr *ia, *ia_next;
196 ia = indirects;
197 while (ia != NULL) {
198 ia_next = ia->next;
199 stgFree(ia);
200 ia = ia_next;
201 }
202 indirects = NULL;
203 }
204
205 const char *
206 addDLL_PEi386( pathchar *dll_name )
207 {
208 /* ------------------- Win32 DLL loader ------------------- */
209
210 pathchar* buf;
211 HINSTANCE instance;
212
213 IF_DEBUG(linker, debugBelch("addDLL; dll_name = `%" PATH_FMT "'\n", dll_name));
214
215 /* The file name has no suffix (yet) so that we can try
216 both foo.dll and foo.drv
217
218 The documentation for LoadLibrary says:
219 If no file name extension is specified in the lpFileName
220 parameter, the default library extension .dll is
221 appended. However, the file name string can include a trailing
222 point character (.) to indicate that the module name has no
223 extension. */
224
225 size_t bufsize = pathlen(dll_name) + 10;
226 buf = stgMallocBytes(bufsize * sizeof(wchar_t), "addDLL");
227
228 /* These are ordered by probability of success and order we'd like them. */
229 const wchar_t *formats[] = { L"%ls.DLL", L"%ls.DRV", L"lib%ls.DLL", L"%ls" };
230 const DWORD flags[] = { LOAD_LIBRARY_SEARCH_USER_DIRS | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS, 0 };
231
232 int cFormat, cFlag;
233 int flags_start = 1; /* Assume we don't support the new API. */
234
235 /* Detect if newer API are available, if not, skip the first flags entry. */
236 if (GetProcAddress((HMODULE)LoadLibraryW(L"Kernel32.DLL"), "AddDllDirectory")) {
237 flags_start = 0;
238 }
239
240 /* Iterate through the possible flags and formats. */
241 for (cFlag = flags_start; cFlag < 2; cFlag++)
242 {
243 for (cFormat = 0; cFormat < 4; cFormat++)
244 {
245 snwprintf(buf, bufsize, formats[cFormat], dll_name);
246 instance = LoadLibraryExW(buf, NULL, flags[cFlag]);
247 if (instance == NULL)
248 {
249 if (GetLastError() != ERROR_MOD_NOT_FOUND)
250 {
251 goto error;
252 }
253 }
254 else
255 {
256 break; /* We're done. DLL has been loaded. */
257 }
258 }
259 }
260
261 /* Check if we managed to load the DLL. */
262 if (instance == NULL) {
263 goto error;
264 }
265
266 addDLLHandle(buf, instance);
267 stgFree(buf);
268
269 return NULL;
270
271 error:
272 stgFree(buf);
273
274 char* errormsg = malloc(sizeof(char) * 80);
275 snprintf(errormsg, 80, "addDLL: %" PATH_FMT " or dependencies not loaded. (Win32 error %lu)", dll_name, GetLastError());
276 /* LoadLibrary failed; return a ptr to the error msg. */
277 return errormsg;
278 }
279
280 pathchar* findSystemLibrary_PEi386( pathchar* dll_name )
281 {
282 const unsigned int init_buf_size = 1024;
283 unsigned int bufsize = init_buf_size;
284 wchar_t* result = malloc(sizeof(wchar_t) * bufsize);
285 DWORD wResult = SearchPathW(NULL, dll_name, NULL, bufsize, result, NULL);
286
287 if (wResult > bufsize) {
288 result = realloc(result, sizeof(wchar_t) * wResult);
289 wResult = SearchPathW(NULL, dll_name, NULL, wResult, result, NULL);
290 }
291
292
293 if (!wResult) {
294 free(result);
295 return NULL;
296 }
297
298 return result;
299 }
300
301 HsPtr addLibrarySearchPath_PEi386(pathchar* dll_path)
302 {
303 HINSTANCE hDLL = LoadLibraryW(L"Kernel32.DLL");
304 LPAddDLLDirectory AddDllDirectory = (LPAddDLLDirectory)GetProcAddress((HMODULE)hDLL, "AddDllDirectory");
305
306 HsPtr result = NULL;
307
308 const unsigned int init_buf_size = 4096;
309 int bufsize = init_buf_size;
310
311 // Make sure the path is an absolute path
312 WCHAR* abs_path = malloc(sizeof(WCHAR) * init_buf_size);
313 DWORD wResult = GetFullPathNameW(dll_path, bufsize, abs_path, NULL);
314 if (!wResult){
315 sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError());
316 }
317 else if (wResult > init_buf_size) {
318 abs_path = realloc(abs_path, sizeof(WCHAR) * wResult);
319 if (!GetFullPathNameW(dll_path, bufsize, abs_path, NULL)) {
320 sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError());
321 }
322 }
323
324 if (AddDllDirectory) {
325 result = AddDllDirectory(abs_path);
326 }
327 else
328 {
329 warnMissingKBLibraryPaths();
330 WCHAR* str = malloc(sizeof(WCHAR) * init_buf_size);
331 wResult = GetEnvironmentVariableW(L"PATH", str, bufsize);
332
333 if (wResult > init_buf_size) {
334 str = realloc(str, sizeof(WCHAR) * wResult);
335 bufsize = wResult;
336 wResult = GetEnvironmentVariableW(L"PATH", str, bufsize);
337 if (!wResult) {
338 sysErrorBelch("addLibrarySearchPath[GetEnvironmentVariableW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError());
339 }
340 }
341
342 bufsize = wResult + 2 + pathlen(abs_path);
343 wchar_t* newPath = malloc(sizeof(wchar_t) * bufsize);
344
345 wcscpy(newPath, abs_path);
346 wcscat(newPath, L";");
347 wcscat(newPath, str);
348 if (!SetEnvironmentVariableW(L"PATH", (LPCWSTR)newPath)) {
349 sysErrorBelch("addLibrarySearchPath[SetEnvironmentVariableW]: %" PATH_FMT " (Win32 error %lu)", abs_path, GetLastError());
350 }
351
352 free(newPath);
353 free(abs_path);
354
355 return str;
356 }
357
358 if (!result) {
359 sysErrorBelch("addLibrarySearchPath: %" PATH_FMT " (Win32 error %lu)", abs_path, GetLastError());
360 free(abs_path);
361 return NULL;
362 }
363
364 free(abs_path);
365 return result;
366 }
367
368 bool removeLibrarySearchPath_PEi386(HsPtr dll_path_index)
369 {
370 bool result = false;
371
372 if (dll_path_index != NULL) {
373 HINSTANCE hDLL = LoadLibraryW(L"Kernel32.DLL");
374 LPRemoveDLLDirectory RemoveDllDirectory = (LPRemoveDLLDirectory)GetProcAddress((HMODULE)hDLL, "RemoveDllDirectory");
375
376 if (RemoveDllDirectory) {
377 result = RemoveDllDirectory(dll_path_index);
378 // dll_path_index is now invalid, do not use it after this point.
379 }
380 else
381 {
382 warnMissingKBLibraryPaths();
383 result = SetEnvironmentVariableW(L"PATH", (LPCWSTR)dll_path_index);
384 free(dll_path_index);
385 }
386
387 if (!result) {
388 sysErrorBelch("removeLibrarySearchPath: (Win32 error %lu)", GetLastError());
389 return false;
390 }
391 }
392
393 return !result;
394 }
395
396
397 /* We assume file pointer is right at the
398 beginning of COFF object.
399 */
400 char *
401 allocateImageAndTrampolines (
402 pathchar* arch_name, char* member_name,
403 FILE* f USED_IF_x86_64_HOST_ARCH,
404 int size,
405 int isThin USED_IF_x86_64_HOST_ARCH)
406 {
407 char* image;
408 #if defined(x86_64_HOST_ARCH)
409 if (!isThin)
410 {
411 /* PeCoff contains number of symbols right in it's header, so
412 we can reserve the room for symbolExtras right here. */
413 COFF_header hdr;
414 size_t n;
415
416 n = fread(&hdr, 1, sizeof_COFF_header, f);
417 if (n != sizeof_COFF_header) {
418 errorBelch("getNumberOfSymbols: error whilst reading `%s' header in `%" PATH_FMT "'",
419 member_name, arch_name);
420 return NULL;
421 }
422 fseek(f, -(long int)sizeof_COFF_header, SEEK_CUR);
423
424 if (!verifyCOFFHeader(&hdr, arch_name)) {
425 return 0;
426 }
427
428 /* We get back 8-byte aligned memory (is that guaranteed?), but
429 the offsets to the sections within the file are all 4 mod 8
430 (is that guaranteed?). We therefore need to offset the image
431 by 4, so that all the pointers are 8-byte aligned, so that
432 pointer tagging works. */
433 /* For 32-bit case we don't need this, hence we use macro PEi386_IMAGE_OFFSET,
434 which equals to 4 for 64-bit case and 0 for 32-bit case. */
435 /* We allocate trampolines area for all symbols right behind
436 image data, aligned on 8. */
437 size = ((PEi386_IMAGE_OFFSET + size + 0x7) & ~0x7)
438 + hdr.NumberOfSymbols * sizeof(SymbolExtra);
439 }
440 #endif
441 image = VirtualAlloc(NULL, size,
442 MEM_RESERVE | MEM_COMMIT,
443 PAGE_EXECUTE_READWRITE);
444
445 if (image == NULL) {
446 errorBelch("%" PATH_FMT ": failed to allocate memory for image for %s",
447 arch_name, member_name);
448 return NULL;
449 }
450
451 return image + PEi386_IMAGE_OFFSET;
452 }
453
454 bool findAndLoadImportLibrary(ObjectCode* oc)
455 {
456 int i;
457
458 COFF_header* hdr;
459 COFF_section* sectab;
460 COFF_symbol* symtab;
461 uint8_t* strtab;
462
463 hdr = (COFF_header*)(oc->image);
464 sectab = (COFF_section*)(
465 ((uint8_t*)(oc->image))
466 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
467 );
468
469 symtab = (COFF_symbol*)(
470 ((uint8_t*)(oc->image))
471 + hdr->PointerToSymbolTable
472 );
473
474 strtab = ((uint8_t*)symtab)
475 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
476
477 for (i = 0; i < oc->n_sections; i++)
478 {
479 COFF_section* sectab_i
480 = (COFF_section*)myindex(sizeof_COFF_section, sectab, i);
481
482 char *secname = cstring_from_section_name(sectab_i->Name, strtab);
483
484 // Find the first entry containing a valid .idata$7 section.
485 if (strcmp(secname, ".idata$7") == 0) {
486 /* First load the containing DLL if not loaded. */
487 Section section = oc->sections[i];
488
489 pathchar* dirName = pathdir(oc->fileName);
490 HsPtr token = addLibrarySearchPath(dirName);
491 stgFree(dirName);
492 char* dllName = (char*)section.start;
493
494 if (strlen(dllName) == 0 || dllName[0] == ' ')
495 {
496 continue;
497 }
498
499 IF_DEBUG(linker, debugBelch("lookupSymbol: on-demand '%ls' => `%s'\n", oc->fileName, dllName));
500
501 pathchar* dll = mkPath(dllName);
502 removeLibrarySearchPath(token);
503
504 const char* result = addDLL(dll);
505 stgFree(dll);
506
507 if (result != NULL) {
508 errorBelch("Could not load `%s'. Reason: %s\n", (char*)dllName, result);
509 return false;
510 }
511
512 break;
513 }
514
515 stgFree(secname);
516 }
517
518 return true;
519 }
520
521 bool checkAndLoadImportLibrary( pathchar* arch_name, char* member_name, FILE* f )
522 {
523 char* image;
524 static bool load_dll_warn = false;
525
526 if (load_dll_warn) { return 0; }
527
528 /* Based on Import Library specification. PE Spec section 7.1 */
529
530 COFF_import_header hdr;
531 size_t n;
532
533 n = fread(&hdr, 1, sizeof_COFF_import_Header, f);
534 if (n != sizeof(COFF_header)) {
535 errorBelch("getNumberOfSymbols: error whilst reading `%s' header in `%" PATH_FMT "'\n",
536 member_name, arch_name);
537 return false;
538 }
539
540 if (hdr.Sig1 != 0x0 || hdr.Sig2 != IMPORT_OBJECT_HDR_SIG2) {
541 fseek(f, -(long int)sizeof_COFF_import_Header, SEEK_CUR);
542 IF_DEBUG(linker, debugBelch("loadArchive: Object `%s` is not an import lib. Skipping...\n", member_name));
543 return false;
544 }
545
546 IF_DEBUG(linker, debugBelch("loadArchive: reading %lu bytes at %ld\n", hdr.SizeOfData, ftell(f)));
547
548 image = malloc(hdr.SizeOfData);
549 n = fread(image, 1, hdr.SizeOfData, f);
550 if (n != hdr.SizeOfData) {
551 errorBelch("loadArchive: error whilst reading `%s' header in `%" PATH_FMT "'. Did not read enough bytes.\n",
552 member_name, arch_name);
553 }
554
555 char* symbol = strtok(image, "\0");
556 int symLen = strlen(symbol) + 1;
557 int nameLen = n - symLen;
558 char* dllName = malloc(sizeof(char) * nameLen);
559 dllName = strncpy(dllName, image + symLen, nameLen);
560 pathchar* dll = malloc(sizeof(wchar_t) * nameLen);
561 mbstowcs(dll, dllName, nameLen);
562 free(dllName);
563
564 IF_DEBUG(linker, debugBelch("loadArchive: read symbol %s from lib `%" PATH_FMT "'\n", symbol, dll));
565 const char* result = addDLL(dll);
566
567 free(image);
568
569 if (result != NULL) {
570 errorBelch("Could not load `%" PATH_FMT "'. Reason: %s\n", dll, result);
571 load_dll_warn = true;
572
573 free(dll);
574 fseek(f, -(n + sizeof_COFF_import_Header), SEEK_CUR);
575 return false;
576 }
577
578 free(dll);
579 return true;
580 }
581
582 static void
583 printName ( uint8_t* name, uint8_t* strtab )
584 {
585 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
586 uint32_t strtab_offset = * (uint32_t*)(name+4);
587 debugBelch("%s", strtab + strtab_offset );
588 } else {
589 int i;
590 for (i = 0; i < 8; i++) {
591 if (name[i] == 0) break;
592 debugBelch("%c", name[i] );
593 }
594 }
595 }
596
597
598 static void
599 copyName ( uint8_t* name, uint8_t* strtab, uint8_t* dst, int dstSize )
600 {
601 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
602 uint32_t strtab_offset = * (uint32_t*)(name+4);
603 strncpy ( (char*)dst, (char*)strtab+strtab_offset, dstSize );
604 dst[dstSize-1] = 0;
605 } else {
606 int i = 0;
607 while (1) {
608 if (i >= 8) break;
609 if (name[i] == 0) break;
610 dst[i] = name[i];
611 i++;
612 }
613 dst[i] = 0;
614 }
615 }
616
617
618 static uint8_t *
619 cstring_from_COFF_symbol_name ( uint8_t* name, uint8_t* strtab )
620 {
621 uint8_t* newstr;
622 /* If the string is longer than 8 bytes, look in the
623 string table for it -- this will be correctly zero terminated.
624 */
625 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
626 uint32_t strtab_offset = * (uint32_t*)(name+4);
627 return strtab + strtab_offset;
628 }
629 /* Otherwise, if shorter than 8 bytes, return the original,
630 which by defn is correctly terminated.
631 */
632 if (name[7]==0) return name;
633 /* The annoying case: 8 bytes. Copy into a temporary
634 (XXX which is never freed ...)
635 */
636 newstr = stgMallocBytes(9, "cstring_from_COFF_symbol_name");
637 ASSERT(newstr);
638 strncpy((char*)newstr,(char*)name,8);
639 newstr[8] = 0;
640 return newstr;
641 }
642
643 /* Getting the name of a section is mildly tricky, so we make a
644 function for it. Sadly, in one case we have to copy the string
645 (when it is exactly 8 bytes long there's no trailing '\0'), so for
646 consistency we *always* copy the string; the caller must free it
647 */
648 char *
649 cstring_from_section_name (uint8_t* name, uint8_t* strtab)
650 {
651 char *newstr;
652
653 if (name[0]=='/') {
654 int strtab_offset = strtol((char*)name+1,NULL,10);
655 int len = strlen(((char*)strtab) + strtab_offset);
656
657 newstr = stgMallocBytes(len+1, "cstring_from_section_symbol_name");
658 strcpy(newstr, (char*)strtab + strtab_offset);
659 return newstr;
660 }
661 else
662 {
663 newstr = stgMallocBytes(9, "cstring_from_section_symbol_name");
664 ASSERT(newstr);
665 strncpy(newstr,(char*)name,8);
666 newstr[8] = 0;
667 return newstr;
668 }
669 }
670
671 /* See Note [mingw-w64 name decoration scheme] */
672 #ifndef x86_64_HOST_ARCH
673 static void
674 zapTrailingAtSign ( uint8_t* sym )
675 {
676 # define my_isdigit(c) ((c) >= '0' && (c) <= '9')
677 int i, j;
678 if (sym[0] == 0) return;
679 i = 0;
680 while (sym[i] != 0) i++;
681 i--;
682 j = i;
683 while (j > 0 && my_isdigit(sym[j])) j--;
684 if (j > 0 && sym[j] == '@' && j != i) sym[j] = 0;
685 # undef my_isdigit
686 }
687 #endif
688
689 SymbolAddr*
690 lookupSymbolInDLLs ( uint8_t *lbl )
691 {
692 OpenedDLL* o_dll;
693 SymbolAddr* sym;
694
695 for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
696 /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */
697
698 sym = GetProcAddress(o_dll->instance, (char*)(lbl+STRIP_LEADING_UNDERSCORE));
699 if (sym != NULL) {
700 /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/
701 return sym;
702 }
703
704 /* Ticket #2283.
705 Long description: http://support.microsoft.com/kb/132044
706 tl;dr:
707 If C/C++ compiler sees __declspec(dllimport) ... foo ...
708 it generates call *__imp_foo, and __imp_foo here has exactly
709 the same semantics as in __imp_foo = GetProcAddress(..., "foo")
710 */
711 if (sym == NULL && strncmp ((const char*)lbl, "__imp_", 6) == 0) {
712 sym = GetProcAddress(o_dll->instance, (char*)(lbl+6+STRIP_LEADING_UNDERSCORE));
713 if (sym != NULL) {
714 IndirectAddr* ret;
715 ret = stgMallocBytes( sizeof(IndirectAddr), "lookupSymbolInDLLs" );
716 ret->addr = sym;
717 ret->next = indirects;
718 indirects = ret;
719 IF_DEBUG(linker,
720 debugBelch("warning: %s from %S is linked instead of %s\n",
721 (char*)(lbl+6+STRIP_LEADING_UNDERSCORE), o_dll->name, (char*)lbl));
722 return (void*) & ret->addr;
723 }
724 }
725
726 sym = GetProcAddress(o_dll->instance, (char*)lbl);
727 if (sym != NULL) {
728 /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/
729 return sym;
730 }
731 }
732 return NULL;
733 }
734
735 static bool
736 verifyCOFFHeader ( COFF_header *hdr, pathchar *fileName )
737 {
738 #if defined(i386_HOST_ARCH)
739 if (hdr->Machine != IMAGE_FILE_MACHINE_I386) {
740 errorBelch("%" PATH_FMT ": Not x86 PEi386", fileName);
741 return false;
742 }
743 #elif defined(x86_64_HOST_ARCH)
744 if (hdr->Machine != IMAGE_FILE_MACHINE_AMD64) {
745 errorBelch("%" PATH_FMT ": Not x86_64 PEi386", fileName);
746 return false;
747 }
748 #else
749 errorBelch("PEi386 not supported on this arch");
750 #endif
751
752 if (hdr->SizeOfOptionalHeader != 0) {
753 errorBelch("%" PATH_FMT ": PEi386 with nonempty optional header",
754 fileName);
755 return 0;
756 }
757 if ( /* (hdr->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) || */
758 (hdr->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) ||
759 (hdr->Characteristics & IMAGE_FILE_DLL ) ||
760 (hdr->Characteristics & IMAGE_FILE_SYSTEM ) ) {
761 errorBelch("%" PATH_FMT ": Not a PEi386 object file", fileName);
762 return false;
763 }
764 if ( (hdr->Characteristics & IMAGE_FILE_BYTES_REVERSED_HI)
765 /* || !(hdr->Characteristics & IMAGE_FILE_32BIT_MACHINE) */ ) {
766 errorBelch("%" PATH_FMT ": Invalid PEi386 word size or endiannness: %d",
767 fileName,
768 (int)(hdr->Characteristics));
769 return false;
770 }
771 return true;
772 }
773
774 bool
775 ocVerifyImage_PEi386 ( ObjectCode* oc )
776 {
777 int i;
778 uint32_t j, noRelocs;
779 COFF_header* hdr;
780 COFF_section* sectab;
781 COFF_symbol* symtab;
782 uint8_t* strtab;
783 /* debugBelch("\nLOADING %s\n", oc->fileName); */
784 hdr = (COFF_header*)(oc->image);
785 sectab = (COFF_section*) (
786 ((uint8_t*)(oc->image))
787 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
788 );
789 symtab = (COFF_symbol*) (
790 ((uint8_t*)(oc->image))
791 + hdr->PointerToSymbolTable
792 );
793 strtab = ((uint8_t*)symtab)
794 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
795
796 if (!verifyCOFFHeader(hdr, oc->fileName)) {
797 return false;
798 }
799
800 /* If the string table size is way crazy, this might indicate that
801 there are more than 64k relocations, despite claims to the
802 contrary. Hence this test. */
803 /* debugBelch("strtab size %d\n", * (uint32_t*)strtab); */
804 #if 0
805 if ( (*(uint32_t*)strtab) > 600000 ) {
806 /* Note that 600k has no special significance other than being
807 big enough to handle the almost-2MB-sized lumps that
808 constitute HSwin32*.o. */
809 debugBelch("PEi386 object has suspiciously large string table; > 64k relocs?");
810 return false;
811 }
812 #endif
813
814 /* .BSS Section is initialized in ocGetNames_PEi386
815 but we need the Sections array initialized here already. */
816 Section *sections;
817 sections = (Section*)stgCallocBytes(
818 sizeof(Section),
819 hdr->NumberOfSections + 1, /* +1 for the global BSS section see ocGetNames_PEi386 */
820 "ocVerifyImage_PEi386(sections)");
821 oc->sections = sections;
822 oc->n_sections = hdr->NumberOfSections + 1;
823
824 /* Initialize the Sections */
825 for (i = 0; i < hdr->NumberOfSections; i++) {
826 COFF_section* sectab_i
827 = (COFF_section*)
828 myindex(sizeof_COFF_section, sectab, i);
829
830 /* Calculate the start of the data section */
831 sections[i].start = oc->image + sectab_i->PointerToRawData;
832 }
833
834 /* No further verification after this point; only debug printing. */
835 i = 0;
836 IF_DEBUG(linker, i=1);
837 if (i == 0) return true;
838
839 debugBelch("sectab offset = %" FMT_SizeT "\n",
840 ((uint8_t*)sectab) - ((uint8_t*)hdr) );
841 debugBelch("symtab offset = %" FMT_SizeT "\n",
842 ((uint8_t*)symtab) - ((uint8_t*)hdr) );
843 debugBelch("strtab offset = %" FMT_SizeT "\n",
844 ((uint8_t*)strtab) - ((uint8_t*)hdr) );
845
846 debugBelch("\n" );
847 debugBelch( "Machine: 0x%x\n", (uint32_t)(hdr->Machine) );
848 debugBelch( "# sections: %d\n", (uint32_t)(hdr->NumberOfSections) );
849 debugBelch( "time/date: 0x%x\n", (uint32_t)(hdr->TimeDateStamp) );
850 debugBelch( "symtab offset: %d\n", (uint32_t)(hdr->PointerToSymbolTable) );
851 debugBelch( "# symbols: %d\n", (uint32_t)(hdr->NumberOfSymbols) );
852 debugBelch( "sz of opt hdr: %d\n", (uint32_t)(hdr->SizeOfOptionalHeader) );
853 debugBelch( "characteristics: 0x%x\n", (uint32_t)(hdr->Characteristics) );
854
855 /* Print the section table. */
856 debugBelch("\n" );
857 for (i = 0; i < hdr->NumberOfSections; i++) {
858 COFF_reloc* reltab;
859 COFF_section* sectab_i
860 = (COFF_section*)
861 myindex ( sizeof_COFF_section, sectab, i );
862 Section section = sections[i];
863 debugBelch(
864 "\n"
865 "section %d\n"
866 " name `",
867 i
868 );
869 printName ( sectab_i->Name, strtab );
870 debugBelch(
871 "'\n"
872 " vsize %lu\n"
873 " vaddr %lu\n"
874 " data sz %lu\n"
875 " data off 0x%p\n"
876 " num rel %hu\n"
877 " off rel %lu\n"
878 " ptr raw 0x%lx\n",
879 sectab_i->Misc.VirtualSize,
880 sectab_i->VirtualAddress,
881 sectab_i->SizeOfRawData,
882 section.start,
883 sectab_i->NumberOfRelocations,
884 sectab_i->PointerToRelocations,
885 sectab_i->PointerToRawData
886 );
887 reltab = (COFF_reloc*) (
888 ((uint8_t*)(oc->image)) + sectab_i->PointerToRelocations
889 );
890
891 if ( sectab_i->Characteristics & IMAGE_SCN_LNK_NRELOC_OVFL ) {
892 /* If the relocation field (a short) has overflowed, the
893 * real count can be found in the first reloc entry.
894 *
895 * See Section 4.1 (last para) of the PE spec (rev6.0).
896 */
897 COFF_reloc* rel = (COFF_reloc*)
898 myindex ( sizeof_COFF_reloc, reltab, 0 );
899 noRelocs = rel->VirtualAddress;
900 j = 1;
901 } else {
902 noRelocs = sectab_i->NumberOfRelocations;
903 j = 0;
904 }
905
906 for (; j < noRelocs; j++) {
907 COFF_symbol* sym;
908 COFF_reloc* rel = (COFF_reloc*)
909 myindex ( sizeof_COFF_reloc, reltab, j );
910 debugBelch(
911 " type 0x%-4x vaddr 0x%-8lx name `",
912 (uint32_t)rel->Type,
913 rel->VirtualAddress );
914 sym = (COFF_symbol*)
915 myindex ( sizeof_COFF_symbol, symtab, rel->SymbolTableIndex );
916 printName ( sym->N.ShortName, strtab );
917 debugBelch("'\n" );
918 }
919
920 debugBelch("\n" );
921 }
922 debugBelch("\n" );
923 debugBelch("string table has size 0x%x\n", * (uint32_t*)strtab );
924 debugBelch("---START of string table---\n");
925 for (i = 4; i < *(int32_t*)strtab; i++) {
926 if (strtab[i] == 0)
927 debugBelch("\n"); else
928 debugBelch("%c", strtab[i] );
929 }
930 debugBelch("--- END of string table---\n");
931
932 debugBelch("\n" );
933 i = 0;
934 while (1) {
935 COFF_symbol* symtab_i;
936 if (i >= (int32_t)(hdr->NumberOfSymbols)) break;
937 symtab_i = (COFF_symbol*)
938 myindex ( sizeof_COFF_symbol, symtab, i );
939 debugBelch(
940 "symbol %d\n"
941 " name `",
942 i
943 );
944 printName ( symtab_i->N.ShortName, strtab );
945 debugBelch(
946 "'\n"
947 " value 0x%lx\n"
948 " 1+sec# %d\n"
949 " type 0x%x\n"
950 " sclass 0x%x\n"
951 " nAux %d\n",
952 symtab_i->Value,
953 (int32_t)(symtab_i->SectionNumber),
954 (uint32_t)symtab_i->Type,
955 (uint32_t)symtab_i->StorageClass,
956 (uint32_t)symtab_i->NumberOfAuxSymbols
957 );
958 i += symtab_i->NumberOfAuxSymbols;
959 i++;
960 }
961
962 debugBelch("\n" );
963 return true;
964 }
965
966 bool
967 ocGetNames_PEi386 ( ObjectCode* oc )
968 {
969 COFF_header* hdr;
970 COFF_section* sectab;
971 COFF_symbol* symtab;
972 uint8_t* strtab;
973
974 uint8_t* sname;
975 SymbolAddr* addr;
976 int i;
977
978 hdr = (COFF_header*)(oc->image);
979 sectab = (COFF_section*) (
980 ((uint8_t*)(oc->image))
981 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
982 );
983 symtab = (COFF_symbol*) (
984 ((uint8_t*)(oc->image))
985 + hdr->PointerToSymbolTable
986 );
987 strtab = ((uint8_t*)(oc->image))
988 + hdr->PointerToSymbolTable
989 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
990
991 /* Allocate space for any (local, anonymous) .bss sections. */
992
993 for (i = 0; i < hdr->NumberOfSections; i++) {
994 uint32_t bss_sz;
995 uint8_t* zspace;
996 COFF_section* sectab_i
997 = (COFF_section*)
998 myindex ( sizeof_COFF_section, sectab, i );
999
1000 char *secname = cstring_from_section_name(sectab_i->Name, strtab);
1001
1002 if (0 != strcmp(secname, ".bss")) {
1003 stgFree(secname);
1004 continue;
1005 }
1006
1007 stgFree(secname);
1008
1009 /* sof 10/05: the PE spec text isn't too clear regarding what
1010 * the SizeOfRawData field is supposed to hold for object
1011 * file sections containing just uninitialized data -- for executables,
1012 * it is supposed to be zero; unclear what it's supposed to be
1013 * for object files. However, VirtualSize is guaranteed to be
1014 * zero for object files, which definitely suggests that SizeOfRawData
1015 * will be non-zero (where else would the size of this .bss section be
1016 * stored?) Looking at the COFF_section info for incoming object files,
1017 * this certainly appears to be the case.
1018 *
1019 * => I suspect we've been incorrectly handling .bss sections in (relocatable)
1020 * object files up until now. This turned out to bite us with ghc-6.4.1's use
1021 * of gcc-3.4.x, which has started to emit initially-zeroed-out local 'static'
1022 * variable decls into the .bss section. (The specific function in Q which
1023 * triggered this is libraries/base/cbits/dirUtils.c:__hscore_getFolderPath())
1024 */
1025 if (sectab_i->Misc.VirtualSize == 0 && sectab_i->SizeOfRawData == 0) continue;
1026 /* This is a non-empty .bss section.
1027 Allocate zeroed space for it */
1028 bss_sz = sectab_i->Misc.VirtualSize;
1029 if ( bss_sz < sectab_i->SizeOfRawData) { bss_sz = sectab_i->SizeOfRawData; }
1030 zspace = stgCallocBytes(1, bss_sz, "ocGetNames_PEi386(anonymous bss)");
1031 oc->sections[i].start = zspace;
1032 addProddableBlock(oc, zspace, bss_sz);
1033 /* debugBelch("BSS anon section at 0x%x\n", zspace); */
1034 }
1035
1036 /* Copy section information into the ObjectCode. */
1037
1038 for (i = 0; i < hdr->NumberOfSections; i++) {
1039 uint8_t* start;
1040 uint8_t* end;
1041 uint32_t sz;
1042
1043 /* By default consider all section as CODE or DATA, which means we want to load them. */
1044 SectionKind kind
1045 = SECTIONKIND_CODE_OR_RODATA;
1046 COFF_section* sectab_i
1047 = (COFF_section*)
1048 myindex ( sizeof_COFF_section, sectab, i );
1049 Section section = oc->sections[i];
1050
1051 char *secname = cstring_from_section_name(sectab_i->Name, strtab);
1052
1053 IF_DEBUG(linker, debugBelch("section name = %s\n", secname ));
1054
1055 /* The PE file section flag indicates whether the section contains code or data. */
1056 if (sectab_i->Characteristics & IMAGE_SCN_CNT_CODE ||
1057 sectab_i->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
1058 kind = SECTIONKIND_CODE_OR_RODATA;
1059
1060 /* Check next if it contains any uninitialized data */
1061 if (sectab_i->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
1062 kind = SECTIONKIND_RWDATA;
1063
1064 /* Finally check if it can be discarded. This will also ignore .debug sections */
1065 if (sectab_i->Characteristics & IMAGE_SCN_MEM_DISCARDABLE ||
1066 sectab_i->Characteristics & IMAGE_SCN_LNK_REMOVE)
1067 kind = SECTIONKIND_OTHER;
1068
1069 if (0==strcmp(".ctors", (char*)secname))
1070 kind = SECTIONKIND_INIT_ARRAY;
1071
1072 ASSERT(sectab_i->SizeOfRawData == 0 || sectab_i->Misc.VirtualSize == 0);
1073 sz = sectab_i->SizeOfRawData;
1074 if (sz < sectab_i->Misc.VirtualSize) sz = sectab_i->Misc.VirtualSize;
1075
1076 start = section.start;
1077 end = start + sz - 1;
1078
1079 if (kind != SECTIONKIND_OTHER && end >= start) {
1080 addSection(&oc->sections[i], kind, SECTION_NOMEM, start, sz, 0, 0, 0);
1081 addProddableBlock(oc, start, sz);
1082 }
1083
1084 stgFree(secname);
1085 }
1086
1087 /* Copy exported symbols into the ObjectCode. */
1088
1089 oc->n_symbols = hdr->NumberOfSymbols;
1090 oc->symbols = stgCallocBytes(sizeof(SymbolName*), oc->n_symbols,
1091 "ocGetNames_PEi386(oc->symbols)");
1092
1093 /* Work out the size of the global BSS section */
1094 StgWord globalBssSize = 0;
1095 for (i=0; i < (int)hdr->NumberOfSymbols; i++) {
1096 COFF_symbol* symtab_i;
1097 symtab_i = (COFF_symbol*)
1098 myindex ( sizeof_COFF_symbol, symtab, i );
1099 if (symtab_i->SectionNumber == IMAGE_SYM_UNDEFINED
1100 && symtab_i->Value > 0
1101 && symtab_i->StorageClass != IMAGE_SYM_CLASS_SECTION) {
1102 globalBssSize += symtab_i->Value;
1103 }
1104 i += symtab_i->NumberOfAuxSymbols;
1105 }
1106
1107 /* Allocate BSS space */
1108 SymbolAddr* bss = NULL;
1109 if (globalBssSize > 0) {
1110 bss = stgCallocBytes(1, globalBssSize,
1111 "ocGetNames_PEi386(non-anonymous bss)");
1112 addSection(&oc->sections[oc->n_sections-1],
1113 SECTIONKIND_RWDATA, SECTION_MALLOC,
1114 bss, globalBssSize, 0, 0, 0);
1115 IF_DEBUG(linker, debugBelch("bss @ %p %" FMT_Word "\n", bss, globalBssSize));
1116 addProddableBlock(oc, bss, globalBssSize);
1117 } else {
1118 addSection(&oc->sections[oc->n_sections-1],
1119 SECTIONKIND_OTHER, SECTION_NOMEM, NULL, 0, 0, 0, 0);
1120 }
1121
1122 for (i = 0; i < oc->n_symbols; i++) {
1123 COFF_symbol* symtab_i;
1124 symtab_i = (COFF_symbol*)
1125 myindex ( sizeof_COFF_symbol, symtab, i );
1126
1127 addr = NULL;
1128 bool isWeak = false;
1129 if ( symtab_i->SectionNumber != IMAGE_SYM_UNDEFINED
1130 && symtab_i->SectionNumber > 0) {
1131 /* This symbol is global and defined, viz, exported */
1132 /* for IMAGE_SYMCLASS_EXTERNAL
1133 && !IMAGE_SYM_UNDEFINED,
1134 the address of the symbol is:
1135 address of relevant section + offset in section
1136 */
1137 COFF_section* sectabent
1138 = (COFF_section*) myindex ( sizeof_COFF_section,
1139 sectab,
1140 symtab_i->SectionNumber-1 );
1141 if (symtab_i->StorageClass == IMAGE_SYM_CLASS_EXTERNAL
1142 || ( symtab_i->StorageClass == IMAGE_SYM_CLASS_STATIC
1143 && sectabent->Characteristics & IMAGE_SCN_LNK_COMDAT)
1144 ) {
1145 addr = (void*)((size_t)oc->sections[symtab_i->SectionNumber-1].start
1146 + symtab_i->Value);
1147 if (sectabent->Characteristics & IMAGE_SCN_LNK_COMDAT) {
1148 isWeak = true;
1149 }
1150 }
1151 }
1152 else if (symtab_i->StorageClass == IMAGE_SYM_CLASS_WEAK_EXTERNAL) {
1153 isWeak = true;
1154 }
1155 else if ( symtab_i->SectionNumber == IMAGE_SYM_UNDEFINED
1156 && symtab_i->Value > 0) {
1157 /* This symbol isn't in any section at all, ie, global bss.
1158 Allocate zeroed space for it from the BSS section */
1159 addr = bss;
1160 bss = (SymbolAddr*)((StgWord)bss + (StgWord)symtab_i->Value);
1161 IF_DEBUG(linker, debugBelch("bss symbol @ %p %lu\n", addr, symtab_i->Value));
1162 }
1163
1164 sname = cstring_from_COFF_symbol_name(symtab_i->N.ShortName, strtab);
1165 if (addr != NULL || isWeak) {
1166
1167 /* debugBelch("addSymbol %p `%s' Weak:%lld \n", addr, sname, isWeak); */
1168 IF_DEBUG(linker, debugBelch("addSymbol %p `%s'\n", addr,sname));
1169 ASSERT(i >= 0 && i < oc->n_symbols);
1170 /* cstring_from_COFF_symbol_name always succeeds. */
1171 oc->symbols[i] = (SymbolName*)sname;
1172 if (isWeak) {
1173 setWeakSymbol(oc, sname);
1174 }
1175
1176 if (! ghciInsertSymbolTable(oc->fileName, symhash, (SymbolName*)sname, addr,
1177 isWeak, oc)) {
1178 return false;
1179 }
1180 } else {
1181 /* We're skipping the symbol, but if we ever load this
1182 object file we'll want to skip it then too. */
1183 oc->symbols[i] = NULL;
1184
1185 # if 0
1186 debugBelch(
1187 "IGNORING symbol %d\n"
1188 " name `",
1189 i
1190 );
1191 printName ( symtab_i->N.ShortName, strtab );
1192 debugBelch(
1193 "'\n"
1194 " value 0x%x\n"
1195 " 1+sec# %d\n"
1196 " type 0x%x\n"
1197 " sclass 0x%x\n"
1198 " nAux %d\n",
1199 symtab_i->Value,
1200 (int32_t)(symtab_i->SectionNumber),
1201 (uint32_t)symtab_i->Type,
1202 (uint32_t)symtab_i->StorageClass,
1203 (uint32_t)symtab_i->NumberOfAuxSymbols
1204 );
1205 # endif
1206 }
1207
1208 i += symtab_i->NumberOfAuxSymbols;
1209 }
1210
1211 return true;
1212 }
1213
1214 #if defined(x86_64_HOST_ARCH)
1215
1216 /* We've already reserved a room for symbol extras in loadObj,
1217 * so simply set correct pointer here.
1218 */
1219 bool
1220 ocAllocateSymbolExtras_PEi386 ( ObjectCode* oc )
1221 {
1222 oc->symbol_extras = (SymbolExtra*)(oc->image - PEi386_IMAGE_OFFSET
1223 + ((PEi386_IMAGE_OFFSET + oc->fileSize + 0x7) & ~0x7));
1224 oc->first_symbol_extra = 0;
1225 oc->n_symbol_extras = ((COFF_header*)oc->image)->NumberOfSymbols;
1226
1227 return true;
1228 }
1229
1230 static size_t
1231 makeSymbolExtra_PEi386( ObjectCode* oc, uint64_t index, size_t s, char* symbol )
1232 {
1233 unsigned int curr_thunk;
1234 SymbolExtra *extra;
1235 curr_thunk = oc->first_symbol_extra + index;
1236 if (index >= oc->n_symbol_extras) {
1237 IF_DEBUG(linker, debugBelch("makeSymbolExtra first:%d, num:%lu, member:%s, index:%llu\n", curr_thunk, oc->n_symbol_extras, oc->archiveMemberName, index));
1238 barf("Can't allocate thunk for `%s' in `%" PATH_FMT "' with member `%s'", symbol, oc->fileName, oc->archiveMemberName);
1239 }
1240
1241 extra = oc->symbol_extras + curr_thunk;
1242
1243 if (!extra->addr)
1244 {
1245 // jmp *-14(%rip)
1246 static uint8_t jmp[] = { 0xFF, 0x25, 0xF2, 0xFF, 0xFF, 0xFF };
1247 extra->addr = (uint64_t)s;
1248 memcpy(extra->jumpIsland, jmp, 6);
1249 }
1250
1251 return (size_t)extra->jumpIsland;
1252 }
1253
1254 #endif /* x86_64_HOST_ARCH */
1255
1256 bool
1257 ocResolve_PEi386 ( ObjectCode* oc )
1258 {
1259 COFF_header* hdr;
1260 COFF_section* sectab;
1261 COFF_symbol* symtab;
1262 uint8_t* strtab;
1263
1264 uint32_t A;
1265 size_t S;
1266 SymbolAddr* pP;
1267
1268 int i;
1269 uint32_t j, noRelocs;
1270
1271 /* ToDo: should be variable-sized? But is at least safe in the
1272 sense of buffer-overrun-proof. */
1273 uint8_t symbol[1000];
1274 /* debugBelch("resolving for %s\n", oc->fileName); */
1275
1276 hdr = (COFF_header*)(oc->image);
1277 sectab = (COFF_section*) (
1278 ((uint8_t*)(oc->image))
1279 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
1280 );
1281 symtab = (COFF_symbol*) (
1282 ((uint8_t*)(oc->image))
1283 + hdr->PointerToSymbolTable
1284 );
1285 strtab = ((uint8_t*)(oc->image))
1286 + hdr->PointerToSymbolTable
1287 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
1288
1289 for (i = 0; i < hdr->NumberOfSections; i++) {
1290 COFF_section* sectab_i
1291 = (COFF_section*)
1292 myindex ( sizeof_COFF_section, sectab, i );
1293 COFF_reloc* reltab
1294 = (COFF_reloc*) (
1295 ((uint8_t*)(oc->image)) + sectab_i->PointerToRelocations
1296 );
1297 Section section = oc->sections[i];
1298
1299 char *secname = cstring_from_section_name(sectab_i->Name, strtab);
1300
1301 /* Ignore sections called which contain stabs debugging information. */
1302 if ( 0 == strcmp(".stab", (char*)secname)
1303 || 0 == strcmp(".stabstr", (char*)secname)
1304 || 0 == strncmp(".pdata", (char*)secname, 6)
1305 || 0 == strncmp(".xdata", (char*)secname, 6)
1306 || 0 == strncmp(".debug", (char*)secname, 6)
1307 || 0 == strcmp(".rdata$zzz", (char*)secname)) {
1308 stgFree(secname);
1309 continue;
1310 }
1311
1312 stgFree(secname);
1313
1314 if ( sectab_i->Characteristics & IMAGE_SCN_LNK_NRELOC_OVFL ) {
1315 /* If the relocation field (a short) has overflowed, the
1316 * real count can be found in the first reloc entry.
1317 *
1318 * See Section 4.1 (last para) of the PE spec (rev6.0).
1319 *
1320 * Nov2003 update: the GNU linker still doesn't correctly
1321 * handle the generation of relocatable object files with
1322 * overflown relocations. Hence the output to warn of potential
1323 * troubles.
1324 */
1325 COFF_reloc* rel = (COFF_reloc*)
1326 myindex ( sizeof_COFF_reloc, reltab, 0 );
1327 noRelocs = rel->VirtualAddress;
1328
1329 /* 10/05: we now assume (and check for) a GNU ld that is capable
1330 * of handling object files with (>2^16) of relocs.
1331 */
1332 #if 0
1333 debugBelch("WARNING: Overflown relocation field (# relocs found: %u)\n",
1334 noRelocs);
1335 #endif
1336 j = 1;
1337 } else {
1338 noRelocs = sectab_i->NumberOfRelocations;
1339 j = 0;
1340 }
1341
1342 for (; j < noRelocs; j++) {
1343 COFF_symbol* sym;
1344 COFF_reloc* reltab_j
1345 = (COFF_reloc*)
1346 myindex ( sizeof_COFF_reloc, reltab, j );
1347
1348 /* the location to patch */
1349 pP = (void*)(
1350 (size_t)section.start
1351 + reltab_j->VirtualAddress
1352 - sectab_i->VirtualAddress
1353 );
1354 /* the existing contents of pP */
1355 A = *(uint32_t*)pP;
1356 /* the symbol to connect to */
1357 sym = (COFF_symbol*)
1358 myindex ( sizeof_COFF_symbol,
1359 symtab, reltab_j->SymbolTableIndex );
1360 uint64_t symIndex = ((uint64_t)myindex(sizeof_COFF_symbol, symtab,
1361 reltab_j->SymbolTableIndex)
1362 - (uint64_t)symtab) / sizeof_COFF_symbol;
1363
1364 IF_DEBUG(linker,
1365 debugBelch(
1366 "reloc sec %2d num %3d: type 0x%-4x "
1367 "vaddr 0x%-8lx name `",
1368 i, j,
1369 (uint32_t)reltab_j->Type,
1370 reltab_j->VirtualAddress );
1371 printName ( sym->N.ShortName, strtab );
1372 debugBelch("'\n" ));
1373
1374 if (sym->StorageClass == IMAGE_SYM_CLASS_STATIC) {
1375 Section section = oc->sections[sym->SectionNumber-1];
1376 S = ((size_t)(section.start))
1377 + ((size_t)(sym->Value));
1378 } else {
1379 copyName ( sym->N.ShortName, strtab, symbol, 1000-1 );
1380 S = (size_t) lookupSymbol_( (char*)symbol );
1381 if ((void*)S == NULL) {
1382
1383 errorBelch(" | %" PATH_FMT ": unknown symbol `%s'", oc->fileName, symbol);
1384 return false;
1385 }
1386 }
1387 /* All supported relocations write at least 4 bytes */
1388 checkProddableBlock(oc, pP, 4);
1389 switch (reltab_j->Type) {
1390 #if defined(i386_HOST_ARCH)
1391 case IMAGE_REL_I386_DIR32:
1392 case IMAGE_REL_I386_DIR32NB:
1393 *(uint32_t *)pP = ((uint32_t)S) + A;
1394 break;
1395 case IMAGE_REL_I386_REL32:
1396 /* Tricky. We have to insert a displacement at
1397 pP which, when added to the PC for the _next_
1398 insn, gives the address of the target (S).
1399 Problem is to know the address of the next insn
1400 when we only know pP. We assume that this
1401 literal field is always the last in the insn,
1402 so that the address of the next insn is pP+4
1403 -- hence the constant 4.
1404 Also I don't know if A should be added, but so
1405 far it has always been zero.
1406
1407 SOF 05/2005: 'A' (old contents of *pP) have been observed
1408 to contain values other than zero (the 'wx' object file
1409 that came with wxhaskell-0.9.4; dunno how it was compiled..).
1410 So, add displacement to old value instead of asserting
1411 A to be zero. Fixes wxhaskell-related crashes, and no other
1412 ill effects have been observed.
1413
1414 Update: the reason why we're seeing these more elaborate
1415 relocations is due to a switch in how the NCG compiles SRTs
1416 and offsets to them from info tables. SRTs live in .(ro)data,
1417 while info tables live in .text, causing GAS to emit REL32/DISP32
1418 relocations with non-zero values. Adding the displacement is
1419 the right thing to do.
1420 */
1421 *(uint32_t *)pP = ((uint32_t)S) + A - ((uint32_t)(size_t)pP) - 4;
1422 break;
1423 #elif defined(x86_64_HOST_ARCH)
1424 case 1: /* R_X86_64_64 (ELF constant 1) - IMAGE_REL_AMD64_ADDR64 (PE constant 1) */
1425 {
1426 uint64_t A;
1427 checkProddableBlock(oc, pP, 8);
1428 A = *(uint64_t*)pP;
1429 *(uint64_t *)pP = ((uint64_t)S) + ((uint64_t)A);
1430 break;
1431 }
1432 case 2: /* R_X86_64_32 (ELF constant 10) - IMAGE_REL_AMD64_ADDR32 (PE constant 2) */
1433 case 3: /* R_X86_64_32S (ELF constant 11) - IMAGE_REL_AMD64_ADDR32NB (PE constant 3) */
1434 case 17: /* R_X86_64_32S ELF constant, no PE mapping. See note [ELF constant in PE file] */
1435 {
1436 size_t v;
1437 v = S + ((size_t)A);
1438 if (v >> 32) {
1439 copyName ( sym->N.ShortName, strtab, symbol, 1000-1 );
1440 S = makeSymbolExtra_PEi386(oc, symIndex, S, (char *)symbol);
1441 /* And retry */
1442 v = S + ((size_t)A);
1443 if (v >> 32) {
1444 barf("IMAGE_REL_AMD64_ADDR32[NB]: High bits are set in %zx for %s",
1445 v, (char *)symbol);
1446 }
1447 }
1448 *(uint32_t *)pP = (uint32_t)v;
1449 break;
1450 }
1451 case 4: /* R_X86_64_PC32 (ELF constant 2) - IMAGE_REL_AMD64_REL32 (PE constant 4) */
1452 {
1453 intptr_t v;
1454 v = ((intptr_t)S) + ((intptr_t)(int32_t)A) - ((intptr_t)pP) - 4;
1455 if ((v >> 32) && ((-v) >> 32)) {
1456 /* Make the trampoline then */
1457 copyName ( sym->N.ShortName, strtab, symbol, 1000-1 );
1458 S = makeSymbolExtra_PEi386(oc, symIndex, S, (char *)symbol);
1459 /* And retry */
1460 v = ((intptr_t)S) + ((intptr_t)(int32_t)A) - ((intptr_t)pP) - 4;
1461 if ((v >> 32) && ((-v) >> 32)) {
1462 barf("IMAGE_REL_AMD64_REL32: High bits are set in %zx for %s",
1463 v, (char *)symbol);
1464 }
1465 }
1466 *(uint32_t *)pP = (uint32_t)v;
1467 break;
1468 }
1469 #endif
1470 default:
1471 debugBelch("%" PATH_FMT ": unhandled PEi386 relocation type %d\n",
1472 oc->fileName, reltab_j->Type);
1473 return false;
1474 }
1475
1476 }
1477 }
1478
1479 IF_DEBUG(linker, debugBelch("completed %" PATH_FMT "\n", oc->fileName));
1480 return true;
1481 }
1482
1483 /*
1484 Note [ELF constant in PE file]
1485
1486 For some reason, the PE files produced by GHC contain a linux
1487 relocation constant 17 (0x11) in the object files. As far as I (Phyx-) can tell
1488 this constant doesn't seem like it's coming from GHC, or at least I could not find
1489 anything in the .s output that GHC produces which specifies the relocation type.
1490
1491 This leads me to believe that this is a bug in GAS. However because this constant is
1492 there we must deal with it. This is done by mapping it to the equivalent in behaviour PE
1493 relocation constant 0x03.
1494
1495 See #9907
1496 */
1497
1498 bool
1499 ocRunInit_PEi386 ( ObjectCode *oc )
1500 {
1501 COFF_header* hdr;
1502 COFF_section* sectab;
1503 uint8_t* strtab;
1504 int i;
1505
1506 hdr = (COFF_header*)(oc->image);
1507 sectab = (COFF_section*) (
1508 ((uint8_t*)(oc->image))
1509 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
1510 );
1511 strtab = ((uint8_t*)(oc->image))
1512 + hdr->PointerToSymbolTable
1513 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
1514
1515 int argc, envc;
1516 char **argv, **envv;
1517
1518 getProgArgv(&argc, &argv);
1519 getProgEnvv(&envc, &envv);
1520
1521 /* TODO: This part is just looking for .ctors section. This can be optimized
1522 and should for objects compiled with function sections as these produce a
1523 large amount of sections.
1524
1525 This can be done by saving the index of the .ctor section in the ObjectCode
1526 from ocGetNames. Then this loop isn't needed. */
1527 for (i = 0; i < hdr->NumberOfSections; i++) {
1528 COFF_section* sectab_i
1529 = (COFF_section*)
1530 myindex ( sizeof_COFF_section, sectab, i );
1531 Section section = oc->sections[i];
1532 char *secname = cstring_from_section_name(sectab_i->Name, strtab);
1533 if (0 == strcmp(".ctors", (char*)secname)) {
1534 uint8_t *init_startC = section.start;
1535 init_t *init_start, *init_end, *init;
1536 init_start = (init_t*)init_startC;
1537 init_end = (init_t*)(init_startC + sectab_i->SizeOfRawData);
1538 // ctors are run *backwards*!
1539 for (init = init_end - 1; init >= init_start; init--) {
1540 (*init)(argc, argv, envv);
1541 }
1542 }
1543 }
1544 freeProgEnvv(envc, envv);
1545 return true;
1546 }
1547
1548 SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl)
1549 {
1550 RtsSymbolInfo *pinfo;
1551
1552 if (!ghciLookupSymbolInfo(symhash, lbl, &pinfo)) {
1553 IF_DEBUG(linker, debugBelch("lookupSymbol: symbol '%s' not found\n", lbl));
1554
1555 SymbolAddr* sym;
1556
1557 /* See Note [mingw-w64 name decoration scheme] */
1558 #ifndef x86_64_HOST_ARCH
1559 zapTrailingAtSign ( (unsigned char*)lbl );
1560 #endif
1561 sym = lookupSymbolInDLLs((unsigned char*)lbl);
1562 return sym; // might be NULL if not found
1563 } else {
1564 #if defined(mingw32_HOST_OS)
1565 // If Windows, perform initialization of uninitialized
1566 // Symbols from the C runtime which was loaded above.
1567 // We do this on lookup to prevent the hit when
1568 // The symbol isn't being used.
1569 if (pinfo->value == (void*)0xBAADF00D)
1570 {
1571 char symBuffer[50];
1572 sprintf(symBuffer, "_%s", lbl);
1573 pinfo->value = GetProcAddress(GetModuleHandle("msvcrt"), symBuffer);
1574 }
1575 #endif
1576 return loadSymbol(lbl, pinfo);
1577 }
1578 }
1579
1580 #endif /* mingw32_HOST_OS */