Mercurial > hg > xemacs-beta
annotate src/unexfreebsd.c @ 1204:e22b0213b713
[xemacs-hg @ 2003-01-12 11:07:58 by michaels]
modules/ChangeLog:
2002-12-16 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c:
remove ifdef USE_KKCC.
src/ChangeLog:
2003-01-08 Mike Sperber <mike@xemacs.org>
* console.h (CDFW_CONSOLE): Don't lead to a crash if we're dealing
with a dead window/frame/device/console.
2002-12-20 Mike Sperber <mike@xemacs.org>
* ui-gtk.c: Fix typo from Ben's patch: emacs_ffi_data is a
typedef, not a struct. emacs_gtk_object_data is a typedef, not a
struct.
* gtk-glue.c (gdk_event_to_emacs_event): Fix typos from Ben's
patch: le -> emacs_event + rearrange the code.
* event-gtk.c (gtk_event_to_emacs_event): Fix typos from Ben's
patch: ..._UNDERLYING_GDK_EVENT -> ..._GDK_EVENT, ev -> key_event.
* device-gtk.c: Fix typo from Ben's patch: x_keysym_map_hash_table
-> x_keysym_map_hashtable.
2002-12-19 Mike Sperber <mike@xemacs.org>
* menubar-x.c (set_frame_menubar): Initialize protect_me field of
popup_data.
2002-12-16 Ben Wing <ben@xemacs.org>
Major cleanup of KKCC, etc.
KKCC, pdump-related:
-- descriptions are written for all objects. this required some
changes in the format of some objects, e.g. extents, popup-data,
coding system, lstream, lcrecord-list.
-- KKCC now handles weakness in markers, hash tables, elsewhere
correctly (formerly, you'd eventually get a stack overflow due
to endlessly expanding markers).
-- textual changes: lrecord_description -> memory_description,
struct_description -> sized_memory_description.
-- extensive comment describing descriptions and pdump.
-- redo XD_UNION so it works inline and change its format to provide
sufficient info for pdump. implement XD_UNION in pdump. also add
XD_UNION_DYNAMIC_SIZE, which works like XD_UNION except for when
auto-computing structure sizes.
-- add support for XD_INDIRECT in description offsets (used by
extents).
-- add support for "description maps", allowing for indirect
descriptions that are retrieved from an object at run-time. this
generalizes XD_CODING_SYSTEM_END, XD_SPECIFIER_END, etc., which
have now been eliminated.
-- add a fifth field "flags" to memory_description, to support flags
that can be specified for this particular line. Currently defined
flags are XD_FLAG_NO_KKCC (KKCC should ignore this entry; useful
for the weakness above in markers, etc.), XD_FLAG_NO_PDUMP (pdump
should ignore this entry), XD_FLAG_UNION_DEFAULT_ENTRY (in
union maps, this specifies a "default" entry for all remaining
values), and XD_FLAG_FREE_LISP_OBJECT (for use with lcrecord-lists).
-- clean up the kkcc-itis in events, so that the differences
between event data as separate objects and as a union are now
minimized to a small number of places. with the new XD_UNION, we
no longer need event data as separate objects, so this code is no
longer ifdef USE_KKCC, but instead ifdef EVENT_DATA_AS_OBJECTS,
not used by default. make sure that we explicitly free the
separate event data objects when no longer in use, to maintain the
invariant the event processing causes no consing.
-- also remove other USE_KKCC ifdefs when not necessary.
-- allow for KKCC compilation under MS Windows.
-- fix README.kkcc.
-- dump_add_root_object -> dump_add_root_lisp_object.
-- implement dump_add_root_block and use this to handle
dump_add_opaque.
-- factor out some code duplicated in kkcc and pdump.
Other allocation/object-related:
-- change various *slots.h so MARKED_SLOT() call no longer
includes semicolon.
-- free_marker() takes a Lisp_Object not a direct pointer.
-- make bit vectors lcrecords, like vectors, and eliminate code
that essentially duplicated the lcrecord handling.
-- additional asserts in FREE_FIXED_TYPE, formerly duplicated in
the various callers of this.
-- all lcrecord allocation functions now zero out the returned
lcrecords. unnecessary calls to zero_lcrecord removed. add long
comment describing these functions.
-- extract out process and coding system slots, like for buffers,
frames, etc.
-- lcrecords now set the type of items sitting on the free list to
lcrecord_type_free.
-- changes to the way that gap arrays are allocated, for kkcc's
benefit -- now, one single memory block with a stretchy array on
the end, instead of a separate block holding the array.
Error-checking-related:
-- now can compile with C++ under MS Windows. clean up compile errors
discovered that way. (a few were real problems)
-- add C++ error-checking code to verify problems with mismatched
GCPRO/UNGCPRO. (there were a few in the kkcc code.) add long
comment about how to catch insufficient GCPRO (yes, it's possible
using C++).
-- add debug_p4(), a simple object printer, when debug_print()
doesn't work.
-- add dp() and db() as short synonyms of debug_print(),
debug_backtrace().
-- `print' tries EXTREMELY hard to avoid core dumping when printing
when crashing or from debug_print(), and tries as hard as it
reasonably can in other situations.
-- Correct the message output upon crashing to be more up-to-date.
Event-related:
-- document event-matches-key-specifier-p better.
-- generalize the dispatch queues formerly duplicated in the
various event implementations. add event methods to drain pending
events. generalize and clean up QUIT handling, removing
event-specific quit processing. allow arbitrary keystrokes, not
just ASCII, to be the QUIT char. among other things, this should
fix some longstanding bugs in X quit handling. long comment
describing the various event queues.
-- implement delaying of XFlush() if there are pending expose events.
SOMEONE PLEASE TRY THIS OUT.
-- Fix `xemacs -batch -l dunnet' under Cygwin. Try to fix under
MS Windows but not quite there yet.
Other:
-- class -> class_ and no more C++ games with this item.
new -> new_ in the lwlib code, so far not elsewhere.
-- use `struct htentry' not `struct hentry' in elhash.c to avoid
debugger confusion with hash.c.
-- new macros ALIST_LOOP_3, ALIST_LOOP_4.
* README.kkcc:
* alloc.c:
* alloc.c (deadbeef_memory):
* alloc.c (allocate_lisp_storage):
* alloc.c (copy_lisp_object):
* alloc.c (ALLOCATE_FIXED_TYPE_1):
* alloc.c (FREE_FIXED_TYPE):
* alloc.c (make_vector_internal):
* alloc.c (make_bit_vector_internal):
* 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 (struct string_chars_block):
* alloc.c (mark_lcrecord_list):
* alloc.c (make_lcrecord_list):
* alloc.c (alloc_managed_lcrecord):
* alloc.c (free_managed_lcrecord):
* alloc.c (alloc_automanaged_lcrecord):
* alloc.c (staticpro_1):
* alloc.c (staticpro):
* alloc.c (lispdesc_indirect_count_1):
* alloc.c (lispdesc_indirect_description_1):
* alloc.c (lispdesc_one_description_line_size):
* alloc.c (lispdesc_structure_size):
* alloc.c (mark_object_maybe_checking_free):
* alloc.c (mark_with_description):
* alloc.c (mark_struct_contents):
* alloc.c (mark_object):
* alloc.c (tick_lcrecord_stats):
* alloc.c (free_cons):
* alloc.c (free_key_data):
* alloc.c (free_button_data):
* alloc.c (free_motion_data):
* alloc.c (free_process_data):
* alloc.c (free_timeout_data):
* alloc.c (free_magic_data):
* alloc.c (free_magic_eval_data):
* alloc.c (free_eval_data):
* alloc.c (free_misc_user_data):
* alloc.c (free_marker):
* alloc.c (compact_string_chars):
* alloc.c (gc_sweep):
* alloc.c (garbage_collect_1):
* alloc.c (Fgarbage_collect):
* alloc.c (common_init_alloc_early):
* alloc.c (init_alloc_early):
* alloc.c (init_alloc_once_early):
* buffer.c:
* buffer.c (mark_buffer):
* buffer.c (MARKED_SLOT):
* buffer.c (cleanup_buffer_undo_lists):
* buffer.c (Fget_file_buffer):
* buffer.h (MARKED_SLOT):
* bufslots.h:
* bytecode.c:
* callint.c:
* casetab.c:
* chartab.c:
* chartab.c (symbol_to_char_table_type):
* cmdloop.c:
* cmdloop.c (Fcommand_loop_1):
* config.h.in (new):
* conslots.h:
* console-gtk-impl.h (struct gtk_frame):
* console-impl.h:
* console-impl.h (struct console):
* console-impl.h (MARKED_SLOT):
* console-impl.h (CONSOLE_QUIT_EVENT):
* console-msw-impl.h (XM_BUMPQUEUE):
* console-msw.c (write_string_to_mswindows_debugging_output):
* console-msw.h:
* console-stream-impl.h:
* console-stream-impl.h (struct stream_console):
* console-stream.c:
* console-stream.c (stream_init_console):
* console-stream.h:
* console-tty.c:
* console-tty.h:
* console-x.h:
* console.c:
* console.c (mark_console):
* console.c (MARKED_SLOT):
* console.c (allocate_console):
* console.c (get_console_variant):
* console.c (create_console):
* console.c (delete_console_internal):
* console.c (Fset_input_mode):
* console.c (Fcurrent_input_mode):
* console.c (common_init_complex_vars_of_console):
* console.h:
* console.h (console_variant):
* console.h (device_metrics):
* data.c:
* data.c (Faref):
* data.c (Faset):
* data.c (decode_weak_list_type):
* database.c:
* debug.c (xemacs_debug_loop):
* debug.c (FROB):
* debug.c (Fadd_debug_class_to_check):
* debug.c (Fdelete_debug_class_to_check):
* debug.c (Fset_debug_classes_to_check):
* debug.c (Fset_debug_class_types_to_check):
* debug.c (Fdebug_types_being_checked):
* debug.h (DASSERT):
* device-gtk.c:
* device-impl.h (struct device):
* device-impl.h (MARKED_SLOT):
* device-msw.c:
* device-x.c:
* device-x.c (x_init_device_class):
* device-x.c (x_comp_visual_info):
* device-x.c (x_try_best_visual_class):
* device-x.c (x_init_device):
* device-x.c (construct_name_list):
* device-x.c (x_get_resource_prefix):
* device-x.c (Fx_get_resource):
* device-x.c (Fx_display_visual_class):
* device.c:
* device.c (MARKED_SLOT):
* device.c (allocate_device):
* device.c (Fmake_device):
* device.c (delete_device_internal):
* device.c (Fset_device_class):
* device.h:
* devslots.h:
* devslots.h (MARKED_SLOT):
* dialog-msw.c:
* dired-msw.c (mswindows_ls_sort_fcn):
* dired-msw.c (mswindows_get_files):
* dired-msw.c (mswindows_format_file):
* doprnt.c (parse_doprnt_spec):
* dumper.c:
* dumper.c (struct):
* dumper.c (dump_add_root_block):
* dumper.c (dump_add_root_struct_ptr):
* dumper.c (dump_add_root_lisp_object):
* dumper.c (pdump_struct_list_elt):
* dumper.c (pdump_get_entry_list):
* dumper.c (pdump_backtrace):
* dumper.c (pdump_bump_depth):
* dumper.c (pdump_register_sub):
* dumper.c (pdump_register_object):
* dumper.c (pdump_register_struct_contents):
* dumper.c (pdump_register_struct):
* dumper.c (pdump_store_new_pointer_offsets):
* dumper.c (pdump_dump_data):
* dumper.c (pdump_reloc_one):
* dumper.c (pdump_allocate_offset):
* dumper.c (pdump_scan_by_alignment):
* dumper.c (pdump_dump_root_blocks):
* dumper.c (pdump_dump_rtables):
* dumper.c (pdump_dump_root_lisp_objects):
* dumper.c (pdump):
* dumper.c (pdump_load_finish):
* dumper.c (pdump_file_get):
* dumper.c (pdump_resource_get):
* dumper.c (pdump_load):
* editfns.c (save_excursion_restore):
* editfns.c (user_login_name):
* editfns.c (save_restriction_restore):
* elhash.c:
* elhash.c (htentry):
* elhash.c (struct Lisp_Hash_Table):
* elhash.c (HTENTRY_CLEAR_P):
* elhash.c (LINEAR_PROBING_LOOP):
* elhash.c (check_hash_table_invariants):
* elhash.c (mark_hash_table):
* elhash.c (hash_table_equal):
* elhash.c (print_hash_table_data):
* elhash.c (free_hentries):
* elhash.c (make_general_lisp_hash_table):
* elhash.c (decode_hash_table_weakness):
* elhash.c (decode_hash_table_test):
* elhash.c (Fcopy_hash_table):
* elhash.c (resize_hash_table):
* elhash.c (pdump_reorganize_hash_table):
* elhash.c (find_htentry):
* elhash.c (Fgethash):
* elhash.c (Fputhash):
* elhash.c (remhash_1):
* elhash.c (Fremhash):
* elhash.c (Fclrhash):
* elhash.c (copy_compress_hentries):
* elhash.c (elisp_maphash_unsafe):
* elhash.c (finish_marking_weak_hash_tables):
* elhash.c (prune_weak_hash_tables):
* elhash.h:
* emacs.c:
* emacs.c (main_1):
* emacs.c (main):
* emacs.c (shut_down_emacs):
* emodules.h (dump_add_root_lisp_object):
* eval.c:
* eval.c (unwind_to_catch):
* eval.c (maybe_signal_error_1):
* eval.c (maybe_signal_continuable_error_1):
* eval.c (maybe_signal_error):
* eval.c (maybe_signal_continuable_error):
* eval.c (maybe_signal_error_2):
* eval.c (maybe_signal_continuable_error_2):
* eval.c (maybe_signal_ferror):
* eval.c (maybe_signal_continuable_ferror):
* eval.c (maybe_signal_ferror_with_frob):
* eval.c (maybe_signal_continuable_ferror_with_frob):
* eval.c (maybe_syntax_error):
* eval.c (maybe_sferror):
* eval.c (maybe_invalid_argument):
* eval.c (maybe_invalid_constant):
* eval.c (maybe_invalid_operation):
* eval.c (maybe_invalid_change):
* eval.c (maybe_invalid_state):
* eval.c (Feval):
* eval.c (call_trapping_problems):
* eval.c (call_with_suspended_errors):
* eval.c (warn_when_safe_lispobj):
* eval.c (warn_when_safe):
* eval.c (vars_of_eval):
* event-Xt.c:
* event-Xt.c (maybe_define_x_key_as_self_inserting_character):
* event-Xt.c (x_to_emacs_keysym):
* event-Xt.c (x_event_to_emacs_event):
* event-Xt.c (emacs_Xt_enqueue_focus_event):
* event-Xt.c (emacs_Xt_format_magic_event):
* event-Xt.c (emacs_Xt_compare_magic_event):
* event-Xt.c (emacs_Xt_hash_magic_event):
* event-Xt.c (emacs_Xt_handle_magic_event):
* event-Xt.c (Xt_timeout_to_emacs_event):
* event-Xt.c (Xt_process_to_emacs_event):
* event-Xt.c (signal_special_Xt_user_event):
* event-Xt.c (emacs_Xt_next_event):
* event-Xt.c (emacs_Xt_event_handler):
* event-Xt.c (emacs_Xt_drain_queue):
* event-Xt.c (emacs_Xt_event_pending_p):
* event-Xt.c (check_if_pending_expose_event):
* event-Xt.c (reinit_vars_of_event_Xt):
* event-Xt.c (vars_of_event_Xt):
* event-gtk.c:
* event-gtk.c (IS_MODIFIER_KEY):
* event-gtk.c (emacs_gtk_format_magic_event):
* event-gtk.c (emacs_gtk_compare_magic_event):
* event-gtk.c (emacs_gtk_hash_magic_event):
* event-gtk.c (emacs_gtk_handle_magic_event):
* event-gtk.c (gtk_to_emacs_keysym):
* event-gtk.c (gtk_timeout_to_emacs_event):
* event-gtk.c (gtk_process_to_emacs_event):
* event-gtk.c (dragndrop_data_received):
* event-gtk.c (signal_special_gtk_user_event):
* event-gtk.c (emacs_gtk_next_event):
* event-gtk.c (gtk_event_to_emacs_event):
* event-gtk.c (generic_event_handler):
* event-gtk.c (emacs_shell_event_handler):
* event-gtk.c (emacs_gtk_drain_queue):
* event-gtk.c (emacs_gtk_event_pending_p):
* event-gtk.c (reinit_vars_of_event_gtk):
* event-gtk.c (vars_of_event_gtk):
* event-msw.c:
* event-msw.c (struct winsock_stream):
* event-msw.c (winsock_reader):
* event-msw.c (winsock_writer):
* event-msw.c (mswindows_enqueue_dispatch_event):
* event-msw.c (mswindows_enqueue_misc_user_event):
* event-msw.c (mswindows_enqueue_magic_event):
* event-msw.c (mswindows_enqueue_process_event):
* event-msw.c (mswindows_enqueue_mouse_button_event):
* event-msw.c (mswindows_enqueue_keypress_event):
* event-msw.c (mswindows_dequeue_dispatch_event):
* event-msw.c (emacs_mswindows_drain_queue):
* event-msw.c (mswindows_need_event_in_modal_loop):
* event-msw.c (mswindows_need_event):
* event-msw.c (mswindows_wm_timer_callback):
* event-msw.c (dde_eval_string):
* event-msw.c (Fdde_alloc_advise_item):
* event-msw.c (mswindows_dde_callback):
* event-msw.c (mswindows_wnd_proc):
* event-msw.c (remove_timeout_mapper):
* event-msw.c (emacs_mswindows_remove_timeout):
* event-msw.c (emacs_mswindows_event_pending_p):
* event-msw.c (emacs_mswindows_format_magic_event):
* event-msw.c (emacs_mswindows_compare_magic_event):
* event-msw.c (emacs_mswindows_hash_magic_event):
* event-msw.c (emacs_mswindows_handle_magic_event):
* event-msw.c (emacs_mswindows_select_console):
* event-msw.c (emacs_mswindows_unselect_console):
* event-msw.c (reinit_vars_of_event_mswindows):
* event-msw.c (vars_of_event_mswindows):
* event-stream.c:
* event-stream.c (mark_command_builder):
* event-stream.c (reset_command_builder_event_chain):
* event-stream.c (allocate_command_builder):
* event-stream.c (copy_command_builder):
* event-stream.c (command_builder_append_event):
* event-stream.c (event_stream_event_pending_p):
* event-stream.c (event_stream_force_event_pending):
* event-stream.c (maybe_read_quit_event):
* event-stream.c (event_stream_drain_queue):
* event-stream.c (remove_quit_p_event):
* event-stream.c (event_stream_quit_p):
* event-stream.c (echo_key_event):
* event-stream.c (maybe_kbd_translate):
* event-stream.c (execute_help_form):
* event-stream.c (event_stream_generate_wakeup):
* event-stream.c (enqueue_dispatch_event):
* event-stream.c (enqueue_magic_eval_event):
* event-stream.c (Fenqueue_eval_event):
* event-stream.c (enqueue_misc_user_event):
* event-stream.c (enqueue_misc_user_event_pos):
* event-stream.c (next_event_internal):
* event-stream.c (Fnext_event):
* event-stream.c (Faccept_process_output):
* event-stream.c (execute_internal_event):
* event-stream.c (munge_keymap_translate):
* event-stream.c (command_builder_find_leaf_no_mule_processing):
* event-stream.c (command_builder_find_leaf):
* event-stream.c (lookup_command_event):
* event-stream.c (is_scrollbar_event):
* event-stream.c (execute_command_event):
* event-stream.c (Fdispatch_event):
* event-stream.c (Fread_key_sequence):
* event-stream.c (dribble_out_event):
* event-stream.c (vars_of_event_stream):
* event-tty.c (tty_timeout_to_emacs_event):
* event-tty.c (emacs_tty_next_event):
* event-tty.c (emacs_tty_drain_queue):
* event-tty.c (reinit_vars_of_event_tty):
* event-unixoid.c:
* event-unixoid.c (find_tty_or_stream_console_from_fd):
* event-unixoid.c (read_event_from_tty_or_stream_desc):
* event-unixoid.c (drain_tty_devices):
* event-unixoid.c (poll_fds_for_input):
* events.c:
* events.c (deinitialize_event):
* events.c (zero_event):
* events.c (mark_event):
* events.c (print_event_1):
* events.c (print_event):
* events.c (event_equal):
* events.c (event_hash):
* events.c (Fmake_event):
* events.c (Fdeallocate_event):
* events.c (Fcopy_event):
* events.c (map_event_chain_remove):
* events.c (character_to_event):
* events.c (event_to_character):
* events.c (Fevent_to_character):
* events.c (format_event_object):
* events.c (upshift_event):
* events.c (downshift_event):
* events.c (event_upshifted_p):
* events.c (Fevent_live_p):
* events.c (Fevent_type):
* events.c (Fevent_timestamp):
* events.c (CHECK_EVENT_TYPE):
* events.c (CHECK_EVENT_TYPE2):
* events.c (CHECK_EVENT_TYPE3):
* events.c (Fevent_key):
* events.c (Fevent_button):
* events.c (Fevent_modifier_bits):
* events.c (event_x_y_pixel_internal):
* events.c (event_pixel_translation):
* events.c (Fevent_process):
* events.c (Fevent_function):
* events.c (Fevent_object):
* events.c (Fevent_properties):
* events.c (syms_of_events):
* events.c (vars_of_events):
* events.h:
* events.h (struct event_stream):
* events.h (struct Lisp_Key_Data):
* events.h (KEY_DATA_KEYSYM):
* events.h (EVENT_KEY_KEYSYM):
* events.h (struct Lisp_Button_Data):
* events.h (EVENT_BUTTON_BUTTON):
* events.h (struct Lisp_Motion_Data):
* events.h (EVENT_MOTION_X):
* events.h (struct Lisp_Process_Data):
* events.h (EVENT_PROCESS_PROCESS):
* events.h (struct Lisp_Timeout_Data):
* events.h (EVENT_TIMEOUT_INTERVAL_ID):
* events.h (struct Lisp_Eval_Data):
* events.h (EVENT_EVAL_FUNCTION):
* events.h (struct Lisp_Misc_User_Data):
* events.h (EVENT_MISC_USER_FUNCTION):
* events.h (struct Lisp_Magic_Eval_Data):
* events.h (EVENT_MAGIC_EVAL_INTERNAL_FUNCTION):
* events.h (struct Lisp_Magic_Data):
* events.h (EVENT_MAGIC_UNDERLYING):
* events.h (EVENT_MAGIC_GDK_EVENT):
* events.h (struct Lisp_Event):
* events.h (XEVENT_CHANNEL):
* events.h (SET_EVENT_TIMESTAMP_ZERO):
* events.h (SET_EVENT_CHANNEL):
* events.h (SET_EVENT_NEXT):
* events.h (XSET_EVENT_TYPE):
* events.h (struct command_builder):
* extents.c:
* extents.c (gap_array_adjust_markers):
* extents.c (gap_array_recompute_derived_values):
* extents.c (gap_array_move_gap):
* extents.c (gap_array_make_gap):
* extents.c (gap_array_insert_els):
* extents.c (gap_array_delete_els):
* extents.c (gap_array_make_marker):
* extents.c (gap_array_delete_marker):
* extents.c (gap_array_move_marker):
* extents.c (make_gap_array):
* extents.c (free_gap_array):
* extents.c (extent_list_num_els):
* extents.c (extent_list_insert):
* extents.c (mark_extent_auxiliary):
* extents.c (allocate_extent_auxiliary):
* extents.c (decode_extent_at_flag):
* extents.c (verify_extent_mapper):
* extents.c (symbol_to_glyph_layout):
* extents.c (syms_of_extents):
* faces.c:
* file-coding.c:
* file-coding.c (struct_detector_category_description =):
* file-coding.c (detector_category_dynarr_description_1):
* file-coding.c (struct_detector_description =):
* file-coding.c (detector_dynarr_description_1):
* file-coding.c (MARKED_SLOT):
* file-coding.c (mark_coding_system):
* file-coding.c (coding_system_extra_description_map):
* file-coding.c (coding_system_description):
* file-coding.c (allocate_coding_system):
* file-coding.c (symbol_to_eol_type):
* file-coding.c (Fcoding_system_aliasee):
* file-coding.c (set_coding_stream_coding_system):
* file-coding.c (struct convert_eol_coding_system):
* file-coding.c (struct undecided_coding_system):
* file-coding.c (undecided_mark_coding_stream):
* file-coding.c (coding_category_symbol_to_id):
* file-coding.c (struct gzip_coding_system):
* file-coding.c (coding_system_type_create):
* file-coding.h:
* file-coding.h (struct Lisp_Coding_System):
* file-coding.h (CODING_SYSTEM_SLOT_DECLARATION):
* file-coding.h (coding_system_variant):
* file-coding.h (struct coding_system_methods):
* file-coding.h (DEFINE_CODING_SYSTEM_TYPE_WITH_DATA):
* file-coding.h (INITIALIZE_CODING_SYSTEM_TYPE_WITH_DATA):
* file-coding.h (struct coding_stream):
* fileio.c (Fsubstitute_in_file_name):
* floatfns.c:
* fns.c:
* fns.c (base64_encode_1):
* frame-gtk.c:
* frame-gtk.c (Fgtk_start_drag_internal):
* frame-impl.h (struct frame):
* frame-impl.h (MARKED_SLOT):
* frame-msw.c:
* frame-x.c:
* frame-x.c (Fcde_start_drag_internal):
* frame-x.c (Foffix_start_drag_internal):
* frame.c:
* frame.c (MARKED_SLOT):
* frame.c (allocate_frame_core):
* frame.c (delete_frame_internal):
* frame.c (Fmouse_position_as_motion_event):
* frameslots.h:
* frameslots.h (MARKED_SLOT_ARRAY):
* free-hook.c:
* glyphs-msw.c (mswindows_widget_instantiate):
* glyphs-x.c:
* glyphs-x.c (convert_EImage_to_XImage):
* glyphs.c:
* glyphs.c (process_image_string_instantiator):
* glyphs.c (mark_image_instance):
* glyphs.c (allocate_image_instance):
* glyphs.c (unmap_subwindow):
* glyphs.c (map_subwindow):
* glyphs.c (syms_of_glyphs):
* glyphs.c (specifier_type_create_image):
* glyphs.h:
* glyphs.h (struct text_image_instance):
* glyphs.h (struct Lisp_Image_Instance):
* gmalloc.c:
* gmalloc.c ("C"):
* gpmevent.c (Freceive_gpm_event):
* gpmevent.c (gpm_next_event_cb):
* gpmevent.c (vars_of_gpmevent):
* gtk-glue.c (gdk_event_to_emacs_event):
* gtk-xemacs.c (gtk_xemacs_class_init):
* gui-msw.c:
* gui-msw.c (mswindows_handle_gui_wm_command):
* gui-msw.c (mswindows_translate_menu_or_dialog_item):
* gui-x.c:
* gui-x.c (mark_popup_data):
* gui-x.c (snarf_widget_value_mapper):
* gui-x.c (gcpro_popup_callbacks):
* gui-x.c (ungcpro_popup_callbacks):
* gui-x.c (free_popup_widget_value_tree):
* gui-x.c (popup_selection_callback):
* gui-x.h:
* gui-x.h (struct popup_data):
* gui.c:
* gui.c (allocate_gui_item):
* gutter.c (decode_gutter_position):
* hash.c (NULL_ENTRY):
* indent.c (vmotion_1):
* indent.c (vmotion_pixels):
* input-method-motif.c (res):
* input-method-xlib.c (IMInstantiateCallback):
* input-method-xlib.c (XIM_init_device):
* input-method-xlib.c (res):
* intl-encap-win32.c:
* intl-encap-win32.c (qxeSHGetDataFromIDList):
* intl-win32.c:
* intl-win32.c (mswindows_multibyte_cp_type):
* intl-win32.c (struct mswindows_multibyte_coding_system):
* keymap.c:
* keymap.c (make_key_description):
* keymap.c (keymap_store):
* keymap.c (get_keyelt):
* keymap.c (keymap_lookup_1):
* keymap.c (define_key_parser):
* keymap.c (key_desc_list_to_event):
* keymap.c (event_matches_key_specifier_p):
* keymap.c (meta_prefix_char_p):
* keymap.c (ensure_meta_prefix_char_keymapp):
* keymap.c (Fdefine_key):
* keymap.c (struct raw_lookup_key_mapper_closure):
* keymap.c (raw_lookup_key):
* keymap.c (raw_lookup_key_mapper):
* keymap.c (lookup_keys):
* keymap.c (lookup_events):
* keymap.c (Flookup_key):
* keymap.c (struct map_keymap_unsorted_closure):
* keymap.c (map_keymap_unsorted_mapper):
* keymap.c (map_keymap_sorted):
* keymap.c (map_keymap_mapper):
* keymap.c (map_keymap):
* keymap.c (accessible_keymaps_mapper_1):
* keymap.c (Faccessible_keymaps):
* keymap.c (Fsingle_key_description):
* keymap.c (raw_keys_to_keys):
* keymap.c (format_raw_keys):
* keymap.c (where_is_recursive_mapper):
* keymap.c (where_is_internal):
* keymap.c (describe_map_mapper_shadow_search):
* keymap.c (keymap_lookup_inherited_mapper):
* keymap.c (describe_map_mapper):
* keymap.h (event_matches_key_specifier_p):
* lisp.h:
* lisp.h (this):
* lisp.h (RETURN_NOT_REACHED):
* lisp.h (struct Lisp_Vector):
* lisp.h (struct Lisp_Bit_Vector):
* lisp.h (UNGCPRO_1):
* lisp.h (NUNGCPRO):
* lisp.h (NNUNGCPRO):
* lisp.h (DECLARE_INLINE_HEADER):
* lrecord.h:
* lrecord.h (struct lrecord_header):
* lrecord.h (struct lcrecord_header):
* lrecord.h (lrecord_type):
* lrecord.h (struct lrecord_implementation):
* lrecord.h (RECORD_DUMPABLE):
* lrecord.h (memory_description_type):
* lrecord.h (data_description_entry_flags):
* lrecord.h (struct memory_description):
* lrecord.h (struct sized_memory_description):
* lrecord.h (XD_INDIRECT):
* lrecord.h (XD_IS_INDIRECT):
* lrecord.h (XD_DYNARR_DESC):
* lrecord.h (DEFINE_BASIC_LRECORD_IMPLEMENTATION):
* lrecord.h (MAKE_LRECORD_IMPLEMENTATION):
* lrecord.h (MAKE_EXTERNAL_LRECORD_IMPLEMENTATION):
* lrecord.h (alloc_lcrecord_type):
* lstream.c:
* lstream.c (Lstream_new):
* lstream.c (lisp_buffer_marker):
* lstream.h:
* lstream.h (lstream_implementation):
* lstream.h (DEFINE_LSTREAM_IMPLEMENTATION):
* lstream.h (DEFINE_LSTREAM_IMPLEMENTATION_WITH_DATA):
* marker.c:
* marker.c (copy_marker_1):
* mem-limits.h:
* menubar-gtk.c:
* menubar-gtk.c (gtk_popup_menu):
* menubar-msw.c:
* menubar-msw.c (mswindows_popup_menu):
* menubar-x.c (make_dummy_xbutton_event):
* menubar-x.c (command_builder_operate_menu_accelerator):
* menubar-x.c (menu_accelerator_safe_compare):
* menubar-x.c (menu_accelerator_safe_mod_compare):
* mule-charset.c:
* mule-charset.c (make_charset):
* mule-charset.c (Fcharset_property):
* mule-coding.c:
* mule-coding.c (ccs_description_1):
* mule-coding.c (ccs_description =):
* mule-coding.c (ccsd_description_1):
* mule-coding.c (ccsd_description =):
* nt.c (getpwnam):
* nt.c (init_mswindows_environment):
* nt.c (get_cached_volume_information):
* nt.c (mswindows_is_executable):
* nt.c (read_unc_volume):
* nt.c (mswindows_access):
* nt.c (mswindows_link):
* nt.c (mswindows_fstat):
* nt.c (mswindows_stat):
* nt.c (mswindows_executable_type):
* nt.c (Fmswindows_short_file_name):
* nt.c (Fmswindows_long_file_name):
* objects-impl.h (struct Lisp_Color_Instance):
* objects-impl.h (struct Lisp_Font_Instance):
* objects-tty.c:
* objects-x.c (allocate_nearest_color):
* objects.c:
* objects.c (Fmake_color_instance):
* objects.c (Fmake_font_instance):
* objects.c (font_instantiate):
* opaque.c:
* opaque.c (make_opaque):
* opaque.c (make_opaque_ptr):
* opaque.c (reinit_opaque_early):
* opaque.c (init_opaque_once_early):
* print.c:
* print.c (printing_badness):
* print.c (printing_major_badness):
* print.c (print_internal):
* print.c (debug_p4):
* print.c (dp):
* print.c (debug_backtrace):
* process-nt.c (nt_create_process):
* process-nt.c (get_internet_address):
* process-unix.c:
* process-unix.c (struct unix_process_data):
* process-unix.c (get_internet_address):
* process-unix.c (unix_alloc_process_data):
* process-unix.c (unix_create_process):
* process-unix.c (try_to_initialize_subtty):
* process-unix.c (unix_kill_child_process):
* process-unix.c (process_type_create_unix):
* process.c:
* process.c (mark_process):
* process.c (MARKED_SLOT):
* process.c (make_process_internal):
* process.c (Fprocess_tty_name):
* process.c (decode_signal):
* process.h:
* procimpl.h:
* procimpl.h (struct process_methods):
* procimpl.h (struct Lisp_Process):
* rangetab.c:
* realpath.c (readlink_and_correct_case):
* redisplay-x.c (x_window_output_end):
* redisplay-x.c (x_redraw_exposed_area):
* redisplay-x.c (x_clear_frame):
* redisplay.c:
* redisplay.h:
* redisplay.h (struct rune_dglyph):
* redisplay.h (struct rune):
* scrollbar.c:
* scrollbar.c (create_scrollbar_instance):
* specifier.c:
* specifier.c (specifier_empty_extra_description_1):
* specifier.c (make_specifier_internal):
* specifier.c (decode_locale_type):
* specifier.c (decode_how_to_add_specification):
* specifier.h:
* specifier.h (struct specifier_methods):
* specifier.h (DEFINE_SPECIFIER_TYPE_WITH_DATA):
* specifier.h (INITIALIZE_SPECIFIER_TYPE_WITH_DATA):
* symbols.c:
* symbols.c (Fsetplist):
* symbols.c (default_value):
* symbols.c (decode_magic_handler_type):
* symbols.c (handler_type_from_function_symbol):
* symbols.c (Fdefvaralias):
* symbols.c (init_symbols_once_early):
* symbols.c (reinit_symbols_early):
* symsinit.h:
* sysdep.c (sys_subshell):
* sysdep.c (tty_init_sys_modes_on_device):
* syswindows.h:
* text.c (dfc_convert_to_external_format):
* text.c (dfc_convert_to_internal_format):
* text.c (reinit_eistring_early):
* text.c (init_eistring_once_early):
* text.c (reinit_vars_of_text):
* text.h:
* text.h (INC_IBYTEPTR_FMT):
* text.h (DEC_IBYTEPTR_FMT):
* toolbar.c:
* toolbar.c (decode_toolbar_position):
* tooltalk.c:
* ui-gtk.c:
* unexnt.c:
* unexnt.c (_start):
* unexnt.c (unexec):
* unexnt.c (get_section_info):
* unicode.c:
* unicode.c (vars_of_unicode):
* window.c:
* window.c (allocate_window):
* window.c (new_window_mirror):
* window.c (update_mirror_internal):
* winslots.h:
author | michaels |
---|---|
date | Sun, 12 Jan 2003 11:08:22 +0000 |
parents | 2b6fa2618f76 |
children | 04bc9d2f42c7 |
rev | line source |
---|---|
428 | 1 /* Code to do an unexec for FreeBSD-1.1 for a temacs linked -Bdynamic. |
2 Derived from unexnetbsd.c, which was derived from unexsunos4.c | |
3 Copyright (C) 1992, 1993 Free Software Foundation, Inc. | |
4 | |
5 This file is part of XEmacs. | |
6 | |
7 XEmacs is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 2, or (at your option) any | |
10 later version. | |
11 | |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with XEmacs; see the file COPYING. If not, write to | |
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 Boston, MA 02111-1307, USA. */ | |
21 | |
22 /* Synched up with: Not in FSF? */ | |
23 | |
24 /* | |
25 Created 29-Oct-92 by Harlan Sexton | |
26 Tweaked 06-Aug-93 by Dean Michaels to work with sun3. | |
27 Converted 01-Dec-93 by Paul Mackerras to work with NetBSD shared libraries. | |
28 Tweaked 26-Feb-94 by Shawn Carey for use with FreeBSD-1.1 shared libraries. | |
29 */ | |
30 | |
31 /********************** Included .h Files **************************/ | |
32 | |
33 #include <config.h> | |
34 | |
35 #include <stdarg.h> | |
36 #include <sys/param.h> | |
37 #include <sys/mman.h> | |
38 #include <sys/file.h> | |
39 #include <sys/stat.h> | |
40 #include <sys/types.h> | |
41 #include <string.h> | |
42 #include <stdio.h> | |
438 | 43 #include <errno.h> |
428 | 44 #include <a.out.h> |
45 #include <unistd.h> | |
46 #include <ctype.h> | |
47 #include <stab.h> | |
48 #include <sys/dir.h> | |
49 #include <link.h> | |
50 | |
51 /********************** Macros *************************************/ | |
52 | |
53 #define SYS_ERR strerror(errno) | |
54 | |
55 #define MASK_UP(x,p_of_two) \ | |
56 ((((unsigned long) (x)) + ((p_of_two) - 1)) & (~((p_of_two) - 1))) | |
57 | |
58 #define MASK_DOWN(x,p_of_two) (((unsigned long) (x)) & (~((p_of_two) - 1))) | |
59 | |
60 /********************** Typedefs and Structs ***********************/ | |
61 | |
62 struct translation_struct | |
63 { | |
64 long txtaddr; | |
65 long txtoff; | |
66 long dataddr; | |
67 long datoff; | |
68 long bssaddr; | |
69 long endaddr; | |
70 }; | |
71 | |
72 /********************** Function Prototypes/Declarations ***********/ | |
73 | |
442 | 74 static void unexec_error (const char *m, int use_errno, ...); |
428 | 75 static int unexec_open (char *filename, int flag, int mode); |
76 static caddr_t unexec_mmap (int fd, size_t len, int prot, int flags); | |
77 static long unexec_seek (int fd, long position); | |
78 static void unexec_read (int fd, long position, char *buf, int bytes); | |
79 static void unexec_write (int fd, long position, char *buf, int bytes); | |
80 static void unexec_pad (int fd, int bytes); | |
81 static void unexec_fstat (int fd, struct stat *statptr); | |
82 static void unexec_fchmod (int fd, int mode); | |
83 static long unexec_addr_to_offset (long addr, struct translation_struct *ts); | |
84 static void copy_relocation_site (struct relocation_info *ri, | |
85 caddr_t from_base_addr, | |
86 caddr_t to_base_addr, | |
87 struct translation_struct *ts); | |
88 static void reset_symtab (struct nlist *start, struct nlist *end, | |
89 char *strtab, long edata_value, long end_value, | |
90 int shlib_image); | |
91 static void reset_ldso_symtab (struct nzlist *start, struct nzlist *end, | |
92 char *strtab, long edata_value, long end_value, | |
93 int shlib_image); | |
94 int run_time_remap (char *dummy); | |
95 | |
96 /********************** Variables **********************************/ | |
97 | |
98 /* for reporting error messages from system calls */ | |
99 extern int _DYNAMIC; | |
100 extern char **environ; | |
101 | |
102 static unsigned long sbrk_of_0_at_unexec; | |
103 | |
104 /*******************************************************************/ | |
105 | |
106 static void | |
442 | 107 unexec_error (const char *fmt, int use_errno, ...) |
428 | 108 { |
442 | 109 const char *err_msg = SYS_ERR; |
428 | 110 va_list args; |
111 | |
112 fprintf (stderr, "unexec - "); | |
113 va_start (args, use_errno); | |
114 vfprintf (stderr, fmt, args); | |
115 va_end (args); | |
116 | |
117 if (use_errno) | |
118 fprintf (stderr, ": %s", err_msg); | |
119 fprintf (stderr, "\n"); | |
120 exit (1); | |
121 return; | |
122 } | |
123 | |
124 static int | |
125 unexec_open (char *filename, int flag, int mode) | |
126 { | |
127 int fd; | |
128 | |
129 errno = 0; | |
130 | |
131 fd = open (filename, flag, mode); | |
132 | |
133 if (fd < 0) | |
134 unexec_error ("Failure opening file %s", 1, filename); | |
135 return fd; | |
136 } | |
137 | |
138 static caddr_t | |
139 unexec_mmap (int fd, size_t len, int prot, int flags) | |
140 { | |
141 caddr_t return_val; | |
142 | |
143 unexec_seek (fd, 0); | |
144 errno = 0; | |
145 return_val = mmap (0, len, prot, flags, fd, 0); | |
146 | |
147 if (return_val == (caddr_t) -1) | |
148 unexec_error ("Failure mmap'ing file", 1); | |
149 return return_val; | |
150 } | |
151 | |
152 | |
153 static long | |
154 unexec_seek (int fd, long position) | |
155 { | |
156 long seek_value; | |
157 | |
158 if (fd <= 0) | |
159 unexec_error ("No file open in which to seek", 0); | |
160 | |
161 errno = 0; | |
162 | |
163 if (position < 0) | |
164 seek_value = (long) lseek (fd, 0, L_INCR); | |
165 else | |
166 seek_value = (long) lseek (fd, position, L_SET); | |
167 | |
168 if (seek_value < 0) | |
169 unexec_error ("Failed to do a seek to 0x%x in %s", 1, | |
170 position, "unexec() output file"); | |
171 | |
172 return seek_value; | |
173 } | |
174 | |
175 static void | |
176 unexec_read (int fd, long position, char *buf, int bytes) | |
177 { | |
178 int n_read; | |
179 int remains = bytes; | |
180 position = unexec_seek (fd, position); | |
181 | |
182 if (bytes < 0) | |
183 unexec_error ("Attempted read of %d bytes", 0, bytes); | |
184 | |
185 errno = 0; | |
186 | |
187 while (remains > 0) | |
188 { | |
189 n_read = read (fd, buf, remains); | |
190 if (n_read <= 0) | |
191 unexec_error ("Read failed for 0x%x bytes at offset 0x%x in %s", | |
192 1, bytes, position, "unexec() output file"); | |
193 buf += n_read; | |
194 remains -= n_read; | |
195 } | |
196 | |
197 return; | |
198 } | |
199 | |
200 static void | |
201 unexec_write (int fd, long position, char *buf, int bytes) | |
202 { | |
203 int n_written; | |
204 int remains = bytes; | |
205 position = unexec_seek (fd, position); | |
206 | |
207 if (bytes < 0) | |
208 unexec_error ("Attempted write of %d bytes in %s", | |
209 0, bytes, "unexec() output file"); | |
210 | |
211 errno = 0; | |
212 | |
213 while (remains > 0) | |
214 { | |
215 n_written = write (fd, buf, remains); | |
216 if (n_written <= 0) | |
217 unexec_error ("Write failed for 0x%x bytes at offset 0x%x in %s", | |
218 1, bytes, position, "unexec() output file"); | |
219 buf += n_written; | |
220 remains -= n_written; | |
221 } | |
222 | |
223 return; | |
224 } | |
225 | |
226 static void | |
227 unexec_pad (int fd, int bytes) | |
228 { | |
229 if (bytes > 0) | |
230 { | |
231 char buf[1024]; | |
232 int remaining = bytes; | |
233 | |
234 memset (buf, 0, sizeof (buf)); | |
235 | |
236 while (remaining > 0) | |
237 { | |
238 int this_write = (remaining > sizeof(buf))?sizeof(buf):remaining; | |
239 unexec_write (fd, -1, buf, this_write); | |
240 remaining -= this_write; | |
241 } | |
242 } | |
243 } | |
244 | |
245 static void | |
246 unexec_fstat (int fd, struct stat *statptr) | |
247 { | |
248 errno = 0; | |
249 if (-1 == fstat (fd, statptr)) | |
250 unexec_error ("fstat() failed for descriptor %d", 1, fd); | |
251 return; | |
252 } | |
253 | |
254 static void | |
255 unexec_fchmod (int fd, int mode) | |
256 { | |
257 errno = 0; | |
258 if (-1 == fchmod (fd, mode)) | |
259 unexec_error ("fchmod() failed for descriptor %d", 1, fd); | |
260 return; | |
261 } | |
262 | |
263 static long | |
264 unexec_addr_to_offset (long addr, struct translation_struct *ts) | |
265 | |
266 { | |
267 if ((addr < ts->txtaddr) || (addr >= ts->bssaddr)) | |
268 return -1; | |
269 else if (addr >= ts->dataddr) | |
270 return ((long) ((addr - ts->dataddr) + ts->datoff)); | |
271 else | |
272 return ((long) ((addr - ts->txtaddr) + ts->txtoff)); | |
273 } | |
274 | |
275 | |
276 /* | |
277 * "LD.SO" DATA AND SYMBOL TABLE OPERATIONS | |
278 */ | |
279 | |
280 static void | |
281 copy_relocation_site (struct relocation_info *ri, | |
282 caddr_t from_base_addr, | |
283 caddr_t to_base_addr, | |
284 struct translation_struct *ts) | |
285 { | |
286 long offset; | |
287 caddr_t from, to; | |
288 | |
289 /* We can get relocation sites in the bss region, for objects whose | |
290 contents are copied from a shared library. We don't need or want | |
291 to restore these at present. */ | |
292 #ifndef sparc | |
293 if (ri->r_copy) | |
294 return; | |
295 #else | |
296 /* Struct relocation_info_sparc doesn't have member r_copy. | |
297 Instead, we use the address to check if this is run-time-copied. */ | |
298 if (ri->r_address >= ts->bssaddr && ri->r_address < ts->endaddr) | |
299 return; | |
300 #endif | |
301 | |
302 offset = unexec_addr_to_offset (ri->r_address, ts); | |
303 if (offset == -1) | |
304 unexec_error ("bad relocation address 0x%x (0x%x)", 0, ri->r_address, | |
305 ((long *)ri)[1]); | |
306 | |
307 from = from_base_addr + offset; | |
308 to = to_base_addr + offset; | |
309 /* This stuff should be in a md_ file somewhere... */ | |
310 #ifndef sparc | |
311 switch (ri->r_length) | |
312 { | |
313 case 0: | |
314 *((char *) to) = *((char *) from); | |
315 break; | |
316 case 1: | |
317 *((short *) to) = *((short *) from); | |
318 break; | |
319 case 2: | |
320 *((long *) to) = *((long *) from); | |
321 break; | |
322 default: | |
323 unexec_error ("unknown reloc length %d seen during unexec()", | |
324 0, ri->r_length); | |
325 break; | |
326 } | |
327 #else /* sparc */ | |
328 switch (ri->r_type) | |
329 { | |
330 case RELOC_8: | |
331 case RELOC_DISP8: | |
332 *((char *) to) = *((char *) from); | |
333 break; | |
334 case RELOC_16: | |
335 case RELOC_DISP16: | |
336 *((short *) to) = *((short *) from); | |
337 break; | |
338 case RELOC_LO10: | |
339 case RELOC_13: | |
340 case RELOC_22: | |
341 case RELOC_HI22: | |
342 case RELOC_WDISP22: | |
343 case RELOC_WDISP30: | |
344 case RELOC_32: | |
345 case RELOC_DISP32: | |
346 case RELOC_GLOB_DAT: | |
347 *((long *) to) = *((long *) from); | |
348 break; | |
349 case RELOC_JMP_SLOT: | |
350 { | |
351 long *target = (long *) to; | |
352 long *source = (long *) from; | |
353 *target = *source; | |
354 target++; | |
355 source++; | |
356 *target = *source; | |
357 target++; | |
358 source++; | |
359 *target = *source; | |
360 } | |
361 break; | |
362 default: | |
363 unexec_error ("unknown reloc type %d seen during unexec()", | |
364 0, ri->r_type); | |
365 break; | |
366 } | |
367 #endif /* sparc */ | |
368 } | |
369 | |
370 static void | |
371 reset_symtab (struct nlist *start, struct nlist *end, char *strtab, | |
372 long edata_value, long end_value, int shlib_image) | |
373 { | |
374 struct nlist *tmp = start; | |
375 int found_edata = 0; | |
376 int found_end = 0; | |
377 | |
378 while (tmp < end) | |
379 { | |
380 int type = tmp->n_type; | |
381 | |
382 if ((type == (N_UNDF | N_EXT)) && | |
383 (tmp->n_value != 0)) | |
384 unexec_error ("unexec'ing image has COMMON symbols in it -- we quit!", | |
385 0); | |
386 | |
387 if (!(type & N_STAB)) | |
388 { | |
389 if (!found_edata && | |
390 (type == (N_EXT | N_DATA)) && | |
391 tmp->n_un.n_strx && | |
392 !strcmp ("_edata", strtab + tmp->n_un.n_strx)) | |
393 { | |
394 tmp->n_value = edata_value; | |
395 found_edata = 1; | |
396 } | |
397 | |
398 | |
399 if ((type & N_TYPE) == N_BSS) | |
400 { | |
401 if (!found_end && | |
402 (type == (N_EXT | N_BSS)) && | |
403 tmp->n_un.n_strx && | |
404 !strcmp ("_end", strtab + tmp->n_un.n_strx)) | |
405 { | |
406 tmp->n_value = end_value; | |
407 found_end = 1; | |
408 } | |
409 else if (type & N_EXT) | |
410 tmp->n_type = N_DATA | N_EXT; | |
411 else | |
412 tmp->n_type = N_DATA; | |
413 } | |
414 | |
415 /* the way things are being handled here, having sbrk() in the | |
416 image is fatal for an image linked with shared lib's (although | |
417 the code could be modified to support it), but this should | |
418 never happen anyway */ | |
419 if (shlib_image && | |
420 (type == (N_EXT | N_TEXT)) && | |
421 tmp->n_un.n_strx && | |
422 !strcmp ("_sbrk", strtab + tmp->n_un.n_strx)) | |
423 unexec_error ("unexec'd shlib image has sbrk() in it -- we quit!", | |
424 0); | |
425 } | |
426 | |
427 tmp++; | |
428 } | |
429 } | |
430 | |
431 static void | |
432 reset_ldso_symtab (struct nzlist *start, struct nzlist *end, char *strtab, | |
433 long edata_value, long end_value, int shlib_image) | |
434 { | |
435 struct nzlist *tmp = start; | |
436 int found_edata = 0; | |
437 int found_end = 0; | |
438 | |
439 while (tmp < end) { | |
440 int type = tmp->nz_type; | |
441 /* | |
442 * the following code breaks under FreeBSD-1.1-BETA, but everything | |
443 * seems to work perfectly if it's commented out. This did not break | |
444 * anything until the changes to ld.so were made. | |
445 */ | |
446 /* | |
447 if ((type == (N_UNDF | N_EXT)) && (tmp->nz_value != 0)) | |
448 unexec_error("unexec'ing image has COMMON symbols in rel -- we quit!",0); | |
449 */ | |
450 if (!(type & N_STAB)) { | |
451 if (!found_edata && | |
452 (type == (N_EXT | N_DATA)) && | |
453 !strcmp ("_edata", strtab + tmp->nz_strx)) { | |
454 tmp->nz_value = edata_value; | |
455 found_edata = 1; | |
456 } | |
457 | |
458 if ((type & N_TYPE) == N_BSS) { | |
459 if (!found_end && | |
460 (type == (N_EXT | N_BSS)) && | |
461 !strcmp ("_end", strtab + tmp->nz_strx)) { | |
462 tmp->nz_value = end_value; | |
463 found_end = 1; | |
464 } else if (type & N_EXT) | |
465 tmp->nz_type = N_DATA | N_EXT; | |
466 else | |
467 tmp->nz_type = N_DATA; | |
468 } | |
469 | |
470 /* the way things are being handled here, having sbrk() in the | |
471 image is fatal for an image linked with shared lib's (although | |
472 the code could be modified to support it), but this should | |
473 never happen anyway */ | |
474 if (shlib_image && | |
475 (type == (N_EXT | N_TEXT)) && | |
476 !strcmp ("_sbrk", strtab + tmp->nz_strx)) | |
477 unexec_error("unexec'd shlib image has sbrk() ref -- we quit!", 0); | |
478 } | |
479 tmp++; | |
480 } | |
481 } | |
482 | |
483 extern int getpagesize (void); | |
484 | |
485 /* | |
486 * EXPORTED FUNCTIONS | |
487 */ | |
488 | |
489 /* this has to be a global variable to prevent the optimizers from | |
490 * assuming that it can not be 0. | |
491 */ | |
492 static void *dynamic_addr = (void *) &_DYNAMIC; | |
493 | |
494 int | |
495 unexec (char *new_name, char *old_name, | |
496 unsigned int emacs_edata, unsigned int dummy1, unsigned int dummy2) | |
497 { | |
498 /* ld.so data */ | |
499 struct _dynamic *ld = 0; | |
500 struct section_dispatch_table *ld2 = 0; | |
501 /* old and new state */ | |
502 int old_fd; | |
503 int new_fd; | |
504 caddr_t old_base_addr; | |
505 caddr_t new_base_addr; | |
506 struct exec old_hdr; | |
507 struct exec new_hdr; | |
508 struct stat old_buf; | |
509 struct stat new_buf; | |
510 /* some process specific "constants" */ | |
511 unsigned long n_pagsiz, new_edata; | |
512 long page_size = getpagesize (); | |
513 caddr_t plt_end; | |
514 caddr_t current_break = (caddr_t) sbrk (0); | |
515 | |
516 if (!page_size) | |
517 unexec_error ("unexec() failed because we can't get the size of a page!", | |
518 0); | |
519 | |
520 /* see if this is a -Bdynamic image -- if so, find ld.so structures */ | |
521 if (dynamic_addr) | |
522 { | |
523 ld = (struct _dynamic *) dynamic_addr; | |
524 ld2 = ld->d_un.d_sdt; | |
525 if (ld->d_version < LD_VERSION_BSD) | |
526 unexec_error ("%s linked with obsolete version of ld -- we quit!", | |
527 0, old_name); | |
528 } | |
529 | |
530 /* open the old and new files, figuring out how big the old one is | |
531 so that we can map it in */ | |
532 old_fd = unexec_open (old_name, O_RDONLY, 0); | |
533 new_fd = unexec_open (new_name, O_RDWR | O_CREAT | O_TRUNC, 0666); | |
534 | |
535 /* setup the header and the statbuf for old_fd */ | |
536 unexec_read (old_fd, 0, (char *) &old_hdr, sizeof (old_hdr)); | |
537 unexec_fstat (old_fd, &old_buf); | |
538 | |
539 | |
540 /* set up some important constants */ | |
541 n_pagsiz = __LDPGSZ; | |
542 if (dynamic_addr) | |
543 plt_end = (caddr_t) MASK_UP (ld2->sdt_plt + ld2->sdt_plt_sz, sizeof (double)); | |
544 else | |
545 plt_end = (caddr_t) N_DATADDR (old_hdr); | |
546 | |
547 #if 0 | |
548 /* never write protect the variable "environ", defined in /lib/crt0.o, and | |
853 | 549 set in process.c */ |
428 | 550 mprotect_bottom_addr = ((unsigned long) &environ) + sizeof (char **); |
551 /* never protect ABOVE the end of data emacs_edata specified */ | |
552 mprotect_top_addr = MIN (emacs_edata, N_DATADDR (old_hdr) + old_hdr.a_data); | |
553 #endif | |
554 | |
555 /* Set up the image of the old file */ | |
556 old_base_addr = unexec_mmap (old_fd, old_buf.st_size, PROT_READ, | |
557 MAP_FILE | MAP_PRIVATE); | |
558 close (old_fd); | |
559 | |
560 /* set up the new exec */ | |
561 new_hdr = old_hdr; | |
562 new_edata = (unsigned long) MASK_UP (current_break, n_pagsiz); | |
563 new_hdr.a_data = new_edata - ((unsigned long) N_DATADDR (old_hdr)); | |
564 new_hdr.a_bss = 0; | |
565 | |
566 /* set up this variable, in case we want to reset "the break" | |
567 when restarting */ | |
568 sbrk_of_0_at_unexec = ((unsigned long) MASK_UP (current_break, n_pagsiz)); | |
569 | |
570 /* Write out the first approximation to the new file. The sizes of | |
571 each section will be correct, but there will be a number of | |
572 corrections that will need to be made. */ | |
573 { | |
574 long old_datoff = N_DATOFF (old_hdr); | |
575 long old_dataddr = N_DATADDR (old_hdr); | |
576 long new_treloff = N_RELOFF (new_hdr); | |
577 long old_treloff = N_RELOFF (old_hdr); | |
578 long ld_so_size = ((unsigned long) plt_end) - old_dataddr; | |
579 long real_data_size = current_break - plt_end; | |
580 long pad_size = | |
581 MASK_UP (current_break, n_pagsiz) - ((unsigned long) current_break); | |
582 | |
583 | |
584 /* First, write the text segment with new header -- copy everything until | |
585 the start of the data segment from the old file, and then go back and | |
586 write the new header. */ | |
587 unexec_write (new_fd, 0, old_base_addr, old_datoff + ld_so_size); | |
588 unexec_write (new_fd, 0, (char *) &new_hdr, sizeof (new_hdr)); | |
589 | |
590 /* Copy the rest of the data segment from the running image. */ | |
591 unexec_write (new_fd, old_datoff + ld_so_size, | |
592 plt_end, real_data_size); | |
593 | |
594 /* pad out the data segment */ | |
595 unexec_pad (new_fd, pad_size); | |
596 | |
597 /* Finally, copy the symbol table information from the old file. */ | |
598 unexec_write (new_fd, new_treloff, | |
599 old_base_addr + old_treloff, | |
600 old_buf.st_size - old_treloff); | |
601 } | |
602 | |
603 | |
604 /* Next, map in the output file so that we can jump around fixing it | |
605 up. We retain the old file so that we can refer to it. */ | |
606 unexec_fstat (new_fd, &new_buf); | |
607 new_base_addr = unexec_mmap (new_fd, | |
608 MASK_UP (new_buf.st_size, page_size), | |
609 PROT_READ | PROT_WRITE, | |
610 MAP_FILE | MAP_SHARED); | |
611 | |
612 | |
613 | |
614 /* We need to do 2 things. First, make sure that _edata and _end (and | |
615 hence, curbrk) are set to the correct values. At the same time, for | |
616 neatness and to help with debugging, mark all the types of all ld.so | |
617 and nm BSS symbols in the new file to be DATA, and make sure that | |
618 there are no COMMON symbols in the output file, as any references to | |
619 these can lose really big. Second, reset all of the ld.so "relocation | |
620 sites" in the new file to have the values that appear in the old file | |
621 -- the failure to do this was the biggest loser in the old version of | |
622 this code. */ | |
623 | |
624 /* STEP 1 */ | |
625 /* Reset the regular symbol table first. */ | |
626 reset_symtab ((struct nlist *) (new_base_addr + N_SYMOFF(new_hdr)), | |
627 (struct nlist *) (new_base_addr + N_SYMOFF(new_hdr) + | |
628 new_hdr.a_syms), | |
629 (char *) (new_base_addr + N_STROFF(new_hdr)), | |
630 new_edata, new_edata, | |
631 !!dynamic_addr); | |
632 | |
633 /* Now reset the ld.so symbol table. */ | |
634 if (dynamic_addr) | |
635 { | |
636 struct translation_struct ts; | |
637 struct relocation_info *tmp, *end; | |
638 caddr_t syms, strings; | |
639 | |
640 /* set up the structure that we use to translate addresses in the | |
641 old file into file offsets */ | |
642 ts.txtaddr = N_TXTADDR (old_hdr); | |
643 ts.txtoff = N_TXTOFF (old_hdr); | |
644 ts.dataddr = N_DATADDR (old_hdr); | |
645 ts.datoff = N_DATOFF (old_hdr); | |
646 ts.bssaddr = N_DATADDR (old_hdr) + old_hdr.a_data; | |
647 ts.endaddr = ts.bssaddr + old_hdr.a_bss; | |
648 | |
649 syms = new_base_addr + unexec_addr_to_offset(ld2->sdt_nzlist, &ts); | |
650 strings = new_base_addr + unexec_addr_to_offset(ld2->sdt_strings, &ts); | |
651 reset_ldso_symtab ((struct nzlist *) syms, (struct nzlist *) strings, | |
652 (char *) strings, | |
653 new_edata, new_edata, | |
654 !!dynamic_addr); | |
655 | |
656 /* STEP 2 */ | |
657 tmp = (struct relocation_info *) | |
658 (old_base_addr + unexec_addr_to_offset(ld2->sdt_rel, &ts)); | |
659 end = (struct relocation_info *) | |
660 (old_base_addr + unexec_addr_to_offset(ld2->sdt_hash, &ts)); | |
661 while (tmp < end) | |
662 { | |
663 copy_relocation_site (tmp, old_base_addr, new_base_addr, &ts); | |
664 tmp++; | |
665 } | |
666 } | |
667 | |
668 /* get rid of the mmap-ed file space and make the output file | |
669 executable -- then quit */ | |
670 munmap (new_base_addr, MASK_UP (new_buf.st_size, page_size)); | |
671 munmap (old_base_addr, MASK_UP (old_buf.st_size, page_size)); | |
672 unexec_fchmod (new_fd, 0755); | |
673 close (new_fd); | |
674 return 0; | |
675 } | |
676 | |
677 | |
678 int | |
679 run_time_remap (char *dummy) | |
680 { | |
681 unsigned long current_sbrk = (unsigned long) sbrk (0); | |
682 | |
683 #if __FreeBSD_version < 300000 /* 2.x can work with this code */ | |
684 if (sbrk_of_0_at_unexec < current_sbrk) | |
685 { | |
686 if (sbrk_of_0_at_unexec != 0) | |
687 fprintf (stderr, "Absurd new brk addr = %lx (current = %lx)\n", | |
688 sbrk_of_0_at_unexec, current_sbrk); | |
689 } | |
690 else | |
691 #endif | |
692 if (sbrk_of_0_at_unexec > current_sbrk) | |
693 { | |
694 errno = 0; | |
695 if (brk ((caddr_t) sbrk_of_0_at_unexec)) | |
696 fprintf (stderr, "failed to change brk addr to %lx: %s\n", | |
697 sbrk_of_0_at_unexec, SYS_ERR); | |
698 } | |
699 | |
700 #if 0 | |
701 /* with proper COW, i don't think we really need to do this... */ | |
702 { | |
703 long page_size = getpagesize(); | |
704 unsigned long base_addr = MASK_UP (mprotect_bottom_addr, page_size); | |
705 unsigned long top_addr = MASK_DOWN (mprotect_top_addr, page_size); | |
706 long len = top_addr - base_addr; | |
707 | |
708 if (len > 0) | |
709 { | |
710 errno = 0; | |
711 if (mprotect ((caddr_t) base_addr, len, PROT_READ | PROT_EXEC)) | |
712 fprintf (stderr, "failed to change protection on data pages: %s\n", | |
713 SYS_ERR); | |
714 } | |
715 } | |
716 #endif | |
717 | |
718 return 0; | |
719 } |