diff options
| author | Geoff Voelker | 1995-12-24 00:38:36 +0000 |
|---|---|---|
| committer | Geoff Voelker | 1995-12-24 00:38:36 +0000 |
| commit | a610993dc341b0b184e82ba11dbb05cd7bb11616 (patch) | |
| tree | f80e9bcc5c197cc244b867a656a0b043596859e8 | |
| parent | b72535bccfe5cee9e27e254b193fdbc5eeb88e3e (diff) | |
| download | emacs-a610993dc341b0b184e82ba11dbb05cd7bb11616.tar.gz emacs-a610993dc341b0b184e82ba11dbb05cd7bb11616.zip | |
(get_bss_info_from_map_file): New function.
(get_section_info): When .bss section parameters are not in the
executable, search the symbol map file for them.
| -rw-r--r-- | src/unexw32.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/src/unexw32.c b/src/unexw32.c index 475fcf8cf96..7b9712c11c5 100644 --- a/src/unexw32.c +++ b/src/unexw32.c | |||
| @@ -291,6 +291,44 @@ close_file_data (file_data *p_file) | |||
| 291 | 291 | ||
| 292 | /* Routines to manipulate NT executable file sections. */ | 292 | /* Routines to manipulate NT executable file sections. */ |
| 293 | 293 | ||
| 294 | static void | ||
| 295 | get_bss_info_from_map_file (file_data *p_infile, PUCHAR *p_bss_start, | ||
| 296 | DWORD *p_bss_size) | ||
| 297 | { | ||
| 298 | int n, start, len; | ||
| 299 | char map_filename[MAX_PATH]; | ||
| 300 | char buffer[256]; | ||
| 301 | FILE *map; | ||
| 302 | |||
| 303 | /* Overwrite the .exe extension on the executable file name with | ||
| 304 | the .map extension. */ | ||
| 305 | strcpy (map_filename, p_infile->name); | ||
| 306 | n = strlen (map_filename) - 3; | ||
| 307 | strcpy (&map_filename[n], "map"); | ||
| 308 | |||
| 309 | map = fopen (map_filename, "r"); | ||
| 310 | if (!map) | ||
| 311 | { | ||
| 312 | printf ("Failed to open map file %s, error %d...bailing out.\n", | ||
| 313 | map_filename, GetLastError ()); | ||
| 314 | exit (-1); | ||
| 315 | } | ||
| 316 | |||
| 317 | while (fgets (buffer, sizeof (buffer), map)) | ||
| 318 | { | ||
| 319 | if (!(strstr (buffer, ".bss") && strstr (buffer, "DATA"))) | ||
| 320 | continue; | ||
| 321 | n = sscanf (buffer, " %*d:%x %x", &start, &len); | ||
| 322 | if (n != 2) | ||
| 323 | { | ||
| 324 | printf ("Failed to scan the .bss section line:\n%s", buffer); | ||
| 325 | exit (-1); | ||
| 326 | } | ||
| 327 | break; | ||
| 328 | } | ||
| 329 | *p_bss_start = (PUCHAR) start; | ||
| 330 | *p_bss_size = (DWORD) len; | ||
| 331 | } | ||
| 294 | 332 | ||
| 295 | static unsigned long | 333 | static unsigned long |
| 296 | get_section_size (PIMAGE_SECTION_HEADER p_section) | 334 | get_section_size (PIMAGE_SECTION_HEADER p_section) |
| @@ -311,7 +349,7 @@ get_section_info (file_data *p_infile) | |||
| 311 | { | 349 | { |
| 312 | PIMAGE_DOS_HEADER dos_header; | 350 | PIMAGE_DOS_HEADER dos_header; |
| 313 | PIMAGE_NT_HEADERS nt_header; | 351 | PIMAGE_NT_HEADERS nt_header; |
| 314 | PIMAGE_SECTION_HEADER section; | 352 | PIMAGE_SECTION_HEADER section, data_section; |
| 315 | unsigned char *ptr; | 353 | unsigned char *ptr; |
| 316 | int i; | 354 | int i; |
| 317 | 355 | ||
| @@ -355,6 +393,7 @@ get_section_info (file_data *p_infile) | |||
| 355 | extern char my_edata[]; | 393 | extern char my_edata[]; |
| 356 | 394 | ||
| 357 | /* The .data section. */ | 395 | /* The .data section. */ |
| 396 | data_section = section; | ||
| 358 | ptr = (char *) nt_header->OptionalHeader.ImageBase + | 397 | ptr = (char *) nt_header->OptionalHeader.ImageBase + |
| 359 | section->VirtualAddress; | 398 | section->VirtualAddress; |
| 360 | data_start_va = ptr; | 399 | data_start_va = ptr; |
| @@ -368,6 +407,21 @@ get_section_info (file_data *p_infile) | |||
| 368 | } | 407 | } |
| 369 | section++; | 408 | section++; |
| 370 | } | 409 | } |
| 410 | |||
| 411 | if (!bss_start && !bss_size) | ||
| 412 | { | ||
| 413 | /* Starting with MSVC 4.0, the .bss section has been eliminated | ||
| 414 | and appended virtually to the end of the .data section. Our | ||
| 415 | only hint about where the .bss section starts in the address | ||
| 416 | comes from the SizeOfRawData field in the .data section | ||
| 417 | header. Unfortunately, this field is only approximate, as it | ||
| 418 | is a rounded number and is typically rounded just beyond the | ||
| 419 | start of the .bss section. To find the start and size of the | ||
| 420 | .bss section exactly, we have to peek into the map file. */ | ||
| 421 | get_bss_info_from_map_file (p_infile, &ptr, &bss_size); | ||
| 422 | bss_start = ptr + nt_header->OptionalHeader.ImageBase | ||
| 423 | + data_section->VirtualAddress; | ||
| 424 | } | ||
| 371 | } | 425 | } |
| 372 | 426 | ||
| 373 | 427 | ||