Mercurial > hg > xemacs-beta
annotate src/unexalpha.c @ 5127:a9c41067dd88 ben-lisp-object
more cleanups, terminology clarification, lots of doc work
-------------------- ChangeLog entries follow: --------------------
man/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* internals/internals.texi (Introduction to Allocation):
* internals/internals.texi (Integers and Characters):
* internals/internals.texi (Allocation from Frob Blocks):
* internals/internals.texi (lrecords):
* internals/internals.texi (Low-level allocation):
Rewrite section on allocation of Lisp objects to reflect the new
reality. Remove references to nonexistent XSETINT and XSETCHAR.
modules/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c (allocate_pgconn):
* postgresql/postgresql.c (allocate_pgresult):
* postgresql/postgresql.h (struct Lisp_PGconn):
* postgresql/postgresql.h (struct Lisp_PGresult):
* ldap/eldap.c (allocate_ldap):
* ldap/eldap.h (struct Lisp_LDAP):
Same changes as in src/ dir. See large log there in ChangeLog,
but basically:
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
../hlo/src/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (old_alloc_sized_lcrecord):
* alloc.c (very_old_free_lcrecord):
* alloc.c (copy_lisp_object):
* alloc.c (zero_sized_lisp_object):
* alloc.c (zero_nonsized_lisp_object):
* alloc.c (lisp_object_storage_size):
* alloc.c (free_normal_lisp_object):
* alloc.c (FREE_FIXED_TYPE_WHEN_NOT_IN_GC):
* alloc.c (ALLOC_FROB_BLOCK_LISP_OBJECT):
* alloc.c (Fcons):
* alloc.c (noseeum_cons):
* alloc.c (make_float):
* alloc.c (make_bignum):
* alloc.c (make_bignum_bg):
* alloc.c (make_ratio):
* alloc.c (make_ratio_bg):
* alloc.c (make_ratio_rt):
* alloc.c (make_bigfloat):
* alloc.c (make_bigfloat_bf):
* alloc.c (size_vector):
* alloc.c (make_compiled_function):
* alloc.c (Fmake_symbol):
* alloc.c (allocate_extent):
* alloc.c (allocate_event):
* alloc.c (make_key_data):
* alloc.c (make_button_data):
* alloc.c (make_motion_data):
* alloc.c (make_process_data):
* alloc.c (make_timeout_data):
* alloc.c (make_magic_data):
* alloc.c (make_magic_eval_data):
* alloc.c (make_eval_data):
* alloc.c (make_misc_user_data):
* alloc.c (Fmake_marker):
* alloc.c (noseeum_make_marker):
* alloc.c (size_string_direct_data):
* alloc.c (make_uninit_string):
* alloc.c (make_string_nocopy):
* alloc.c (mark_lcrecord_list):
* alloc.c (alloc_managed_lcrecord):
* alloc.c (free_managed_lcrecord):
* alloc.c (sweep_lcrecords_1):
* alloc.c (malloced_storage_size):
* buffer.c (allocate_buffer):
* buffer.c (compute_buffer_usage):
* buffer.c (DEFVAR_BUFFER_LOCAL_1):
* buffer.c (nuke_all_buffer_slots):
* buffer.c (common_init_complex_vars_of_buffer):
* buffer.h (struct buffer_text):
* buffer.h (struct buffer):
* bytecode.c:
* bytecode.c (make_compiled_function_args):
* bytecode.c (size_compiled_function_args):
* bytecode.h (struct compiled_function_args):
* casetab.c (allocate_case_table):
* casetab.h (struct Lisp_Case_Table):
* charset.h (struct Lisp_Charset):
* chartab.c (fill_char_table):
* chartab.c (Fmake_char_table):
* chartab.c (make_char_table_entry):
* chartab.c (copy_char_table_entry):
* chartab.c (Fcopy_char_table):
* chartab.c (put_char_table):
* chartab.h (struct Lisp_Char_Table_Entry):
* chartab.h (struct Lisp_Char_Table):
* console-gtk-impl.h (struct gtk_device):
* console-gtk-impl.h (struct gtk_frame):
* console-impl.h (struct console):
* console-msw-impl.h (struct Lisp_Devmode):
* console-msw-impl.h (struct mswindows_device):
* console-msw-impl.h (struct msprinter_device):
* console-msw-impl.h (struct mswindows_frame):
* console-msw-impl.h (struct mswindows_dialog_id):
* console-stream-impl.h (struct stream_console):
* console-stream.c (stream_init_console):
* console-tty-impl.h (struct tty_console):
* console-tty-impl.h (struct tty_device):
* console-tty.c (allocate_tty_console_struct):
* console-x-impl.h (struct x_device):
* console-x-impl.h (struct x_frame):
* console.c (allocate_console):
* console.c (nuke_all_console_slots):
* console.c (DEFVAR_CONSOLE_LOCAL_1):
* console.c (common_init_complex_vars_of_console):
* data.c (make_weak_list):
* data.c (make_weak_box):
* data.c (make_ephemeron):
* database.c:
* database.c (struct Lisp_Database):
* database.c (allocate_database):
* database.c (finalize_database):
* device-gtk.c (allocate_gtk_device_struct):
* device-impl.h (struct device):
* device-msw.c:
* device-msw.c (mswindows_init_device):
* device-msw.c (msprinter_init_device):
* device-msw.c (finalize_devmode):
* device-msw.c (allocate_devmode):
* device-tty.c (allocate_tty_device_struct):
* device-x.c (allocate_x_device_struct):
* device.c:
* device.c (nuke_all_device_slots):
* device.c (allocate_device):
* dialog-msw.c (handle_question_dialog_box):
* elhash.c:
* elhash.c (struct Lisp_Hash_Table):
* elhash.c (finalize_hash_table):
* elhash.c (make_general_lisp_hash_table):
* elhash.c (Fcopy_hash_table):
* elhash.h (htentry):
* emacs.c (main_1):
* eval.c:
* eval.c (size_multiple_value):
* event-stream.c (finalize_command_builder):
* event-stream.c (allocate_command_builder):
* event-stream.c (free_command_builder):
* event-stream.c (event_stream_generate_wakeup):
* event-stream.c (event_stream_resignal_wakeup):
* event-stream.c (event_stream_disable_wakeup):
* event-stream.c (event_stream_wakeup_pending_p):
* events.h (struct Lisp_Timeout):
* events.h (struct command_builder):
* extents-impl.h:
* extents-impl.h (struct extent_auxiliary):
* extents-impl.h (struct extent_info):
* extents-impl.h (set_extent_no_chase_aux_field):
* extents-impl.h (set_extent_no_chase_normal_field):
* extents.c:
* extents.c (gap_array_marker):
* extents.c (gap_array):
* extents.c (extent_list_marker):
* extents.c (extent_list):
* extents.c (stack_of_extents):
* extents.c (gap_array_make_marker):
* extents.c (extent_list_make_marker):
* extents.c (allocate_extent_list):
* extents.c (SLOT):
* extents.c (mark_extent_auxiliary):
* extents.c (allocate_extent_auxiliary):
* extents.c (attach_extent_auxiliary):
* extents.c (size_gap_array):
* extents.c (finalize_extent_info):
* extents.c (allocate_extent_info):
* extents.c (uninit_buffer_extents):
* extents.c (allocate_soe):
* extents.c (copy_extent):
* extents.c (vars_of_extents):
* extents.h:
* faces.c (allocate_face):
* faces.h (struct Lisp_Face):
* faces.h (struct face_cachel):
* file-coding.c:
* file-coding.c (finalize_coding_system):
* file-coding.c (sizeof_coding_system):
* file-coding.c (Fcopy_coding_system):
* file-coding.h (struct Lisp_Coding_System):
* file-coding.h (MARKED_SLOT):
* fns.c (size_bit_vector):
* font-mgr.c:
* font-mgr.c (finalize_fc_pattern):
* font-mgr.c (print_fc_pattern):
* font-mgr.c (Ffc_pattern_p):
* font-mgr.c (Ffc_pattern_create):
* font-mgr.c (Ffc_name_parse):
* font-mgr.c (Ffc_name_unparse):
* font-mgr.c (Ffc_pattern_duplicate):
* font-mgr.c (Ffc_pattern_add):
* font-mgr.c (Ffc_pattern_del):
* font-mgr.c (Ffc_pattern_get):
* font-mgr.c (fc_config_create_using):
* font-mgr.c (fc_strlist_to_lisp_using):
* font-mgr.c (fontset_to_list):
* font-mgr.c (Ffc_config_p):
* font-mgr.c (Ffc_config_up_to_date):
* font-mgr.c (Ffc_config_build_fonts):
* font-mgr.c (Ffc_config_get_cache):
* font-mgr.c (Ffc_config_get_fonts):
* font-mgr.c (Ffc_config_set_current):
* font-mgr.c (Ffc_config_get_blanks):
* font-mgr.c (Ffc_config_get_rescan_interval):
* font-mgr.c (Ffc_config_set_rescan_interval):
* font-mgr.c (Ffc_config_app_font_add_file):
* font-mgr.c (Ffc_config_app_font_add_dir):
* font-mgr.c (Ffc_config_app_font_clear):
* font-mgr.c (size):
* font-mgr.c (Ffc_config_substitute):
* font-mgr.c (Ffc_font_render_prepare):
* font-mgr.c (Ffc_font_match):
* font-mgr.c (Ffc_font_sort):
* font-mgr.c (finalize_fc_config):
* font-mgr.c (print_fc_config):
* font-mgr.h:
* font-mgr.h (struct fc_pattern):
* font-mgr.h (XFC_PATTERN):
* font-mgr.h (struct fc_config):
* font-mgr.h (XFC_CONFIG):
* frame-gtk.c (allocate_gtk_frame_struct):
* frame-impl.h (struct frame):
* frame-msw.c (mswindows_init_frame_1):
* frame-x.c (allocate_x_frame_struct):
* frame.c (nuke_all_frame_slots):
* frame.c (allocate_frame_core):
* gc.c:
* gc.c (GC_CHECK_NOT_FREE):
* glyphs.c (finalize_image_instance):
* glyphs.c (allocate_image_instance):
* glyphs.c (Fcolorize_image_instance):
* glyphs.c (allocate_glyph):
* glyphs.c (unmap_subwindow_instance_cache_mapper):
* glyphs.c (register_ignored_expose):
* glyphs.h (struct Lisp_Image_Instance):
* glyphs.h (struct Lisp_Glyph):
* glyphs.h (struct glyph_cachel):
* glyphs.h (struct expose_ignore):
* gui.c (allocate_gui_item):
* gui.h (struct Lisp_Gui_Item):
* keymap.c (struct Lisp_Keymap):
* keymap.c (make_keymap):
* lisp.h:
* lisp.h (struct Lisp_String_Direct_Data):
* lisp.h (struct Lisp_String_Indirect_Data):
* lisp.h (struct Lisp_Vector):
* lisp.h (struct Lisp_Bit_Vector):
* lisp.h (DECLARE_INLINE_LISP_BIT_VECTOR):
* lisp.h (struct weak_box):
* lisp.h (struct ephemeron):
* lisp.h (struct weak_list):
* lrecord.h:
* lrecord.h (struct lrecord_implementation):
* lrecord.h (MC_ALLOC_CALL_FINALIZER):
* lrecord.h (struct lcrecord_list):
* lstream.c (finalize_lstream):
* lstream.c (sizeof_lstream):
* lstream.c (Lstream_new):
* lstream.c (Lstream_delete):
* lstream.h (struct lstream):
* marker.c:
* marker.c (finalize_marker):
* marker.c (compute_buffer_marker_usage):
* mule-charset.c:
* mule-charset.c (make_charset):
* mule-charset.c (compute_charset_usage):
* objects-impl.h (struct Lisp_Color_Instance):
* objects-impl.h (struct Lisp_Font_Instance):
* objects-tty-impl.h (struct tty_color_instance_data):
* objects-tty-impl.h (struct tty_font_instance_data):
* objects-tty.c (tty_initialize_color_instance):
* objects-tty.c (tty_initialize_font_instance):
* objects.c (finalize_color_instance):
* objects.c (Fmake_color_instance):
* objects.c (finalize_font_instance):
* objects.c (Fmake_font_instance):
* objects.c (reinit_vars_of_objects):
* opaque.c:
* opaque.c (sizeof_opaque):
* opaque.c (make_opaque_ptr):
* opaque.c (free_opaque_ptr):
* opaque.h:
* opaque.h (Lisp_Opaque):
* opaque.h (Lisp_Opaque_Ptr):
* print.c (printing_unreadable_lcrecord):
* print.c (external_object_printer):
* print.c (debug_p4):
* process.c (finalize_process):
* process.c (make_process_internal):
* procimpl.h (struct Lisp_Process):
* rangetab.c (Fmake_range_table):
* rangetab.c (Fcopy_range_table):
* rangetab.h (struct Lisp_Range_Table):
* scrollbar.c:
* scrollbar.c (create_scrollbar_instance):
* scrollbar.c (compute_scrollbar_instance_usage):
* scrollbar.h (struct scrollbar_instance):
* specifier.c (finalize_specifier):
* specifier.c (sizeof_specifier):
* specifier.c (set_specifier_caching):
* specifier.h (struct Lisp_Specifier):
* specifier.h (struct specifier_caching):
* symeval.h:
* symeval.h (SYMBOL_VALUE_MAGIC_P):
* symeval.h (DEFVAR_SYMVAL_FWD):
* symsinit.h:
* syntax.c (init_buffer_syntax_cache):
* syntax.h (struct syntax_cache):
* toolbar.c:
* toolbar.c (allocate_toolbar_button):
* toolbar.c (update_toolbar_button):
* toolbar.h (struct toolbar_button):
* tooltalk.c (struct Lisp_Tooltalk_Message):
* tooltalk.c (make_tooltalk_message):
* tooltalk.c (struct Lisp_Tooltalk_Pattern):
* tooltalk.c (make_tooltalk_pattern):
* ui-gtk.c:
* ui-gtk.c (allocate_ffi_data):
* ui-gtk.c (emacs_gtk_object_finalizer):
* ui-gtk.c (allocate_emacs_gtk_object_data):
* ui-gtk.c (allocate_emacs_gtk_boxed_data):
* ui-gtk.h:
* window-impl.h (struct window):
* window-impl.h (struct window_mirror):
* window.c (finalize_window):
* window.c (allocate_window):
* window.c (new_window_mirror):
* window.c (mark_window_as_deleted):
* window.c (make_dummy_parent):
* window.c (compute_window_mirror_usage):
* window.c (compute_window_usage):
Overall point of this change and previous ones in this repository:
(1) Introduce new, clearer terminology: everything other than int
or char is a "record" object, which comes in two types: "normal
objects" and "frob-block objects". Fix up all places that
referred to frob-block objects as "simple", "basic", etc.
(2) Provide an advertised interface for doing operations on Lisp
objects, including creating new types, that is clean and
consistent in its naming, uses the above-referenced terms and
avoids referencing "lrecords", "old lcrecords", etc., which should
hide under the surface.
(3) Make the size_in_bytes and finalizer methods take a
Lisp_Object rather than a void * for consistency with other methods.
(4) Separate finalizer method into finalizer and disksaver, so
that normal finalize methods don't have to worry about disksaving.
Other specifics:
(1) Renaming:
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
implementation->basic_p -> implementation->frob_block_p
ALLOCATE_FIXED_TYPE_AND_SET_IMPL -> ALLOC_FROB_BLOCK_LISP_OBJECT
*FCCONFIG*, wrap_fcconfig -> *FC_CONFIG*, wrap_fc_config
*FCPATTERN*, wrap_fcpattern -> *FC_PATTERN*, wrap_fc_pattern
(the last two changes make the naming of these macros consistent
with the naming of all other macros, since the objects are named
fc-config and fc-pattern with a hyphen)
(2) Lots of documentation fixes in lrecord.h.
(3) Eliminate macros for copying, freeing, zeroing objects, getting
their storage size. Instead, new functions:
zero_sized_lisp_object()
zero_nonsized_lisp_object()
lisp_object_storage_size()
free_normal_lisp_object()
(copy_lisp_object() already exists)
LISP_OBJECT_FROB_BLOCK_P() (actually a macro)
Eliminated:
free_lrecord()
zero_lrecord()
copy_lrecord()
copy_sized_lrecord()
old_copy_lcrecord()
old_copy_sized_lcrecord()
old_zero_lcrecord()
old_zero_sized_lcrecord()
LISP_OBJECT_STORAGE_SIZE()
COPY_SIZED_LISP_OBJECT()
COPY_SIZED_LCRECORD()
COPY_LISP_OBJECT()
ZERO_LISP_OBJECT()
FREE_LISP_OBJECT()
(4) Catch the remaining places where lrecord stuff was used directly
and use the advertised interface, e.g. alloc_sized_lrecord() ->
ALLOC_SIZED_LISP_OBJECT().
(5) Make certain statically-declared pseudo-objects
(buffer_local_flags, console_local_flags) have their lheader
initialized correctly, so things like copy_lisp_object() can work
on them. Make extent_auxiliary_defaults a proper heap object
Vextent_auxiliary_defaults, and make extent auxiliaries dumpable
so that this object can be dumped. allocate_extent_auxiliary()
now just creates the object, and attach_extent_auxiliary()
creates an extent auxiliary and attaches to an extent, like the
old allocate_extent_auxiliary().
(6) Create EXTENT_AUXILIARY_SLOTS macro, similar to the foo-slots.h
files but in a macro instead of a file. The purpose is to avoid
duplication when iterating over all the slots in an extent auxiliary.
Use it.
(7) In lstream.c, don't zero out object after allocation because
allocation routines take care of this.
(8) In marker.c, fix a mistake in computing marker overhead.
(9) In print.c, clean up printing_unreadable_lcrecord(),
external_object_printer() to avoid lots of ifdef NEW_GC's.
(10) Separate toolbar-button allocation into a separate
allocate_toolbar_button() function for use in the example code
in lrecord.h.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Fri, 05 Mar 2010 04:08:17 -0600 |
parents | facf3239ba30 |
children | 308d34e9f07d |
rev | line source |
---|---|
428 | 1 /* Unexec for DEC alpha. schoepf@sc.ZIB-Berlin.DE (Rainer Schoepf). |
2 | |
3 Copyright (C) 1994 Free Software Foundation, Inc. | |
4 | |
613 | 5 This file is part of XEmacs. |
428 | 6 |
613 | 7 XEmacs is free software; you can redistribute it and/or modify |
428 | 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 | |
613 | 12 XEmacs is distributed in the hope that it will be useful, |
428 | 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 | |
613 | 18 along with XEmacs; see the file COPYING. If not, write to |
428 | 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
20 Boston, MA 02111-1307, USA. */ | |
21 | |
22 /* Synched up with: FSF 19.31. */ | |
23 | |
24 | |
25 #include <config.h> | |
26 #include <stdlib.h> | |
27 #include <string.h> | |
28 #include <unistd.h> | |
29 #include <sys/types.h> | |
30 #include <sys/file.h> | |
31 #include <sys/stat.h> | |
32 #include <sys/mman.h> | |
33 #include <stdio.h> | |
438 | 34 #include <errno.h> |
428 | 35 #include <varargs.h> |
36 #include <filehdr.h> | |
37 #include <aouthdr.h> | |
38 #include <scnhdr.h> | |
39 #include <syms.h> | |
2286 | 40 #include "compiler.h" |
428 | 41 |
42 static void fatal_unexec (char *, char *); | |
43 static void mark_x (char *); | |
44 | |
45 #define READ(_fd, _buffer, _size, _error_message, _error_arg) \ | |
46 errno = EEOF; \ | |
47 if (read (_fd, _buffer, _size) != _size) \ | |
48 fatal_unexec (_error_message, _error_arg); | |
49 | |
50 #define WRITE(_fd, _buffer, _size, _error_message, _error_arg) \ | |
51 if (write (_fd, _buffer, _size) != _size) \ | |
52 fatal_unexec (_error_message, _error_arg); | |
53 | |
54 #define SEEK(_fd, _position, _error_message, _error_arg) \ | |
55 errno = EEOF; \ | |
56 if (lseek (_fd, _position, L_SET) != _position) \ | |
57 fatal_unexec (_error_message, _error_arg); | |
58 | |
59 #define EEOF -1 | |
60 | |
61 static struct scnhdr *text_section; | |
62 static struct scnhdr *init_section; | |
63 static struct scnhdr *finit_section; | |
64 static struct scnhdr *rdata_section; | |
65 static struct scnhdr *rconst_section; | |
66 static struct scnhdr *data_section; | |
67 static struct scnhdr *pdata_section; | |
68 static struct scnhdr *xdata_section; | |
69 static struct scnhdr *got_section; | |
70 static struct scnhdr *lit8_section; | |
71 static struct scnhdr *lit4_section; | |
72 static struct scnhdr *sdata_section; | |
73 static struct scnhdr *sbss_section; | |
74 static struct scnhdr *bss_section; | |
75 | |
76 static unsigned long Brk; | |
77 | |
78 struct headers { | |
79 struct filehdr fhdr; | |
80 struct aouthdr aout; | |
81 struct scnhdr section[_MIPS_NSCNS_MAX]; | |
82 }; | |
83 | |
84 | |
85 /* Define name of label for entry point for the dumped executable. */ | |
86 | |
87 #ifndef DEFAULT_ENTRY_ADDRESS | |
88 #define DEFAULT_ENTRY_ADDRESS __start | |
89 #endif | |
442 | 90 EXTERN_C int DEFAULT_ENTRY_ADDRESS (void); |
91 | |
428 | 92 |
93 int | |
94 unexec (char *new_name, char *a_name, | |
95 unsigned long data_start, | |
2286 | 96 unsigned long UNUSED (bss_start), |
428 | 97 unsigned long entry_address) |
98 { | |
3025 | 99 int new_, old; |
428 | 100 char * oldptr; |
101 struct headers ohdr, nhdr; | |
102 struct stat stat; | |
103 long pagesize, brk; | |
104 long newsyms, symrel; | |
105 int i; | |
106 long vaddr, scnptr; | |
107 #define BUFSIZE 8192 | |
108 char buffer[BUFSIZE]; | |
109 | |
110 if ((old = open (a_name, O_RDONLY)) < 0) | |
111 fatal_unexec ("opening %s", a_name); | |
112 | |
3025 | 113 new_ = creat (new_name, 0666); |
114 if (new_ < 0) fatal_unexec ("creating %s", new_name); | |
428 | 115 |
116 if ((fstat (old, &stat) == -1)) | |
117 fatal_unexec ("fstat %s", a_name); | |
118 | |
119 oldptr = (char *)mmap (0, stat.st_size, PROT_READ, MAP_FILE|MAP_SHARED, old, 0); | |
120 | |
121 if (oldptr == (char *)-1) | |
122 fatal_unexec ("mmap %s", a_name); | |
123 | |
124 close (old); | |
125 | |
126 /* This is a copy of the a.out header of the original executable */ | |
127 | |
128 ohdr = (*(struct headers *)oldptr); | |
129 | |
130 /* This is where we build the new header from the in-memory copy */ | |
131 | |
132 nhdr = *((struct headers *)TEXT_START); | |
133 | |
134 /* First do some consistency checks */ | |
135 | |
136 if (nhdr.fhdr.f_magic != ALPHAMAGIC | |
137 && nhdr.fhdr.f_magic != ALPHAUMAGIC) | |
138 { | |
139 fprintf (stderr, "unexec: input file magic number is %x, not %x or %x.\n", | |
140 nhdr.fhdr.f_magic, ALPHAMAGIC, ALPHAUMAGIC); | |
141 exit (1); | |
142 } | |
143 | |
144 if (nhdr.fhdr.f_opthdr != sizeof (nhdr.aout)) | |
145 { | |
146 fprintf (stderr, "unexec: input a.out header is %d bytes, not %ld.\n", | |
147 nhdr.fhdr.f_opthdr, (long) (sizeof (nhdr.aout))); | |
148 exit (1); | |
149 } | |
150 if (nhdr.aout.magic != ZMAGIC) | |
151 { | |
152 fprintf (stderr, "unexec: input file a.out magic number is %o, not %o.\n", | |
153 nhdr.aout.magic, ZMAGIC); | |
154 exit (1); | |
155 } | |
156 | |
157 | |
158 /* Now check the existence of certain header section and grab | |
159 their addresses. */ | |
160 | |
161 #define CHECK_SCNHDR(ptr, name, flags) \ | |
162 ptr = NULL; \ | |
163 for (i = 0; i < nhdr.fhdr.f_nscns && !ptr; i++) \ | |
164 if (strcmp (nhdr.section[i].s_name, name) == 0) \ | |
165 { \ | |
166 if (nhdr.section[i].s_flags != flags) \ | |
167 fprintf (stderr, "unexec: %x flags (%x expected) in %s section.\n", \ | |
168 nhdr.section[i].s_flags, flags, name); \ | |
169 ptr = nhdr.section + i; \ | |
170 } \ | |
171 | |
172 CHECK_SCNHDR (text_section, _TEXT, STYP_TEXT); | |
173 CHECK_SCNHDR (init_section, _INIT, STYP_INIT); | |
174 #ifdef _FINI | |
175 CHECK_SCNHDR (finit_section, _FINI, STYP_FINI); | |
176 #endif /* _FINI */ | |
177 CHECK_SCNHDR (rdata_section, _RDATA, STYP_RDATA); | |
178 #ifdef _RCONST | |
179 CHECK_SCNHDR (rconst_section, _RCONST, STYP_RCONST); | |
180 #endif | |
181 #ifdef _PDATA | |
182 CHECK_SCNHDR (pdata_section, _PDATA, STYP_PDATA); | |
183 #endif /* _PDATA */ | |
184 #ifdef _GOT | |
185 CHECK_SCNHDR (got_section, _GOT, STYP_GOT); | |
186 #endif /* _GOT */ | |
187 CHECK_SCNHDR (data_section, _DATA, STYP_DATA); | |
188 #ifdef _XDATA | |
189 CHECK_SCNHDR (xdata_section, _XDATA, STYP_XDATA); | |
190 #endif /* _XDATA */ | |
191 #ifdef _LIT8 | |
192 CHECK_SCNHDR (lit8_section, _LIT8, STYP_LIT8); | |
193 CHECK_SCNHDR (lit4_section, _LIT4, STYP_LIT4); | |
194 #endif /* _LIT8 */ | |
195 CHECK_SCNHDR (sdata_section, _SDATA, STYP_SDATA); | |
196 CHECK_SCNHDR (sbss_section, _SBSS, STYP_SBSS); | |
197 CHECK_SCNHDR (bss_section, _BSS, STYP_BSS); | |
198 | |
199 | |
200 pagesize = getpagesize (); | |
201 brk = (((long) (sbrk (0))) + pagesize - 1) & (-pagesize); | |
202 | |
203 /* Remember the current break */ | |
204 | |
205 Brk = brk; | |
206 | |
207 nhdr.aout.dsize = brk - DATA_START; | |
208 nhdr.aout.bsize = 0; | |
209 if (entry_address == 0) | |
210 { | |
211 nhdr.aout.entry = (unsigned long)DEFAULT_ENTRY_ADDRESS; | |
212 } | |
213 else | |
214 nhdr.aout.entry = entry_address; | |
215 | |
216 nhdr.aout.bss_start = nhdr.aout.data_start + nhdr.aout.dsize; | |
217 | |
218 if (rdata_section != NULL) | |
219 { | |
220 rdata_section->s_size = data_start - DATA_START; | |
221 | |
222 /* Adjust start and virtual addresses of rdata_section, too. */ | |
223 rdata_section->s_vaddr = DATA_START; | |
224 rdata_section->s_paddr = DATA_START; | |
225 rdata_section->s_scnptr = text_section->s_scnptr + nhdr.aout.tsize; | |
226 } | |
227 | |
228 data_section->s_vaddr = data_start; | |
229 data_section->s_paddr = data_start; | |
230 data_section->s_size = brk - data_start; | |
231 | |
232 if (rdata_section != NULL) | |
233 { | |
234 data_section->s_scnptr = rdata_section->s_scnptr + rdata_section->s_size; | |
235 } | |
236 | |
237 vaddr = data_section->s_vaddr + data_section->s_size; | |
238 scnptr = data_section->s_scnptr + data_section->s_size; | |
239 if (lit8_section != NULL) | |
240 { | |
241 lit8_section->s_vaddr = vaddr; | |
242 lit8_section->s_paddr = vaddr; | |
243 lit8_section->s_size = 0; | |
244 lit8_section->s_scnptr = scnptr; | |
245 } | |
246 if (lit4_section != NULL) | |
247 { | |
248 lit4_section->s_vaddr = vaddr; | |
249 lit4_section->s_paddr = vaddr; | |
250 lit4_section->s_size = 0; | |
251 lit4_section->s_scnptr = scnptr; | |
252 } | |
253 if (sdata_section != NULL) | |
254 { | |
255 sdata_section->s_vaddr = vaddr; | |
256 sdata_section->s_paddr = vaddr; | |
257 sdata_section->s_size = 0; | |
258 sdata_section->s_scnptr = scnptr; | |
259 } | |
260 #ifdef _XDATA | |
261 if (xdata_section != NULL) | |
262 { | |
263 xdata_section->s_vaddr = vaddr; | |
264 xdata_section->s_paddr = vaddr; | |
265 xdata_section->s_size = 0; | |
266 xdata_section->s_scnptr = scnptr; | |
267 } | |
268 #endif | |
269 #ifdef _GOT | |
270 if (got_section != NULL) | |
271 { | |
272 got_section->s_vaddr = vaddr; | |
273 got_section->s_paddr = vaddr; | |
274 got_section->s_size = 0; | |
275 got_section->s_scnptr = scnptr; | |
276 } | |
277 #endif /*_GOT */ | |
278 if (sbss_section != NULL) | |
279 { | |
280 sbss_section->s_vaddr = vaddr; | |
281 sbss_section->s_paddr = vaddr; | |
282 sbss_section->s_size = 0; | |
283 sbss_section->s_scnptr = scnptr; | |
284 } | |
285 if (bss_section != NULL) | |
286 { | |
287 bss_section->s_vaddr = vaddr; | |
288 bss_section->s_paddr = vaddr; | |
289 bss_section->s_size = 0; | |
290 bss_section->s_scnptr = scnptr; | |
291 } | |
292 | |
3025 | 293 WRITE (new_, (char *)TEXT_START, nhdr.aout.tsize, |
428 | 294 "writing text section to %s", new_name); |
3025 | 295 WRITE (new_, (char *)DATA_START, nhdr.aout.dsize, |
428 | 296 "writing data section to %s", new_name); |
297 | |
298 | |
299 /* | |
300 * Construct new symbol table header | |
301 */ | |
302 | |
303 memcpy (buffer, oldptr + nhdr.fhdr.f_symptr, cbHDRR); | |
304 | |
305 #define symhdr ((pHDRR)buffer) | |
306 newsyms = nhdr.aout.tsize + nhdr.aout.dsize; | |
307 symrel = newsyms - nhdr.fhdr.f_symptr; | |
308 nhdr.fhdr.f_symptr = newsyms; | |
309 symhdr->cbLineOffset += symrel; | |
310 symhdr->cbDnOffset += symrel; | |
311 symhdr->cbPdOffset += symrel; | |
312 symhdr->cbSymOffset += symrel; | |
313 symhdr->cbOptOffset += symrel; | |
314 symhdr->cbAuxOffset += symrel; | |
315 symhdr->cbSsOffset += symrel; | |
316 symhdr->cbSsExtOffset += symrel; | |
317 symhdr->cbFdOffset += symrel; | |
318 symhdr->cbRfdOffset += symrel; | |
319 symhdr->cbExtOffset += symrel; | |
320 | |
3025 | 321 WRITE (new_, buffer, cbHDRR, "writing symbol table header of %s", new_name); |
428 | 322 |
323 /* | |
324 * Copy the symbol table and line numbers | |
325 */ | |
3025 | 326 WRITE (new_, oldptr + ohdr.fhdr.f_symptr + cbHDRR, |
428 | 327 stat.st_size - ohdr.fhdr.f_symptr - cbHDRR, |
328 "writing symbol table of %s", new_name); | |
329 | |
330 #if 0 | |
331 | |
332 /* Not needed for now */ | |
333 | |
3025 | 334 update_dynamic_symbols (oldptr, new_name, new_, newsyms, |
428 | 335 ((pHDRR) (oldptr + ohdr.fhdr.f_symptr))->issExtMax, |
336 ((pHDRR) (oldptr + ohdr.fhdr.f_symptr))->cbExtOffset, | |
337 ((pHDRR) (oldptr + ohdr.fhdr.f_symptr))->cbSsExtOffset); | |
338 | |
339 #endif | |
340 | |
341 #undef symhdr | |
342 | |
3025 | 343 SEEK (new_, 0, "seeking to start of header in %s", new_name); |
344 WRITE (new_, &nhdr, sizeof (nhdr), | |
428 | 345 "writing header of %s", new_name); |
346 | |
347 close (old); | |
3025 | 348 close (new_); |
428 | 349 mark_x (new_name); |
350 return 0; | |
351 } | |
352 | |
353 | |
354 #if 0 | |
355 | |
356 /* Not needed for now */ | |
357 | |
358 /* The following function updates the values of some symbols | |
359 that are used by the dynamic loader: | |
360 | |
361 _edata | |
362 _end | |
363 | |
364 */ | |
365 | |
366 int | |
367 update_dynamic_symbols ( | |
368 char *old, /* Pointer to old executable */ | |
369 char *new_name, /* Name of new executable */ | |
3025 | 370 int new_, /* File descriptor for new executable */ |
428 | 371 long newsyms, /* Offset of Symbol table in new executable */ |
372 int nsyms, /* Number of symbol table entries */ | |
373 long symoff, /* Offset of External Symbols in old file */ | |
374 long stroff) /* Offset of string table in old file */ | |
375 { | |
376 long i; | |
377 int found = 0; | |
378 EXTR n_end, n_edata; | |
379 | |
380 /* We go through the symbol table entries until we have found the two | |
381 symbols. */ | |
382 | |
383 /* cbEXTR is the size of an external symbol table entry */ | |
384 | |
385 for (i = 0; i < nsyms && found < 2; i += cbEXTR) | |
386 { | |
387 REGISTER pEXTR x = (pEXTR) (old + symoff + i); | |
388 char *s; | |
389 | |
390 s = old + stroff + x->asym.iss; /* name of the symbol */ | |
391 | |
392 if (!strcmp(s,"_edata")) | |
393 { | |
394 found++; | |
395 memcpy (&n_edata, x, cbEXTR); | |
396 n_edata.asym.value = Brk; | |
3025 | 397 SEEK (new_, newsyms + cbHDRR + i, |
428 | 398 "seeking to symbol _edata in %s", new_name); |
3025 | 399 WRITE (new_, &n_edata, cbEXTR, |
428 | 400 "writing symbol table entry for _edata into %s", new_name); |
401 } | |
402 else if (!strcmp(s,"_end")) | |
403 { | |
404 found++; | |
405 memcpy (&n_end, x, cbEXTR); | |
406 n_end.asym.value = Brk; | |
3025 | 407 SEEK (new_, newsyms + cbHDRR + i, |
428 | 408 "seeking to symbol _end in %s", new_name); |
3025 | 409 WRITE (new_, &n_end, cbEXTR, |
428 | 410 "writing symbol table entry for _end into %s", new_name); |
411 } | |
412 } | |
413 | |
414 } | |
415 | |
416 #endif | |
417 | |
418 | |
419 /* | |
420 * mark_x | |
421 * | |
422 * After successfully building the new a.out, mark it executable | |
423 */ | |
424 | |
425 static void | |
426 mark_x (char *name) | |
427 { | |
428 struct stat sbuf; | |
429 int um = umask (777); | |
430 umask (um); | |
431 if (stat (name, &sbuf) < 0) | |
432 fatal_unexec ("getting protection on %s", name); | |
433 sbuf.st_mode |= 0111 & ~um; | |
434 if (chmod (name, sbuf.st_mode) < 0) | |
435 fatal_unexec ("setting protection on %s", name); | |
436 } | |
437 | |
438 static void | |
439 fatal_unexec (char *s, char *arg) | |
440 { | |
441 if (errno == EEOF) | |
442 fputs ("unexec: unexpected end of file, ", stderr); | |
443 else | |
444 fprintf (stderr, "unexec: %s, ", strerror (errno)); | |
445 fprintf (stderr, s, arg); | |
446 fputs (".\n", stderr); | |
447 exit (1); | |
448 } |