Mercurial > emacs
annotate src/unexapollo.c @ 69478:e8bb5df2ba7a
Add index entries around each paragraph rather than depend on entries
from beginning of node. Doing so ensures that index entries are less
likely to be forgotten if text is cut and pasted, and are necessary
anyway if the references are on a separate page. It seems that
makeinfo is now (v. 4.8) only producing one index entry per node, so
there is no longer any excuse not to. Use subheading instead of
heading. The incorrect use of heading produced very large fonts in
Info--as large as the main heading.
(From Bill Wohler): MH-E never did appear in Emacs 21--MH-E versions 6
and 7 appeared *around* the time of these Emacs releases.
author | Bill Wohler <wohler@newt.com> |
---|---|
date | Wed, 15 Mar 2006 00:26:12 +0000 |
parents | 3bd95f4f2941 |
children | e90d04cd455a c5406394f567 |
rev | line source |
---|---|
20572 | 1 /* unexapollo.c -- COFF File UNEXEC for GNU Emacs on Apollo SR10.x |
64770
a0d1312ede66
Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
64084
diff
changeset
|
2 Copyright (C) 1988, 1994, 2002, 2003, 2004, |
68651
3bd95f4f2941
Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
64770
diff
changeset
|
3 2005, 2006 Free Software Foundation, Inc. |
20572 | 4 |
5 This file is part of GNU Emacs. | |
6 | |
7 GNU Emacs is free software; you can redistribute it and/or modify | |
8 it under the terms of the GNU General Public License as published by | |
9 the Free Software Foundation; either version 2, or (at your option) | |
10 any later version. | |
11 | |
12 GNU Emacs is distributed in the hope that it will be useful, | |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 GNU General Public License for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with GNU Emacs; see the file COPYING. If not, write to | |
64084 | 19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 Boston, MA 02110-1301, USA. */ | |
20572 | 21 |
22 /* Written by Leonard N. Zubkoff. */ | |
23 | |
42469 | 24 #ifdef HAVE_CONFIG_H |
25 #include <config.h> | |
26 #endif | |
27 | |
20572 | 28 #include <fcntl.h> |
29 | |
30 | |
31 #include <a.out.h> | |
32 #include <sys/file.h> | |
33 #include <apollo/base.h> | |
34 #include <apollo/ios.h> | |
35 #include <apollo/type_uids.h> | |
36 #include <apollo/dst.h> | |
37 | |
38 | |
39 #define DST_RECORD_HDR_SIZE 2 | |
40 #define LONG_ALIGN(X) (((X)+3)&(~3)) | |
41 | |
42 | |
43 void | |
44 unexec (target_file_name, source_file_name) | |
45 char *target_file_name, *source_file_name; | |
46 { | |
47 struct filehdr file_header; | |
48 struct aouthdr domain_header; | |
49 struct scnhdr *section, *sections, *sections_limit; | |
50 struct scnhdr *first_data_section, *last_data_section; | |
51 struct scnhdr *rwdi_section, *blocks_section; | |
52 struct reloc reloc_entry; | |
53 unsigned long data_size, old_data_section_size, source_file_offset_past_rwdi; | |
54 unsigned char buffer[4096]; | |
55 long delta_before_rwdi, delta_after_rwdi, byte_count; | |
56 long first_changed_vaddr, old_rwdi_vaddr, i; | |
57 ios_$id_t target_file, source_file; | |
58 status_$t status; | |
59 /* Open the Source File. */ | |
60 if ((source_file = open (source_file_name, O_RDONLY)) < 0) | |
61 error ("cannot open source file for input"); | |
62 /* Read the File Header. */ | |
63 if (read (source_file, &file_header, sizeof (file_header)) != sizeof (file_header)) | |
64 error ("cannot read file header"); | |
65 | |
66 /* Read the Domain Header. */ | |
67 if (read (source_file, &domain_header, sizeof (domain_header)) | |
68 != sizeof (domain_header)) | |
69 error ("cannot read domain header"); | |
70 /* Read the Section Headers. */ | |
71 sections = | |
72 (struct scnhdr *) malloc (file_header.f_nscns*sizeof (struct scnhdr)); | |
73 if (sections == (struct scnhdr *) 0) | |
74 error ("cannot allocate section header storage"); | |
75 sections_limit = sections + file_header.f_nscns; | |
76 if (read (source_file, sections, file_header.f_nscns*sizeof (struct scnhdr)) | |
77 != file_header.f_nscns*sizeof (struct scnhdr)) | |
78 error ("cannot read section headers"); | |
79 /* Compute the new Size of the Data Section. */ | |
80 data_size = sbrk (0) - domain_header.data_start; | |
81 delta_before_rwdi = delta_after_rwdi = data_size - domain_header.dsize; | |
82 old_rwdi_vaddr = 0; | |
83 /* Find and Deallocate the .rwdi Section Information. */ | |
84 for (rwdi_section = sections; rwdi_section != sections_limit; rwdi_section++) | |
85 if (strcmp (rwdi_section->s_name, ".rwdi") == 0) | |
86 { | |
87 /* If there are relocation entries, we cannot "unrelocate" them. */ | |
88 if (rwdi_section->s_nreloc > 0) | |
89 error (".rwdi section needs relocation - cannot dump Emacs"); | |
90 delta_after_rwdi = delta_before_rwdi - rwdi_section->s_size; | |
91 old_rwdi_vaddr = rwdi_section->s_vaddr; | |
92 rwdi_section->s_paddr = 0; | |
93 rwdi_section->s_vaddr = 0; | |
94 rwdi_section->s_scnptr = 0; | |
95 rwdi_section->s_size = 0; | |
96 source_file_offset_past_rwdi = (rwdi_section+1)->s_scnptr; | |
97 break; | |
98 } | |
99 /* Skip over the Text Section Headers. */ | |
100 for (section = sections; (section->s_flags & STYP_TEXT) != 0; section++) ; | |
101 /* | |
102 Find the First and Last Data Sections and Fixup | |
103 Section Header Relocation Pointers. | |
104 */ | |
105 first_data_section = last_data_section = (struct scnhdr *) 0; | |
106 for (; section != sections_limit; section++) | |
107 { | |
108 if ((section->s_flags & STYP_DATA) != 0) | |
109 { | |
110 if (first_data_section == (struct scnhdr *) 0) | |
111 first_data_section = section; | |
112 last_data_section = section; | |
113 } | |
114 if (section->s_relptr != 0) | |
115 section->s_relptr += delta_after_rwdi; | |
116 } | |
117 /* Increment the Size of the Last Data Section. */ | |
118 old_data_section_size = last_data_section->s_size; | |
119 last_data_section->s_size += delta_before_rwdi; | |
120 | |
121 /* Update the File Header and Domain Header. */ | |
122 file_header.f_symptr += delta_after_rwdi; | |
123 domain_header.dsize = data_size; | |
124 domain_header.bsize = 0; | |
125 /* Skip over subsequent Bss Section Headers. */ | |
126 for (section = last_data_section+1; | |
127 (section->s_flags & STYP_BSS) != 0; section++) ; | |
128 /* Update the remaining Section Headers. */ | |
129 blocks_section = (struct scnhdr *) 0; | |
130 first_changed_vaddr = 0; | |
131 for (; section != sections_limit; section++) | |
132 { | |
133 long delta = (section < rwdi_section ? delta_before_rwdi : delta_after_rwdi); | |
134 if (section->s_paddr != 0) | |
135 section->s_paddr += delta; | |
136 if (section->s_vaddr != 0) | |
137 { | |
138 if (first_changed_vaddr == 0) | |
139 first_changed_vaddr = section->s_vaddr; | |
140 section->s_vaddr += delta; | |
141 } | |
142 if (section->s_scnptr != 0) | |
143 section->s_scnptr += delta; | |
144 if (strcmp (section->s_name, ".blocks") == 0) | |
145 blocks_section = section; | |
146 else if (strcmp (section->s_name, ".sri") == 0 && | |
147 domain_header.o_sri != 0) | |
148 domain_header.o_sri += delta; | |
149 else if (strcmp (section->s_name, ".inlib") == 0 && | |
150 domain_header.o_inlib != 0) | |
151 domain_header.o_inlib += delta; | |
152 } | |
153 /* Open the Target File. */ | |
154 ios_$create (target_file_name, strlen (target_file_name), coff_$uid, | |
155 ios_$recreate_mode, ios_$write_opt, &target_file, &status); | |
156 if (status.all != status_$ok) | |
157 error ("cannot open target file for output"); | |
158 /* Write the File Header. */ | |
159 if (write (target_file, &file_header, sizeof (file_header)) != sizeof (file_header)) | |
160 error ("cannot write file header"); | |
161 /* Write the Domain Header. */ | |
162 if (write (target_file, &domain_header, sizeof (domain_header)) | |
163 != sizeof (domain_header)) | |
164 error ("cannot write domain header"); | |
165 /* Write the Section Headers. */ | |
166 if (write (target_file, sections, file_header.f_nscns*sizeof (struct scnhdr)) | |
167 != file_header.f_nscns*sizeof (struct scnhdr)) | |
168 error ("cannot write section headers"); | |
169 /* Copy the Allocated Sections. */ | |
170 for (section = sections; section != first_data_section; section++) | |
171 if (section->s_scnptr != 0) | |
172 CopyData (target_file, source_file, LONG_ALIGN(section->s_size)); | |
173 /* Write the Expanded Data Segment. */ | |
174 if (write (target_file, first_data_section->s_vaddr, data_size) != data_size) | |
175 error ("cannot write new data section"); | |
176 | |
177 /* Skip over the Last Data Section and Copy until the .rwdi Section. */ | |
178 if (lseek (source_file, last_data_section->s_scnptr | |
179 +old_data_section_size, L_SET) == -1) | |
180 error ("cannot seek past data section"); | |
181 for (section = last_data_section+1; section != rwdi_section; section++) | |
182 if (section->s_scnptr != 0) | |
183 CopyData (target_file, source_file, LONG_ALIGN(section->s_size)); | |
184 /* Skip over the .rwdi Section and Copy Remainder of Source File. */ | |
185 if (lseek (source_file, source_file_offset_past_rwdi, L_SET) == -1) | |
186 error ("cannot seek past .rwdi section"); | |
187 while ((byte_count = read (source_file, buffer, sizeof (buffer))) > 0) | |
188 if (write (target_file, buffer, byte_count) != byte_count) | |
189 error ("cannot write data"); | |
190 /* Unrelocate .data references to Global Symbols. */ | |
191 for (section = first_data_section; section <= last_data_section; section++) | |
192 for (i = 0; i < section->s_nreloc; i++) | |
193 { | |
194 if (lseek (source_file, section->s_relptr | |
195 +i*sizeof (struct reloc)-delta_after_rwdi, L_SET) == -1) | |
196 error ("cannot seek to relocation info"); | |
197 if (read (source_file, &reloc_entry, sizeof (reloc_entry)) | |
198 != sizeof (reloc_entry)) | |
199 error ("cannot read reloc entry"); | |
200 if (lseek (source_file, reloc_entry.r_vaddr-section->s_vaddr | |
201 +section->s_scnptr, L_SET) == -1) | |
202 error ("cannot seek to data element"); | |
203 if (lseek (target_file, reloc_entry.r_vaddr-section->s_vaddr | |
204 +section->s_scnptr, L_SET) == -1) | |
205 error ("cannot seek to data element"); | |
206 if (read (source_file, buffer, 4) != 4) | |
207 error ("cannot read data element"); | |
208 if (write (target_file, buffer, 4) != 4) | |
209 error ("cannot write data element"); | |
210 } | |
211 | |
212 /* Correct virtual addresses in .blocks section. */ | |
213 if (blocks_section != (struct scnhdr *) 0) | |
214 { | |
215 dst_rec_t dst_record; | |
216 dst_rec_comp_unit_t *comp_unit; | |
217 unsigned short number_of_sections; | |
218 unsigned long section_base; | |
219 unsigned long section_offset = 0; | |
220 /* Find section tables and update section base addresses. */ | |
221 while (section_offset < blocks_section->s_size) | |
222 { | |
223 if (lseek (target_file, | |
224 blocks_section->s_scnptr+section_offset, L_SET) == -1) | |
225 error ("cannot seek to comp unit record"); | |
226 /* Handle pad records before the comp unit record. */ | |
227 if (read (target_file, &dst_record, DST_RECORD_HDR_SIZE) | |
228 != DST_RECORD_HDR_SIZE) | |
229 error ("cannot read dst record tag"); | |
230 if (dst_record.rec_type == dst_typ_pad) | |
231 section_offset += DST_RECORD_HDR_SIZE; | |
232 else if (dst_record.rec_type == dst_typ_comp_unit) | |
233 { | |
234 comp_unit = &dst_record.rec_data.comp_unit_; | |
235 if (read (target_file, comp_unit, sizeof (*comp_unit)) | |
236 != sizeof (*comp_unit)) | |
237 error ("cannot read comp unit record"); | |
238 if (lseek (target_file, blocks_section->s_scnptr | |
239 +section_offset | |
240 #if dst_version_major == 1 && dst_version_minor < 4 | |
241 +comp_unit->section_table | |
242 #else | |
243 +comp_unit->section_table.rel_offset | |
244 #endif | |
245 +DST_RECORD_HDR_SIZE, | |
246 L_SET) == -1) | |
247 error ("cannot seek to section table"); | |
248 if (read (target_file, &number_of_sections, sizeof (number_of_sections)) | |
249 != sizeof (number_of_sections)) | |
250 error ("cannot read section table size"); | |
251 for (i = 0; i < number_of_sections; i++) | |
252 { | |
253 if (read (target_file, §ion_base, sizeof (section_base)) | |
254 != sizeof (section_base)) | |
255 error ("cannot read section base value"); | |
256 if (section_base < first_changed_vaddr) | |
257 continue; | |
258 else if (section_base < old_rwdi_vaddr) | |
259 section_base += delta_before_rwdi; | |
260 else section_base += delta_after_rwdi; | |
261 if (lseek (target_file, -sizeof (section_base), L_INCR) == -1) | |
262 error ("cannot seek to section base value"); | |
263 if (write (target_file, §ion_base, sizeof (section_base)) | |
264 != sizeof (section_base)) | |
265 error ("cannot write section base"); | |
266 } | |
267 section_offset += comp_unit->data_size; | |
268 } | |
269 else error ("unexpected dst record type"); | |
270 } | |
271 } | |
272 | |
273 if (close (source_file) == -1) | |
274 error("cannot close source file"); | |
275 if (close (target_file) == -1) | |
276 error ("cannot close target file"); | |
277 } | |
278 | |
279 | |
280 static | |
281 CopyData (target_file, source_file, total_byte_count) | |
282 int target_file, source_file; | |
283 long total_byte_count; | |
284 { | |
285 unsigned char buffer[4096]; | |
286 long byte_count; | |
287 while (total_byte_count > 0) | |
288 { | |
289 if (total_byte_count > sizeof (buffer)) | |
290 byte_count = sizeof (buffer); | |
291 else byte_count = total_byte_count; | |
292 if (read (source_file, buffer, byte_count) != byte_count) | |
293 error ("cannot read data"); | |
294 if (write (target_file, buffer, byte_count) != byte_count) | |
295 error ("cannot write data"); | |
296 total_byte_count -= byte_count; | |
297 } | |
298 } | |
52401 | 299 |
300 /* arch-tag: 783ebbdf-7d26-4df8-9469-17a1747dce96 | |
301 (do not change this comment) */ |