annotate src/unexsunos4.c @ 853:2b6fa2618f76

[xemacs-hg @ 2002-05-28 08:44:22 by ben] merge my stderr-proc ws make-docfile.c: Fix places where we forget to check for EOF. code-init.el: Don't use CRLF conversion by default on process output. CMD.EXE and friends work both ways but Cygwin programs don't like the CRs. code-process.el, multicast.el, process.el: Removed. Improvements to call-process-internal: -- allows a buffer to be specified for input and stderr output -- use it on all systems -- implement C-g as documented -- clean up and comment call-process-region uses new call-process facilities; no temp file. remove duplicate funs in process.el. comment exactly how coding systems work and fix various problems. open-multicast-group now does similar coding-system frobbing to open-network-stream. dumped-lisp.el, faces.el, msw-faces.el: Fix some hidden errors due to code not being defined at the right time. xemacs.mak: Add -DSTRICT. ================================================================ ALLOW SEPARATION OF STDOUT AND STDERR IN PROCESSES ================================================================ Standard output and standard error can be processed separately in a process. Each can have its own buffer, its own mark in that buffer, and its filter function. You can specify a separate buffer for stderr in `start-process' to get things started, or use the new primitives: set-process-stderr-buffer process-stderr-buffer process-stderr-mark set-process-stderr-filter process-stderr-filter Also, process-send-region takes a 4th optional arg, a buffer. Currently always uses a pipe() under Unix to read the error output. (#### Would a PTY be better?) sysdep.h, sysproc.h, unexfreebsd.c, unexsunos4.c, nt.c, emacs.c, callproc.c, symsinit.h, sysdep.c, Makefile.in.in, process-unix.c: Delete callproc.c. Move child_setup() to process-unix.c. wait_for_termination() now only needed on a few really old systems. console-msw.h, event-Xt.c, event-msw.c, event-stream.c, event-tty.c, event-unixoid.c, events.h, process-nt.c, process-unix.c, process.c, process.h, procimpl.h: Rewrite the process methods to handle a separate channel for error input. Create Lstreams for reading in the error channel. Many process methods need change. In general the changes are fairly clear as they involve duplicating what's used for reading the normal stdout and changing for stderr -- although tedious, as such changes are required throughout the entire process code. Rewrote the code that reads process output to do two loops, one for stdout and one for stderr. gpmevent.c, tooltalk.c: set_process_filter takes an argument for stderr. ================================================================ NEW ERROR-TRAPPING MECHANISM ================================================================ Totally rewrite error trapping code to be unified and support more features. Basic function is call_trapping_problems(), which lets you specify, by means of flags, what sorts of problems you want trapped. these can include -- quit -- errors -- throws past the function -- creation of "display objects" (e.g. buffers) -- deletion of already-existing "display objects" (e.g. buffers) -- modification of already-existing buffers -- entering the debugger -- gc -- errors->warnings (ala suspended errors) etc. All other error funs rewritten in terms of this one. Various older mechanisms removed or rewritten. window.c, insdel.c, console.c, buffer.c, device.c, frame.c: When creating a display object, added call to note_object_created(), for use with trapping_problems mechanism. When deleting, call check_allowed_operation() and note_object deleted(). The trapping-problems code records the objects created since the call-trapping-problems began. Those objects can be deleted, but none others (i.e. previously existing ones). bytecode.c, cmdloop.c: internal_catch takes another arg. eval.c: Add long comments describing the "five lists" used to maintain state (backtrace, gcpro, specbind, etc.) in the Lisp engine. backtrace.h, eval.c: Implement trapping-problems mechanism, eliminate old mechanisms or redo in terms of new one. frame.c, gutter.c: Flush out the concept of "critical display section", defined by the in_display() var. Use an internal_bind() to get it reset, rather than just doing it at end, because there may be a non-local exit. event-msw.c, event-stream.c, console-msw.h, device.c, dialog-msw.c, frame.c, frame.h, intl.c, toolbar.c, menubar-msw.c, redisplay.c, alloc.c, menubar-x.c: Make use of new trapping-errors stuff and rewrite code based on old mechanisms. glyphs-widget.c, redisplay.h: Protect calling Lisp in redisplay. insdel.c: Protect hooks against deleting existing buffers. frame-msw.c: Use EQ, not EQUAL in hash tables whose keys are just numbers. Otherwise we run into stickiness in redisplay because internal_equal() can QUIT. ================================================================ SIGNAL, C-G CHANGES ================================================================ Here we change the way that C-g interacts with event reading. The idea is that a C-g occurring while we're reading a user event should be read as C-g, but elsewhere should be a QUIT. The former code did all sorts of bizarreness -- requiring that no QUIT occurs anywhere in event-reading code (impossible to enforce given the stuff called or Lisp code invoked), and having some weird system involving enqueue/dequeue of a C-g and interaction with Vquit_flag -- and it didn't work. Now, we simply enclose all code where we want C-g read as an event with {begin/end}_dont_check_for_quit(). This completely turns off the mechanism that checks (and may remove or alter) C-g in the read-ahead queues, so we just get the C-g normal. Signal.c documents this very carefully. cmdloop.c: Correct use of dont_check_for_quit to new scheme, remove old out-of-date comments. event-stream.c: Fix C-g handling to actually work. device-x.c: Disable quit checking when err out. signal.c: Cleanup. Add large descriptive comment. process-unix.c, process-nt.c, sysdep.c: Use QUIT instead of REALLY_QUIT. It's not necessary to use REALLY_QUIT and just confuses the issue. lisp.h: Comment quit handlers. ================================================================ CONS CHANGES ================================================================ free_cons() now takes a Lisp_Object not the result of XCONS(). car and cdr have been renamed so that they don't get used directly; go through XCAR(), XCDR() instead. alloc.c, dired.c, editfns.c, emodules.c, fns.c, glyphs-msw.c, glyphs-x.c, glyphs.c, keymap.c, minibuf.c, search.c, eval.c, lread.c, lisp.h: Correct free_cons calling convention: now takes Lisp_Object, not Lisp_Cons chartab.c: Eliminate direct use of ->car, ->cdr, should be black box. callint.c: Rewrote using EXTERNAL_LIST_LOOP to avoid use of Lisp_Cons. ================================================================ USE INTERNAL-BIND-* ================================================================ eval.c: Cleanups of these funs. alloc.c, fileio.c, undo.c, specifier.c, text.c, profile.c, lread.c, redisplay.c, menubar-x.c, macros.c: Rewrote to use internal_bind_int() and internal_bind_lisp_object() in place of whatever varied and cumbersome mechanisms were formerly there. ================================================================ SPECBIND SANITY ================================================================ backtrace.h: - Improved comments backtrace.h, bytecode.c, eval.c: Add new mechanism check_specbind_stack_sanity() for sanity checking code each time the catchlist or specbind stack change. Removed older prototype of same mechanism. ================================================================ MISC ================================================================ lisp.h, insdel.c, window.c, device.c, console.c, buffer.c: Fleshed out authorship. device-msw.c: Correct bad Unicode-ization. print.c: Be more careful when not initialized or in fatal error handling. search.c: Eliminate running_asynch_code, an FSF holdover. alloc.c: Added comments about gc-cons-threshold. dialog-x.c: Use begin_gc_forbidden() around code to build up a widget value tree, like in menubar-x.c. gui.c: Use Qunbound not Qnil as the default for gethash. lisp-disunion.h, lisp-union.h: Added warnings on use of VOID_TO_LISP(). lisp.h: Use ERROR_CHECK_STRUCTURES to turn on ERROR_CHECK_TRAPPING_PROBLEMS and ERROR_CHECK_TYPECHECK lisp.h: Add assert_with_message. lisp.h: Add macros for gcproing entire arrays. (You could do this before but it required manual twiddling the gcpro structure.) lisp.h: Add prototypes for new functions defined elsewhere.
author ben
date Tue, 28 May 2002 08:45:36 +0000
parents 74fd4e045ea6
children 04bc9d2f42c7
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>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
54
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
55 /********************** Macros *************************************/
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
56
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
57 #define SYS_ERR \
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
58 ((errno > 0)?((errno < sys_nerr)?(sys_errlist[errno]):\
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
59 "unknown system error"): "unknown error")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
60
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
61 #define MASK_UP(x,p_of_two) \
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
62 ((((unsigned long) (x)) + ((p_of_two) - 1)) & (~((p_of_two) - 1)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
63
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
64 #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
65
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
66 #ifndef mc68020
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
67 #define relocation_info reloc_info_sparc
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
68 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
69
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
70 /********************** Typedefs and Structs ***********************/
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
71
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
72 struct translation_struct
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
73 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
74 long txtaddr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
75 long txtoff;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
76 long dataddr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
77 long datoff;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
78 long bssaddr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
79 };
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
80
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
81 /********************** Function Prototypes/Declarations ***********/
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
82
398
74fd4e045ea6 Import from CVS: tag r21-2-29
cvs
parents: 0
diff changeset
83 static void unexec_error (const char *m, int use_errno, ...);
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
84 static int unexec_open (char *filename, int flag, int mode);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
85 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
86 static long unexec_seek (int fd, long position);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
87 static void unexec_read (int fd, long position, char *buf, int bytes);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
88 static void unexec_write (int fd, long position, char *buf, int bytes);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
89 static void unexec_pad (int fd, int bytes);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
90 static void unexec_fstat (int fd, struct stat *statptr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
91 static void unexec_fchmod (int fd, int mode);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
92 static long unexec_addr_to_offset (long addr, struct translation_struct *ts);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
93 static void copy_relocation_site (struct relocation_info *ri,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
94 caddr_t from_base_addr,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
95 caddr_t to_base_addr,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
96 struct translation_struct *ts);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
97 static void reset_symtab (struct nlist *start, struct nlist *end,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
98 char *strtab, long edata_value, long end_value,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
99 int ld_so_table, int shlib_image);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
100 int run_time_remap (char *dummy);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
101
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
102 /********************** Variables **********************************/
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
103
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
104 /* for reporting error messages from system calls */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
105 extern int sys_nerr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
106 extern char *sys_errlist[];
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
107 extern int errno;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
108 extern int _DYNAMIC;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
109 extern char **environ;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
110
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
111 static unsigned long mprotect_bottom_addr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
112 static unsigned long mprotect_top_addr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
113
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
114 static unsigned long sbrk_of_0_at_unexec;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
115
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 static void
398
74fd4e045ea6 Import from CVS: tag r21-2-29
cvs
parents: 0
diff changeset
119 unexec_error (const char *fmt, int use_errno, ...)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
120 {
398
74fd4e045ea6 Import from CVS: tag r21-2-29
cvs
parents: 0
diff changeset
121 const char *err_msg = SYS_ERR;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
122 va_list args;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
123
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
124 fprintf (stderr, "unexec - ");
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
125 va_start (args, use_errno);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
126 vfprintf (stderr, fmt, args);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
127 va_end (args);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
128
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
129 if (use_errno)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
130 fprintf (stderr, ": %s", err_msg);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
131 fprintf (stderr, "\n");
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
132 exit (1);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
133 return;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
134 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
135
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
136 static int
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
137 unexec_open (char *filename, int flag, int mode)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
138 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
139 int fd;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
140
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
141 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
142
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
143 fd = open (filename, flag, mode);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
144
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
145 if (fd < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
146 unexec_error ("Failure opening file %s", 1, (void *) filename, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
147 return fd;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
148 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
149
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
150 static caddr_t
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
151 unexec_mmap (int fd, size_t len, int prot, int flags)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
152 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
153 caddr_t return_val;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
154
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
155 unexec_seek (fd, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
156 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
157 return_val = mmap (0, len, prot, flags, fd, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
158
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
159 if (return_val == (caddr_t) -1)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
160 unexec_error ("Failure mmap'ing file", 1, 0, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
161 return return_val;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
162 }
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 static long
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
166 unexec_seek (int fd, long position)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
167 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
168 long seek_value;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
169
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
170 if (fd <= 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
171 unexec_error ("No file open in which to seek", 0, 0, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
172
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
173 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
174
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
175 if (position < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
176 seek_value = (long) lseek (fd, 0, L_INCR);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
177 else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
178 seek_value = (long) lseek (fd, position, L_SET);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
179
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
180 if (seek_value < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
181 unexec_error ("Failed to do a seek to 0x%x in %s", 1,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
182 (char *) position, "unexec() output file", 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
183
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
184 return seek_value;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
185 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
186
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
187 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
188 unexec_read (int fd, long position, char *buf, int bytes)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
189 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
190 int n_read;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
191 int remains = bytes;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
192 position = unexec_seek (fd, position);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
193
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
194 if (bytes < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
195 unexec_error ("Attempted read of %d bytes", 0, (char *) bytes, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
196
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
197 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
198
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
199 while (remains > 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
200 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
201 n_read = read (fd, buf, remains);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
202 if (n_read <= 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
203 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
204 1, (char *) bytes, (char *) position,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
205 "unexec() output file");
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
206 buf += n_read;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
207 remains -= n_read;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
208 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
209
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
210 return;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
211 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
212
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
213 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
214 unexec_write (int fd, long position, char *buf, int bytes)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
215 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
216 int n_written;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
217 int remains = bytes;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
218 position = unexec_seek (fd, position);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
219
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
220 if (bytes < 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
221 unexec_error ("Attempted write of %d bytes in %s",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
222 0, (char *) bytes, "unexec() output file", 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
223
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
224 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
225
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
226 while (remains > 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
227 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
228 n_written = write (fd, buf, remains);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
229 if (n_written <= 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
230 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
231 1, (char *) bytes, (char *) position,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
232 "unexec() output file");
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
233 buf += n_written;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
234 remains -= n_written;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
235 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
236
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
237 return;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
238 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
239
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
240 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
241 unexec_pad (int fd, int bytes)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
242 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
243 if (bytes > 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
244 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
245 char buf[1024];
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
246 int remaining = bytes;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
247
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
248 memset (buf, 0, sizeof (buf));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
249
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
250 while (remaining > 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
251 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
252 int this_write = (remaining > sizeof(buf))?sizeof(buf):remaining;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
253 unexec_write (fd, -1, buf, this_write);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
254 remaining -= this_write;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
255 }
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 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
260 unexec_fstat (int fd, struct stat *statptr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
261 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
262 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
263 if (-1 == fstat (fd, statptr))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
264 unexec_error ("fstat() failed for descriptor %d", 1, (char *) fd, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
265 return;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
266 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
267
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
268 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
269 unexec_fchmod (int fd, int mode)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
270 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
271 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
272 if (-1 == fchmod (fd, mode))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
273 unexec_error ("fchmod() failed for descriptor %d", 1, (char *) fd, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
274 return;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
275 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
276
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
277 static long
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
278 unexec_addr_to_offset (long addr, struct translation_struct *ts)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
279
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
280 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
281 if ((addr < ts->txtaddr) || (addr >= ts->bssaddr))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
282 unexec_error ("bad address 0x%x to addr_to_offset()",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
283 0, (char *) addr, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
284 if (addr >= ts->dataddr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
285 return ((long) ((addr - ts->dataddr) + ts->datoff));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
286 else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
287 return ((long) ((addr - ts->txtaddr) + ts->txtoff));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
288 }
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 * "LD.SO" DATA AND SYMBOL TABLE OPERATIONS
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
293 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
294
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
295 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
296 copy_relocation_site (struct relocation_info *ri,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
297 caddr_t from_base_addr,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
298 caddr_t to_base_addr,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
299 struct translation_struct *ts)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
300 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
301 long offset = unexec_addr_to_offset (ri->r_address, ts);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
302 caddr_t from = from_base_addr + offset;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
303 caddr_t to = to_base_addr + offset;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
304
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
305 #ifdef mc68020
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
306 #define r_type r_length
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
307 #endif /* mc68020 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
308 switch (ri->r_type)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
309 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
310 #ifdef mc68020
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
311 case 0:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
312 *((char *) to) = *((char *) from);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
313 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
314 case 1:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
315 *((short *) to) = *((short *) from);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
316 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
317 case 2:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
318 *((long *) to) = *((long *) from);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
319 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
320 #else /* !mc68020 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
321 case RELOC_8:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
322 case RELOC_DISP8:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
323 *((char *) to) = *((char *) from);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
324 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
325 case RELOC_16:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
326 case RELOC_DISP16:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
327 *((short *) to) = *((short *) from);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
328 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
329 case RELOC_LO10:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
330 case RELOC_13:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
331 case RELOC_22:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
332 case RELOC_HI22:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
333 case RELOC_WDISP22:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
334 case RELOC_WDISP30:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
335 case RELOC_32:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
336 case RELOC_DISP32:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
337 case RELOC_GLOB_DAT:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
338 *((long *) to) = *((long *) from);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
339 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
340 case RELOC_JMP_SLOT:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
341 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
342 long *target = (long *) to;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
343 long *source = (long *) from;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
344 *target = *source;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
345 target++;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
346 source++;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
347 *target = *source;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
348 target++;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
349 source++;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
350 *target = *source;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
351 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
352 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
353 #endif /* !mc68020 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
354 default:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
355 unexec_error ("unknown reloc type %d seen during unexec()",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
356 0, (char *) ri->r_type, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
357 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
358 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
359 return;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
360 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
361
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
362 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
363 reset_symtab (struct nlist *start, struct nlist *end, char *strtab,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
364 long edata_value, long end_value, int ld_so_table,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
365 int shlib_image)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
366 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
367 struct nlist *tmp = start;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
368 int found_edata = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
369 int found_end = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
370
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
371 while (tmp < end)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
372 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
373 int type = tmp->n_type;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
374 int named = (ld_so_table)?1:(tmp->n_un.n_strx);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
375
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
376 if ((type == (N_UNDF | N_EXT)) &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
377 (tmp->n_value != 0))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
378 unexec_error ("unexec'ing image has COMMON symbols in it -- we quit!",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
379 0, 0, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
380
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
381 if (!(type & N_STAB))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
382 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
383 if (!found_edata &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
384 (type == (N_EXT | N_DATA)) &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
385 named &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
386 !strcmp ("_edata", strtab + tmp->n_un.n_strx))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
387 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
388 tmp->n_value = edata_value;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
389 found_edata = 1;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
390 }
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 if ((type & N_TYPE) == N_BSS)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
394 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
395 if (!found_end &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
396 (type == (N_EXT | N_BSS)) &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
397 named &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
398 !strcmp ("_end", strtab + tmp->n_un.n_strx))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
399 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
400 tmp->n_value = end_value;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
401 found_end = 1;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
402 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
403 else if (type & N_EXT)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
404 tmp->n_type = N_DATA | N_EXT;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
405 else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
406 tmp->n_type = N_DATA;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
407 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
408
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
409 /* the way things are being handled here, having sbrk() in the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
410 image is fatal for an image linked with shared lib's (although
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
411 the code could be modified to support it), but this should
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
412 never happen anyway */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
413 if (shlib_image &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
414 (type == (N_EXT | N_TEXT)) &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
415 named &&
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
416 !strcmp ("_sbrk", strtab + tmp->n_un.n_strx))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
417 unexec_error ("unexec'd shlib image has sbrk() in it -- we quit!",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
418 0, 0, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
419 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
420
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
421 tmp++;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
422 }
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 extern int getpagesize (void);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
426
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
427 /*
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
428 * EXPORTED FUNCTIONS
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
429 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
430
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
431 /* this has to be a global variable to prevent the optimizers from
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
432 * assuming that it can not be 0.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
433 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
434 static void *dynamic_addr = (void *) &_DYNAMIC;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
435
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
436 int
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
437 unexec (char *new_name, char *old_name,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
438 unsigned int emacs_edata, unsigned int dummy1, unsigned int dummy2)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
439 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
440 /* ld.so data */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
441 struct link_dynamic *ld = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
442 struct link_dynamic_2 *ld2 = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
443 /* old and new state */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
444 int old_fd;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
445 int new_fd;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
446 caddr_t old_base_addr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
447 caddr_t new_base_addr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
448 struct exec old_hdr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
449 struct exec new_hdr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
450 struct stat old_buf;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
451 struct stat new_buf;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
452 /* some process specific "constants" */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
453 unsigned long n_pagsiz;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
454 long page_size = getpagesize ();
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
455 caddr_t plt_end;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
456 caddr_t current_break = (caddr_t) sbrk (0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
457
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
458 if (!page_size)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
459 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
460 0, 0, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
461
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
462 /* see if this is a -Bdynamic image -- if so, find ld.so structures */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
463 if (dynamic_addr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
464 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
465 ld = (struct link_dynamic *) dynamic_addr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
466 ld2 = ld->ld_un.ld_2;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
467 if (ld->ld_version < 2)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
468 unexec_error ("%s linked with obsolete version of ld -- we quit!",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
469 0, old_name, 0, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
470 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
471
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
472 /* 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
473 so that we can map it in */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
474 old_fd = unexec_open (old_name, O_RDONLY, 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
475 new_fd = unexec_open (new_name, O_RDWR | O_CREAT | O_TRUNC, 0666);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
476
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
477 /* setup the header and the statbuf for old_fd */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
478 unexec_read (old_fd, 0, (char *) &old_hdr, sizeof (old_hdr));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
479 unexec_fstat (old_fd, &old_buf);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
480
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
481
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
482 /* set up some important constants */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
483 n_pagsiz = N_PAGSIZ (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
484 if (dynamic_addr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
485 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
486 else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
487 plt_end = (caddr_t) N_DATADDR (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
488
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
489 /* 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
490 set in process.c */
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
491 mprotect_bottom_addr = ((unsigned long) &environ) + sizeof (char **);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
492 /* never protect ABOVE the end of data emacs_edata specified */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
493 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
494
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
495 /* Set up the image of the old file */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
496 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
497 close (old_fd);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
498
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
499 /* set up the new exec */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
500 new_hdr = old_hdr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
501 new_hdr.a_data = (((unsigned long) MASK_UP (current_break, n_pagsiz)) -
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
502 ((unsigned long) N_DATADDR (old_hdr)));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
503 new_hdr.a_bss = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
504
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
505 /* set up this variable, in case we want to reset "the break"
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
506 when restarting */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
507 sbrk_of_0_at_unexec = ((unsigned long) MASK_UP (current_break, n_pagsiz));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
508
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
509 /* Write out the first approximation to the new file. The sizes of
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
510 each section will be correct, but there will be a number of
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
511 corrections that will need to be made. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
512 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
513 long old_datoff = N_DATOFF (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
514 long old_dataddr = N_DATADDR (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
515 long new_treloff = N_TRELOFF (new_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
516 long old_treloff = N_TRELOFF (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
517 long ld_so_size = ((unsigned long) plt_end) - old_dataddr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
518 long real_data_size = current_break - plt_end;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
519 long pad_size =
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
520 MASK_UP (current_break, n_pagsiz) - ((unsigned long) current_break);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
521
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
522
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
523 /* First, write the text segment with new header -- copy everything until
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
524 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
525 write the new header. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
526 unexec_write (new_fd, 0, old_base_addr, old_datoff + ld_so_size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
527 unexec_write (new_fd, 0, (char *) &new_hdr, sizeof (new_hdr));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
528
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
529 /* Copy the rest of the data segment from the running image. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
530 unexec_write (new_fd, old_datoff + ld_so_size,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
531 plt_end, real_data_size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
532
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
533 /* pad out the data segment */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
534 unexec_pad (new_fd, pad_size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
535
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
536 /* Finally, copy the symbol table information from the old file. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
537 unexec_write (new_fd, new_treloff,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
538 old_base_addr + old_treloff,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
539 old_buf.st_size - old_treloff);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
540 }
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 /* 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
544 up. We retain the old file so that we can refer to it. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
545 unexec_fstat (new_fd, &new_buf);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
546 new_base_addr = unexec_mmap (new_fd,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
547 MASK_UP (new_buf.st_size, page_size),
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
548 PROT_READ | PROT_WRITE, MAP_SHARED);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
549
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 /* 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
553 hence, curbrk) are set to the correct values. At the same time, for
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
554 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
555 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
556 there are no COMMON symbols in the output file, as any references to
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
557 these can lose really big. Second, reset all of the ld.so "relocation
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
558 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
559 -- 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
560 this code. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
561
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
562 /* STEP 1 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
563 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
564 /* Reset the regular symbol table first. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
565 reset_symtab ((struct nlist *) (new_base_addr + N_SYMOFF(new_hdr)),
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
566 (struct nlist *) (new_base_addr + N_SYMOFF(new_hdr) +
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
567 new_hdr.a_syms),
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
568 (char *) (new_base_addr + N_STROFF(new_hdr)),
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
569 N_DATADDR (new_hdr) + new_hdr.a_data,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
570 N_BSSADDR (new_hdr) + new_hdr.a_bss,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
571 0, !!dynamic_addr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
572 /* Now reset the ld.so symbol table. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
573 if (dynamic_addr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
574 reset_symtab ((struct nlist *) (new_base_addr + ld2->ld_stab),
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
575 (struct nlist *) (new_base_addr + ld2->ld_symbols),
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
576 (char *) (new_base_addr + ld2->ld_symbols),
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
577 N_DATADDR (new_hdr) + new_hdr.a_data,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
578 N_BSSADDR (new_hdr) + new_hdr.a_bss,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
579 1, !!dynamic_addr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
580 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
581
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
582 /* STEP 2 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
583 if (dynamic_addr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
584 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
585 struct translation_struct ts;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
586 struct relocation_info *tmp =
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
587 (struct relocation_info *) (old_base_addr + ld2->ld_rel);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
588 struct relocation_info *end =
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
589 (struct relocation_info *)(old_base_addr + ld2->ld_hash);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
590
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
591 /* set up the structure that we use to translate addresses in the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
592 old file into file offsets */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
593 ts.txtaddr = N_TXTADDR (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
594 ts.txtoff = N_TXTOFF (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
595 ts.dataddr = N_DATADDR (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
596 ts.datoff = N_DATOFF (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
597 ts.bssaddr = N_BSSADDR (old_hdr);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
598
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
599 while (tmp < end)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
600 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
601 copy_relocation_site (tmp, old_base_addr, new_base_addr, &ts);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
602 tmp++;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
603 }
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 /* get rid of the mmap-ed file space and make the output file
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
608 executable -- then quit */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
609 munmap (new_base_addr, MASK_UP (new_buf.st_size, page_size));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
610 munmap (old_base_addr, MASK_UP (old_buf.st_size, page_size));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
611 unexec_fchmod (new_fd, 0755);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
612 close (new_fd);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
613 return 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
614 }
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 int
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
618 run_time_remap (char *dummy)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
619 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
620 long page_size = getpagesize();
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
621 unsigned long base_addr = MASK_UP (mprotect_bottom_addr, page_size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
622 unsigned long top_addr = MASK_DOWN (mprotect_top_addr, page_size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
623 long len = top_addr - base_addr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
624
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
625 if (!dynamic_addr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
626 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
627 unsigned long current_sbrk = (unsigned long) sbrk (0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
628
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
629 if (sbrk_of_0_at_unexec < current_sbrk)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
630 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
631 if (sbrk_of_0_at_unexec != 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
632 /* GCC -Wall even catches incorrect printf type errors.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
633 How utterly cool. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
634 fprintf (stderr,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
635 "Absurd new brk addr = 0x%lx (current = 0x%lx)\n",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
636 sbrk_of_0_at_unexec, current_sbrk);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
637 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
638 else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
639 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
640 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
641 if (brk ((caddr_t) sbrk_of_0_at_unexec))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
642 fprintf (stderr, "failed to change brk addr to 0x%lx: %s\n",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
643 sbrk_of_0_at_unexec, SYS_ERR);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
644 }
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 if (len > 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
648 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
649 errno = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
650 if (mprotect ((caddr_t) base_addr, len, PROT_READ | PROT_EXEC))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
651 fprintf (stderr, "failed to change protection on data pages: %s\n",
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
652 SYS_ERR);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
653 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
654
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
655 return 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
656 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
657