diff options
| author | Geoff Voelker | 1998-04-17 05:06:37 +0000 |
|---|---|---|
| committer | Geoff Voelker | 1998-04-17 05:06:37 +0000 |
| commit | 9c8056fe19279f2ac8cb89bcf666d2d54456e95b (patch) | |
| tree | b7189601c378d497f05afe716983a6152dd48f2b | |
| parent | b2140d4b797012edd5b093ecc0db90a6f9dde9c0 (diff) | |
| download | emacs-9c8056fe19279f2ac8cb89bcf666d2d54456e95b.tar.gz emacs-9c8056fe19279f2ac8cb89bcf666d2d54456e95b.zip | |
(my_begbss_static, my_endbss_static): Declare.
(get_bss_info_from_map_file): Only define if SEPARATE_BSS_SECTION.
(get_section_info): Use my_begbss_static, my_endbss_static to
determine bounds of bss.
(w32_fatal_reload_error): New function.
(read_in_bss, map_in_heap): Invoke w32_fatal_reload_error upon error.
| -rw-r--r-- | src/unexw32.c | 98 |
1 files changed, 63 insertions, 35 deletions
diff --git a/src/unexw32.c b/src/unexw32.c index 5d196a8b1cb..ebd934c5f1d 100644 --- a/src/unexw32.c +++ b/src/unexw32.c | |||
| @@ -44,6 +44,8 @@ extern char my_begdata[]; | |||
| 44 | extern char my_edata[]; | 44 | extern char my_edata[]; |
| 45 | extern char my_begbss[]; | 45 | extern char my_begbss[]; |
| 46 | extern char my_endbss[]; | 46 | extern char my_endbss[]; |
| 47 | extern char *my_begbss_static; | ||
| 48 | extern char *my_endbss_static; | ||
| 47 | 49 | ||
| 48 | #include "w32heap.h" | 50 | #include "w32heap.h" |
| 49 | 51 | ||
| @@ -332,6 +334,7 @@ close_file_data (file_data *p_file) | |||
| 332 | 334 | ||
| 333 | /* Routines to manipulate NT executable file sections. */ | 335 | /* Routines to manipulate NT executable file sections. */ |
| 334 | 336 | ||
| 337 | #ifdef SEPARATE_BSS_SECTION | ||
| 335 | static void | 338 | static void |
| 336 | get_bss_info_from_map_file (file_data *p_infile, PUCHAR *p_bss_start, | 339 | get_bss_info_from_map_file (file_data *p_infile, PUCHAR *p_bss_start, |
| 337 | DWORD *p_bss_size) | 340 | DWORD *p_bss_size) |
| @@ -370,6 +373,7 @@ get_bss_info_from_map_file (file_data *p_infile, PUCHAR *p_bss_start, | |||
| 370 | *p_bss_start = (PUCHAR) start; | 373 | *p_bss_start = (PUCHAR) start; |
| 371 | *p_bss_size = (DWORD) len; | 374 | *p_bss_size = (DWORD) len; |
| 372 | } | 375 | } |
| 376 | #endif | ||
| 373 | 377 | ||
| 374 | unsigned long | 378 | unsigned long |
| 375 | get_section_size (PIMAGE_SECTION_HEADER p_section) | 379 | get_section_size (PIMAGE_SECTION_HEADER p_section) |
| @@ -517,8 +521,20 @@ get_section_info (file_data *p_infile) | |||
| 517 | + data_section->VirtualAddress; | 521 | + data_section->VirtualAddress; |
| 518 | } | 522 | } |
| 519 | #else | 523 | #else |
| 520 | bss_start = my_begbss; | 524 | /* As noted in lastfile.c, the Alpha (but not the Intel) MSVC linker |
| 521 | bss_size = my_endbss - bss_start; | 525 | globally segregates all static and public bss data (ie. across all |
| 526 | linked modules, not just per module), so we must take both static and | ||
| 527 | public bss areas into account to determine the true extent of the bss | ||
| 528 | area used by Emacs. | ||
| 529 | |||
| 530 | To be strictly correct, we should dump the static and public bss | ||
| 531 | areas used by Emacs separately if non-overlapping (since otherwise we | ||
| 532 | are dumping bss data belonging to system libraries, eg. the static | ||
| 533 | bss system data on the Alpha). However, in practice this doesn't | ||
| 534 | seem to matter, since presumably the system libraries always | ||
| 535 | reinitialize their bss variables. */ | ||
| 536 | bss_start = min (my_begbss, my_begbss_static); | ||
| 537 | bss_size = max (my_endbss, my_endbss_static) - bss_start; | ||
| 522 | #endif | 538 | #endif |
| 523 | } | 539 | } |
| 524 | 540 | ||
| @@ -596,6 +612,43 @@ dump_bss_and_heap (file_data *p_infile, file_data *p_outfile) | |||
| 596 | 612 | ||
| 597 | /* Reload and remap routines. */ | 613 | /* Reload and remap routines. */ |
| 598 | 614 | ||
| 615 | void | ||
| 616 | w32_fatal_reload_error (char *step) | ||
| 617 | { | ||
| 618 | int error = GetLastError (); | ||
| 619 | char *buffer = alloca (4096); | ||
| 620 | |||
| 621 | sprintf (buffer, | ||
| 622 | "Emacs failed to load its dumped heap back into its address space.\n" | ||
| 623 | "The error occurred during the following step:\n\n" | ||
| 624 | "%s\n\n" | ||
| 625 | "GetLastError = %d\n\n" | ||
| 626 | "Heap start: 0x%08x\n" | ||
| 627 | "Heap commit: 0x%08x\n" | ||
| 628 | "Heap end: 0x%08x\n\n" | ||
| 629 | "This error typically happens when the system loads a DLL into\n" | ||
| 630 | "the middle of Emacs' address space, preventing Emacs from\n" | ||
| 631 | "loading its heap there. If you think that you have installed\n" | ||
| 632 | "Emacs correctly, then you have two options:\n\n" | ||
| 633 | "1) You can dump Emacs yourself. By doing this, you ensure that\n" | ||
| 634 | "Emacs' heap fits around the DLLs in your system. To dump Emacs,\n" | ||
| 635 | "download the emacs-(version)-undump-(arch) distribution file\n" | ||
| 636 | "from the site where you downloaded the executable distribution.\n\n" | ||
| 637 | "2) You can build Emacs from source. This is just another way\n" | ||
| 638 | "to dump Emacs on your system.", | ||
| 639 | step, | ||
| 640 | error, | ||
| 641 | get_heap_start (), | ||
| 642 | get_heap_start () + get_committed_heap_size (), | ||
| 643 | get_heap_end ()); | ||
| 644 | |||
| 645 | MessageBox (NULL, | ||
| 646 | buffer, | ||
| 647 | "Emacs Abort Dialog", | ||
| 648 | MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL); | ||
| 649 | |||
| 650 | exit (-1); | ||
| 651 | } | ||
| 599 | 652 | ||
| 600 | /* Load the dumped .bss section into the .bss area of our address space. */ | 653 | /* Load the dumped .bss section into the .bss area of our address space. */ |
| 601 | void | 654 | void |
| @@ -609,27 +662,17 @@ read_in_bss (char *filename) | |||
| 609 | file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, | 662 | file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, |
| 610 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); | 663 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); |
| 611 | if (file == INVALID_HANDLE_VALUE) | 664 | if (file == INVALID_HANDLE_VALUE) |
| 612 | { | 665 | w32_fatal_reload_error ("Opening Emacs executable file for .bss."); |
| 613 | i = GetLastError (); | ||
| 614 | exit (1); | ||
| 615 | } | ||
| 616 | 666 | ||
| 617 | /* Seek to where the .bss section is tucked away after the heap... */ | 667 | /* Seek to where the .bss section is tucked away after the heap... */ |
| 618 | index = heap_index_in_executable + get_committed_heap_size (); | 668 | index = heap_index_in_executable + get_committed_heap_size (); |
| 619 | if (SetFilePointer (file, index, NULL, FILE_BEGIN) == 0xFFFFFFFF) | 669 | if (SetFilePointer (file, index, NULL, FILE_BEGIN) == 0xFFFFFFFF) |
| 620 | { | 670 | w32_fatal_reload_error ("Seeking to the saved .bss section."); |
| 621 | i = GetLastError (); | ||
| 622 | exit (1); | ||
| 623 | } | ||
| 624 | |||
| 625 | 671 | ||
| 626 | /* Ok, read in the saved .bss section and initialize all | 672 | /* Ok, read in the saved .bss section and initialize all |
| 627 | uninitialized variables. */ | 673 | uninitialized variables. */ |
| 628 | if (!ReadFile (file, bss_start, bss_size, &n_read, NULL)) | 674 | if (!ReadFile (file, bss_start, bss_size, &n_read, NULL)) |
| 629 | { | 675 | w32_fatal_reload_error ("Reading the saved .bss section."); |
| 630 | i = GetLastError (); | ||
| 631 | exit (1); | ||
| 632 | } | ||
| 633 | 676 | ||
| 634 | CloseHandle (file); | 677 | CloseHandle (file); |
| 635 | } | 678 | } |
| @@ -647,19 +690,13 @@ map_in_heap (char *filename) | |||
| 647 | file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, | 690 | file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, |
| 648 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); | 691 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); |
| 649 | if (file == INVALID_HANDLE_VALUE) | 692 | if (file == INVALID_HANDLE_VALUE) |
| 650 | { | 693 | w32_fatal_reload_error ("Opening Emacs executable file for heap."); |
| 651 | i = GetLastError (); | ||
| 652 | exit (1); | ||
| 653 | } | ||
| 654 | 694 | ||
| 655 | size = GetFileSize (file, &upper_size); | 695 | size = GetFileSize (file, &upper_size); |
| 656 | file_mapping = CreateFileMapping (file, NULL, PAGE_WRITECOPY, | 696 | file_mapping = CreateFileMapping (file, NULL, PAGE_WRITECOPY, |
| 657 | 0, size, NULL); | 697 | 0, size, NULL); |
| 658 | if (!file_mapping) | 698 | if (!file_mapping) |
| 659 | { | 699 | w32_fatal_reload_error ("Creating file mapping to heap in executable."); |
| 660 | i = GetLastError (); | ||
| 661 | exit (1); | ||
| 662 | } | ||
| 663 | 700 | ||
| 664 | size = get_committed_heap_size (); | 701 | size = get_committed_heap_size (); |
| 665 | file_base = MapViewOfFileEx (file_mapping, FILE_MAP_COPY, 0, | 702 | file_base = MapViewOfFileEx (file_mapping, FILE_MAP_COPY, 0, |
| @@ -677,26 +714,17 @@ map_in_heap (char *filename) | |||
| 677 | 714 | ||
| 678 | if (VirtualAlloc (get_heap_start (), get_committed_heap_size (), | 715 | if (VirtualAlloc (get_heap_start (), get_committed_heap_size (), |
| 679 | MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE) == NULL) | 716 | MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE) == NULL) |
| 680 | { | 717 | w32_fatal_reload_error ("Allocating heap address space."); |
| 681 | i = GetLastError (); | ||
| 682 | exit (1); | ||
| 683 | } | ||
| 684 | 718 | ||
| 685 | /* Seek to the location of the heap data in the executable. */ | 719 | /* Seek to the location of the heap data in the executable. */ |
| 686 | i = heap_index_in_executable; | 720 | i = heap_index_in_executable; |
| 687 | if (SetFilePointer (file, i, NULL, FILE_BEGIN) == 0xFFFFFFFF) | 721 | if (SetFilePointer (file, i, NULL, FILE_BEGIN) == 0xFFFFFFFF) |
| 688 | { | 722 | w32_fatal_reload_error ("Seeking to saved heap in executable file."); |
| 689 | i = GetLastError (); | ||
| 690 | exit (1); | ||
| 691 | } | ||
| 692 | 723 | ||
| 693 | /* Read in the data. */ | 724 | /* Read in the data. */ |
| 694 | if (!ReadFile (file, get_heap_start (), | 725 | if (!ReadFile (file, get_heap_start (), |
| 695 | get_committed_heap_size (), &n_read, NULL)) | 726 | get_committed_heap_size (), &n_read, NULL)) |
| 696 | { | 727 | w32_fatal_reload_error ("Reading saved heap from executable file."); |
| 697 | i = GetLastError (); | ||
| 698 | exit (1); | ||
| 699 | } | ||
| 700 | 728 | ||
| 701 | CloseHandle (file); | 729 | CloseHandle (file); |
| 702 | } | 730 | } |