Mercurial > emacs
view src/unexapollo.c @ 54341:80dfe07a1d65
New file (image.c) for Image consolidation:
(COLOR_TABLE_SUPPORT): New define to control whether
color table support is available (X only).
(Bitmap_Record): Common name for x_bitmap_record,
w32_bitmap_record, and mac_bitmap_record.
(XImagePtr): Common name for pointer to XImage or equivalent.
(XImagePtr_or_DC): New type to simplify code sharing; equivalent
to XImagePtr on X+MAC, and to HDC on W32.
(GET_PIXEL): Wrapper for XGetPixel or equivalent.
(NO_PIXMAP): Common name for "None" or equivalent.
(PNG_BG_COLOR_SHIFT): Bits to shift PNG background colors.
(RGB_PIXEL_COLOR): Common type for an integer "pixel color" value.
(PIX_MASK_RETAIN, PIX_MASK_DRAW): Portability macros (from macfns.c).
(FRAME_X_VISUAL, x_defined_color, DefaultDepthOfScreen): Define
with suitable equivalents on W32 and MAC for code sharing.
(XDrawLine): Define on MAC for code sharing.
(Destroy_Image, Free_Pixmap): Wrappers for code sharing.
(IF_LIB_AVAILABLE): Macro to simplify code sharing.
(Vx_bitmap_file_path, Vimage_cache_eviction_delay)
(x_bitmap_height, x_bitmap_width, x_bitmap_pixmap)
(x_reference_bitmap, x_create_bitmap_from_data)
(x_create_bitmap_from_file, x_destroy_bitmap)
(x_destroy_all_bitmaps, x_create_bitmap_mask)
(XGetImage, XPutPixel, XGetPixel, XDestroyImage)
(QCascent, QCmargin, QCrelief, QCconversion, QCcolor_symbols)
(QCheuristic_mask, QCindex, QCmatrix, QCcolor_adjustment, QCmask)
(Qlaplace, Qemboss, Qedge_detection, Qheuristic, Qcenter)
(define_image_type, lookup_image_type, valid_image_p)
(image_error, enum image_value_type, struct image_keyword)
(parse_image_spec, image_spec_value, Fimage_size, Fimage_mask_p)
(make_image, free_image, prepare_image_for_display, image_ascent)
(four_corners_best, image_background, image_background_transparent)
(x_clear_image_1, x_clear_image, x_alloc_image_color)
(make_image_cache, free_image_cache, clear_image_cache)
(Fclear_image_cache, postprocess_image, lookup_image, cache_image)
(forall_images_in_image_cache, x_create_x_image_and_pixmap)
(x_destroy_x_image, x_put_x_image, x_find_image_file, slurp_file)
(find_image_fsspec, image_load_qt_1, image_load_quicktime)
(init_image_func_pointer, image_load_quartz2d)
(struct ct_color, init_color_table, free_color_table)
(lookup_rgb_color, lookup_pixel_color, colors_in_color_table)
(cross_disabled_images, x_to_xcolors, x_from_xcolors)
(x_detect_edges, x_emboss, x_laplace, x_edge_detection)
(x_disable_image, x_build_heuristic_mask)
(XBM support, XPM support, PBM support, PNG support, JPEG support)
(TIFF support, GIF support, Ghostscript support): Consolidate image
code from xfns.c, w32fns.c, and macfns.c.
(syms_of_image): Consolidate image related symbol setup here.
(init_image): Consolidate image related initializations here.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Thu, 11 Mar 2004 00:28:24 +0000 |
parents | 695cf19ef79e |
children | a8fa7c632ee4 375f2633d815 |
line wrap: on
line source
/* unexapollo.c -- COFF File UNEXEC for GNU Emacs on Apollo SR10.x Copyright (C) 1988, 1994 Free Software Foundation, Inc. This file is part of GNU Emacs. GNU Emacs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Written by Leonard N. Zubkoff. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <fcntl.h> #include <a.out.h> #include <sys/file.h> #include <apollo/base.h> #include <apollo/ios.h> #include <apollo/type_uids.h> #include <apollo/dst.h> #define DST_RECORD_HDR_SIZE 2 #define LONG_ALIGN(X) (((X)+3)&(~3)) void unexec (target_file_name, source_file_name) char *target_file_name, *source_file_name; { struct filehdr file_header; struct aouthdr domain_header; struct scnhdr *section, *sections, *sections_limit; struct scnhdr *first_data_section, *last_data_section; struct scnhdr *rwdi_section, *blocks_section; struct reloc reloc_entry; unsigned long data_size, old_data_section_size, source_file_offset_past_rwdi; unsigned char buffer[4096]; long delta_before_rwdi, delta_after_rwdi, byte_count; long first_changed_vaddr, old_rwdi_vaddr, i; ios_$id_t target_file, source_file; status_$t status; /* Open the Source File. */ if ((source_file = open (source_file_name, O_RDONLY)) < 0) error ("cannot open source file for input"); /* Read the File Header. */ if (read (source_file, &file_header, sizeof (file_header)) != sizeof (file_header)) error ("cannot read file header"); /* Read the Domain Header. */ if (read (source_file, &domain_header, sizeof (domain_header)) != sizeof (domain_header)) error ("cannot read domain header"); /* Read the Section Headers. */ sections = (struct scnhdr *) malloc (file_header.f_nscns*sizeof (struct scnhdr)); if (sections == (struct scnhdr *) 0) error ("cannot allocate section header storage"); sections_limit = sections + file_header.f_nscns; if (read (source_file, sections, file_header.f_nscns*sizeof (struct scnhdr)) != file_header.f_nscns*sizeof (struct scnhdr)) error ("cannot read section headers"); /* Compute the new Size of the Data Section. */ data_size = sbrk (0) - domain_header.data_start; delta_before_rwdi = delta_after_rwdi = data_size - domain_header.dsize; old_rwdi_vaddr = 0; /* Find and Deallocate the .rwdi Section Information. */ for (rwdi_section = sections; rwdi_section != sections_limit; rwdi_section++) if (strcmp (rwdi_section->s_name, ".rwdi") == 0) { /* If there are relocation entries, we cannot "unrelocate" them. */ if (rwdi_section->s_nreloc > 0) error (".rwdi section needs relocation - cannot dump Emacs"); delta_after_rwdi = delta_before_rwdi - rwdi_section->s_size; old_rwdi_vaddr = rwdi_section->s_vaddr; rwdi_section->s_paddr = 0; rwdi_section->s_vaddr = 0; rwdi_section->s_scnptr = 0; rwdi_section->s_size = 0; source_file_offset_past_rwdi = (rwdi_section+1)->s_scnptr; break; } /* Skip over the Text Section Headers. */ for (section = sections; (section->s_flags & STYP_TEXT) != 0; section++) ; /* Find the First and Last Data Sections and Fixup Section Header Relocation Pointers. */ first_data_section = last_data_section = (struct scnhdr *) 0; for (; section != sections_limit; section++) { if ((section->s_flags & STYP_DATA) != 0) { if (first_data_section == (struct scnhdr *) 0) first_data_section = section; last_data_section = section; } if (section->s_relptr != 0) section->s_relptr += delta_after_rwdi; } /* Increment the Size of the Last Data Section. */ old_data_section_size = last_data_section->s_size; last_data_section->s_size += delta_before_rwdi; /* Update the File Header and Domain Header. */ file_header.f_symptr += delta_after_rwdi; domain_header.dsize = data_size; domain_header.bsize = 0; /* Skip over subsequent Bss Section Headers. */ for (section = last_data_section+1; (section->s_flags & STYP_BSS) != 0; section++) ; /* Update the remaining Section Headers. */ blocks_section = (struct scnhdr *) 0; first_changed_vaddr = 0; for (; section != sections_limit; section++) { long delta = (section < rwdi_section ? delta_before_rwdi : delta_after_rwdi); if (section->s_paddr != 0) section->s_paddr += delta; if (section->s_vaddr != 0) { if (first_changed_vaddr == 0) first_changed_vaddr = section->s_vaddr; section->s_vaddr += delta; } if (section->s_scnptr != 0) section->s_scnptr += delta; if (strcmp (section->s_name, ".blocks") == 0) blocks_section = section; else if (strcmp (section->s_name, ".sri") == 0 && domain_header.o_sri != 0) domain_header.o_sri += delta; else if (strcmp (section->s_name, ".inlib") == 0 && domain_header.o_inlib != 0) domain_header.o_inlib += delta; } /* Open the Target File. */ ios_$create (target_file_name, strlen (target_file_name), coff_$uid, ios_$recreate_mode, ios_$write_opt, &target_file, &status); if (status.all != status_$ok) error ("cannot open target file for output"); /* Write the File Header. */ if (write (target_file, &file_header, sizeof (file_header)) != sizeof (file_header)) error ("cannot write file header"); /* Write the Domain Header. */ if (write (target_file, &domain_header, sizeof (domain_header)) != sizeof (domain_header)) error ("cannot write domain header"); /* Write the Section Headers. */ if (write (target_file, sections, file_header.f_nscns*sizeof (struct scnhdr)) != file_header.f_nscns*sizeof (struct scnhdr)) error ("cannot write section headers"); /* Copy the Allocated Sections. */ for (section = sections; section != first_data_section; section++) if (section->s_scnptr != 0) CopyData (target_file, source_file, LONG_ALIGN(section->s_size)); /* Write the Expanded Data Segment. */ if (write (target_file, first_data_section->s_vaddr, data_size) != data_size) error ("cannot write new data section"); /* Skip over the Last Data Section and Copy until the .rwdi Section. */ if (lseek (source_file, last_data_section->s_scnptr +old_data_section_size, L_SET) == -1) error ("cannot seek past data section"); for (section = last_data_section+1; section != rwdi_section; section++) if (section->s_scnptr != 0) CopyData (target_file, source_file, LONG_ALIGN(section->s_size)); /* Skip over the .rwdi Section and Copy Remainder of Source File. */ if (lseek (source_file, source_file_offset_past_rwdi, L_SET) == -1) error ("cannot seek past .rwdi section"); while ((byte_count = read (source_file, buffer, sizeof (buffer))) > 0) if (write (target_file, buffer, byte_count) != byte_count) error ("cannot write data"); /* Unrelocate .data references to Global Symbols. */ for (section = first_data_section; section <= last_data_section; section++) for (i = 0; i < section->s_nreloc; i++) { if (lseek (source_file, section->s_relptr +i*sizeof (struct reloc)-delta_after_rwdi, L_SET) == -1) error ("cannot seek to relocation info"); if (read (source_file, &reloc_entry, sizeof (reloc_entry)) != sizeof (reloc_entry)) error ("cannot read reloc entry"); if (lseek (source_file, reloc_entry.r_vaddr-section->s_vaddr +section->s_scnptr, L_SET) == -1) error ("cannot seek to data element"); if (lseek (target_file, reloc_entry.r_vaddr-section->s_vaddr +section->s_scnptr, L_SET) == -1) error ("cannot seek to data element"); if (read (source_file, buffer, 4) != 4) error ("cannot read data element"); if (write (target_file, buffer, 4) != 4) error ("cannot write data element"); } /* Correct virtual addresses in .blocks section. */ if (blocks_section != (struct scnhdr *) 0) { dst_rec_t dst_record; dst_rec_comp_unit_t *comp_unit; unsigned short number_of_sections; unsigned long section_base; unsigned long section_offset = 0; /* Find section tables and update section base addresses. */ while (section_offset < blocks_section->s_size) { if (lseek (target_file, blocks_section->s_scnptr+section_offset, L_SET) == -1) error ("cannot seek to comp unit record"); /* Handle pad records before the comp unit record. */ if (read (target_file, &dst_record, DST_RECORD_HDR_SIZE) != DST_RECORD_HDR_SIZE) error ("cannot read dst record tag"); if (dst_record.rec_type == dst_typ_pad) section_offset += DST_RECORD_HDR_SIZE; else if (dst_record.rec_type == dst_typ_comp_unit) { comp_unit = &dst_record.rec_data.comp_unit_; if (read (target_file, comp_unit, sizeof (*comp_unit)) != sizeof (*comp_unit)) error ("cannot read comp unit record"); if (lseek (target_file, blocks_section->s_scnptr +section_offset #if dst_version_major == 1 && dst_version_minor < 4 +comp_unit->section_table #else +comp_unit->section_table.rel_offset #endif +DST_RECORD_HDR_SIZE, L_SET) == -1) error ("cannot seek to section table"); if (read (target_file, &number_of_sections, sizeof (number_of_sections)) != sizeof (number_of_sections)) error ("cannot read section table size"); for (i = 0; i < number_of_sections; i++) { if (read (target_file, §ion_base, sizeof (section_base)) != sizeof (section_base)) error ("cannot read section base value"); if (section_base < first_changed_vaddr) continue; else if (section_base < old_rwdi_vaddr) section_base += delta_before_rwdi; else section_base += delta_after_rwdi; if (lseek (target_file, -sizeof (section_base), L_INCR) == -1) error ("cannot seek to section base value"); if (write (target_file, §ion_base, sizeof (section_base)) != sizeof (section_base)) error ("cannot write section base"); } section_offset += comp_unit->data_size; } else error ("unexpected dst record type"); } } if (close (source_file) == -1) error("cannot close source file"); if (close (target_file) == -1) error ("cannot close target file"); } static CopyData (target_file, source_file, total_byte_count) int target_file, source_file; long total_byte_count; { unsigned char buffer[4096]; long byte_count; while (total_byte_count > 0) { if (total_byte_count > sizeof (buffer)) byte_count = sizeof (buffer); else byte_count = total_byte_count; if (read (source_file, buffer, byte_count) != byte_count) error ("cannot read data"); if (write (target_file, buffer, byte_count) != byte_count) error ("cannot write data"); total_byte_count -= byte_count; } } /* arch-tag: 783ebbdf-7d26-4df8-9469-17a1747dce96 (do not change this comment) */