annotate src/unexelfsgi.c @ 844:047d37eb70d7

[xemacs-hg @ 2002-05-16 13:30:23 by ben] ui fixes for things that were bothering me bytecode.c, editfns.c, lisp.h, lread.c: Fix save-restriction to use markers rather than pseudo-markers (integers representing the amount of text on either side of the region). That way, all inserts are handled correctly, not just those inside old restriction. Add buffer argument to save_restriction_save(). process.c: Clean up very dirty and kludgy code that outputs into a buffer -- use proper unwind protects, etc. font-lock.c: Do save-restriction/widen around the function -- otherwise, incorrect results will ensue when a buffer has been narrowed before a call to e.g. `buffer-syntactic-context' -- something that happens quite often. fileio.c: Look for a handler for make-temp-name. window.c, winslots.h: Try to solve this annoying problem: have two frames displaying the buffer, in different places; in one, temporarily switch away to another buffer and then back -- and you've lost your position; it's reset to the other one in the other frame. My current solution involves window-level caches of buffers and points (also a cache for window-start); when set-window-buffer is called, it looks to see if the buffer was previously visited in the window, and if so, uses the most recent point at that time. (It's a marker, so it handles changes.) #### Note: It could be argued that doing it on the frame level would be better -- e.g. if you visit a buffer temporarily through a grep, and then go back to that buffer, you presumably want the grep's position rather than some previous position provided everything was in the same frame, even though the grep was in another window in the frame. However, doing it on the frame level fails when you have two windows on the same frame. Perhaps we keep both a window and a frame cache, and use the frame cache if there are no other windows on the frame showing the buffer, else the window's cache? This is probably something to be configurable using a specifier. Suggestions please please please? window.c: Clean up a bit code that deals with the annoyance of window-point vs. point. dialog.el: Function to ask a multiple-choice question, automatically choosing a dialog box or minibuffer representation as necessary. Generalized version of yes-or-no-p, y-or-n-p. files.el: Use get-user-response to ask "yes/no/diff" question when recovering. "diff" means that a diff is displayed between the current file and the autosave. (Converts/deconverts escape-quoted as necessary. No more complaints from you, Mr. Turnbull!) One known problem: when a dialog is used, it's modal, so you can't scroll the diff. Will fix soon. lisp-mode.el: If we're filling a string, don't treat semicolon as a comment, which would give very unfriendly results. Uses `buffer-syntactic-context'. simple.el: all changes back to the beginning. (Useful if you've saved the file in the middle of the changes.) simple.el: Add option kill-word-into-kill-ring, which controls whether words deleted with kill-word, backward-kill-word, etc. are "cut" into the kill ring, or "cleared" into nothingness. (My preference is the latter, by far. I'd almost go so far as suggesting we make it the default, as you can always select a word and then cut it if you want it cut.) menubar-items.el: Add option corresponding to kill-word-into-kill-ring.
author ben
date Thu, 16 May 2002 13:30:58 +0000
parents 023b83f4e54b
children 04bc9d2f42c7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
1 /* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992, 1999, 2000
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2 Free Software Foundation, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
4 This file is part of XEmacs.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
6 XEmacs is free software; you can redistribute it and/or modify it
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
7 under the terms of the GNU General Public License as published by
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
8 the Free Software Foundation; either version 2, or (at your option)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
9 any later version.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10
613
023b83f4e54b [xemacs-hg @ 2001-06-10 10:42:16 by ben]
ben
parents: 448
diff changeset
11 XEmacs is distributed in the hope that it will be useful, but
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
12 WITHOUT ANY WARRANTY; without even the implied warranty of
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
14 General Public License for more details.
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
15
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
16 You should have received a copy of the GNU General Public License
613
023b83f4e54b [xemacs-hg @ 2001-06-10 10:42:16 by ben]
ben
parents: 448
diff changeset
17 along with XEmacs; see the file COPYING. If not, write to the
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
19 Boston, MA 02111-1307, USA.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
21 In other words, you are welcome to use, share and improve this
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
22 program. You are forbidden to forbid anyone else to use, share and
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
23 improve what you give them. Help stamp out software-hoarding! */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27 * unexec.c - Convert a running program into an a.out file.
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 * Author: Spencer W. Thomas
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30 * Computer Science Dept.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31 * University of Utah
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 * Date: Tue Mar 2 1982
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 * Modified heavily since then.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 * Synopsis:
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
36 * void
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
37 * unexec (char *new_name,
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
38 * char *old_name,
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
39 * uintptr_t data_start,
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
40 * uintptr_t bss_start,
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
41 * uintptr_t entry_address)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 *
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
43 * The basic idea is that we start with an ELF file which contains
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
44 * .bss (uninitialized global data) section which is normally not in
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
45 * the file. As we load lisp the variables, which were first set to 0,
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
46 * will change their values. We want to save those changed values into
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
47 * another ELF file, which will become a new xemacs image. To do this,
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
48 * we need to change several structures in the ELF file.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 *
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
50 * First of all, we need to change the programm header which tells
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
51 * the linker how to load stuff into memory so that data will come
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
52 * from the file and not from the /dev/zero. To do this, we find the
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
53 * segment, which is marked as loadable (type PT_LOAD) and which
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
54 * covers the old .bss section. We will next change the filesz and
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
55 * memsz for that segment to extend over the new data section.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 *
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
57 * Next we have to make sure that section header for the stuff which
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
58 * used to be uninitialized is changed to be initialized and to come
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
59 * from the file. To do this, we change the size and the type of the old
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
60 * .bss section (and all other section of the type SHT_NOBITS) to cover the
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
61 * new section and to be of type SHT_PROCBITS.
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
62 *
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
63 * We also insert a new SHT_NOBITS section to keep some tools, which expect
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
64 * .bss happy.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 *
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
66 * Finally we need to patch up some references to the section
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
67 * indexes since we change the order and undo the relocation info to
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
68 * be the same as it was "before" because we actually used the data
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
69 * from the memory which were changed by the run-time linker.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 */
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
71
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
72 #ifndef emacs
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
73 #define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
74 #include <string.h>
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
75 #else
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
76 #include <config.h>
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
77 extern void fatal (const char *, ...);
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
78 #endif
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 #include <sys/types.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 #include <stdio.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 #include <sys/stat.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 #include <memory.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 #include <errno.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85 #include <unistd.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 #include <fcntl.h>
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
87 #ifdef HAVE_ELF_H
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 #include <elf.h>
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
89 #endif
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90 #include <sys/mman.h>
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
91 #if defined (__sony_news) && defined (_SYSTYPE_SYSV)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
92 #include <sys/elf_mips.h>
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
93 #include <sym.h>
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
94 #endif /* __sony_news && _SYSTYPE_SYSV */
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
95 #if __sgi
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
96 #include <syms.h> /* for HDRR declaration */
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
97 #endif /* __sgi */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
99 #if __GNU_LIBRARY__ - 0 >= 6
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
100 # include <link.h> /* get ElfW etc */
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
101 #endif
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
102
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
103 #ifndef ElfW
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
104 # ifdef __STDC__
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
105 # define ElfBitsW(bits, type) Elf##bits##_##type
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
106 # else
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
107 # define ElfBitsW(bits, type) Elf/**/bits/**/_/**/type
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
108 # endif
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
109 # ifdef _LP64
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
110 # define ELFSIZE 64
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
111 # else
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
112 # define ELFSIZE 32
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
113 # endif
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
114 /* This macro expands `bits' before invoking ElfBitsW. */
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
115 # define ElfExpandBitsW(bits, type) ElfBitsW (bits, type)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
116 # define ElfW(type) ElfExpandBitsW (ELFSIZE, type)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
117 #endif
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
118
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
119 #ifndef ELF_BSS_SECTION_NAME
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
120 #define ELF_BSS_SECTION_NAME ".bss"
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
121 #endif
428
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 /* Get the address of a particular section or program header entry,
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
124 * accounting for the size of the entries. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 #define OLD_SECTION_H(n) \
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
127 (*(ElfW(Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 #define NEW_SECTION_H(n) \
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
129 (*(ElfW(Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 #define OLD_PROGRAM_H(n) \
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
131 (*(ElfW(Phdr) *) ((byte *) old_program_h + old_file_h->e_phentsize * (n)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 #define NEW_PROGRAM_H(n) \
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
133 (*(ElfW(Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
428
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 #define PATCH_INDEX(n) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 do { \
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
137 if ((int) (n) >= growme_index) \
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 (n)++; } while (0)
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
139
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 typedef unsigned char byte;
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 /* Round X up to a multiple of Y. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
144 static ElfW(Addr)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
145 round_up (ElfW(Addr) x, ElfW(Addr) y)
428
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 int rem = x % y;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 if (rem == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 return x;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 return x - rem + y;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 /* Return the index of the section named NAME.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 SECTION_NAMES, FILE_NAME and FILE_H give information
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 about the file we are looking in.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 If we don't find the section NAME, that is a fatal error
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 if NOERROR is 0; we return -1 if NOERROR is nonzero. */
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 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 find_section (char *name,
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
162 const char *section_names,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 char *file_name,
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
164 ElfW(Ehdr) *old_file_h,
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
165 ElfW(Shdr) *old_section_h,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 int noerror)
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 int idx;
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 for (idx = 1; idx < old_file_h->e_shnum; idx++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 #ifdef DEBUG
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 fprintf (stderr, "Looking for %s - found %s\n", name,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 section_names + OLD_SECTION_H (idx).sh_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 if (!strcmp (section_names + OLD_SECTION_H (idx).sh_name,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 name))
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
178 return idx;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
181 /* If we're here, we found nothing or return did not work */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
182 if ( ! noerror)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
183 fatal ("Can't find %s in %s.\n", name, file_name);
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
184
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
185 return -1;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 /* ****************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 * unexec
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 * driving logic.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 * In ELF, this works by replacing the old .bss section with a new
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 * .data section, and inserting an empty .bss immediately afterwards.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 */
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
197 void
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 unexec (char *new_name,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 char *old_name,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 uintptr_t data_start,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 uintptr_t bss_start,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 uintptr_t entry_address)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 {
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
204 int old_file;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
206 struct stat stat_buf;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 caddr_t old_base, new_base;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
209 ElfW(Ehdr) *old_file_h, * new_file_h;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
210 ElfW(Phdr) *old_program_h, * new_program_h;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
211 ElfW(Shdr) *old_section_h, * new_section_h;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
212 ElfW(Shdr) * growme = NULL, * grown = NULL;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
213 ElfW(Addr) old_bss_addr = 0, new_data2_addr = 0;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
215 int growme_index = -1;
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
216 int n, nn;
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
217 const char *old_section_names;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
218 int old_mdebug_index, old_data_index;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
219 int new_bss_addr, new_data2_size, new_data2_offset, new_file, new_file_size;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
221 /* Open the old file */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
222 if ( (old_file = open (old_name, O_RDONLY)) < 0 )
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
223 fatal ("Can't open %s for reading: errno %d\n", old_name, errno);
428
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 if (fstat (old_file, &stat_buf) == -1)
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
226 fatal ("Can't fstat (%s): errno %d\n", old_name, errno);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
228 /* map old file into the address space. */
448
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
229 old_base = (caddr_t) mmap ((caddr_t) 0, stat_buf.st_size,
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
230 PROT_READ, MAP_SHARED, old_file, 0);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
231 if (old_base == (caddr_t) MAP_FAILED)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
232 fatal ("Can't mmap (%s): errno %d\n", old_name, errno);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
234 old_file_h = (ElfW(Ehdr) *) old_base;
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
235 old_program_h = (ElfW(Phdr) *) ((byte *) old_base + old_file_h->e_phoff);
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
236 old_section_h = (ElfW(Shdr) *) ((byte *) old_base + old_file_h->e_shoff);
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
237 old_section_names = (const char *) old_base
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
238 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
240 /* Find a section which we will grow by looking for the SHT_NOBITS
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
241 * section with ALLOCATE flag and with the biggest address. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
242 for (n = 1; n < old_file_h->e_shnum; n++) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
243 ElfW(Shdr) * sh = & OLD_SECTION_H(n);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
245 if ((sh->sh_type == SHT_NOBITS) && (sh->sh_flags & SHF_ALLOC)) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
246 if ( old_bss_addr < sh->sh_addr ) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
247 growme = sh;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
248 growme_index = n;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
249 new_data2_addr = old_bss_addr = sh->sh_addr;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
250 }
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
251 }
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
252 }
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
254 if (growme == NULL )
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
255 fatal ("Can't find a section to grow\n", 0, 0);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 old_data_index = find_section (".data", old_section_names,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 old_name, old_file_h, old_section_h, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
260 new_bss_addr = (ElfW(Addr)) sbrk (0);
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
261 new_data2_size = new_bss_addr - old_bss_addr;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset +
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
263 (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
265 if ( new_bss_addr < old_bss_addr + growme->sh_size )
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
266 fatal (".bss shrank when undumping???\n", 0, 0);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
268 /* Set the output file to the right size and mmap it. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
269 if ( (new_file = open (new_name, O_RDWR | O_CREAT, 0666)) < 0 )
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
270 fatal ("Can't create (%s): errno %d\n", new_name, errno);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
272 new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_size;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 if (ftruncate (new_file, new_file_size))
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
275 fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
277 new_base = (caddr_t) mmap ((caddr_t) 0, new_file_size,
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
278 PROT_READ | PROT_WRITE,
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
279 #ifdef UNEXEC_USE_MAP_PRIVATE
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
280 MAP_PRIVATE,
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
281 #else
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
282 MAP_SHARED,
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
283 #endif
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
284 new_file, 0);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 if (new_base == (caddr_t) -1)
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
287 fatal ("Can't mmap (%s): errno %d\n", new_name, errno);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
289 new_file_h = (ElfW(Ehdr) *) new_base;
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
290 new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
291 new_section_h = (ElfW(Shdr) *) ((byte *) new_base + old_file_h->e_shoff +
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
292 new_data2_size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 /* Make our new file, program and section headers as copies of the
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
295 * originals. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 memcpy (new_file_h, old_file_h, old_file_h->e_ehsize);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 memcpy (new_program_h, old_program_h,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 old_file_h->e_phnum * old_file_h->e_phentsize);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 /* Modify the e_shstrndx if necessary. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 PATCH_INDEX (new_file_h->e_shstrndx);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 /* Fix up file header. We'll add one section. Section header is
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
304 * further away now. */
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
305 new_file_h->e_shoff += new_data2_size;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 new_file_h->e_shnum += 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
308 /* Fix up a new program header by extending the writable data
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
309 * segment so that the bss area is covered too. Find that segment by
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
310 * looking for one that starts before and ends after the .bss and is
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
311 * PT_LOADable. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
312 for (n = new_file_h->e_phnum - 1; n >= 0; n--) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
313 ElfW(Phdr) * ph = & NEW_PROGRAM_H(n);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 #ifdef DEBUG
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
315 printf ("%d @ %0x + %0x against %0x + %0x",
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
316 n, ph->p_vaddr, ph->p_memsz,growme->sh_addr, growme->sh_size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 #endif
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
318 if ((ph->p_type == PT_LOAD) &&
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
319 (ph->p_vaddr <= growme->sh_addr) &&
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
320 ((ph->p_vaddr+ph->p_memsz) >= (growme->sh_addr + growme->sh_size))) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
321 /* Make sure that the size includes any padding before the
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
322 * old .bss section. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
323 ph->p_memsz = ph->p_filesz = new_bss_addr - ph->p_vaddr;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
324 #ifdef DEBUG
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
325 puts (" That's the one!");
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
326 #endif
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
327 break;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
328 }
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
329 #ifdef DEBUG
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
330 putchar ('\n');
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
331 #endif
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
332 }
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
334 if (n < 0)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
335 fatal ("Couldn't find segment which covers %s",
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
336 old_section_names + growme->sh_name);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
338 /* Walk through all section headers, insert the new data2 section
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
339 * right before the new bss section. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
340 for (n = 1, nn = 1; n < (int) old_file_h->e_shnum; n++, nn++) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
341 ElfW(Shdr) * nsec = & NEW_SECTION_H(nn);
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
342 ElfW(Shdr) * osec = & OLD_SECTION_H(n);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
344 /* If this is the section we want to grow, insert the new data
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
345 * section before it. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
346 if ( osec == growme ) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
347 /* Steal the data section header for this data2 section but
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
348 * use the * 'grow' section's alignment. This * will assure
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
349 * that the new section * always be placed in the same spot
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
350 * * as the old section by any other * application. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
351 ElfW(Shdr) * od = &OLD_SECTION_H(old_data_index);
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
352
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
353 memcpy (nsec, od, new_file_h->e_shentsize);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
355 nsec->sh_addr = new_data2_addr;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
356 nsec->sh_offset = new_data2_offset;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
357 nsec->sh_size = new_data2_size;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
358 nsec->sh_addralign = osec->sh_addralign;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
359
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
360 /* Copy over what we have in memory now. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
361 memcpy (nsec->sh_offset + new_base, (caddr_t) osec->sh_addr,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 new_data2_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363 nn++;
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
364 grown = nsec++;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
365 }
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
366
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
367 memcpy (nsec, osec, old_file_h->e_shentsize);
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
368
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
369 if ( osec == growme ) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
370 /* The new bss section's size is zero, and its file offset
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
371 * and virtual address should be off by NEW_DATA2_SIZE. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
372 nsec->sh_offset = grown->sh_offset + new_data2_size;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
373 nsec->sh_addr = grown->sh_addr + new_data2_size;
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
374
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
375 /* Let the new bss section address alignment be the same as
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
376 * the section address alignment followed the old bss
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
377 * section, so this section will be placed in exactly the
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
378 * same place. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
379 nsec->sh_addralign = osec->sh_addralign;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
380 nsec->sh_size = 0;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
381 } else {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
382 /* Any section that was originally placed AFTER the bss
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
383 * section should now be off by NEW_DATA2_SIZE. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
384 if ( round_up (nsec->sh_offset, growme->sh_addralign) >=
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
385 new_data2_offset)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
386 nsec->sh_offset += new_data2_size;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
387 }
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
388
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
389 /* Any section that was originally placed after the section *
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
390 * header table should now be off by the size of one section
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
391 * header table entry. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
392 if (nsec->sh_offset > new_file_h->e_shoff)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
393 nsec->sh_offset += new_file_h->e_shentsize;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
394
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 /* If any section hdr refers to the section after the new .data
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
397 * section, make it refer to next one because we have inserted a
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
398 * new section in between. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
399 PATCH_INDEX (nsec->sh_link);
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
400
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
401 /* For symbol tables, info is a symbol table index, so don't
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
402 * change it. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
403 if (nsec->sh_type != SHT_SYMTAB && nsec->sh_type != SHT_DYNSYM)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
404 PATCH_INDEX (nsec->sh_info);
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
405
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
406 /* Any section which used to be NOBITS will now becomes PROGBITS
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
407 * if it's ALLOC-atable, unless, of cause, it's not the one we
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
408 * decided to grow */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
409 if ( (osec->sh_type == SHT_NOBITS) && (osec->sh_flags & SHF_ALLOC) &&
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
410 (osec != growme ) ) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
411 nsec->sh_type = SHT_PROGBITS;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
412 }
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
413
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
414 /* Now, start to copy the content of sections */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
415 if ( nsec->sh_type != SHT_NULL || nsec->sh_type != SHT_NOBITS ) {
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
417 /* Write out the sections. .data and .data1 (and data2,
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
418 * called ".data" in the strings table) get copied from the
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
419 * current process instead of the old file. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
420 caddr_t src = old_base + osec->sh_offset;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
421 const char * secname = old_section_names + nsec->sh_name;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
422 const char * names[] = {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
423 ".data",".sdata", ".lit4", ".lit8", ".sdata1", ".data1",
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
424 ".sbss", NULL};
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
425 int i;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
426
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
427 for ( i=0; names[i] != NULL; i++ ) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
428 if ( ! strcmp (secname, names[i]) ) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
429 src = (caddr_t) osec->sh_addr;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
430 break;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
431 }
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
432 }
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
433
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
434 memcpy (nsec->sh_offset + new_base, src, nsec->sh_size);
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
435 }
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
436
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
437 old_mdebug_index = find_section (".mdebug", old_section_names,
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
438 old_name, old_file_h, old_section_h, 1);
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
439
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
440 #if defined (__sony_news) && defined (_SYSTYPE_SYSV)
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
441 if (nsec->sh_type == SHT_MIPS_DEBUG && old_mdebug_index != -1) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
442 int diff = nsec->sh_offset-OLD_SECTION_H(old_mdebug_index).sh_offset;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
443 HDRR *phdr = (HDRR *)(nsec->sh_offset + new_base);
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
444
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
445 if (diff) {
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
446 phdr->cbLineOffset += diff;
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
447 phdr->cbDnOffset += diff;
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
448 phdr->cbPdOffset += diff;
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
449 phdr->cbSymOffset += diff;
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
450 phdr->cbOptOffset += diff;
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
451 phdr->cbAuxOffset += diff;
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
452 phdr->cbSsOffset += diff;
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
453 phdr->cbSsExtOffset += diff;
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
454 phdr->cbFdOffset += diff;
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
455 phdr->cbRfdOffset += diff;
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
456 phdr->cbExtOffset += diff;
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
457 }
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
458 }
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
459 #endif /* __sony_news && _SYSTYPE_SYSV */
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
460
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
461 #if __sgi
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
462 /* Adjust the HDRR offsets in .mdebug and copy the line data if
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
463 * it's in its usual 'hole' in the object. Makes the new file
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
464 * debuggable with dbx. patches up two problems: the absolute
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
465 * file offsets in the HDRR record of .mdebug (see
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
466 * /usr/include/syms.h), and the ld bug that gets the line table
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
467 * in a hole in the elf file rather than in the .mdebug section
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
468 * proper.
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
469 *
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
470 * David Anderson. davea@sgi.com Jan 16,1994 */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 #define MDEBUGADJUST(__ct,__fileaddr) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 if (n_phdrr->__ct > 0) \
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 n_phdrr->__fileaddr += movement; \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
477 if (n == old_mdebug_index) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
478 HDRR * o_phdrr = (HDRR *)((byte *)old_base + osec->sh_offset);
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
479 HDRR * n_phdrr = (HDRR *)((byte *)new_base + nsec->sh_offset);
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
480 unsigned movement = new_data2_size;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 MDEBUGADJUST (idnMax, cbDnOffset);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 MDEBUGADJUST (ipdMax, cbPdOffset);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 MDEBUGADJUST (isymMax, cbSymOffset);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 MDEBUGADJUST (ioptMax, cbOptOffset);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486 MDEBUGADJUST (iauxMax, cbAuxOffset);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 MDEBUGADJUST (issMax, cbSsOffset);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488 MDEBUGADJUST (issExtMax, cbSsExtOffset);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489 MDEBUGADJUST (ifdMax, cbFdOffset);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 MDEBUGADJUST (crfd, cbRfdOffset);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 MDEBUGADJUST (iextMax, cbExtOffset);
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
492
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
493 /* The Line Section, being possible off in a hole of the
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
494 * object, requires special handling. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
495 if (n_phdrr->cbLine > 0) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
496 if (o_phdrr->cbLineOffset >
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
497 osec->sh_offset+ osec->sh_size){
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
498 /* line data is in a hole in elf. do special copy
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
499 * and adjust for this ld mistake. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 n_phdrr->cbLineOffset += movement;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502 memcpy (n_phdrr->cbLineOffset + new_base,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 o_phdrr->cbLineOffset + old_base, n_phdrr->cbLine);
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
504 } else {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
505 /* somehow line data is in .mdebug as it is supposed
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
506 * to be. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 MDEBUGADJUST (cbLine, cbLineOffset);
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
508 }
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
509 }
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
510 }
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
511 #endif /* __sgi */
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
512 /* If it is the symbol table, its st_shndx field needs to be
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
513 * patched. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
514 if (nsec->sh_type == SHT_SYMTAB || nsec->sh_type == SHT_DYNSYM) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
515 unsigned int num = nsec->sh_size / nsec->sh_entsize;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
516 ElfW(Sym) * sym = (ElfW(Sym) *)(nsec->sh_offset + new_base);
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
517 byte *symnames = ((byte *) new_base +
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
518 NEW_SECTION_H (nsec->sh_link).sh_offset);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
520 for (; num--; sym++) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
521 const char * symnam = (char *) (symnames + sym->st_name);
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
522
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
523 /* Update the symbol values of _edata and _end. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
524 if (strcmp (symnam, "_end") == 0
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
525 || strcmp (symnam, "end") == 0
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
526 || strcmp (symnam, "_edata") == 0
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
527 || strcmp (symnam, "edata") == 0)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
528 memcpy (&sym->st_value, &new_bss_addr,sizeof (new_bss_addr));
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
529
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
530
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
531 if ((sym->st_shndx == SHN_UNDEF) || (sym->st_shndx == SHN_ABS)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
532 || (sym->st_shndx == SHN_COMMON)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
533 || (sym->st_shndx >= SHN_LOPROC &&
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
534 sym->st_shndx <= SHN_HIPROC))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
535 continue;
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
536
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 PATCH_INDEX (sym->st_shndx);
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
538 }
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
539 }
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
540 }
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
541
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
542 /* This loop seeks out relocation sections for the data section, so
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
543 * that it can undo relocations performed by the runtime linker. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
544 for (n = new_file_h->e_shnum - 1; n; n--) {
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
545 ElfW(Shdr) section = NEW_SECTION_H (n);
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
546
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
547 if ( section.sh_type == SHT_REL || section.sh_type == SHT_RELA ) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
548 /* This code handles two different size structs, but there
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
549 * should be no harm in that provided that r_offset is
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
550 * always the first member. */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
551 ElfW(Shdr) * info = & NEW_SECTION_H(section.sh_info);
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
552 const char * nm = old_section_names + info->sh_name;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
553
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
554 if (!strcmp (nm, ".data") || !strcmp (nm, ".sdata")
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
555 || !strcmp (nm, ".lit4") || !strcmp (nm, ".lit8")
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
556 || !strcmp (nm, ".sdata1") || !strcmp (nm, ".data1")) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
557 ElfW(Addr) offset = info->sh_addr - info->sh_offset;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
558 caddr_t end, reloc = old_base + section.sh_offset;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
559
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
560 for (end = reloc + section.sh_size; reloc < end;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
561 reloc += section.sh_entsize) {
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
562 ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset;
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
563 #ifdef __alpha__
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
564 /* The Alpha ELF binutils currently have a bug that
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
565 * sometimes results in relocs that contain all
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
566 * zeroes. Work around this for now... */
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
567 if (((ElfW(Rel) *) reloc)->r_offset == 0)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
568 continue;
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
569 #endif
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
570 memcpy (new_base + addr, old_base + addr,
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
571 sizeof(ElfW(Addr)));
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
572 }
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
573 }
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
574 }
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
575 }
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
576
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
577 #ifdef UNEXEC_USE_MAP_PRIVATE
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
578 if (lseek (new_file, 0, SEEK_SET) == -1)
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
579 fatal ("Can't rewind (%s): errno %d\n", new_name, errno);
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
580
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
581 if (write (new_file, new_base, new_file_size) != new_file_size)
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
582 fatal ("Can't write (%s): errno %d\n", new_name, errno);
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
583 #endif
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 440
diff changeset
584
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
585 /* Close the files and make the new file executable. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
586 if (close (old_file))
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
587 fatal ("Can't close (%s): errno %d\n", old_name, errno);
428
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 if (close (new_file))
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
590 fatal ("Can't close (%s): errno %d\n", new_name, errno);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
592 if (stat (new_name, &stat_buf) == -1)
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
593 fatal ("Can't stat (%s): errno %d\n", new_name, errno);
428
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 n = umask (777);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 umask (n);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597 stat_buf.st_mode |= 0111 & ~n;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 if (chmod (new_name, stat_buf.st_mode) == -1)
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
599 fatal ("Can't chmod (%s): errno %d\n", new_name, errno);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 }