annotate src/unexfreebsd.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
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 /* Code to do an unexec for FreeBSD-1.1 for a temacs linked -Bdynamic.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2 Derived from unexnetbsd.c, which was derived from unexsunos4.c
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3 Copyright (C) 1992, 1993 Free Software Foundation, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5 This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7 XEmacs is free software; you can redistribute it and/or modify it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 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
9 Free Software Foundation; either version 2, or (at your option) any
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10 later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12 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
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 along with XEmacs; see the file COPYING. If not, write to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 Boston, MA 02111-1307, USA. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22 /* Synched up with: Not in FSF? */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 Created 29-Oct-92 by Harlan Sexton
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 Tweaked 06-Aug-93 by Dean Michaels to work with sun3.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27 Converted 01-Dec-93 by Paul Mackerras to work with NetBSD shared libraries.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28 Tweaked 26-Feb-94 by Shawn Carey for use with FreeBSD-1.1 shared libraries.
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31 /********************** Included .h Files **************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 #include <config.h>
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 #include <stdarg.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 #include <sys/param.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 #include <sys/mman.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 #include <sys/file.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 #include <sys/stat.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 #include <sys/types.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 #include <string.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 #include <stdio.h>
438
84b14dcb0985 Import from CVS: tag r21-2-27
cvs
parents: 428
diff changeset
43 #include <errno.h>
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 #include <a.out.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 #include <unistd.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 #include <ctype.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 #include <stab.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 #include <sys/dir.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 #include <link.h>
2286
04bc9d2f42c7 [xemacs-hg @ 2004-09-20 19:18:55 by james]
james
parents: 853
diff changeset
50 #include "compiler.h"
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 /********************** Macros *************************************/
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 #define SYS_ERR strerror(errno)
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 #define MASK_UP(x,p_of_two) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 ((((unsigned long) (x)) + ((p_of_two) - 1)) & (~((p_of_two) - 1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 #define MASK_DOWN(x,p_of_two) (((unsigned long) (x)) & (~((p_of_two) - 1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 /********************** Typedefs and Structs ***********************/
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 struct translation_struct
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 long txtaddr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 long txtoff;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 long dataddr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 long datoff;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 long bssaddr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 long endaddr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 /********************** Function Prototypes/Declarations ***********/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 438
diff changeset
75 static void unexec_error (const char *m, int use_errno, ...);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 static int unexec_open (char *filename, int flag, int mode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 static caddr_t unexec_mmap (int fd, size_t len, int prot, int flags);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 static long unexec_seek (int fd, long position);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 static void unexec_read (int fd, long position, char *buf, int bytes);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 static void unexec_write (int fd, long position, char *buf, int bytes);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 static void unexec_pad (int fd, int bytes);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 static void unexec_fstat (int fd, struct stat *statptr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 static void unexec_fchmod (int fd, int mode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 static long unexec_addr_to_offset (long addr, struct translation_struct *ts);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85 static void copy_relocation_site (struct relocation_info *ri,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 caddr_t from_base_addr,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 caddr_t to_base_addr,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 struct translation_struct *ts);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 static void reset_symtab (struct nlist *start, struct nlist *end,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90 char *strtab, long edata_value, long end_value,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 int shlib_image);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 static void reset_ldso_symtab (struct nzlist *start, struct nzlist *end,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 char *strtab, long edata_value, long end_value,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 int shlib_image);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 int run_time_remap (char *dummy);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 /********************** Variables **********************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 /* for reporting error messages from system calls */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 extern int _DYNAMIC;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 extern char **environ;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 static unsigned long sbrk_of_0_at_unexec;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 static void
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 438
diff changeset
108 unexec_error (const char *fmt, int use_errno, ...)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 438
diff changeset
110 const char *err_msg = SYS_ERR;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 va_list args;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 fprintf (stderr, "unexec - ");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 va_start (args, use_errno);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 vfprintf (stderr, fmt, args);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 va_end (args);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 if (use_errno)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 fprintf (stderr, ": %s", err_msg);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 fprintf (stderr, "\n");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 exit (1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 unexec_open (char *filename, int flag, int mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 int fd;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 errno = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 fd = open (filename, flag, mode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 if (fd < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 unexec_error ("Failure opening file %s", 1, filename);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 return fd;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 static caddr_t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 unexec_mmap (int fd, size_t len, int prot, int flags)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 caddr_t return_val;
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 unexec_seek (fd, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 errno = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 return_val = mmap (0, len, prot, flags, fd, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 if (return_val == (caddr_t) -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 unexec_error ("Failure mmap'ing file", 1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 return return_val;
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
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 static long
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 unexec_seek (int fd, long position)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 long seek_value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 if (fd <= 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 unexec_error ("No file open in which to seek", 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 errno = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 if (position < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 seek_value = (long) lseek (fd, 0, L_INCR);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 seek_value = (long) lseek (fd, position, L_SET);
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 if (seek_value < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 unexec_error ("Failed to do a seek to 0x%x in %s", 1,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 position, "unexec() output file");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 return seek_value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 unexec_read (int fd, long position, char *buf, int bytes)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 int n_read;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 int remains = bytes;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 position = unexec_seek (fd, position);
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 if (bytes < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 unexec_error ("Attempted read of %d bytes", 0, bytes);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 errno = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 while (remains > 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 n_read = read (fd, buf, remains);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 if (n_read <= 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 unexec_error ("Read failed for 0x%x bytes at offset 0x%x in %s",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 1, bytes, position, "unexec() output file");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 buf += n_read;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 remains -= n_read;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 unexec_write (int fd, long position, char *buf, int bytes)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 int n_written;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 int remains = bytes;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 position = unexec_seek (fd, position);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 if (bytes < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 unexec_error ("Attempted write of %d bytes in %s",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 0, bytes, "unexec() output file");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 errno = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 while (remains > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 n_written = write (fd, buf, remains);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 if (n_written <= 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 unexec_error ("Write failed for 0x%x bytes at offset 0x%x in %s",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 1, bytes, position, "unexec() output file");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 buf += n_written;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 remains -= n_written;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 }
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 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 unexec_pad (int fd, int bytes)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 if (bytes > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 char buf[1024];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 int remaining = bytes;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235 memset (buf, 0, sizeof (buf));
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 while (remaining > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 int this_write = (remaining > sizeof(buf))?sizeof(buf):remaining;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 unexec_write (fd, -1, buf, this_write);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 remaining -= this_write;
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 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 }
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 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 unexec_fstat (int fd, struct stat *statptr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 errno = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 if (-1 == fstat (fd, statptr))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 unexec_error ("fstat() failed for descriptor %d", 1, fd);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 return;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 unexec_fchmod (int fd, int mode)
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 errno = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 if (-1 == fchmod (fd, mode))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 unexec_error ("fchmod() failed for descriptor %d", 1, fd);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 return;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 static long
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 unexec_addr_to_offset (long addr, struct translation_struct *ts)
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 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 if ((addr < ts->txtaddr) || (addr >= ts->bssaddr))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 else if (addr >= ts->dataddr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 return ((long) ((addr - ts->dataddr) + ts->datoff));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 return ((long) ((addr - ts->txtaddr) + ts->txtoff));
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 * "LD.SO" DATA AND SYMBOL TABLE OPERATIONS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 */
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 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 copy_relocation_site (struct relocation_info *ri,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 caddr_t from_base_addr,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 caddr_t to_base_addr,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 struct translation_struct *ts)
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 long offset;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 caddr_t from, to;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 /* We can get relocation sites in the bss region, for objects whose
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 contents are copied from a shared library. We don't need or want
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 to restore these at present. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 #ifndef sparc
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 if (ri->r_copy)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 #else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 /* Struct relocation_info_sparc doesn't have member r_copy.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 Instead, we use the address to check if this is run-time-copied. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 if (ri->r_address >= ts->bssaddr && ri->r_address < ts->endaddr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 offset = unexec_addr_to_offset (ri->r_address, ts);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 if (offset == -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 unexec_error ("bad relocation address 0x%x (0x%x)", 0, ri->r_address,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 ((long *)ri)[1]);
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 from = from_base_addr + offset;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 to = to_base_addr + offset;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 /* This stuff should be in a md_ file somewhere... */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 #ifndef sparc
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 switch (ri->r_length)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 case 0:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 *((char *) to) = *((char *) from);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 case 1:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318 *((short *) to) = *((short *) from);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 case 2:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321 *((long *) to) = *((long *) from);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 default:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 unexec_error ("unknown reloc length %d seen during unexec()",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 0, ri->r_length);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 #else /* sparc */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 switch (ri->r_type)
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 case RELOC_8:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 case RELOC_DISP8:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 *((char *) to) = *((char *) from);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 case RELOC_16:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 case RELOC_DISP16:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337 *((short *) to) = *((short *) from);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 case RELOC_LO10:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 case RELOC_13:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 case RELOC_22:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 case RELOC_HI22:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 case RELOC_WDISP22:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 case RELOC_WDISP30:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 case RELOC_32:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 case RELOC_DISP32:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 case RELOC_GLOB_DAT:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 *((long *) to) = *((long *) from);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 case RELOC_JMP_SLOT:
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 long *target = (long *) to;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 long *source = (long *) from;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 *target = *source;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 target++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 source++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 *target = *source;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 target++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 source++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 *target = *source;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363 default:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 unexec_error ("unknown reloc type %d seen during unexec()",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 0, ri->r_type);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 break;
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 #endif /* sparc */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372 reset_symtab (struct nlist *start, struct nlist *end, char *strtab,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 long edata_value, long end_value, int shlib_image)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 struct nlist *tmp = start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 int found_edata = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 int found_end = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379 while (tmp < end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 int type = tmp->n_type;
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 if ((type == (N_UNDF | N_EXT)) &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 (tmp->n_value != 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 unexec_error ("unexec'ing image has COMMON symbols in it -- we quit!",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 if (!(type & N_STAB))
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 if (!found_edata &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 (type == (N_EXT | N_DATA)) &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 tmp->n_un.n_strx &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 !strcmp ("_edata", strtab + tmp->n_un.n_strx))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 tmp->n_value = edata_value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 found_edata = 1;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 if ((type & N_TYPE) == N_BSS)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 if (!found_end &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 (type == (N_EXT | N_BSS)) &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 tmp->n_un.n_strx &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 !strcmp ("_end", strtab + tmp->n_un.n_strx))
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 tmp->n_value = end_value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408 found_end = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 else if (type & N_EXT)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 tmp->n_type = N_DATA | N_EXT;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413 tmp->n_type = N_DATA;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416 /* the way things are being handled here, having sbrk() in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417 image is fatal for an image linked with shared lib's (although
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
418 the code could be modified to support it), but this should
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419 never happen anyway */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
420 if (shlib_image &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
421 (type == (N_EXT | N_TEXT)) &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422 tmp->n_un.n_strx &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
423 !strcmp ("_sbrk", strtab + tmp->n_un.n_strx))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 unexec_error ("unexec'd shlib image has sbrk() in it -- we quit!",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428 tmp++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
430 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433 reset_ldso_symtab (struct nzlist *start, struct nzlist *end, char *strtab,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 long edata_value, long end_value, int shlib_image)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 struct nzlist *tmp = start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 int found_edata = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 int found_end = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
439
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 while (tmp < end) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441 int type = tmp->nz_type;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 * the following code breaks under FreeBSD-1.1-BETA, but everything
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 * seems to work perfectly if it's commented out. This did not break
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 * anything until the changes to ld.so were made.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
446 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 if ((type == (N_UNDF | N_EXT)) && (tmp->nz_value != 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 unexec_error("unexec'ing image has COMMON symbols in rel -- we quit!",0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 if (!(type & N_STAB)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452 if (!found_edata &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 (type == (N_EXT | N_DATA)) &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454 !strcmp ("_edata", strtab + tmp->nz_strx)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 tmp->nz_value = edata_value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 found_edata = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459 if ((type & N_TYPE) == N_BSS) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 if (!found_end &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 (type == (N_EXT | N_BSS)) &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 !strcmp ("_end", strtab + tmp->nz_strx)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463 tmp->nz_value = end_value;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 found_end = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 } else if (type & N_EXT)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 tmp->nz_type = N_DATA | N_EXT;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 tmp->nz_type = N_DATA;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 /* the way things are being handled here, having sbrk() in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 image is fatal for an image linked with shared lib's (although
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 the code could be modified to support it), but this should
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 never happen anyway */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 if (shlib_image &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476 (type == (N_EXT | N_TEXT)) &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 !strcmp ("_sbrk", strtab + tmp->nz_strx))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478 unexec_error("unexec'd shlib image has sbrk() ref -- we quit!", 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 tmp++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 }
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 extern int getpagesize (void);
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 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 * EXPORTED FUNCTIONS
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 /* this has to be a global variable to prevent the optimizers from
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 * assuming that it can not be 0.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 static void *dynamic_addr = (void *) &_DYNAMIC;
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 int
2286
04bc9d2f42c7 [xemacs-hg @ 2004-09-20 19:18:55 by james]
james
parents: 853
diff changeset
496 unexec (char *new_name, char *old_name, unsigned int UNUSED (emacs_edata),
04bc9d2f42c7 [xemacs-hg @ 2004-09-20 19:18:55 by james]
james
parents: 853
diff changeset
497 unsigned int UNUSED (dummy1), unsigned int UNUSED (dummy2))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 /* ld.so data */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 struct _dynamic *ld = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501 struct section_dispatch_table *ld2 = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502 /* old and new state */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 int old_fd;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504 int new_fd;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 caddr_t old_base_addr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 caddr_t new_base_addr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 struct exec old_hdr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 struct exec new_hdr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 struct stat old_buf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 struct stat new_buf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 /* some process specific "constants" */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 unsigned long n_pagsiz, new_edata;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 long page_size = getpagesize ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 caddr_t plt_end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 caddr_t current_break = (caddr_t) sbrk (0);
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 if (!page_size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 unexec_error ("unexec() failed because we can't get the size of a page!",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 /* see if this is a -Bdynamic image -- if so, find ld.so structures */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 if (dynamic_addr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
523 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 ld = (struct _dynamic *) dynamic_addr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 ld2 = ld->d_un.d_sdt;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 if (ld->d_version < LD_VERSION_BSD)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 unexec_error ("%s linked with obsolete version of ld -- we quit!",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 0, old_name);
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 /* open the old and new files, figuring out how big the old one is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 so that we can map it in */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 old_fd = unexec_open (old_name, O_RDONLY, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 new_fd = unexec_open (new_name, O_RDWR | O_CREAT | O_TRUNC, 0666);
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 /* setup the header and the statbuf for old_fd */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 unexec_read (old_fd, 0, (char *) &old_hdr, sizeof (old_hdr));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 unexec_fstat (old_fd, &old_buf);
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 /* set up some important constants */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 n_pagsiz = __LDPGSZ;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
543 if (dynamic_addr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544 plt_end = (caddr_t) MASK_UP (ld2->sdt_plt + ld2->sdt_plt_sz, sizeof (double));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
546 plt_end = (caddr_t) N_DATADDR (old_hdr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
548 #if 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
549 /* 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: 442
diff changeset
550 set in process.c */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
551 mprotect_bottom_addr = ((unsigned long) &environ) + sizeof (char **);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
552 /* never protect ABOVE the end of data emacs_edata specified */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
553 mprotect_top_addr = MIN (emacs_edata, N_DATADDR (old_hdr) + old_hdr.a_data);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
554 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
556 /* Set up the image of the old file */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557 old_base_addr = unexec_mmap (old_fd, old_buf.st_size, PROT_READ,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
558 MAP_FILE | MAP_PRIVATE);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
559 close (old_fd);
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 /* set up the new exec */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562 new_hdr = old_hdr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
563 new_edata = (unsigned long) MASK_UP (current_break, n_pagsiz);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
564 new_hdr.a_data = new_edata - ((unsigned long) N_DATADDR (old_hdr));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
565 new_hdr.a_bss = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
566
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
567 /* set up this variable, in case we want to reset "the break"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
568 when restarting */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569 sbrk_of_0_at_unexec = ((unsigned long) MASK_UP (current_break, n_pagsiz));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
570
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 /* Write out the first approximation to the new file. The sizes of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572 each section will be correct, but there will be a number of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
573 corrections that will need to be made. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
574 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
575 long old_datoff = N_DATOFF (old_hdr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
576 long old_dataddr = N_DATADDR (old_hdr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
577 long new_treloff = N_RELOFF (new_hdr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
578 long old_treloff = N_RELOFF (old_hdr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
579 long ld_so_size = ((unsigned long) plt_end) - old_dataddr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580 long real_data_size = current_break - plt_end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
581 long pad_size =
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582 MASK_UP (current_break, n_pagsiz) - ((unsigned long) current_break);
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
585 /* First, write the text segment with new header -- copy everything until
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
586 the start of the data segment from the old file, and then go back and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
587 write the new header. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
588 unexec_write (new_fd, 0, old_base_addr, old_datoff + ld_so_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
589 unexec_write (new_fd, 0, (char *) &new_hdr, sizeof (new_hdr));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
590
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591 /* Copy the rest of the data segment from the running image. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
592 unexec_write (new_fd, old_datoff + ld_so_size,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593 plt_end, real_data_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
594
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
595 /* pad out the data segment */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 unexec_pad (new_fd, pad_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 /* Finally, copy the symbol table information from the old file. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
599 unexec_write (new_fd, new_treloff,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 old_base_addr + old_treloff,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
601 old_buf.st_size - old_treloff);
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605 /* Next, map in the output file so that we can jump around fixing it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
606 up. We retain the old file so that we can refer to it. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
607 unexec_fstat (new_fd, &new_buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
608 new_base_addr = unexec_mmap (new_fd,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
609 MASK_UP (new_buf.st_size, page_size),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
610 PROT_READ | PROT_WRITE,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
611 MAP_FILE | MAP_SHARED);
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
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 /* We need to do 2 things. First, make sure that _edata and _end (and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
616 hence, curbrk) are set to the correct values. At the same time, for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617 neatness and to help with debugging, mark all the types of all ld.so
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618 and nm BSS symbols in the new file to be DATA, and make sure that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619 there are no COMMON symbols in the output file, as any references to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
620 these can lose really big. Second, reset all of the ld.so "relocation
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
621 sites" in the new file to have the values that appear in the old file
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
622 -- the failure to do this was the biggest loser in the old version of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
623 this code. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
624
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
625 /* STEP 1 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
626 /* Reset the regular symbol table first. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
627 reset_symtab ((struct nlist *) (new_base_addr + N_SYMOFF(new_hdr)),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
628 (struct nlist *) (new_base_addr + N_SYMOFF(new_hdr) +
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
629 new_hdr.a_syms),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
630 (char *) (new_base_addr + N_STROFF(new_hdr)),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
631 new_edata, new_edata,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
632 !!dynamic_addr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
633
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
634 /* Now reset the ld.so symbol table. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
635 if (dynamic_addr)
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 struct translation_struct ts;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
638 struct relocation_info *tmp, *end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
639 caddr_t syms, strings;
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 /* set up the structure that we use to translate addresses in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
642 old file into file offsets */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
643 ts.txtaddr = N_TXTADDR (old_hdr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
644 ts.txtoff = N_TXTOFF (old_hdr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
645 ts.dataddr = N_DATADDR (old_hdr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
646 ts.datoff = N_DATOFF (old_hdr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
647 ts.bssaddr = N_DATADDR (old_hdr) + old_hdr.a_data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
648 ts.endaddr = ts.bssaddr + old_hdr.a_bss;
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 syms = new_base_addr + unexec_addr_to_offset(ld2->sdt_nzlist, &ts);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
651 strings = new_base_addr + unexec_addr_to_offset(ld2->sdt_strings, &ts);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
652 reset_ldso_symtab ((struct nzlist *) syms, (struct nzlist *) strings,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
653 (char *) strings,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
654 new_edata, new_edata,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
655 !!dynamic_addr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
656
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
657 /* STEP 2 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
658 tmp = (struct relocation_info *)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
659 (old_base_addr + unexec_addr_to_offset(ld2->sdt_rel, &ts));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
660 end = (struct relocation_info *)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
661 (old_base_addr + unexec_addr_to_offset(ld2->sdt_hash, &ts));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
662 while (tmp < end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
663 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
664 copy_relocation_site (tmp, old_base_addr, new_base_addr, &ts);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
665 tmp++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
666 }
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
669 /* get rid of the mmap-ed file space and make the output file
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
670 executable -- then quit */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
671 munmap (new_base_addr, MASK_UP (new_buf.st_size, page_size));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
672 munmap (old_base_addr, MASK_UP (old_buf.st_size, page_size));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
673 unexec_fchmod (new_fd, 0755);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
674 close (new_fd);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
675 return 0;
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 int
2286
04bc9d2f42c7 [xemacs-hg @ 2004-09-20 19:18:55 by james]
james
parents: 853
diff changeset
680 run_time_remap (char *UNUSED (dummy))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
681 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
682 unsigned long current_sbrk = (unsigned long) sbrk (0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
683
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
684 #if __FreeBSD_version < 300000 /* 2.x can work with this code */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
685 if (sbrk_of_0_at_unexec < current_sbrk)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
686 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
687 if (sbrk_of_0_at_unexec != 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
688 fprintf (stderr, "Absurd new brk addr = %lx (current = %lx)\n",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
689 sbrk_of_0_at_unexec, current_sbrk);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
690 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
691 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
692 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
693 if (sbrk_of_0_at_unexec > current_sbrk)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
694 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
695 errno = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
696 if (brk ((caddr_t) sbrk_of_0_at_unexec))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
697 fprintf (stderr, "failed to change brk addr to %lx: %s\n",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
698 sbrk_of_0_at_unexec, SYS_ERR);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
699 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
700
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
701 #if 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
702 /* with proper COW, i don't think we really need to do this... */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
703 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
704 long page_size = getpagesize();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
705 unsigned long base_addr = MASK_UP (mprotect_bottom_addr, page_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
706 unsigned long top_addr = MASK_DOWN (mprotect_top_addr, page_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
707 long len = top_addr - base_addr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
708
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
709 if (len > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
710 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
711 errno = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
712 if (mprotect ((caddr_t) base_addr, len, PROT_READ | PROT_EXEC))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
713 fprintf (stderr, "failed to change protection on data pages: %s\n",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
714 SYS_ERR);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
715 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
716 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
717 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
718
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
719 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
720 }