aboutsummaryrefslogtreecommitdiffstats
path: root/src/unexec.c
diff options
context:
space:
mode:
authorRichard M. Stallman1994-09-23 06:18:31 +0000
committerRichard M. Stallman1994-09-23 06:18:31 +0000
commit52a2b13bc58f493616d53cbe8a2a612b965eafd9 (patch)
tree66e0fa0e194a3e010e4a8a6536895c4f6326bc4d /src/unexec.c
parentc9a95ab2732f12c2e3c44851dfaf2b6c14b44265 (diff)
downloademacs-52a2b13bc58f493616d53cbe8a2a612b965eafd9.tar.gz
emacs-52a2b13bc58f493616d53cbe8a2a612b965eafd9.zip
(copy_text_and_data): Add RISCiX changes.
Diffstat (limited to 'src/unexec.c')
-rw-r--r--src/unexec.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/unexec.c b/src/unexec.c
index 2de8b20b588..26e63fa55d8 100644
--- a/src/unexec.c
+++ b/src/unexec.c
@@ -909,9 +909,95 @@ copy_text_and_data (new, a_out)
909 lseek (new, (long) N_TXTOFF (hdr), 0); 909 lseek (new, (long) N_TXTOFF (hdr), 0);
910#endif /* no A_TEXT_SEEK */ 910#endif /* no A_TEXT_SEEK */
911 911
912#ifdef RISCiX
913
914 /* Acorn's RISC-iX has a wacky way of initialising the position of the heap.
915 * There is a little table in crt0.o that is filled at link time with
916 * the min and current brk positions, among other things. When start()
917 * runs, it copies the table to where these parameters live during
918 * execution. This data is in text space, so it cannot be modified here
919 * before saving the executable, so the data is written manually. In
920 * addition, the table does not have a label, and the nearest accessable
921 * label (mcount) is not prefixed with a '_', thus making it inaccessable
922 * from within C programs. To overcome this, emacs's executable is passed
923 * through the command 'nm %s | fgrep mcount' into a pipe, and the
924 * resultant output is then used to find the address of 'mcount'. As far as
925 * is possible to determine, in RISC-iX releases prior to 1.2, the negative
926 * offset of the table from mcount is 0x2c, whereas from 1.2 onwards it is
927 * 0x30. bss_end has been rounded up to page boundary. This solution is
928 * based on suggestions made by Kevin Welton and Steve Hunt of Acorn, and
929 * avoids the need for a custom version of crt0.o for emacs which has its
930 * table in data space.
931 */
932
933 {
934 char command[1024];
935 char errbuf[1024];
936 char address_text[32];
937 int proforma[4];
938 FILE *pfile;
939 char *temp_ptr;
940 char c;
941 int mcount_address, mcount_offset, count;
942 extern char *_execname;
943
944
945 /* The use of _execname is incompatible with RISCiX 1.1 */
946 sprintf (command, "nm %s | fgrep mcount", _execname);
947
948 if ( (pfile = popen(command, "r")) == NULL)
949 {
950 sprintf (errbuf, "Could not open pipe");
951 PERROR (errbuf);
952 }
953
954 count=0;
955 while ( ((c=getc(pfile)) != EOF) && (c != ' ') && (count < 31))
956 address_text[count++]=c;
957 address_text[count]=0;
958
959 if ((count == 0) || pclose(pfile) != NULL)
960 {
961 sprintf (errbuf, "Failed to execute the command '%s'\n", command);
962 PERROR (errbuf);
963 }
964
965 sscanf(address_text, "%x", &mcount_address);
966 ptr = (char *) unexec_text_start;
967 mcount_offset = (char *)mcount_address - ptr;
968
969#ifdef RISCiX_1_1
970#define EDATA_OFFSET 0x2c
971#else
972#define EDATA_OFFSET 0x30
973#endif
974
975 end = ptr + mcount_offset - EDATA_OFFSET;
976 printf ("Writing from %08x to %08x\n", ptr, end);
977
978 write_segment (new, ptr, end);
979
980 proforma[0] = bss_end; /* becomes _edata */
981 proforma[1] = bss_end; /* becomes _end */
982 proforma[2] = bss_end; /* becomes _minbrk */
983 proforma[3] = bss_end; /* becomes _curbrk */
984
985 puts ("Writing 'args_proforma' (16 bytes)");
986 write (new, proforma, 16);
987
988 temp_ptr = ptr;
989 ptr = end + 16;
990 end = temp_ptr + hdr.a_text;
991
992 printf ("Writing from %08x to %08x\n", ptr, end);
993 write_segment (new, ptr, end);
994 }
995
996#else /* !RISCiX */
912 ptr = (char *) unexec_text_start; 997 ptr = (char *) unexec_text_start;
913 end = ptr + hdr.a_text; 998 end = ptr + hdr.a_text;
914 write_segment (new, ptr, end); 999 write_segment (new, ptr, end);
1000#endif /* RISCiX */
915 1001
916 ptr = (char *) unexec_data_start; 1002 ptr = (char *) unexec_data_start;
917 end = ptr + hdr.a_data; 1003 end = ptr + hdr.a_data;