diff options
| author | Richard M. Stallman | 1998-01-02 21:48:33 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1998-01-02 21:48:33 +0000 |
| commit | 5303ab61e0fbf40ed6ec7f421dbd767d5276ac1e (patch) | |
| tree | 77bb244ded844923ec942842c6127a4b3bcdca10 /src | |
| parent | fe0066f50fdafe0d93b523ee34420324f4bead0a (diff) | |
| download | emacs-5303ab61e0fbf40ed6ec7f421dbd767d5276ac1e.tar.gz emacs-5303ab61e0fbf40ed6ec7f421dbd767d5276ac1e.zip | |
Initial revision
Diffstat (limited to 'src')
| -rw-r--r-- | src/prefix-args.c | 53 | ||||
| -rw-r--r-- | src/unexapollo.c | 294 |
2 files changed, 347 insertions, 0 deletions
diff --git a/src/prefix-args.c b/src/prefix-args.c new file mode 100644 index 00000000000..8be1558f08a --- /dev/null +++ b/src/prefix-args.c | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | /* prefix-args.c - echo each argument, prefixed by a string. | ||
| 2 | Jim Blandy <jimb@occs.cs.oberlin.edu> - September 1992 | ||
| 3 | |||
| 4 | When using GCC 2 as the linker in the build process, options | ||
| 5 | intended for the linker need to be prefixed with the "-Xlinker" | ||
| 6 | option. If an option takes an argument, we need to use -Xlinker | ||
| 7 | twice - once for the option and once for its argument. For | ||
| 8 | example, to run the linker with the options "-Bstatic" "-e" | ||
| 9 | "_start", you'd need to pass the following options to GCC: | ||
| 10 | |||
| 11 | -Xlinker -Bstatic -Xlinker -e -Xlinker _start. | ||
| 12 | |||
| 13 | The Emacs makefile used to use a Bourne Shell `for' loop to prefix | ||
| 14 | each linker option with "-Xlinker", but 1) the for loop was hairier | ||
| 15 | than one might hope because it had to work when there were no | ||
| 16 | arguments to pass to the linker - the shell barfs on a loop like | ||
| 17 | this: | ||
| 18 | |||
| 19 | for arg in ; do echo -Xlinker "$arg"; done | ||
| 20 | |||
| 21 | and 2) the whole compilation command containing this loop seems to | ||
| 22 | exit with a non-zero status and halt the build under Ultrix. | ||
| 23 | |||
| 24 | If I can't write a completely portable program to do this in C, | ||
| 25 | I'm quitting and taking up gardening. */ | ||
| 26 | |||
| 27 | #include <stdio.h> | ||
| 28 | |||
| 29 | main (argc, argv) | ||
| 30 | int argc; | ||
| 31 | char **argv; | ||
| 32 | { | ||
| 33 | char *progname; | ||
| 34 | char *prefix; | ||
| 35 | |||
| 36 | progname = argv[0]; | ||
| 37 | argc--, argv++; | ||
| 38 | |||
| 39 | if (argc < 1) | ||
| 40 | { | ||
| 41 | fprintf (stderr, "Usage: %s PREFIX ARGS...\n\ | ||
| 42 | Echo each ARG preceded by PREFIX and a space.\n", progname); | ||
| 43 | exit (2); | ||
| 44 | } | ||
| 45 | |||
| 46 | prefix = argv[0]; | ||
| 47 | argc--, argv++; | ||
| 48 | |||
| 49 | for (; argc > 0; argc--, argv++) | ||
| 50 | printf ("%s %s%c", prefix, argv[0], (argc > 1) ? ' ' : '\n'); | ||
| 51 | |||
| 52 | exit (0); | ||
| 53 | } | ||
diff --git a/src/unexapollo.c b/src/unexapollo.c new file mode 100644 index 00000000000..4c87bfa3fe4 --- /dev/null +++ b/src/unexapollo.c | |||
| @@ -0,0 +1,294 @@ | |||
| 1 | /* unexapollo.c -- COFF File UNEXEC for GNU Emacs on Apollo SR10.x | ||
| 2 | Copyright (C) 1988, 1994 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 19 | Boston, MA 02111-1307, USA. */ | ||
| 20 | |||
| 21 | /* Written by Leonard N. Zubkoff. */ | ||
| 22 | |||
| 23 | #include "config.h" | ||
| 24 | #include <fcntl.h> | ||
| 25 | |||
| 26 | |||
| 27 | #include <a.out.h> | ||
| 28 | #include <sys/file.h> | ||
| 29 | #include <apollo/base.h> | ||
| 30 | #include <apollo/ios.h> | ||
| 31 | #include <apollo/type_uids.h> | ||
| 32 | #include <apollo/dst.h> | ||
| 33 | |||
| 34 | |||
| 35 | #define DST_RECORD_HDR_SIZE 2 | ||
| 36 | #define LONG_ALIGN(X) (((X)+3)&(~3)) | ||
| 37 | |||
| 38 | |||
| 39 | void | ||
| 40 | unexec (target_file_name, source_file_name) | ||
| 41 | char *target_file_name, *source_file_name; | ||
| 42 | { | ||
| 43 | struct filehdr file_header; | ||
| 44 | struct aouthdr domain_header; | ||
| 45 | struct scnhdr *section, *sections, *sections_limit; | ||
| 46 | struct scnhdr *first_data_section, *last_data_section; | ||
| 47 | struct scnhdr *rwdi_section, *blocks_section; | ||
| 48 | struct reloc reloc_entry; | ||
| 49 | unsigned long data_size, old_data_section_size, source_file_offset_past_rwdi; | ||
| 50 | unsigned char buffer[4096]; | ||
| 51 | long delta_before_rwdi, delta_after_rwdi, byte_count; | ||
| 52 | long first_changed_vaddr, old_rwdi_vaddr, i; | ||
| 53 | ios_$id_t target_file, source_file; | ||
| 54 | status_$t status; | ||
| 55 | /* Open the Source File. */ | ||
| 56 | if ((source_file = open (source_file_name, O_RDONLY)) < 0) | ||
| 57 | error ("cannot open source file for input"); | ||
| 58 | /* Read the File Header. */ | ||
| 59 | if (read (source_file, &file_header, sizeof (file_header)) != sizeof (file_header)) | ||
| 60 | error ("cannot read file header"); | ||
| 61 | |||
| 62 | /* Read the Domain Header. */ | ||
| 63 | if (read (source_file, &domain_header, sizeof (domain_header)) | ||
| 64 | != sizeof (domain_header)) | ||
| 65 | error ("cannot read domain header"); | ||
| 66 | /* Read the Section Headers. */ | ||
| 67 | sections = | ||
| 68 | (struct scnhdr *) malloc (file_header.f_nscns*sizeof (struct scnhdr)); | ||
| 69 | if (sections == (struct scnhdr *) 0) | ||
| 70 | error ("cannot allocate section header storage"); | ||
| 71 | sections_limit = sections + file_header.f_nscns; | ||
| 72 | if (read (source_file, sections, file_header.f_nscns*sizeof (struct scnhdr)) | ||
| 73 | != file_header.f_nscns*sizeof (struct scnhdr)) | ||
| 74 | error ("cannot read section headers"); | ||
| 75 | /* Compute the new Size of the Data Section. */ | ||
| 76 | data_size = sbrk (0) - domain_header.data_start; | ||
| 77 | delta_before_rwdi = delta_after_rwdi = data_size - domain_header.dsize; | ||
| 78 | old_rwdi_vaddr = 0; | ||
| 79 | /* Find and Deallocate the .rwdi Section Information. */ | ||
| 80 | for (rwdi_section = sections; rwdi_section != sections_limit; rwdi_section++) | ||
| 81 | if (strcmp (rwdi_section->s_name, ".rwdi") == 0) | ||
| 82 | { | ||
| 83 | /* If there are relocation entries, we cannot "unrelocate" them. */ | ||
| 84 | if (rwdi_section->s_nreloc > 0) | ||
| 85 | error (".rwdi section needs relocation - cannot dump Emacs"); | ||
| 86 | delta_after_rwdi = delta_before_rwdi - rwdi_section->s_size; | ||
| 87 | old_rwdi_vaddr = rwdi_section->s_vaddr; | ||
| 88 | rwdi_section->s_paddr = 0; | ||
| 89 | rwdi_section->s_vaddr = 0; | ||
| 90 | rwdi_section->s_scnptr = 0; | ||
| 91 | rwdi_section->s_size = 0; | ||
| 92 | source_file_offset_past_rwdi = (rwdi_section+1)->s_scnptr; | ||
| 93 | break; | ||
| 94 | } | ||
| 95 | /* Skip over the Text Section Headers. */ | ||
| 96 | for (section = sections; (section->s_flags & STYP_TEXT) != 0; section++) ; | ||
| 97 | /* | ||
| 98 | Find the First and Last Data Sections and Fixup | ||
| 99 | Section Header Relocation Pointers. | ||
| 100 | */ | ||
| 101 | first_data_section = last_data_section = (struct scnhdr *) 0; | ||
| 102 | for (; section != sections_limit; section++) | ||
| 103 | { | ||
| 104 | if ((section->s_flags & STYP_DATA) != 0) | ||
| 105 | { | ||
| 106 | if (first_data_section == (struct scnhdr *) 0) | ||
| 107 | first_data_section = section; | ||
| 108 | last_data_section = section; | ||
| 109 | } | ||
| 110 | if (section->s_relptr != 0) | ||
| 111 | section->s_relptr += delta_after_rwdi; | ||
| 112 | } | ||
| 113 | /* Increment the Size of the Last Data Section. */ | ||
| 114 | old_data_section_size = last_data_section->s_size; | ||
| 115 | last_data_section->s_size += delta_before_rwdi; | ||
| 116 | |||
| 117 | /* Update the File Header and Domain Header. */ | ||
| 118 | file_header.f_symptr += delta_after_rwdi; | ||
| 119 | domain_header.dsize = data_size; | ||
| 120 | domain_header.bsize = 0; | ||
| 121 | /* Skip over subsequent Bss Section Headers. */ | ||
| 122 | for (section = last_data_section+1; | ||
| 123 | (section->s_flags & STYP_BSS) != 0; section++) ; | ||
| 124 | /* Update the remaining Section Headers. */ | ||
| 125 | blocks_section = (struct scnhdr *) 0; | ||
| 126 | first_changed_vaddr = 0; | ||
| 127 | for (; section != sections_limit; section++) | ||
| 128 | { | ||
| 129 | long delta = (section < rwdi_section ? delta_before_rwdi : delta_after_rwdi); | ||
| 130 | if (section->s_paddr != 0) | ||
| 131 | section->s_paddr += delta; | ||
| 132 | if (section->s_vaddr != 0) | ||
| 133 | { | ||
| 134 | if (first_changed_vaddr == 0) | ||
| 135 | first_changed_vaddr = section->s_vaddr; | ||
| 136 | section->s_vaddr += delta; | ||
| 137 | } | ||
| 138 | if (section->s_scnptr != 0) | ||
| 139 | section->s_scnptr += delta; | ||
| 140 | if (strcmp (section->s_name, ".blocks") == 0) | ||
| 141 | blocks_section = section; | ||
| 142 | else if (strcmp (section->s_name, ".sri") == 0 && | ||
| 143 | domain_header.o_sri != 0) | ||
| 144 | domain_header.o_sri += delta; | ||
| 145 | else if (strcmp (section->s_name, ".inlib") == 0 && | ||
| 146 | domain_header.o_inlib != 0) | ||
| 147 | domain_header.o_inlib += delta; | ||
| 148 | } | ||
| 149 | /* Open the Target File. */ | ||
| 150 | ios_$create (target_file_name, strlen (target_file_name), coff_$uid, | ||
| 151 | ios_$recreate_mode, ios_$write_opt, &target_file, &status); | ||
| 152 | if (status.all != status_$ok) | ||
| 153 | error ("cannot open target file for output"); | ||
| 154 | /* Write the File Header. */ | ||
| 155 | if (write (target_file, &file_header, sizeof (file_header)) != sizeof (file_header)) | ||
| 156 | error ("cannot write file header"); | ||
| 157 | /* Write the Domain Header. */ | ||
| 158 | if (write (target_file, &domain_header, sizeof (domain_header)) | ||
| 159 | != sizeof (domain_header)) | ||
| 160 | error ("cannot write domain header"); | ||
| 161 | /* Write the Section Headers. */ | ||
| 162 | if (write (target_file, sections, file_header.f_nscns*sizeof (struct scnhdr)) | ||
| 163 | != file_header.f_nscns*sizeof (struct scnhdr)) | ||
| 164 | error ("cannot write section headers"); | ||
| 165 | /* Copy the Allocated Sections. */ | ||
| 166 | for (section = sections; section != first_data_section; section++) | ||
| 167 | if (section->s_scnptr != 0) | ||
| 168 | CopyData (target_file, source_file, LONG_ALIGN(section->s_size)); | ||
| 169 | /* Write the Expanded Data Segment. */ | ||
| 170 | if (write (target_file, first_data_section->s_vaddr, data_size) != data_size) | ||
| 171 | error ("cannot write new data section"); | ||
| 172 | |||
| 173 | /* Skip over the Last Data Section and Copy until the .rwdi Section. */ | ||
| 174 | if (lseek (source_file, last_data_section->s_scnptr | ||
| 175 | +old_data_section_size, L_SET) == -1) | ||
| 176 | error ("cannot seek past data section"); | ||
| 177 | for (section = last_data_section+1; section != rwdi_section; section++) | ||
| 178 | if (section->s_scnptr != 0) | ||
| 179 | CopyData (target_file, source_file, LONG_ALIGN(section->s_size)); | ||
| 180 | /* Skip over the .rwdi Section and Copy Remainder of Source File. */ | ||
| 181 | if (lseek (source_file, source_file_offset_past_rwdi, L_SET) == -1) | ||
| 182 | error ("cannot seek past .rwdi section"); | ||
| 183 | while ((byte_count = read (source_file, buffer, sizeof (buffer))) > 0) | ||
| 184 | if (write (target_file, buffer, byte_count) != byte_count) | ||
| 185 | error ("cannot write data"); | ||
| 186 | /* Unrelocate .data references to Global Symbols. */ | ||
| 187 | for (section = first_data_section; section <= last_data_section; section++) | ||
| 188 | for (i = 0; i < section->s_nreloc; i++) | ||
| 189 | { | ||
| 190 | if (lseek (source_file, section->s_relptr | ||
| 191 | +i*sizeof (struct reloc)-delta_after_rwdi, L_SET) == -1) | ||
| 192 | error ("cannot seek to relocation info"); | ||
| 193 | if (read (source_file, &reloc_entry, sizeof (reloc_entry)) | ||
| 194 | != sizeof (reloc_entry)) | ||
| 195 | error ("cannot read reloc entry"); | ||
| 196 | if (lseek (source_file, reloc_entry.r_vaddr-section->s_vaddr | ||
| 197 | +section->s_scnptr, L_SET) == -1) | ||
| 198 | error ("cannot seek to data element"); | ||
| 199 | if (lseek (target_file, reloc_entry.r_vaddr-section->s_vaddr | ||
| 200 | +section->s_scnptr, L_SET) == -1) | ||
| 201 | error ("cannot seek to data element"); | ||
| 202 | if (read (source_file, buffer, 4) != 4) | ||
| 203 | error ("cannot read data element"); | ||
| 204 | if (write (target_file, buffer, 4) != 4) | ||
| 205 | error ("cannot write data element"); | ||
| 206 | } | ||
| 207 | |||
| 208 | /* Correct virtual addresses in .blocks section. */ | ||
| 209 | if (blocks_section != (struct scnhdr *) 0) | ||
| 210 | { | ||
| 211 | dst_rec_t dst_record; | ||
| 212 | dst_rec_comp_unit_t *comp_unit; | ||
| 213 | unsigned short number_of_sections; | ||
| 214 | unsigned long section_base; | ||
| 215 | unsigned long section_offset = 0; | ||
| 216 | /* Find section tables and update section base addresses. */ | ||
| 217 | while (section_offset < blocks_section->s_size) | ||
| 218 | { | ||
| 219 | if (lseek (target_file, | ||
| 220 | blocks_section->s_scnptr+section_offset, L_SET) == -1) | ||
| 221 | error ("cannot seek to comp unit record"); | ||
| 222 | /* Handle pad records before the comp unit record. */ | ||
| 223 | if (read (target_file, &dst_record, DST_RECORD_HDR_SIZE) | ||
| 224 | != DST_RECORD_HDR_SIZE) | ||
| 225 | error ("cannot read dst record tag"); | ||
| 226 | if (dst_record.rec_type == dst_typ_pad) | ||
| 227 | section_offset += DST_RECORD_HDR_SIZE; | ||
| 228 | else if (dst_record.rec_type == dst_typ_comp_unit) | ||
| 229 | { | ||
| 230 | comp_unit = &dst_record.rec_data.comp_unit_; | ||
| 231 | if (read (target_file, comp_unit, sizeof (*comp_unit)) | ||
| 232 | != sizeof (*comp_unit)) | ||
| 233 | error ("cannot read comp unit record"); | ||
| 234 | if (lseek (target_file, blocks_section->s_scnptr | ||
| 235 | +section_offset | ||
| 236 | #if dst_version_major == 1 && dst_version_minor < 4 | ||
| 237 | +comp_unit->section_table | ||
| 238 | #else | ||
| 239 | +comp_unit->section_table.rel_offset | ||
| 240 | #endif | ||
| 241 | +DST_RECORD_HDR_SIZE, | ||
| 242 | L_SET) == -1) | ||
| 243 | error ("cannot seek to section table"); | ||
| 244 | if (read (target_file, &number_of_sections, sizeof (number_of_sections)) | ||
| 245 | != sizeof (number_of_sections)) | ||
| 246 | error ("cannot read section table size"); | ||
| 247 | for (i = 0; i < number_of_sections; i++) | ||
| 248 | { | ||
| 249 | if (read (target_file, §ion_base, sizeof (section_base)) | ||
| 250 | != sizeof (section_base)) | ||
| 251 | error ("cannot read section base value"); | ||
| 252 | if (section_base < first_changed_vaddr) | ||
| 253 | continue; | ||
| 254 | else if (section_base < old_rwdi_vaddr) | ||
| 255 | section_base += delta_before_rwdi; | ||
| 256 | else section_base += delta_after_rwdi; | ||
| 257 | if (lseek (target_file, -sizeof (section_base), L_INCR) == -1) | ||
| 258 | error ("cannot seek to section base value"); | ||
| 259 | if (write (target_file, §ion_base, sizeof (section_base)) | ||
| 260 | != sizeof (section_base)) | ||
| 261 | error ("cannot write section base"); | ||
| 262 | } | ||
| 263 | section_offset += comp_unit->data_size; | ||
| 264 | } | ||
| 265 | else error ("unexpected dst record type"); | ||
| 266 | } | ||
| 267 | } | ||
| 268 | |||
| 269 | if (close (source_file) == -1) | ||
| 270 | error("cannot close source file"); | ||
| 271 | if (close (target_file) == -1) | ||
| 272 | error ("cannot close target file"); | ||
| 273 | } | ||
| 274 | |||
| 275 | |||
| 276 | static | ||
| 277 | CopyData (target_file, source_file, total_byte_count) | ||
| 278 | int target_file, source_file; | ||
| 279 | long total_byte_count; | ||
| 280 | { | ||
| 281 | unsigned char buffer[4096]; | ||
| 282 | long byte_count; | ||
| 283 | while (total_byte_count > 0) | ||
| 284 | { | ||
| 285 | if (total_byte_count > sizeof (buffer)) | ||
| 286 | byte_count = sizeof (buffer); | ||
| 287 | else byte_count = total_byte_count; | ||
| 288 | if (read (source_file, buffer, byte_count) != byte_count) | ||
| 289 | error ("cannot read data"); | ||
| 290 | if (write (target_file, buffer, byte_count) != byte_count) | ||
| 291 | error ("cannot write data"); | ||
| 292 | total_byte_count -= byte_count; | ||
| 293 | } | ||
| 294 | } | ||