~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to o/unexmips.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Unexec for MIPS (including IRIS4D).
 
2
   Note that the GNU project considers support for MIPS operation
 
3
   a peripheral activity which should not be allowed to divert effort
 
4
   from development of the GNU system.  Changes in this code will be
 
5
   installed when users send them in, but aside from that
 
6
   we don't plan to think about it, or about whether other Emacs
 
7
   maintenance might break it.
 
8
 
 
9
   Copyright (C) 1988, 1994 Free Software Foundation, Inc.
 
10
 
 
11
This file is part of GNU Emacs.
 
12
 
 
13
GNU Emacs is free software; you can redistribute it and/or modify
 
14
it under the terms of the GNU General Public License as published by
 
15
the Free Software Foundation; either version 2, or (at your option)
 
16
any later version.
 
17
 
 
18
GNU Emacs is distributed in the hope that it will be useful,
 
19
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
20
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
21
GNU General Public License for more details.
 
22
 
 
23
You should have received a copy of the GNU General Public License
 
24
along with GNU Emacs; see the file COPYING.  If not, write to
 
25
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
26
 
 
27
 
 
28
#include "config.h"
 
29
#include <sys/types.h>
 
30
#include <sys/file.h>
 
31
#include <sys/stat.h>
 
32
#include <stdio.h>
 
33
#include <filehdr.h>
 
34
#include <aouthdr.h>
 
35
#include <scnhdr.h>
 
36
#include <sym.h>
 
37
 
 
38
#if defined (IRIS_4D) || defined (sony)
 
39
#include "getpagesize.h"
 
40
#include <fcntl.h>
 
41
#endif
 
42
 
 
43
static void fatal_unexec ();
 
44
static void mark_x ();
 
45
 
 
46
#define READ(_fd, _buffer, _size, _error_message, _error_arg) \
 
47
        errno = EEOF; \
 
48
        if (read (_fd, _buffer, _size) != _size) \
 
49
          fatal_unexec (_error_message, _error_arg);
 
50
 
 
51
#define WRITE(_fd, _buffer, _size, _error_message, _error_arg) \
 
52
        if (write (_fd, _buffer, _size) != _size) \
 
53
          fatal_unexec (_error_message, _error_arg);
 
54
 
 
55
#define SEEK(_fd, _position, _error_message, _error_arg) \
 
56
        errno = EEOF; \
 
57
        if (lseek (_fd, _position, L_SET) != _position) \
 
58
          fatal_unexec (_error_message, _error_arg);
 
59
 
 
60
extern int errno;
 
61
extern char *strerror ();
 
62
#define EEOF -1
 
63
 
 
64
static struct scnhdr *text_section;
 
65
static struct scnhdr *init_section;
 
66
static struct scnhdr *finit_section;
 
67
static struct scnhdr *rdata_section;
 
68
static struct scnhdr *xdata_section;
 
69
static struct scnhdr *pdata_section;
 
70
static struct scnhdr *data_section;
 
71
static struct scnhdr *lit8_section;
 
72
static struct scnhdr *lit4_section;
 
73
static struct scnhdr *sdata_section;
 
74
static struct scnhdr *sbss_section;
 
75
static struct scnhdr *bss_section;
 
76
 
 
77
 
 
78
struct headers {
 
79
    struct filehdr fhdr;
 
80
    struct aouthdr aout;
 
81
    struct scnhdr section[16];
 
82
};
 
83
 
 
84
/* Define name of label for entry point for the dumped executable.  */
 
85
 
 
86
#ifndef DEFAULT_ENTRY_ADDRESS
 
87
#define DEFAULT_ENTRY_ADDRESS __start
 
88
#endif
 
89
 
 
90
unexec (new_name, a_name, data_start, bss_start, entry_address)
 
91
     char *new_name, *a_name;
 
92
     unsigned long data_start, bss_start, entry_address;
 
