aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGerd Moellmann1999-11-17 20:58:06 +0000
committerGerd Moellmann1999-11-17 20:58:06 +0000
commitb6f8e8063f114cb2083245dbaa243d225841fd60 (patch)
tree20addf81cf101d679c6b14db03aea49de9ab90f4 /src
parentb5b41e0276ef2aa8287d7d044c114fe3585700cf (diff)
downloademacs-b6f8e8063f114cb2083245dbaa243d225841fd60.tar.gz
emacs-b6f8e8063f114cb2083245dbaa243d225841fd60.zip
(unexec): Handle .rel.dyn section.
Diffstat (limited to 'src')
-rw-r--r--src/unexsni.c87
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.
23You are forbidden to forbid anyone else to use, share and improve 23You are forbidden to forbid anyone else to use, share and improve
24what you give them. Help stamp out software-hoarding! */ 24what 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