diff options
| author | Gerd Moellmann | 1999-11-17 20:58:06 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 1999-11-17 20:58:06 +0000 |
| commit | b6f8e8063f114cb2083245dbaa243d225841fd60 (patch) | |
| tree | 20addf81cf101d679c6b14db03aea49de9ab90f4 /src | |
| parent | b5b41e0276ef2aa8287d7d044c114fe3585700cf (diff) | |
| download | emacs-b6f8e8063f114cb2083245dbaa243d225841fd60.tar.gz emacs-b6f8e8063f114cb2083245dbaa243d225841fd60.zip | |
(unexec): Handle .rel.dyn section.
Diffstat (limited to 'src')
| -rw-r--r-- | src/unexsni.c | 87 |
1 files changed, 86 insertions, 1 deletions
diff --git a/src/unexsni.c b/src/unexsni.c index f8a6f01ed1d..c819b0b7938 100644 --- a/src/unexsni.c +++ b/src/unexsni.c | |||
| @@ -23,7 +23,6 @@ In other words, you are welcome to use, share and improve this program. | |||
| 23 | You are forbidden to forbid anyone else to use, share and improve | 23 | You are forbidden to forbid anyone else to use, share and improve |
| 24 | what you give them. Help stamp out software-hoarding! */ | 24 | what you give them. Help stamp out software-hoarding! */ |
| 25 | 25 | ||
| 26 | |||
| 27 | /* | 26 | /* |
| 28 | * unexec.c - Convert a running program into an a.out file. | 27 | * unexec.c - Convert a running program into an a.out file. |
| 29 | * | 28 | * |
| @@ -117,6 +116,7 @@ what you give them. Help stamp out software-hoarding! */ | |||
| 117 | /* | 116 | /* |
| 118 | * New modifications for Siemens Nixdorf's MIPS-based machines. | 117 | * New modifications for Siemens Nixdorf's MIPS-based machines. |
| 119 | * Marco.Walther@mch.sni.de | 118 | * Marco.Walther@mch.sni.de |
| 119 | * marco@inreach.com | ||
| 120 | * | 120 | * |
| 121 | * The problem: Before the bss segment we have a so called sbss segment | 121 | * The problem: Before the bss segment we have a so called sbss segment |
| 122 | * (small bss) and maybe an sdata segment. These segments | 122 | * (small bss) and maybe an sdata segment. These segments |
| @@ -305,6 +305,9 @@ what you give them. Help stamp out software-hoarding! */ | |||
| 305 | #include <fcntl.h> | 305 | #include <fcntl.h> |
| 306 | #include <elf.h> | 306 | #include <elf.h> |
| 307 | #include <sys/mman.h> | 307 | #include <sys/mman.h> |
| 308 | #include <assert.h> | ||
| 309 | |||
| 310 | /* #define DEBUG */ | ||
| 308 | 311 | ||
| 309 | #ifndef emacs | 312 | #ifndef emacs |
| 310 | #define fatal(a, b, c) fprintf(stderr, a, b, c), exit(1) | 313 | #define fatal(a, b, c) fprintf(stderr, a, b, c), exit(1) |
| @@ -383,6 +386,11 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 383 | Elf32_Addr new_data2_addr; | 386 | Elf32_Addr new_data2_addr; |
| 384 | Elf32_Addr new_data3_addr; | 387 | Elf32_Addr new_data3_addr; |
| 385 | 388 | ||
| 389 | |||
| 390 | Elf32_Addr old_rel_dyn_addr; | ||
| 391 | Elf32_Word old_rel_dyn_size; | ||
| 392 | int old_rel_dyn_index; | ||
| 393 | |||
| 386 | Elf32_Word old_sdata_size, new_sdata_size; | 394 | Elf32_Word old_sdata_size, new_sdata_size; |
| 387 | int old_sdata_index = 0; | 395 | int old_sdata_index = 0; |
| 388 | 396 | ||
| @@ -463,6 +471,26 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 463 | if (old_sbss_index != (old_bss_index - 1)) | 471 | if (old_sbss_index != (old_bss_index - 1)) |
| 464 | fatal (".sbss should come immediately before .bss in %s.\n", old_name, 0); | 472 | fatal (".sbss should come immediately before .bss in %s.\n", old_name, 0); |
| 465 | 473 | ||
| 474 | /* Find the old .rel.dyn section. | ||
| 475 | */ | ||
| 476 | |||
| 477 | for (old_rel_dyn_index = 1; old_rel_dyn_index < old_file_h->e_shnum; | ||
| 478 | old_rel_dyn_index++) | ||
| 479 | { | ||
| 480 | #ifdef DEBUG | ||
| 481 | fprintf (stderr, "Looking for .rel.dyn - found %s\n", | ||
| 482 | old_section_names + OLD_SECTION_H(old_rel_dyn_index).sh_name); | ||
| 483 | #endif | ||
| 484 | if (!strcmp (old_section_names + OLD_SECTION_H(old_rel_dyn_index).sh_name, | ||
| 485 | ".rel.dyn")) | ||
| 486 | break; | ||
| 487 | } | ||
| 488 | if (old_rel_dyn_index == old_file_h->e_shnum) | ||
| 489 | fatal ("Can't find .rel_dyn in %s.\n", old_name, 0); | ||
| 490 | |||
| 491 | old_rel_dyn_addr = OLD_SECTION_H(old_rel_dyn_index).sh_addr; | ||
| 492 | old_rel_dyn_size = OLD_SECTION_H(old_rel_dyn_index).sh_size; | ||
| 493 | |||
| 466 | /* Figure out parameters of the new data3 and data2 sections. | 494 | /* Figure out parameters of the new data3 and data2 sections. |
| 467 | * Change the sbss and bss sections. | 495 | * Change the sbss and bss sections. |
| 468 | */ | 496 | */ |
| @@ -516,6 +544,8 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 516 | fprintf (stderr, "old_sbss_index %d\n", old_sbss_index); | 544 | fprintf (stderr, "old_sbss_index %d\n", old_sbss_index); |
| 517 | fprintf (stderr, "old_sbss_addr %x\n", old_sbss_addr); | 545 | fprintf (stderr, "old_sbss_addr %x\n", old_sbss_addr); |
| 518 | fprintf (stderr, "old_sbss_size %x\n", old_sbss_size); | 546 | fprintf (stderr, "old_sbss_size %x\n", old_sbss_size); |
| 547 | fprintf (stderr, "old_rel_dyn_addr %x\n", old_rel_dyn_addr); | ||
| 548 | fprintf (stderr, "old_rel_dyn_size %x\n", old_rel_dyn_size); | ||
| 519 | if (old_sdata_index) | 549 | if (old_sdata_index) |
| 520 | { | 550 | { |
| 521 | fprintf (stderr, "old_sdata_size %x\n", old_sdata_size); | 551 | fprintf (stderr, "old_sdata_size %x\n", old_sdata_size); |
| @@ -816,6 +846,61 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 816 | } | 846 | } |
| 817 | } | 847 | } |
| 818 | } | 848 | } |
| 849 | { | ||
| 850 | Elf32_Rel *rel_p; | ||
| 851 | unsigned int old_data_addr_start; | ||
| 852 | unsigned int old_data_addr_end; | ||
| 853 | unsigned int old_data_offset; | ||
| 854 | unsigned int new_data_offset; | ||
| 855 | int i; | ||
| 856 | |||
| 857 | rel_p = (Elf32_Rel *)OLD_SECTION_H(old_rel_dyn_index).sh_addr; | ||
| 858 | old_data_addr_start = OLD_SECTION_H(old_data_index).sh_addr; | ||
| 859 | old_data_addr_end = old_data_addr_start + | ||
| 860 | OLD_SECTION_H(old_data_index).sh_size; | ||
| 861 | old_data_offset = (int)OLD_SECTION_H(old_data_index).sh_offset + | ||
| 862 | (unsigned int)old_base; | ||
| 863 | new_data_offset = (int)NEW_SECTION_H(old_data_index).sh_offset + | ||
| 864 | (unsigned int)new_base; | ||
| 865 | |||
| 866 | #ifdef DEBUG | ||
| 867 | fprintf(stderr, "old_data.sh_addr= 0x%08x ... 0x%08x\n", old_data_addr_start, | ||
| 868 | old_data_addr_end); | ||
| 869 | #endif /* DEBUG */ | ||
| 870 | |||
| 871 | for (i = 0; i < old_rel_dyn_size/sizeof(Elf32_Rel); i++) | ||
| 872 | { | ||
| 873 | #ifdef DEBUG | ||
| 874 | fprintf(stderr, ".rel.dyn offset= 0x%08x type= %d sym= %d\n", | ||
| 875 | rel_p->r_offset, ELF32_R_TYPE(rel_p->r_info), ELF32_R_SYM(rel_p->r_info)); | ||
| 876 | #endif /* DEBUG */ | ||
| 877 | |||
| 878 | if (rel_p->r_offset) | ||
| 879 | { | ||
| 880 | unsigned int offset; | ||
| 881 | |||
| 882 | assert(old_data_addr_start <= rel_p->r_offset && | ||
| 883 | rel_p->r_offset <= old_data_addr_end); | ||
| 884 | |||
| 885 | offset = rel_p->r_offset - old_data_addr_start; | ||
| 886 | |||
| 887 | #ifdef DEBUG | ||
| 888 | fprintf(stderr, "r_offset= 0x%08x *r_offset= 0x%08x\n", | ||
| 889 | rel_p->r_offset, *((int *)(rel_p->r_offset))); | ||
| 890 | fprintf(stderr, "old = 0x%08x *old =0x%08x\n", | ||
| 891 | (old_data_offset + offset - (unsigned int)old_base), | ||
| 892 | *((int *)(old_data_offset + offset))); | ||
| 893 | fprintf(stderr, "new = 0x%08x *new =0x%08x\n", | ||
| 894 | (new_data_offset + offset - (unsigned int)new_base), | ||
| 895 | *((int *)(new_data_offset + offset))); | ||
| 896 | #endif /* DEBUG */ | ||
| 897 | |||
| 898 | *((int *)(new_data_offset + offset)) = *((int *)(old_data_offset + offset)); | ||
| 899 | } | ||
| 900 | |||
| 901 | rel_p++; | ||
| 902 | } | ||
| 903 | } | ||
| 819 | 904 | ||
| 820 | /* Close the files and make the new file executable */ | 905 | /* Close the files and make the new file executable */ |
| 821 | 906 | ||