annotate src/unexconvex.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 b39c14581166
children 04bc9d2f42c7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 /* Modified version of unexec for convex machines.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2 Copyright (C) 1985, 1986, 1988 Free Software Foundation, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4 This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6 XEmacs is free software; you can redistribute it and/or modify it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7 under the terms of the GNU General Public License as published by the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 Free Software Foundation; either version 2, or (at your option) any
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9 later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17 along with XEmacs; see the file COPYING. If not, write to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 Boston, MA 02111-1307, USA. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 /* Synched up with: FSF 19.31. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22
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 /* modified for C-1 arch by jthomp@convex 871103 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 /* Corrected to support convex SOFF object file formats and thread specific
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 * regions. streepy@convex 890302
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28
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 * unexec.c - Convert a running program into an a.out file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 * Author: Spencer W. Thomas
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 * Computer Science Dept.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 * University of Utah
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 * Date: Tue Mar 2 1982
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 * Modified heavily since then.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 * Synopsis:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 * unexec (new_name, a_name, data_start, bss_start, entry_address)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 * char *new_name, *a_name;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 * unsigned data_start, bss_start, entry_address;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 * Takes a snapshot of the program and makes an a.out format file in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 * file named by the string argument new_name.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 * If a_name is non-NULL, the symbol table will be taken from the given file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 * On some machines, an existing a_name file is required.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 * The boundaries within the a.out file may be adjusted with the data_start
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 * and bss_start arguments. Either or both may be given as 0 for defaults.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51 * Data_start gives the boundary between the text segment and the data
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 * segment of the program. The text segment can contain shared, read-only
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 * program code and literal data, while the data segment is always unshared
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 * and unprotected. Data_start gives the lowest unprotected address.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 * The value you specify may be rounded down to a suitable boundary
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 * as required by the machine you are using.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 * Specifying zero for data_start means the boundary between text and data
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 * should not be the same as when the program was loaded.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 * If NO_REMAP is defined, the argument data_start is ignored and the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 * segment boundaries are never changed.
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 * Bss_start indicates how much of the data segment is to be saved in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 * a.out file and restored when the program is executed. It gives the lowest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 * unsaved address, and is rounded up to a page boundary. The default when 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 * is given assumes that the entire data segment is to be stored, including
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 * the previous data and bss as well as any additional storage allocated with
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 * break (2).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 * The new file is set up to start at entry_address.
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 * If you make improvements I'd like to get them too.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 * harpo!utah-cs!thomas, thomas@Utah-20
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 /* There are several compilation parameters affecting unexec:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 * COFF
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 Define this if your system uses COFF for executables.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 Otherwise we assume you use Berkeley format.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 * NO_REMAP
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 Define this if you do not want to try to save Emacs's pure data areas
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 as part of the text segment.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 Saving them as text is good because it allows users to share more.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 However, on machines that locate the text area far from the data area,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 the boundary cannot feasibly be moved. Such machines require
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 NO_REMAP.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 Also, remapping can cause trouble with the built-in startup routine
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 /lib/crt0.o, which defines `environ' as an initialized variable.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 Dumping `environ' as pure does not work! So, to use remapping,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 you must write a startup routine for your machine in Emacs's crt0.c.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 If NO_REMAP is defined, Emacs uses the system's crt0.o.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 * SECTION_ALIGNMENT
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 Some machines that use COFF executables require that each section
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 start on a certain boundary *in the COFF file*. Such machines should
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 define SECTION_ALIGNMENT to a mask of the low-order bits that must be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 zero on such a boundary. This mask is used to control padding between
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 segments in the COFF file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 If SECTION_ALIGNMENT is not defined, the segments are written
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 consecutively with no attempt at alignment. This is right for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 unmodified system V.
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 * SEGMENT_MASK
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 Some machines require that the beginnings and ends of segments
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 *in core* be on certain boundaries. For most machines, a page
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 boundary is sufficient. That is the default. When a larger
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 boundary is needed, define SEGMENT_MASK to a mask of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 the bits that must be zero on such a boundary.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 * A_TEXT_OFFSET(HDR)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 Some machines count the a.out header as part of the size of the text
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 segment (a_text); they may actually load the header into core as the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 first data in the text segment. Some have additional padding between
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 the header and the real text of the program that is counted in a_text.
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 For these machines, define A_TEXT_OFFSET(HDR) to examine the header
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 structure HDR and return the number of bytes to add to `a_text'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 before writing it (above and beyond the number of bytes of actual
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 program text). HDR's standard fields are already correct, except that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 this adjustment to the `a_text' field has not yet been made;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 thus, the amount of offset can depend on the data in the file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 * A_TEXT_SEEK(HDR)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 If defined, this macro specifies the number of bytes to seek into the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 a.out file before starting to write the text segment.a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 * EXEC_MAGIC
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 For machines using COFF, this macro, if defined, is a value stored
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 into the magic number field of the output file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 * ADJUST_EXEC_HEADER
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 This macro can be used to generate statements to adjust or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 initialize nonstandard fields in the file header
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 * ADDR_CORRECT(ADDR)
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 Macro to correct an int which is the bit pattern of a pointer to a byte
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 into an int which is the number of a byte.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 This macro has a default definition which is usually right.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 This default definition is a no-op on most machines (where a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 pointer looks like an int) but not on all machines.
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 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 #include <config.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 #define PERROR(file) report_error (file, new)
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 #include <a.out.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 /* Define getpagesize () if the system does not.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 Note that this may depend on symbols defined in a.out.h
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 #include "getpagesize.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 #include <sys/types.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 #include <stdio.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 #include <sys/stat.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 #include <errno.h>
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 extern char *start_of_text (); /* Start of text */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 extern char *start_of_data (); /* Start of initialized data */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 #include <machine/filehdr.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 #include <machine/opthdr.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 #include <machine/scnhdr.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 #include <machine/pte.h>
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 static long block_copy_start; /* Old executable start point */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 static struct filehdr f_hdr; /* File header */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 static struct opthdr f_ohdr; /* Optional file header (a.out) */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 long bias; /* Bias to add for growth */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 #define SYMS_START block_copy_start
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 static long text_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 static long data_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 static int pagemask;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 static int pagesz;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 static
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 report_error (file, fd)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 char *file;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 int fd;
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 if (fd)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 close (fd);
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 428
diff changeset
202 signal_error (Qio_error, "Failure operating on file",
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 428
diff changeset
203 build_string (file));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 #define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 #define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 #define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 static
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 report_error_1 (fd, msg, a1, a2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 int fd;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 char *msg;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 int a1, a2;
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 close (fd);
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 428
diff changeset
217 signal_ferror (Qio_error, msg, a1, a2);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 /* ****************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 * unexec
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 * driving logic.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 unexec (new_name, a_name, data_start, bss_start, entry_address)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 char *new_name, *a_name;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 unsigned data_start, bss_start, entry_address;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 int new, a_out = -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 if (a_name && (a_out = open (a_name, 0)) < 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 PERROR (a_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 if ((new = creat (new_name, 0666)) < 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235 PERROR (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 if (make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 || copy_text_and_data (new) < 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 || copy_sym (new, a_out, a_name, new_name) < 0 ) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 close (new);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 return -1;
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 close (new);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 if (a_out >= 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 close (a_out);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 mark_x (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 /* ****************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 * make_hdr
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 * Make the header in the new a.out from the header in core.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 * Modify the text and data sizes.
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 struct scnhdr *stbl; /* Table of all scnhdr's */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 struct scnhdr *f_thdr; /* Text section header */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 struct scnhdr *f_dhdr; /* Data section header */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 struct scnhdr *f_tdhdr; /* Thread Data section header */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 struct scnhdr *f_bhdr; /* Bss section header */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 struct scnhdr *f_tbhdr; /* Thread Bss section header */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 int new, a_out;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 unsigned data_start, bss_start, entry_address;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 char *a_name;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 char *new_name;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 int scns;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 unsigned int bss_end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 unsigned int eo_data; /* End of initialized data in new exec file */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 int scntype; /* Section type */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 int i; /* Var for sorting by vaddr */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 struct scnhdr scntemp; /* For swapping entries in sort */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 extern char *start_of_data();
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 pagemask = (pagesz = getpagesize()) - 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 /* Adjust text/data boundary. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 if (!data_start)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 data_start = (unsigned) start_of_data ();
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 data_start = data_start & ~pagemask; /* (Down) to page boundary. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 bss_end = (sbrk(0) + pagemask) & ~pagemask;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 /* Adjust data/bss boundary. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 if (bss_start != 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 bss_start = (bss_start + pagemask) & ~pagemask;/* (Up) to page bdry. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 if (bss_start > bss_end) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 ERROR1 ("unexec: Specified bss_start (%x) is past end of program",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 bss_start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 } else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 bss_start = bss_end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 if (data_start > bss_start) { /* Can't have negative data size. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302 ERROR2 ("unexec: data_start (%x) can't be greater than bss_start (%x)",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 data_start, bss_start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 /* Salvage as much info from the existing file as possible */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 if (a_out < 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 ERROR0 ("can't build a COFF file from scratch yet");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 /*NOTREACHED*/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 PERROR (a_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 block_copy_start += sizeof (f_hdr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316 if (f_hdr.h_opthdr > 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 if (read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318 PERROR (a_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 block_copy_start += sizeof (f_ohdr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 /* Allocate room for scn headers */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 stbl = (struct scnhdr *)malloc( sizeof(struct scnhdr) * f_hdr.h_nscns );
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 if( stbl == NULL ) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 ERROR0( "unexec: malloc of stbl failed" );
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 f_tdhdr = f_tbhdr = NULL;
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 /* Loop through section headers, copying them in */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 for (scns = 0; scns < f_hdr.h_nscns; scns++) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 if( read( a_out, &stbl[scns], sizeof(*stbl)) != sizeof(*stbl)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 PERROR (a_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 scntype = stbl[scns].s_flags & S_TYPMASK; /* What type of section */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 if( stbl[scns].s_scnptr > 0L) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 if( block_copy_start < stbl[scns].s_scnptr + stbl[scns].s_size )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 block_copy_start = stbl[scns].s_scnptr + stbl[scns].s_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 if( scntype == S_TEXT) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 f_thdr = &stbl[scns];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 } else if( scntype == S_DATA) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 f_dhdr = &stbl[scns];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 #ifdef S_TDATA
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 } else if( scntype == S_TDATA ) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 f_tdhdr = &stbl[scns];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 } else if( scntype == S_TBSS ) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 f_tbhdr = &stbl[scns];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 #endif /* S_TDATA (thread stuff) */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 } else if( scntype == S_BSS) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 f_bhdr = &stbl[scns];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 /* We will now convert TEXT and DATA into TEXT, BSS into DATA, and leave
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363 * all thread stuff alone.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 /* Now we alter the contents of all the f_*hdr variables
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 to correspond to what we want to dump. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 f_thdr->s_vaddr = (long) start_of_text ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 f_thdr->s_size = data_start - f_thdr->s_vaddr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 f_thdr->s_scnptr = pagesz;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372 f_thdr->s_relptr = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 f_thdr->s_nrel = 0;
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 eo_data = f_thdr->s_scnptr + f_thdr->s_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 if( f_tdhdr ) { /* Process thread data */
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 f_tdhdr->s_vaddr = data_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 f_tdhdr->s_size += f_dhdr->s_size - (data_start - f_dhdr->s_vaddr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 f_tdhdr->s_scnptr = eo_data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 f_tdhdr->s_relptr = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 f_tdhdr->s_nrel = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 eo_data += f_tdhdr->s_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 /* And now for DATA */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 f_dhdr->s_vaddr = f_bhdr->s_vaddr; /* Take BSS start address */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 f_dhdr->s_size = bss_end - f_bhdr->s_vaddr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 f_dhdr->s_scnptr = eo_data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 f_dhdr->s_relptr = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 f_dhdr->s_nrel = 0;
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 eo_data += f_dhdr->s_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397 } else {
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 f_dhdr->s_vaddr = data_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 f_dhdr->s_size = bss_start - data_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 f_dhdr->s_scnptr = eo_data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 f_dhdr->s_relptr = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 f_dhdr->s_nrel = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 eo_data += f_dhdr->s_size;
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 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409 f_bhdr->s_vaddr = bss_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 f_bhdr->s_size = bss_end - bss_start + pagesz /* fudge */;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 f_bhdr->s_scnptr = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 f_bhdr->s_relptr = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413 f_bhdr->s_nrel = 0;
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 text_scnptr = f_thdr->s_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416 data_scnptr = f_dhdr->s_scnptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417 bias = eo_data - block_copy_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
418
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419 if (f_ohdr.o_symptr > 0L) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
420 f_ohdr.o_symptr += bias;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
421 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
423 if (f_hdr.h_strptr > 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 f_hdr.h_strptr += bias;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427 if (write (new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428 PERROR (new_name);
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 if (write (new, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 PERROR (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435 for( scns = 0; scns < f_hdr.h_nscns; scns++ ) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 /* This is a cheesy little loop to write out the section headers
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 * in order of increasing virtual address. Dull but effective.
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441 for( i = scns+1; i < f_hdr.h_nscns; i++ ) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 if( stbl[i].s_vaddr < stbl[scns].s_vaddr ) { /* Swap */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 scntemp = stbl[i];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 stbl[i] = stbl[scns];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 stbl[scns] = scntemp;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 for( scns = 0; scns < f_hdr.h_nscns; scns++ ) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 if( write( new, &stbl[scns], sizeof(*stbl)) != sizeof(*stbl)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454 PERROR (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456
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 return (0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463 /* ****************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 * copy_text_and_data
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 * Copy the text and data segments from memory to the new a.out
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469 copy_text_and_data (new)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 int new;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 int scns;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 for( scns = 0; scns < f_hdr.h_nscns; scns++ )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 write_segment( new, &stbl[scns] );
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 write_segment( new, sptr )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 int new;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 struct scnhdr *sptr;
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 char *ptr, *end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 int nwrite, ret;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486 char buf[80];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 extern int errno;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488 char zeros[128];
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 if( sptr->s_scnptr == 0 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 return; /* Nothing to do */
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 if( lseek( new, (long) sptr->s_scnptr, 0 ) == -1 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494 PERROR( "unexecing" );
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 563
diff changeset
496 memset (zeros, 0, sizeof (zeros));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 ptr = (char *) sptr->s_vaddr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 end = ptr + sptr->s_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501 while( ptr < end ) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 /* distance to next multiple of 128. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504 nwrite = (((int) ptr + 128) & -128) - (int) ptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 /* But not beyond specified end. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 if (nwrite > end - ptr) nwrite = end - ptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 ret = write (new, ptr, nwrite);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 /* If write gets a page fault, it means we reached
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 a gap between the old text segment and the old data segment.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 This gap has probably been remapped into part of the text segment.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 So write zeros for it. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 if (ret == -1 && errno == EFAULT)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 write (new, zeros, nwrite);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 else if (nwrite != ret) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 sprintf (buf,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 ptr, new, nwrite, ret, errno);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 PERROR (buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 ptr += nwrite;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 }
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 /* ****************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 * copy_sym
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 * Copy the relocation information and symbol table from the a.out to the new
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 copy_sym (new, a_out, a_name, new_name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 int new, a_out;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 char *a_name, *new_name;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 char page[1024];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 int n;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 if (a_out < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 return 0;
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 if (SYMS_START == 0L)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
543 lseek (a_out, SYMS_START, 0); /* Position a.out to symtab. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544 lseek( new, (long)f_ohdr.o_symptr, 0 );
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 563
diff changeset
546 while ((n = read (a_out, page, sizeof (page))) > 0) {
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547 if (write (new, page, n) != n) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
548 PERROR (new_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
549 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
550 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
551 if (n < 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
552 PERROR (a_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
553 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
554 return 0;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557 /* ****************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
558 * mark_x
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
559 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
560 * After successfully building the new a.out, mark it executable
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
561 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562 static
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
563 mark_x (name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
564 char *name;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
565 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
566 struct stat sbuf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
567 int um;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
568 int new = 0; /* for PERROR */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
570 um = umask (777);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 umask (um);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572 if (stat (name, &sbuf) == -1) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
573 PERROR (name);
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 sbuf.st_mode |= 0111 & ~um;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
576 if (chmod (name, sbuf.st_mode) == -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
577 PERROR (name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
578 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
579
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580 /* Find the first pty letter. This is usually 'p', as in ptyp0, but
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
581 is sometimes configured down to 'm', 'n', or 'o' for some reason. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
583 first_pty_letter ()
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 struct stat buf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
586 char pty_name[16];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
587 char c;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
588
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
589 for (c = 'o'; c >= 'a'; c--)
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 sprintf (pty_name, "/dev/pty%c0", c);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
592 if (stat (pty_name, &buf) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593 return c + 1;
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 return 'a';
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597