annotate src/unexsunos4.c @ 3767:6b2ef948e140

[xemacs-hg @ 2006-12-29 18:09:38 by aidan] etc/ChangeLog addition: 2006-12-21 Aidan Kehoe <kehoea@parhasard.net> * unicode/unicode-consortium/8859-7.TXT: Update the mapping to the 2003 version of ISO 8859-7. lisp/ChangeLog addition: 2006-12-21 Aidan Kehoe <kehoea@parhasard.net> * mule/cyrillic.el: * mule/cyrillic.el (iso-8859-5): * mule/cyrillic.el (cyrillic-koi8-r-encode-table): Add syntax, case support for Cyrillic; make some parentheses more Lispy. * mule/european.el: Content moved to latin.el, file deleted. * mule/general-late.el: If Unicode tables are to be loaded at dump time, do it here, not in loadup.el. * mule/greek.el: Add syntax, case support for Greek. * mule/latin.el: Move the content of european.el here. Change the case table mappings to use hexadecimal codes, to make cross reference to the standards easier. In all cases, take character syntax from similar characters in Latin-1 , rather than deciding separately what syntax they should take. Add (incomplete) support for case with Turkish. Remove description of the character sets used from the language environments' doc strings, since now that we create variant language environments on the fly, such descriptions will often be inaccurate. Set the native-coding-system language info property while setting the other coding-system properties of the language. * mule/misc-lang.el (ipa): Remove the language environment. The International Phonetic _Alphabet_ is not a language, it's inane to have a corresponding language environment in XEmacs. * mule/mule-cmds.el (create-variant-language-environment): Also modify the coding-priority when creating a new language environment; document that. * mule/mule-cmds.el (get-language-environment-from-locale): Recognise that the 'native-coding-system language-info property can be a list, interpret it correctly when it is one. 2006-12-21 Aidan Kehoe <kehoea@parhasard.net> * coding.el (coding-system-category): Use the new 'unicode-type property for finding what sort of Unicode coding system subtype a coding system is, instead of the overshadowed 'type property. * dumped-lisp.el (preloaded-file-list): mule/european.el has been removed. * loadup.el (really-early-error-handler): Unicode tables loaded at dump time are now in mule/general-late.el. * simple.el (count-lines): Add some backslashes to to parentheses in docstrings to help fontification along. * simple.el (what-cursor-position): Wrap a line to fit in 80 characters. * unicode.el: Use the 'unicode-type property, not 'type, for setting the Unicode coding-system subtype. src/ChangeLog addition: 2006-12-21 Aidan Kehoe <kehoea@parhasard.net> * file-coding.c: Update the make-coding-system docstring to reflect unicode-type * general-slots.h: New symbol, unicode-type, since 'type was being overridden when accessing a coding system's Unicode subtype. * intl-win32.c: Backslash a few parentheses, to help fontification along. * intl-win32.c (complex_vars_of_intl_win32): Use the 'unicode-type symbol, not 'type, when creating the Microsoft Unicode coding system. * unicode.c (unicode_putprop): * unicode.c (unicode_getprop): * unicode.c (unicode_print): Using 'type as the property name when working out what Unicode subtype a given coding system is was broken, since there's a general coding system property called 'type. Change the former to use 'unicode-type instead.
author aidan
date Fri, 29 Dec 2006 18:09:51 +0000
parents 04bc9d2f42c7
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1 /* Code to do an unexec for Sun O/S 4.1 for a temacs linked -Bdynamic.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
2 Copyright (C) 1992, 1993 Free Software Foundation, Inc.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
3
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
4 This file is part of XEmacs.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
5
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
6 XEmacs is free software; you can redistribute it and/or modify it
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
7 under the terms of the GNU General Public License as published by the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
8 Free Software Foundation; either version 2, or (at your option) any
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
9 later version.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
10
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
14 for more details.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
15
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
17 along with XEmacs; see the file COPYING. If not, write to
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
19 Boston, MA 02111-1307, USA. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
20
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
21 /* Synched up with: Not synched with FSF. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
22
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
23 /*
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
24 Created 29-Oct-92 by Harlan Sexton
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
25 Tweaked 06-Aug-93 by Dean Michaels to work with sun3.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
26 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
27
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
28 /********************** Included .h Files **************************/
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
29
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
30 #include <config.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
31
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
32 /* I don't understand this, but it's necessary to get some slots in struct exec
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
33 from /usr/include/sys/exec.h when running LCC in strict ANSI mode. We don't
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
34 need this in K&R mode...
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
35 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
36 #if defined(__lucid) && defined(__sparc) && !defined(sun)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
37 # define sun 1
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
38 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
39
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
40 #include <stdarg.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
41 #include <sys/param.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
42 #include <sys/mman.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
43 #include <sys/file.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
44 #include <sys/stat.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
45 #include <sys/types.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
46 #include <string.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
47 #include <stdio.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
48 #include <a.out.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
49 #include <unistd.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
50 #include <ctype.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
51 #include <stab.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
52 #include <sys/dir.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
53 #include <link.h>
2286
04bc9d2f42c7 [xemacs-hg @ 2004-09-20 19:18:55 by james]
james
parents: 853
diff changeset
54 #include "compiler.h"
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
55
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
56 /********************** Macros *************************************/
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
57
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
58 #define SYS_ERR \
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
59 ((errno > 0)?((errno < sys_nerr)?(sys_errlist[errno]):\
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
60 "unknown system error"): "unknown error")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
61
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
62 #define MASK_UP(x,p_of_two) \
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
63 ((((unsigned long) (x)) + ((p_of_two) - 1)) & (~((p_of_two) - 1)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
64
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
65 #define MASK_DOWN(x,p_of_two) (((unsigned long) (x)) & (~((p_of_two) - 1)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
66
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
67 #ifndef mc68020
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
68 #define relocation_info reloc_info_sparc
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
69 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
70
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
71 /********************** Typedefs and Structs ***********************/
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
72
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
73 struct translation_struct
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
74 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
75 long txtaddr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
76 long txtoff;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
77 long dataddr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
78 long datoff;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
79 long bssaddr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
80 };
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
81
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
82 /********************** Function Prototypes/Declarations ***********/
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
83
398
74fd4e045ea6 Import from CVS: tag r21-2-29
cvs
parents: 0
diff changeset
84 static void unexec_error (const char *m, int use_errno, ...);
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
85 static int unexec_open (char *filename, int flag, int mode);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
86 static caddr_t unexec_mmap (int fd, size_t len, int prot, int flags);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
87 static long unexec_seek (int fd, long position);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
88 static void unexec_read (int fd, long position, char *buf, int bytes);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
89 static void unexec_write (int fd, long position, char *buf, int bytes);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
90 static void unexec_pad (int fd, int bytes);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
91 static void unexec_fstat (int fd, struct stat *statptr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
92 static void unexec_fchmod (int fd, int mode);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
93 static long unexec_addr_to_offset (long addr, struct translation_struct *ts);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
94 static void copy_relocation_site (struct relocation_info *ri,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
95 caddr_t from_base_addr,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
96 caddr_t to_base_addr,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
97 struct translation_struct *ts);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
98 static void reset_symtab (struct nlist *start, struct nlist *end,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
99 char *strtab, long edata_value, long end_value,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
100 int ld_so_table, int shlib_image);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
101 int run_time_remap (char *dummy);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
102
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
103 /********************** Variables **********************************/
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
104
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
105 /* for reporting error messages from system calls */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
106 extern int sys_nerr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
107 extern char *sys_errlist[];
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
108 extern int errno;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
109 extern int _DYNAMIC;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
110 extern char **environ;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
111
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
112 static unsigned long mprotect_bottom_addr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
113 static unsigned long mprotect_top_addr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
114
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
115 static unsigned long sbrk_of_0_at_unexec;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
116
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
117 /*******************************************************************/
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
118
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
119 static void
398
74fd4e045ea6 Import from CVS: tag r21-2-29
cvs
parents: 0
diff changeset
120 unexec_error (const char *fmt, int use_errno, ...)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
121 {
398
74fd4e045ea6 Import from CVS: tag r21-2-29
cvs
parents: 0
diff changeset
122 const char *err_msg = SYS_ERR;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
123 va_list args;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
124
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
125 fprintf (stderr, "unexec - ");
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
126 va_start (args, use_errno);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
127 vfprintf (stderr, fmt, args);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
128 va_end (args);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
129
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
130 if (use_errno)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
131 fprintf (stderr, ": %s", err_msg);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
132 fprintf (stderr, "\n");
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
133 exit (1);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
134 return;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
135 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
136
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
137 static int
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
138 unexec_open (char *filename, int flag, int mode)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
139 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
140 int fd;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
141
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
142 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
143
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
144 fd = open (filename, flag, mode);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
145
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
146 if (fd < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
147 unexec_error ("Failure opening file %s", 1, (void *) filename, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
148 return fd;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
149 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
150
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
151 static caddr_t
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
152 unexec_mmap (int fd, size_t len, int prot, int flags)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
153 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
154 caddr_t return_val;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
155
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
156 unexec_seek (fd, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
157 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
158 return_val = mmap (0, len, prot, flags, fd, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
159
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
160 if (return_val == (caddr_t) -1)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
161 unexec_error ("Failure mmap'ing file", 1, 0, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
162 return return_val;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
163 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
164
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
165
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
166 static long
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
167 unexec_seek (int fd, long position)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
168 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
169 long seek_value;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
170
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
171 if (fd <= 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
172 unexec_error ("No file open in which to seek", 0, 0, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
173
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
174 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
175
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
176 if (position < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
177 seek_value = (long) lseek (fd, 0, L_INCR);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
178 else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
179 seek_value = (long) lseek (fd, position, L_SET);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
180
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
181 if (seek_value < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
182 unexec_error ("Failed to do a seek to 0x%x in %s", 1,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
183 (char *) position, "unexec() output file", 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
184
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
185 return seek_value;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
186 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
187
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
188 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
189 unexec_read (int fd, long position, char *buf, int bytes)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
190 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
191 int n_read;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
192 int remains = bytes;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
193 position = unexec_seek (fd, position);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
194
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
195 if (bytes < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
196 unexec_error ("Attempted read of %d bytes", 0, (char *) bytes, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
197
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
198 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
199
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
200 while (remains > 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
201 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
202 n_read = read (fd, buf, remains);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
203 if (n_read <= 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
204 unexec_error ("Read failed for 0x%x bytes at offset 0x%x in %s",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
205 1, (char *) bytes, (char *) position,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
206 "unexec() output file");
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
207 buf += n_read;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
208 remains -= n_read;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
209 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
210
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
211 return;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
212 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
213
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
214 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
215 unexec_write (int fd, long position, char *buf, int bytes)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
216 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
217 int n_written;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
218 int remains = bytes;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
219 position = unexec_seek (fd, position);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
220
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
221 if (bytes < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
222 unexec_error ("Attempted write of %d bytes in %s",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
223 0, (char *) bytes, "unexec() output file", 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
224
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
225 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
226
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
227 while (remains > 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
228 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
229 n_written = write (fd, buf, remains);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
230 if (n_written <= 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
231 unexec_error ("Write failed for 0x%x bytes at offset 0x%x in %s",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
232 1, (char *) bytes, (char *) position,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
233 "unexec() output file");
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
234 buf += n_written;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
235 remains -= n_written;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
236 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
237
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
238 return;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
239 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
240
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
241 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
242 unexec_pad (int fd, int bytes)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
243 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
244 if (bytes > 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
245 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
246 char buf[1024];
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
247 int remaining = bytes;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
248
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
249 memset (buf, 0, sizeof (buf));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
250
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
251 while (remaining > 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
252 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
253 int this_write = (remaining > sizeof(buf))?sizeof(buf):remaining;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
254 unexec_write (fd, -1, buf, this_write);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
255 remaining -= this_write;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
256 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
257 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
258 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
259
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
260 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
261 unexec_fstat (int fd, struct stat *statptr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
262 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
263 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
264 if (-1 == fstat (fd, statptr))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
265 unexec_error ("fstat() failed for descriptor %d", 1, (char *) fd, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
266 return;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
267 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
268
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
269 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
270 unexec_fchmod (int fd, int mode)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
271 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
272 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
273 if (-1 == fchmod (fd, mode))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
274 unexec_error ("fchmod() failed for descriptor %d", 1, (char *) fd, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
275 return;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
276 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
277
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
278 static long
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
279 unexec_addr_to_offset (long addr, struct translation_struct *ts)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
280
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
281 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
282 if ((addr < ts->txtaddr) || (addr >= ts->bssaddr))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
283 unexec_error ("bad address 0x%x to addr_to_offset()",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
284 0, (char *) addr, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
285 if (addr >= ts->dataddr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
286 return ((long) ((addr - ts->dataddr) + ts->datoff));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
287 else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
288 return ((long) ((addr - ts->txtaddr) + ts->txtoff));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
289 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
290
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
291
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
292 /*
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
293 * "LD.SO" DATA AND SYMBOL TABLE OPERATIONS
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
294 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
295
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
296 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
297 copy_relocation_site (struct relocation_info *ri,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
298 caddr_t from_base_addr,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
299 caddr_t to_base_addr,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
300 struct translation_struct *ts)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
301 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
302 long offset = unexec_addr_to_offset (ri->r_address, ts);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
303 caddr_t from = from_base_addr + offset;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
304 caddr_t to = to_base_addr + offset;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
305
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
306 #ifdef mc68020
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
307 #define r_type r_length
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
308 #endif /* mc68020 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
309 switch (ri->r_type)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
310 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
311 #ifdef mc68020
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
312 case 0:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
313 *((char *) to) = *((char *) from);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
314 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
315 case 1:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
316 *((short *) to) = *((short *) from);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
317 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
318 case 2:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
319 *((long *) to) = *((long *) from);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
320 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
321 #else /* !mc68020 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
322 case RELOC_8:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
323 case RELOC_DISP8:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
324 *((char *) to) = *((char *) from);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
325 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
326 case RELOC_16:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
327 case RELOC_DISP16:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
328 *((short *) to) = *((short *) from);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
329 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
330 case RELOC_LO10:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
331 case RELOC_13:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
332 case RELOC_22:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
333 case RELOC_HI22:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
334 case RELOC_WDISP22:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
335 case RELOC_WDISP30:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
336 case RELOC_32:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
337 case RELOC_DISP32:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
338 case RELOC_GLOB_DAT:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
339 *((long *) to) = *((long *) from);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
340 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
341 case RELOC_JMP_SLOT:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
342 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
343 long *target = (long *) to;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
344 long *source = (long *) from;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
345 *target = *source;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
346 target++;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
347 source++;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
348 *target = *source;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
349 target++;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
350 source++;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
351 *target = *source;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
352 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
353 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
354 #endif /* !mc68020 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
355 default:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
356 unexec_error ("unknown reloc type %d seen during unexec()",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
357 0, (char *) ri->r_type, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
358 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
359 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
360 return;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
361 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
362
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
363 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
364 reset_symtab (struct nlist *start, struct nlist *end, char *strtab,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
365 long edata_value, long end_value, int ld_so_table,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
366 int shlib_image)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
367 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
368 struct nlist *tmp = start;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
369 int found_edata = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
370 int found_end = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
371
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
372 while (tmp < end)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
373 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
374 int type = tmp->n_type;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
375 int named = (ld_so_table)?1:(tmp->n_un.n_strx);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
376
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
377 if ((type == (N_UNDF | N_EXT)) &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
378 (tmp->n_value != 0))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
379 unexec_error ("unexec'ing image has COMMON symbols in it -- we quit!",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
380 0, 0, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
381
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
382 if (!(type & N_STAB))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
383 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
384 if (!found_edata &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
385 (type == (N_EXT | N_DATA)) &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
386 named &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
387 !strcmp ("_edata", strtab + tmp->n_un.n_strx))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
388 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
389 tmp->n_value = edata_value;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
390 found_edata = 1;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
391 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
392
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
393
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
394 if ((type & N_TYPE) == N_BSS)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
395 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
396 if (!found_end &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
397 (type == (N_EXT | N_BSS)) &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
398 named &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
399 !strcmp ("_end", strtab + tmp->n_un.n_strx))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
400 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
401 tmp->n_value = end_value;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
402 found_end = 1;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
403 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
404 else if (type & N_EXT)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
405 tmp->n_type = N_DATA | N_EXT;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
406 else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
407 tmp->n_type = N_DATA;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
408 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
409
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
410 /* the way things are being handled here, having sbrk() in the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
411 image is fatal for an image linked with shared lib's (although
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
412 the code could be modified to support it), but this should
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
413 never happen anyway */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
414 if (shlib_image &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
415 (type == (N_EXT | N_TEXT)) &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
416 named &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
417 !strcmp ("_sbrk", strtab + tmp->n_un.n_strx))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
418 unexec_error ("unexec'd shlib image has sbrk() in it -- we quit!",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
419 0, 0, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
420 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
421
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
422 tmp++;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
423 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
424 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
425
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
426 extern int getpagesize (void);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
427
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
428 /*
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
429 * EXPORTED FUNCTIONS
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
430 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
431
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
432 /* this has to be a global variable to prevent the optimizers from
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
433 * assuming that it can not be 0.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
434 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
435 static void *dynamic_addr = (void *) &_DYNAMIC;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
436
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
437 int
2286
04bc9d2f42c7 [xemacs-hg @ 2004-09-20 19:18:55 by james]
james
parents: 853
diff changeset
438 unexec (char *new_name, char *old_name, unsigned int emacs_edata,
04bc9d2f42c7 [xemacs-hg @ 2004-09-20 19:18:55 by james]
james
parents: 853
diff changeset
439 unsigned int UNUSED (dummy1), unsigned int UNUSED (dummy2))
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
440 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
441 /* ld.so data */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
442 struct link_dynamic *ld = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
443 struct link_dynamic_2 *ld2 = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
444 /* old and new state */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
445 int old_fd;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
446 int new_fd;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
447 caddr_t old_base_addr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
448 caddr_t new_base_addr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
449 struct exec old_hdr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
450 struct exec new_hdr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
451 struct stat old_buf;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
452 struct stat new_buf;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
453 /* some process specific "constants" */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
454 unsigned long n_pagsiz;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
455 long page_size = getpagesize ();
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
456 caddr_t plt_end;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
457 caddr_t current_break = (caddr_t) sbrk (0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
458
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
459 if (!page_size)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
460 unexec_error ("unexec() failed because we can't get the size of a page!",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
461 0, 0, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
462
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
463 /* see if this is a -Bdynamic image -- if so, find ld.so structures */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
464 if (dynamic_addr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
465 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
466 ld = (struct link_dynamic *) dynamic_addr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
467 ld2 = ld->ld_un.ld_2;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
468 if (ld->ld_version < 2)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
469 unexec_error ("%s linked with obsolete version of ld -- we quit!",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
470 0, old_name, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
471 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
472
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
473 /* open the old and new files, figuring out how big the old one is
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
474 so that we can map it in */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
475 old_fd = unexec_open (old_name, O_RDONLY, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
476 new_fd = unexec_open (new_name, O_RDWR | O_CREAT | O_TRUNC, 0666);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
477
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
478 /* setup the header and the statbuf for old_fd */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
479 unexec_read (old_fd, 0, (char *) &old_hdr, sizeof (old_hdr));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
480 unexec_fstat (old_fd, &old_buf);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
481
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
482
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
483 /* set up some important constants */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
484 n_pagsiz = N_PAGSIZ (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
485 if (dynamic_addr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
486 plt_end = (caddr_t) MASK_UP (ld2->ld_plt + ld2->ld_plt_sz, sizeof (double));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
487 else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
488 plt_end = (caddr_t) N_DATADDR (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
489
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
490 /* never write protect the variable "environ", defined in /lib/crt0.o, and
853
2b6fa2618f76 [xemacs-hg @ 2002-05-28 08:44:22 by ben]
ben
parents: 398
diff changeset
491 set in process.c */
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
492 mprotect_bottom_addr = ((unsigned long) &environ) + sizeof (char **);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
493 /* never protect ABOVE the end of data emacs_edata specified */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
494 mprotect_top_addr = MIN (emacs_edata, N_DATADDR (old_hdr) + old_hdr.a_data);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
495
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
496 /* Set up the image of the old file */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
497 old_base_addr = unexec_mmap (old_fd, old_buf.st_size, PROT_READ, MAP_PRIVATE);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
498 close (old_fd);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
499
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
500 /* set up the new exec */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
501 new_hdr = old_hdr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
502 new_hdr.a_data = (((unsigned long) MASK_UP (current_break, n_pagsiz)) -
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
503 ((unsigned long) N_DATADDR (old_hdr)));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
504 new_hdr.a_bss = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
505
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
506 /* set up this variable, in case we want to reset "the break"
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
507 when restarting */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
508 sbrk_of_0_at_unexec = ((unsigned long) MASK_UP (current_break, n_pagsiz));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
509
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
510 /* Write out the first approximation to the new file. The sizes of
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
511 each section will be correct, but there will be a number of
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
512 corrections that will need to be made. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
513 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
514 long old_datoff = N_DATOFF (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
515 long old_dataddr = N_DATADDR (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
516 long new_treloff = N_TRELOFF (new_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
517 long old_treloff = N_TRELOFF (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
518 long ld_so_size = ((unsigned long) plt_end) - old_dataddr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
519 long real_data_size = current_break - plt_end;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
520 long pad_size =
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
521 MASK_UP (current_break, n_pagsiz) - ((unsigned long) current_break);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
522
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
523
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
524 /* First, write the text segment with new header -- copy everything until
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
525 the start of the data segment from the old file, and then go back and
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
526 write the new header. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
527 unexec_write (new_fd, 0, old_base_addr, old_datoff + ld_so_size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
528 unexec_write (new_fd, 0, (char *) &new_hdr, sizeof (new_hdr));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
529
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
530 /* Copy the rest of the data segment from the running image. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
531 unexec_write (new_fd, old_datoff + ld_so_size,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
532 plt_end, real_data_size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
533
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
534 /* pad out the data segment */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
535 unexec_pad (new_fd, pad_size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
536
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
537 /* Finally, copy the symbol table information from the old file. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
538 unexec_write (new_fd, new_treloff,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
539 old_base_addr + old_treloff,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
540 old_buf.st_size - old_treloff);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
541 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
542
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
543
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
544 /* Next, map in the output file so that we can jump around fixing it
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
545 up. We retain the old file so that we can refer to it. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
546 unexec_fstat (new_fd, &new_buf);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
547 new_base_addr = unexec_mmap (new_fd,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
548 MASK_UP (new_buf.st_size, page_size),
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
549 PROT_READ | PROT_WRITE, MAP_SHARED);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
550
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
551
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
552
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
553 /* We need to do 2 things. First, make sure that _edata and _end (and
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
554 hence, curbrk) are set to the correct values. At the same time, for
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
555 neatness and to help with debugging, mark all the types of all ld.so
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
556 and nm BSS symbols in the new file to be DATA, and make sure that
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
557 there are no COMMON symbols in the output file, as any references to
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
558 these can lose really big. Second, reset all of the ld.so "relocation
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
559 sites" in the new file to have the values that appear in the old file
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
560 -- the failure to do this was the biggest loser in the old version of
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
561 this code. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
562
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
563 /* STEP 1 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
564 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
565 /* Reset the regular symbol table first. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
566 reset_symtab ((struct nlist *) (new_base_addr + N_SYMOFF(new_hdr)),
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
567 (struct nlist *) (new_base_addr + N_SYMOFF(new_hdr) +
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
568 new_hdr.a_syms),
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
569 (char *) (new_base_addr + N_STROFF(new_hdr)),
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
570 N_DATADDR (new_hdr) + new_hdr.a_data,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
571 N_BSSADDR (new_hdr) + new_hdr.a_bss,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
572 0, !!dynamic_addr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
573 /* Now reset the ld.so symbol table. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
574 if (dynamic_addr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
575 reset_symtab ((struct nlist *) (new_base_addr + ld2->ld_stab),
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
576 (struct nlist *) (new_base_addr + ld2->ld_symbols),
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
577 (char *) (new_base_addr + ld2->ld_symbols),
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
578 N_DATADDR (new_hdr) + new_hdr.a_data,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
579 N_BSSADDR (new_hdr) + new_hdr.a_bss,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
580 1, !!dynamic_addr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
581 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
582
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
583 /* STEP 2 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
584 if (dynamic_addr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
585 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
586 struct translation_struct ts;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
587 struct relocation_info *tmp =
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
588 (struct relocation_info *) (old_base_addr + ld2->ld_rel);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
589 struct relocation_info *end =
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
590 (struct relocation_info *)(old_base_addr + ld2->ld_hash);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
591
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
592 /* set up the structure that we use to translate addresses in the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
593 old file into file offsets */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
594 ts.txtaddr = N_TXTADDR (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
595 ts.txtoff = N_TXTOFF (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
596 ts.dataddr = N_DATADDR (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
597 ts.datoff = N_DATOFF (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
598 ts.bssaddr = N_BSSADDR (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
599
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
600 while (tmp < end)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
601 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
602 copy_relocation_site (tmp, old_base_addr, new_base_addr, &ts);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
603 tmp++;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
604 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
605 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
606
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
607
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
608 /* get rid of the mmap-ed file space and make the output file
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
609 executable -- then quit */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
610 munmap (new_base_addr, MASK_UP (new_buf.st_size, page_size));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
611 munmap (old_base_addr, MASK_UP (old_buf.st_size, page_size));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
612 unexec_fchmod (new_fd, 0755);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
613 close (new_fd);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
614 return 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
615 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
616
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
617
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
618 int
2286
04bc9d2f42c7 [xemacs-hg @ 2004-09-20 19:18:55 by james]
james
parents: 853
diff changeset
619 run_time_remap (char *UNUSED (dummy))
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
620 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
621 long page_size = getpagesize();
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
622 unsigned long base_addr = MASK_UP (mprotect_bottom_addr, page_size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
623 unsigned long top_addr = MASK_DOWN (mprotect_top_addr, page_size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
624 long len = top_addr - base_addr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
625
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
626 if (!dynamic_addr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
627 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
628 unsigned long current_sbrk = (unsigned long) sbrk (0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
629
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
630 if (sbrk_of_0_at_unexec < current_sbrk)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
631 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
632 if (sbrk_of_0_at_unexec != 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
633 /* GCC -Wall even catches incorrect printf type errors.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
634 How utterly cool. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
635 fprintf (stderr,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
636 "Absurd new brk addr = 0x%lx (current = 0x%lx)\n",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
637 sbrk_of_0_at_unexec, current_sbrk);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
638 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
639 else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
640 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
641 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
642 if (brk ((caddr_t) sbrk_of_0_at_unexec))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
643 fprintf (stderr, "failed to change brk addr to 0x%lx: %s\n",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
644 sbrk_of_0_at_unexec, SYS_ERR);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
645 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
646 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
647
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
648 if (len > 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
649 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
650 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
651 if (mprotect ((caddr_t) base_addr, len, PROT_READ | PROT_EXEC))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
652 fprintf (stderr, "failed to change protection on data pages: %s\n",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
653 SYS_ERR);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
654 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
655
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
656 return 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
657 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
658