93
{
 
94
  int new, old;
 
95
  long pagesize, brk;
 
96
  long newsyms, symrel;
 
97
  int nread;
 
98
  struct headers hdr;
 
99
  int i;
 
100
  long vaddr, scnptr;
 
101
#define BUFSIZE 8192
 
102
  char buffer[BUFSIZE];
 
103
 
 
104
  old = open (a_name, O_RDONLY, 0);
 
105
  if (old < 0) fatal_unexec ("opening %s", a_name);
 
106
 
 
107
  new = creat (new_name, 0666);
 
108
  if (new < 0) fatal_unexec ("creating %s", new_name);
 
109
 
 
110
  hdr = *((struct headers *)TEXT_START);
 
111
#ifdef MIPS2
 
112
  if (hdr.fhdr.f_magic != MIPSELMAGIC
 
113
      && hdr.fhdr.f_magic != MIPSEBMAGIC
 
114
      && hdr.fhdr.f_magic != (MIPSELMAGIC | 1)
 
115
      && hdr.fhdr.f_magic != (MIPSEBMAGIC | 1))
 
116
    {
 
117
      fprintf (stderr,
 
118
               "unexec: input file magic number is %x, not %x, %x, %x or %x.\n",
 
119
               hdr.fhdr.f_magic,
 
120
               MIPSELMAGIC, MIPSEBMAGIC,
 
121
               MIPSELMAGIC | 1, MIPSEBMAGIC | 1);
 
122
      exit(1);
 
123
    }
 
124
#else /* not MIPS2 */
 
125
#ifdef __alpha
 
126
  if (hdr.fhdr.f_magic != ALPHAMAGIC
 
127
      && hdr.fhdr.f_magic != ALPHAUMAGIC)
 
128
    {
 
129
      fprintf(stderr, "unexec: input file magic number is %x, not %x or %x.\n",
 
130
              hdr.fhdr.f_magic, ALPHAMAGIC, ALPHAUMAGIC);
 
131
      exit(1);
 
132
    }
 
133
#else /* not alpha */
 
134
  if (hdr.fhdr.f_magic != MIPSELMAGIC
 
135
      && hdr.fhdr.f_magic != MIPSEBMAGIC)
 
136
    {
 
137
      fprintf(stderr, "unexec: input file magic number is %x, not %x or %x.\n",
 
138
              hdr.fhdr.f_magic, MIPSELMAGIC, MIPSEBMAGIC);
 
139
      exit(1);
 
140
    }
 
141
#endif /* not alpha */
 
142
#endif /* not MIPS2 */
 
143
 
 
144
  if (hdr.fhdr.f_opthdr != sizeof (hdr.aout))
 
145
    {
 
146
      fprintf (stderr, "unexec: input a.out header is %d bytes, not %d.\n",
 
147
               hdr.fhdr.f_opthdr, sizeof (hdr.aout));
 
148
      exit (1);
 
149
    }
 
150
  if (hdr.aout.magic != ZMAGIC)
 
151
    {
 
152
      fprintf (stderr, "unexec: input file a.out magic number is %o, not %o.\n",
 
153
               hdr.aout.magic, ZMAGIC);
 
154
      exit (1);
 
155
    }
 
156
 
 
157
#define CHECK_SCNHDR(ptr, name, flags) \
 
158
for( i = 0, ptr = NULL; i < hdr.fhdr.f_nscns && !ptr; i++){ \
 
159
    if (hdr.section[i].s_name && strcmp (hdr.section[i].s_name, name) == 0){ \
 
160
       if (hdr.section[i].s_flags != flags) { \
 
161
          fprintf(stderr, "unexec: %x flags (%x expected) in %s section.\n", \
 
162
            hdr.section[i].s_flags, flags, name); \
 
163
        } \
 
164
        ptr = hdr.section + i; \
 
165
     } \
 
166
     if(ptr) \
 
167
         break;\
 
168
}
 
169
       
 
170
 
 
171
  CHECK_SCNHDR (text_section,  _TEXT,  STYP_TEXT);
 
172
  CHECK_SCNHDR (init_section,  _INIT,  STYP_INIT);
 
173
  CHECK_SCNHDR (rdata_section, _RDATA, STYP_RDATA);
 
174
#ifdef _RCONST
 
175
  if (!rdata_section)                   /* OSF/1 V3 adds this */
 
176
      CHECK_SCNHDR (rdata_section, _RCONST, STYP_RCONST);
 
177
#endif
 
178
#ifdef _XDATA
 
179
  CHECK_SCNHDR(xdata_section, _XDATA, STYP_XDATA);
 
180
  CHECK_SCNHDR(pdata_section, _PDATA, STYP_PDATA);
 
181
#endif
 
182
  CHECK_SCNHDR (data_section,  _DATA,  STYP_DATA);
 
183
#ifdef _LIT8
 
184
  CHECK_SCNHDR (lit8_section,  _LIT8,  STYP_LIT8);
 
185
  CHECK_SCNHDR (lit4_section,  _LIT4,  STYP_LIT4);
 
186
#endif /* _LIT8 */
 
187
  CHECK_SCNHDR (sdata_section, _SDATA, STYP_SDATA);
 
188
  CHECK_SCNHDR (sbss_section,  _SBSS,  STYP_SBSS);
 
189
  CHECK_SCNHDR (bss_section,   _BSS,   STYP_BSS);
 
190
#if 0 /* Apparently this error check goes off on irix 3.3,
 
191
         but it doesn't indicate a real problem.  */
 
192
  if (i != hdr.fhdr.f_nscns)
 
193
    fprintf (stderr, "unexec: %d sections found instead of %d.\n",
 
194
             i, hdr.fhdr.f_nscns);
 
195
#endif
 
196
 
 
197
  text_section->s_scnptr = 0;
 
198
 
 
199
  pagesize = getpagesize ();
 
200
  /* Casting to int avoids compiler error on NEWS-OS 5.0.2.  */
 
201
  brk = (((int) (sbrk (0))) + pagesize - 1) & (-pagesize);
 
202
  hdr.aout.dsize = brk - DATA_START;
 
203
  hdr.aout.bsize = 0;
 
204
  if (entry_address == 0)
 
205
    {
 
206
      extern DEFAULT_ENTRY_ADDRESS ();
 
207
      hdr.aout.entry = (unsigned long)DEFAULT_ENTRY_ADDRESS;
 
208
    }
 
209
  else
 
210
    hdr.aout.entry = entry_address;
 
211
 
 
212
  hdr.aout.bss_start = hdr.aout.data_start + hdr.aout.dsize;
 
213
  rdata_section->s_size = data_start - DATA_START;
 
214
 
 
215
  /* Adjust start and virtual addresses of rdata_section, too.  */
 
216
  rdata_section->s_vaddr = DATA_START;
 
217
  rdata_section->s_paddr = DATA_START;
 
218
  rdata_section->s_scnptr = text_section->s_scnptr + hdr.aout.tsize;
 
219
 
 
220
  data_section->s_vaddr = data_start;
 
221
  data_section->s_paddr = data_start;
 
222
  data_section->s_size = brk - data_start;
 
223
  data_section->s_scnptr = rdata_section->s_scnptr + rdata_section->s_size;
 
224
  vaddr = data_section->s_vaddr + data_section->s_size;
 
225
  scnptr = data_section->s_scnptr + data_section->s_size;
 
226
  if (lit8_section != NULL)
 
227
    {
 
228
      lit8_section->s_vaddr = vaddr;
 
229
      lit8_section->s_paddr = vaddr;
 
230
      lit8_section->s_size = 0;
 
231
      lit8_section->s_scnptr = scnptr;
 
232
    }
 
233
  if (lit4_section != NULL)
 
234
    {
 
235
      lit4_section->s_vaddr = vaddr;
 
236
      lit4_section->s_paddr = vaddr;
 
237
      lit4_section->s_size = 0;
 
238
      lit4_section->s_scnptr = scnptr;
 
239
    }
 
240
  if (sdata_section != NULL)
 
241
    {
 
242
      sdata_section->s_vaddr = vaddr;
 
243
      sdata_section->s_paddr = vaddr;
 
244
      sdata_section->s_size = 0;
 
245
      sdata_section->s_scnptr = scnptr;
 
246
    }
 
247
  if (sbss_section != NULL)
 
248
    {
 
249
      sbss_section->s_vaddr = vaddr;
 
250
      sbss_section->s_paddr = vaddr;
 
251
      sbss_section->s_size = 0;
 
252
      sbss_section->s_scnptr = scnptr;
 
253
    }
 
254
  if (bss_section != NULL)
 
255
    {
 
256
      bss_section->s_vaddr = vaddr;
 
257
      bss_section->s_paddr = vaddr;
 
258
      bss_section->s_size = 0;
 
259
      bss_section->s_scnptr = scnptr;
 
260
    }
 
261
 
 
262
  WRITE (new, (char *)TEXT_START, hdr.aout.tsize,
 
263
         "writing text section to %s", new_name);
 
264
  WRITE (new, (char *)DATA_START, hdr.aout.dsize,
 
265
         "writing data section to %s", new_name);
 
266
 
 
267
  SEEK (old, hdr.fhdr.f_symptr, "seeking to start of symbols in %s", a_name);
 
268
  errno = EEOF;
 
269
  nread = read (old, buffer, BUFSIZE);
 
270
  if (nread < sizeof (HDRR)) fatal_unexec ("reading symbols from %s", a_name);
 
271
#define symhdr ((pHDRR)buffer)
 
272
  newsyms = hdr.aout.tsize + hdr.aout.dsize;
 
273
  symrel = newsyms - hdr.fhdr.f_symptr;
 
274
  hdr.fhdr.f_symptr = newsyms;
 
275
  symhdr->cbLineOffset += symrel;
 
276
  symhdr->cbDnOffset += symrel;
 
277
  symhdr->cbPdOffset += symrel;
 
278
  symhdr->cbSymOffset += symrel;
 
279
  symhdr->cbOptOffset += symrel;
 
280
  symhdr->cbAuxOffset += symrel;
 
281
  symhdr->cbSsOffset += symrel;
 
282
  symhdr->cbSsExtOffset += symrel;
 
283
  symhdr->cbFdOffset += symrel;
 
284
  symhdr->cbRfdOffset += symrel;
 
285
  symhdr->cbExtOffset += symrel;
 
286
#undef symhdr
 
287
  do
 
288
    {
 
289
      if (write (new, buffer, nread) != nread)
 
290
        fatal_unexec ("writing symbols to %s", new_name);
 
291
      nread = read (old, buffer, BUFSIZE);
 
292
      if (nread < 0) fatal_unexec ("reading symbols from %s", a_name);
 
293
#undef BUFSIZE
 
294
    } while (nread != 0);
 
295
 
 
296
  SEEK (new, 0, "seeking to start of header in %s", new_name);
 
297
  WRITE (new, &hdr, sizeof (hdr),
 
298
         "writing header of %s", new_name);
 
299
 
 
300
  close (old);
 
301
  close (new);
 
302
  mark_x (new_name);
 
303
}
 
