annotate src/unexaix.c @ 771:943eaba38521

[xemacs-hg @ 2002-03-13 08:51:24 by ben] The big ben-mule-21-5 check-in! Various files were added and deleted. See CHANGES-ben-mule. There are still some test suite failures. No crashes, though. Many of the failures have to do with problems in the test suite itself rather than in the actual code. I'll be addressing these in the next day or so -- none of the test suite failures are at all critical. Meanwhile I'll be trying to address the biggest issues -- i.e. build or run failures, which will almost certainly happen on various platforms. All comments should be sent to ben@xemacs.org -- use a Cc: if necessary when sending to mailing lists. There will be pre- and post- tags, something like pre-ben-mule-21-5-merge-in, and post-ben-mule-21-5-merge-in.
author ben
date Wed, 13 Mar 2002 08:54:06 +0000
parents b39c14581166
children 04bc9d2f42c7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 /* Dump an executable image.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2 Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4 This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6 XEmacs is free software; you can redistribute it and/or modify it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7 under the terms of the GNU General Public License as published by the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 Free Software Foundation; either version 2, or (at your option) any
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9 later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17 along with XEmacs; see the file COPYING. If not, write to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 Boston, MA 02111-1307, USA. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 /* Synched up with: FSF 20.2. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 647
diff changeset
23 /* This file has been ... uhhhhh ... Mule-ized. Yeah.
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 647
diff changeset
24
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 647
diff changeset
25 (Everything here is external format. That's potentially dangerous,
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 647
diff changeset
26 but in practice it'll be OK.) --ben */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 647
diff changeset
27
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28 /* Originally based on the COFF unexec.c by Spencer W. Thomas.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30 * Subsequently hacked on by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31 * Bill Mann <Bill_Man@praxisint.com>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 * Andrew Vignaux <Andrew.Vignaux@comp.vuw.ac.nz>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 * Mike Sperber <sperber@informatik.uni-tuebingen.de>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 * Synopsis:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 * unexec (new_name, a_name, data_start, bss_start, entry_address)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 * char *new_name, *a_name;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 * unsigned data_start, bss_start, entry_address;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 * Takes a snapshot of the program and makes an a.out format file in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 * file named by the string argument new_name.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 * If a_name is non-NULL, the symbol table will be taken from the given file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 * On some machines, an existing a_name file is required.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 * data_start and entry_address are ignored.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 * bss_start indicates how much of the data segment is to be saved in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 * a.out file and restored when the program is executed. It gives the lowest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 * unsaved address, and is rounded up to a page boundary. The default when 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 * is given assumes that the entire data segment is to be stored, including
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51 * the previous data and bss as well as any additional storage allocated with
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 * sbrk(2).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 #ifndef emacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 #define PERROR(arg) perror (arg); return -1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 #else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 #include <config.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 #define PERROR(file) report_error (file, new)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63 #include <a.out.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 /* Define getpagesize () if the system does not.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 Note that this may depend on symbols defined in a.out.h
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 #include "getpagesize.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 #include <sys/types.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 #include <stdio.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71 #include <sys/stat.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 #include <errno.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 #include <unistd.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 #include <fcntl.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 extern char *start_of_text (void); /* Start of text */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 extern char *start_of_data (void); /* Start of initialized data */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 extern int _data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 extern int _text;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 #include <filehdr.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 #include <aouthdr.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 #include <scnhdr.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85 #include <syms.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 static struct filehdr f_hdr; /* File header */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 static struct aouthdr f_ohdr; /* Optional file header (a.out) */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 static long bias; /* Bias to add for growth */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90 static long lnnoptr; /* Pointer to line-number info within file */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 static long text_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 static long data_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 #define ALIGN(val, pwr) (((val) + ((1L<<(pwr))-1)) & ~((1L<<(pwr))-1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 static long load_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 static long orig_load_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 static long orig_data_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 static int unrelocate_symbols (int, int, char *, char *);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 #ifndef MAX_SECTIONS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 #define MAX_SECTIONS 10
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 static int adjust_lnnoptrs (int, int, char *);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 static int pagemask;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 /* Correct an int which is the bit pattern of a pointer to a byte
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 into an int which is the number of a byte.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 This is a no-op on ordinary machines, but not on all. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 #ifndef ADDR_CORRECT /* Let m-*.h files override this definition */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 #define ADDR_CORRECT(x) ((char *)(x) - (char*)0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 #ifdef emacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 #include "lisp.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 report_error (char *file, int fd)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122 if (fd)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 close (fd);
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 438
diff changeset
124 report_error_with_errno (Qio_error, "Cannot unexec",
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 438
diff changeset
125 build_string (file));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 #endif /* emacs */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 #define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 #define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 #define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 report_error_1 (int fd, char *msg, int a1, int a2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 close (fd);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 #ifdef emacs
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 438
diff changeset
138 signal_ferror (Qio_error, msg, a1, a2);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 #else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 fprintf (stderr, msg, a1, a2);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 fprintf (stderr, "\n");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 static int make_hdr (int, int, unsigned, unsigned, unsigned, char *, char *);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 static void mark_x (char *);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 static int copy_text_and_data (int);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 static int copy_sym (int, int, char *, char *);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 static void write_segment (int, char *, char *);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 /* ****************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 * unexec
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 * driving logic.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 int unexec (char *new_name, char *a_name,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 uintptr_t data_start,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 uintptr_t bss_start,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 uintptr_t entry_address)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 int new = -1, a_out = -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 if (a_name && (a_out = open (a_name, O_RDONLY)) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 PERROR (a_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 if ((new = creat (new_name, 0666)) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 PERROR (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 if (make_hdr (new, a_out,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 data_start, bss_start,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 entry_address,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 a_name, new_name) < 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 || copy_text_and_data (new) < 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 || copy_sym (new, a_out, a_name, new_name) < 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 || adjust_lnnoptrs (new, a_out, new_name) < 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 || unrelocate_symbols (new, a_out, a_name, new_name) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 close (new);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 close (new);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 if (a_out >= 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 close (a_out);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 mark_x (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 /* ****************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 * make_hdr
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 * Make the header in the new a.out from the header in core.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 * Modify the text and data sizes.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 make_hdr (int new, int a_out,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 unsigned data_start, unsigned bss_start,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 unsigned entry_address,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 char *a_name, char *new_name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 int scns;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 unsigned int bss_end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 struct scnhdr section[MAX_SECTIONS];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 struct scnhdr * f_thdr; /* Text section header */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 struct scnhdr * f_dhdr; /* Data section header */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 struct scnhdr * f_bhdr; /* Bss section header */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 struct scnhdr * f_lhdr; /* Loader section header */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 struct scnhdr * f_tchdr; /* Typechk section header */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 struct scnhdr * f_dbhdr; /* Debug section header */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 struct scnhdr * f_xhdr; /* Except section header */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 load_scnptr = orig_load_scnptr = lnnoptr = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 pagemask = getpagesize () - 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 /* Adjust text/data boundary. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 data_start = (long) start_of_data ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 data_start = ADDR_CORRECT (data_start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 data_start = data_start & ~pagemask; /* (Down) to page boundary. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 bss_end = ADDR_CORRECT (sbrk (0)) + pagemask;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 bss_end &= ~ pagemask;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 /* Adjust data/bss boundary. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 if (bss_start != 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 bss_start = (ADDR_CORRECT (bss_start) + pagemask);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 /* (Up) to page bdry. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 bss_start &= ~ pagemask;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 if (bss_start > bss_end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 ERROR1 ("unexec: Specified bss_start (%u) is past end of program",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235 bss_start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 bss_start = bss_end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 if (data_start > bss_start) /* Can't have negative data size. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 ERROR2 ("unexec: data_start (%u) can't be greater than bss_start (%u)",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 data_start, bss_start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 /* Salvage as much info from the existing file as possible */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 f_thdr = NULL; f_dhdr = NULL; f_bhdr = NULL;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 f_lhdr = NULL; f_tchdr = NULL; f_dbhdr = NULL; f_xhdr = NULL;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 if (a_out >= 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 PERROR (a_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 if (f_hdr.f_opthdr > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 if (read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 PERROR (a_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 if (f_hdr.f_nscns > MAX_SECTIONS)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 ERROR0 ("unexec: too many section headers -- increase MAX_SECTIONS");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 /* Loop through section headers */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 for (scns = 0; scns < f_hdr.f_nscns; scns++) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 struct scnhdr *s = &section[scns];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 if (read (a_out, s, sizeof (*s)) != sizeof (*s))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 PERROR (a_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 #define CHECK_SCNHDR(ptr, name, flags) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 if (strcmp(s->s_name, name) == 0) { \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 if (s->s_flags != flags) { \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 fprintf(stderr, "unexec: %lx flags where %x expected in %s section.\n", \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 (unsigned long)s->s_flags, flags, name); \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 } \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281 if (ptr) { \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 fprintf(stderr, "unexec: duplicate section header for section %s.\n", \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 name); \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 } \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 ptr = s; \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 CHECK_SCNHDR(f_thdr, _TEXT, STYP_TEXT);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 CHECK_SCNHDR(f_dhdr, _DATA, STYP_DATA);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 CHECK_SCNHDR(f_bhdr, _BSS, STYP_BSS);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 CHECK_SCNHDR(f_lhdr, _LOADER, STYP_LOADER);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 CHECK_SCNHDR(f_dbhdr, _DEBUG, STYP_DEBUG);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 CHECK_SCNHDR(f_tchdr, _TYPCHK, STYP_TYPCHK);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 CHECK_SCNHDR(f_xhdr, _EXCEPT, STYP_EXCEPT);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 if (f_thdr == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 ERROR1 ("unexec: couldn't find \"%s\" section", (int) _TEXT);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 if (f_dhdr == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302 ERROR1 ("unexec: couldn't find \"%s\" section", (int) _DATA);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 if (f_bhdr == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 ERROR1 ("unexec: couldn't find \"%s\" section", (int) _BSS);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 ERROR0 ("can't build a COFF file from scratch yet");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 orig_data_scnptr = f_dhdr->s_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 orig_load_scnptr = f_lhdr ? f_lhdr->s_scnptr : 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316 /* Now we alter the contents of all the f_*hdr variables
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 to correspond to what we want to dump. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 /* Indicate that the reloc information is no longer valid for ld (bind);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 we only update it enough to fake out the exec-time loader. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321 f_hdr.f_flags |= (F_RELFLG | F_EXEC);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 f_ohdr.dsize = bss_start - f_ohdr.data_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 f_ohdr.bsize = bss_end - bss_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 f_dhdr->s_size = f_ohdr.dsize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 f_bhdr->s_size = f_ohdr.bsize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 f_bhdr->s_paddr = f_ohdr.data_start + f_ohdr.dsize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 f_bhdr->s_vaddr = f_ohdr.data_start + f_ohdr.dsize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 /* fix scnptr's */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 ulong ptr = section[0].s_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 bias = -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 for (scns = 0; scns < f_hdr.f_nscns; scns++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 struct scnhdr *s = &section[scns];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 if (s->s_flags & STYP_PAD) /* .pad sections omitted in AIX 4.1 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 * the text_start should probably be o_algntext but that doesn't
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 * seem to change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 if (f_ohdr.text_start != 0) /* && scns != 0 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 s->s_size = 512 - (ptr % 512);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 if (s->s_size == 512)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 s->s_size = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 s->s_scnptr = ptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 else if (s->s_flags & STYP_DATA)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 s->s_scnptr = ptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 else if (!(s->s_flags & (STYP_TEXT | STYP_BSS)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 if (bias == -1) /* if first section after bss */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 bias = ptr - s->s_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 s->s_scnptr += bias;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 ptr = s->s_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 ptr = ptr + s->s_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 /* fix other pointers */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 for (scns = 0; scns < f_hdr.f_nscns; scns++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372 struct scnhdr *s = &section[scns];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 if (s->s_relptr != 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 s->s_relptr += bias;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 if (s->s_lnnoptr != 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 if (lnnoptr == 0) lnnoptr = s->s_lnnoptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 s->s_lnnoptr += bias;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 if (f_hdr.f_symptr > 0L)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 f_hdr.f_symptr += bias;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 text_scnptr = f_thdr->s_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 data_scnptr = f_dhdr->s_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 load_scnptr = f_lhdr ? f_lhdr->s_scnptr : 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 if (write (new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 PERROR (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 if (f_hdr.f_opthdr > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 if (write (new, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 PERROR (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 for (scns = 0; scns < f_hdr.f_nscns; scns++) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408 struct scnhdr *s = &section[scns];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409 if (write (new, s, sizeof (*s)) != sizeof (*s))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 PERROR (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
414
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
415 return (0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
418 /* ****************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
420 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
421 * Copy the text and data segments from memory to the new a.out
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
423 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 copy_text_and_data (int new)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426 char *end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427 char *ptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429 lseek (new, (long) text_scnptr, SEEK_SET);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
430 ptr = start_of_text () + text_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431 end = ptr + f_ohdr.tsize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 write_segment (new, ptr, end);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 lseek (new, (long) data_scnptr, SEEK_SET);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435 ptr = (char *) f_ohdr.data_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 end = ptr + f_ohdr.dsize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 write_segment (new, ptr, end);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
439 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 #define UnexBlockSz (1<<12) /* read/write block size */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 write_segment (int new, char *ptr, char *end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
446 int i, nwrite, ret;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447 char buf[80];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 char zeros[UnexBlockSz];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 for (i = 0; ptr < end;)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452 /* distance to next block. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 nwrite = (((int) ptr + UnexBlockSz) & -UnexBlockSz) - (int) ptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454 /* But not beyond specified end. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 if (nwrite > end - ptr) nwrite = end - ptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 ret = write (new, ptr, nwrite);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457 /* If write gets a page fault, it means we reached
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458 a gap between the old text segment and the old data segment.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459 This gap has probably been remapped into part of the text segment.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 So write zeros for it. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 if (ret == -1 && errno == EFAULT)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463 memset (zeros, 0, nwrite);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 write (new, zeros, nwrite);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 else if (nwrite != ret)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 sprintf (buf,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469 "unexec write failure: addr 0x%lx, fileno %d, size 0x%x, wrote 0x%x, errno %d",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 (unsigned long)ptr, new, nwrite, ret, errno);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 PERROR (buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 i += nwrite;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 ptr += nwrite;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478 /* ****************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 * copy_sym
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 * Copy the relocation information and symbol table from the a.out to the new
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 copy_sym (int new, int a_out, char *a_name, char *new_name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486 char page[UnexBlockSz];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 int n;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489 if (a_out < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492 if (orig_load_scnptr == 0L)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495 if (lnnoptr && lnnoptr < orig_load_scnptr) /* if there is line number info */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 lseek (a_out, lnnoptr, SEEK_SET); /* start copying from there */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 lseek (a_out, orig_load_scnptr, SEEK_SET); /* Position a.out to symtab. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 563
diff changeset
500 while ((n = read (a_out, page, sizeof (page))) > 0)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502 if (write (new, page, n) != n)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504 PERROR (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 if (n < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 PERROR (a_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 /* ****************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 * mark_x
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 * After successfully building the new a.out, mark it executable
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 mark_x (char *name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 struct stat sbuf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
523 int um;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 int new = 0; /* for PERROR */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 um = umask (777);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 umask (um);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 if (stat (name, &sbuf) == -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 PERROR (name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 sbuf.st_mode |= 0111 & ~um;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 if (chmod (name, sbuf.st_mode) == -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 PERROR (name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 adjust_lnnoptrs (int writedesc, int readdesc, char *new_name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
540 int nsyms;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 int naux;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 int new;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
543 struct syment symentry;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544 union auxent auxentry;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
546 if (!lnnoptr || !f_hdr.f_symptr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
548
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
549 if ((new = open (new_name, O_RDWR)) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
550 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
551 PERROR (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
552 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
553 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
554
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555 lseek (new, f_hdr.f_symptr, SEEK_SET);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
556 for (nsyms = 0; nsyms < f_hdr.f_nsyms; nsyms++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
558 read (new, &symentry, SYMESZ);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
559 if (symentry.n_sclass == C_BINCL || symentry.n_sclass == C_EINCL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
560 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
561 symentry.n_value += bias;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562 lseek (new, -SYMESZ, SEEK_CUR);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
563 write (new, &symentry, SYMESZ);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
564 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
565
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
566 for (naux = symentry.n_numaux; naux-- != 0; )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
567 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
568 read (new, &auxentry, AUXESZ);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569 nsyms++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
570 if (naux != 0 /* skip csect auxentry (last entry) */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 && (symentry.n_sclass == C_EXT || symentry.n_sclass == C_HIDEXT))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
573 auxentry.x_sym.x_fcnary.x_fcn.x_lnnoptr += bias;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
574 lseek (new, -AUXESZ, SEEK_CUR);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
575 write (new, &auxentry, AUXESZ);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
576 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
577 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
578 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
579 close (new);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
581 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
583
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
584 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
585 unrelocate_symbols (int new, int a_out, char *a_name, char *new_name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
586 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
587 int i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
588 LDHDR ldhdr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
589 LDREL ldrel;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
590 ulong t_reloc = (ulong) &_text - f_ohdr.text_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591 #ifndef ALIGN_DATA_RELOC
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
592 ulong d_reloc = (ulong) &_data - f_ohdr.data_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593 #else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
594 /* This worked (and was needed) before AIX 4.2.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
595 I have no idea why. -- Mike */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 ulong d_reloc = (ulong) &_data - ALIGN(f_ohdr.data_start, 2);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 int * p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
599
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 if (load_scnptr == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
601 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
602
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
603 lseek (a_out, orig_load_scnptr, SEEK_SET);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604 if (read (a_out, &ldhdr, sizeof (ldhdr)) != sizeof (ldhdr))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
606 PERROR (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
607 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
608
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
609 #define SYMNDX_TEXT 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
610 #define SYMNDX_DATA 1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
611 #define SYMNDX_BSS 2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
612
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
613 for (i = 0; i < ldhdr.l_nreloc; i++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
614 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
615 lseek (a_out,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
616 orig_load_scnptr + LDHDRSZ + LDSYMSZ*ldhdr.l_nsyms + LDRELSZ*i,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617 SEEK_SET);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619 if (read (a_out, &ldrel, LDRELSZ) != LDRELSZ)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
620 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
621 PERROR (a_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
622 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
623
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
624 /* move the BSS loader symbols to the DATA segment */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
625 if (ldrel.l_symndx == SYMNDX_BSS)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
626 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
627 ldrel.l_symndx = SYMNDX_DATA;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
628
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
629 lseek (new,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
630 load_scnptr + LDHDRSZ + LDSYMSZ*ldhdr.l_nsyms + LDRELSZ*i,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
631 SEEK_SET);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
632
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
633 if (write (new, &ldrel, LDRELSZ) != LDRELSZ)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
634 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
635 PERROR (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
636 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
637 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
638
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
639 if (ldrel.l_rsecnm == f_ohdr.o_sndata)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
640 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
641 int orig_int;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
642
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
643 lseek (a_out,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
644 orig_data_scnptr + (ldrel.l_vaddr - f_ohdr.data_start),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
645 SEEK_SET);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
646
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
647 if (read (a_out, (void *) &orig_int, sizeof (orig_int))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
648 != sizeof (orig_int))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
649 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
650 PERROR (a_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
651 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
652
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
653 p = (int *) (ldrel.l_vaddr + d_reloc);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
654
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
655 switch (ldrel.l_symndx) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
656 case SYMNDX_TEXT:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
657 orig_int = * p - t_reloc;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
658 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
659
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
660 case SYMNDX_DATA:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
661 case SYMNDX_BSS:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
662 orig_int = * p - d_reloc;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
663 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
664 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
665
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
666 if (orig_int != * p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
667 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
668 lseek (new,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
669 data_scnptr + (ldrel.l_vaddr - f_ohdr.data_start),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
670 SEEK_SET);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
671 if (write (new, (void *) &orig_int, sizeof (orig_int))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
672 != sizeof (orig_int))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
673 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
674 PERROR (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
675 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
676 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
677 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
678 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
679 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
680 }