Mercurial > emacs
changeset 9017:de17ae9463e3
(copy_text_and_data): Add RISCiX changes.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Fri, 23 Sep 1994 06:18:31 +0000 |
parents | 160a90eaa7d8 |
children | e8f02eb00bbf |
files | src/unexec.c |
diffstat | 1 files changed, 86 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/unexec.c Fri Sep 23 05:44:28 1994 +0000 +++ b/src/unexec.c Fri Sep 23 06:18:31 1994 +0000 @@ -909,9 +909,95 @@ lseek (new, (long) N_TXTOFF (hdr), 0); #endif /* no A_TEXT_SEEK */ +#ifdef RISCiX + + /* Acorn's RISC-iX has a wacky way of initialising the position of the heap. + * There is a little table in crt0.o that is filled at link time with + * the min and current brk positions, among other things. When start() + * runs, it copies the table to where these parameters live during + * execution. This data is in text space, so it cannot be modified here + * before saving the executable, so the data is written manually. In + * addition, the table does not have a label, and the nearest accessable + * label (mcount) is not prefixed with a '_', thus making it inaccessable + * from within C programs. To overcome this, emacs's executable is passed + * through the command 'nm %s | fgrep mcount' into a pipe, and the + * resultant output is then used to find the address of 'mcount'. As far as + * is possible to determine, in RISC-iX releases prior to 1.2, the negative + * offset of the table from mcount is 0x2c, whereas from 1.2 onwards it is + * 0x30. bss_end has been rounded up to page boundary. This solution is + * based on suggestions made by Kevin Welton and Steve Hunt of Acorn, and + * avoids the need for a custom version of crt0.o for emacs which has its + * table in data space. + */ + + { + char command[1024]; + char errbuf[1024]; + char address_text[32]; + int proforma[4]; + FILE *pfile; + char *temp_ptr; + char c; + int mcount_address, mcount_offset, count; + extern char *_execname; + + + /* The use of _execname is incompatible with RISCiX 1.1 */ + sprintf (command, "nm %s | fgrep mcount", _execname); + + if ( (pfile = popen(command, "r")) == NULL) + { + sprintf (errbuf, "Could not open pipe"); + PERROR (errbuf); + } + + count=0; + while ( ((c=getc(pfile)) != EOF) && (c != ' ') && (count < 31)) + address_text[count++]=c; + address_text[count]=0; + + if ((count == 0) || pclose(pfile) != NULL) + { + sprintf (errbuf, "Failed to execute the command '%s'\n", command); + PERROR (errbuf); + } + + sscanf(address_text, "%x", &mcount_address); + ptr = (char *) unexec_text_start; + mcount_offset = (char *)mcount_address - ptr; + +#ifdef RISCiX_1_1 +#define EDATA_OFFSET 0x2c +#else +#define EDATA_OFFSET 0x30 +#endif + + end = ptr + mcount_offset - EDATA_OFFSET; + printf ("Writing from %08x to %08x\n", ptr, end); + + write_segment (new, ptr, end); + + proforma[0] = bss_end; /* becomes _edata */ + proforma[1] = bss_end; /* becomes _end */ + proforma[2] = bss_end; /* becomes _minbrk */ + proforma[3] = bss_end; /* becomes _curbrk */ + + puts ("Writing 'args_proforma' (16 bytes)"); + write (new, proforma, 16); + + temp_ptr = ptr; + ptr = end + 16; + end = temp_ptr + hdr.a_text; + + printf ("Writing from %08x to %08x\n", ptr, end); + write_segment (new, ptr, end); + } + +#else /* !RISCiX */ ptr = (char *) unexec_text_start; end = ptr + hdr.a_text; write_segment (new, ptr, end); +#endif /* RISCiX */ ptr = (char *) unexec_data_start; end = ptr + hdr.a_data;