diff options
| author | Richard M. Stallman | 1994-09-23 06:18:31 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-09-23 06:18:31 +0000 |
| commit | 52a2b13bc58f493616d53cbe8a2a612b965eafd9 (patch) | |
| tree | 66e0fa0e194a3e010e4a8a6536895c4f6326bc4d /src/unexec.c | |
| parent | c9a95ab2732f12c2e3c44851dfaf2b6c14b44265 (diff) | |
| download | emacs-52a2b13bc58f493616d53cbe8a2a612b965eafd9.tar.gz emacs-52a2b13bc58f493616d53cbe8a2a612b965eafd9.zip | |
(copy_text_and_data): Add RISCiX changes.
Diffstat (limited to 'src/unexec.c')
| -rw-r--r-- | src/unexec.c | 86 |
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; |