304
 
 
305
/*
 
306
 * mark_x
 
307
 *
 
308
 * After successfully building the new a.out, mark it executable
 
309
 */
 
310
 
 
311
static void
 
312
mark_x (name)
 
313
     char *name;
 
314
{
 
315
  struct stat sbuf;
 
316
  int um = umask (777);
 
317
  umask (um);
 
318
  if (stat (name, &sbuf) < 0)
 
319
    fatal_unexec ("getting protection on %s", name);
 
320
  sbuf.st_mode |= 0111 & ~um;
 
321
  if (chmod (name, sbuf.st_mode) < 0)
 
322
    fatal_unexec ("setting protection on %s", name);
 
323
}
 
324
 
 
325
static void
 
326
fatal_unexec (const char *s, ...)
 
327
{
 
328
  va_list ap;
 
329
  if (errno == EEOF)
 
330
    fputs ("unexec: unexpected end of file, ", stderr);
 
331
  else
 
332
    fprintf (stderr, "unexec: %s, ", strerror (errno));
 
333
  va_start (ap,s);
 
334
  _doprnt (s, ap, stderr);
 
335
  fputs (".\n", stderr);
 
336
  exit (1);
 
337
}
 
338
 
 
339
#ifdef UNIXSAVE
 
340
#include "save.c"
 
341
#endif
 
342