/* * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #if defined(__MWERKS__) && !defined(__private_extern__) #define __private_extern__ __declspec(private_extern) #endif /* * Global types, variables and routines declared in the file objects.c. * * The following include file need to be included before this file: * #include "ld.h" * #include "sections.h" */ /* * The structure to hold the information for the object files actually loaded. */ struct object_file { char *file_name; /* Name of the file the object is in. */ char *obj_addr; /* Address of the object file in memory. */ unsigned long obj_size; /* Size of the object file. */ enum bool swapped; /* TRUE if the bytesex of the object does not */ /* match the host bytesex. */ enum bool fvmlib_stuff; /* TRUE if any SG_FVMLIB segments or any */ /* LC_LOADFVMLIB or LC_IDFVMLIB load */ /* commands in the file. */ enum bool dylib; /* TRUE if mh->filetype == MH_DYLIB */ enum bool dylib_stuff; /* TRUE if any LC_LOAD_DYLIB or LC_ID_DYLIB */ /* load commands in the file. */ enum bool bundle_loader; /* TRUE this the -bundle_loader object */ unsigned long /* when -twolevel_name space is in effect */ library_ordinal; /* this the library_ordinal for recording */ unsigned long isub_image; /* when -twolevel_name space is in effect */ /* this the sub_image index for recording */ unsigned long nload_dylibs; /* Number of LC_LOAD_DYLIB commands */ enum bool dylinker; /* TRUE if mh->filetype == MH_DYLINKER */ enum bool command_line; /* TRUE if object is created for a symbol */ /* created on the command line. */ struct ar_hdr *ar_hdr; /* Archive header (NULL in not in archive). */ char *ar_name; /* Archive member name */ unsigned long ar_name_size; /* Size of archive member name */ struct dylib_module /* Dynamic shared library module this object */ *dylib_module; /* file struct refers to or NULL. */ unsigned long nsection_maps;/* Total number of sections in this object. */ struct section_map /* A section map for each section in this. */ *section_maps; /* object file. */ struct symtab_command /* The LC_SYMTAB load command which has */ *symtab; /* offsets to the symbol and string tables. */ struct dysymtab_command /* The LC_DYSYMTAB load command which has */ *dysymtab; /* offsets to the tables for dynamic linking.*/ struct routines_command *rc;/* The LC_ROUTINES load command */ unsigned long nundefineds; /* Number of undefined symbols in the object */ struct undefined_map /* Map of undefined symbol indexes and */ *undefined_maps; /* pointers to merged symbols (for external */ /* relocation) */ unsigned long nextdefsym; /* number of externally defined symbols */ unsigned long iextdefsym; /* output index to above symbols for MH_DYLIB */ unsigned long nprivatesym; /* number of private external symbols */ unsigned long iprivatesym; /* output index to above symbols */ unsigned long cprivatesym; /* current output index being assigned to */ /* private external symbols */ unsigned long nlocalsym; /* number of local symbols in output */ unsigned long ilocalsym; /* output index to above symbols */ struct localsym_block /* the list of blocks of local symbols that */ *localsym_blocks; /* that are to be excluded from the output */ struct section_map /* Current map of symbols used for -sectorder */ *cur_section_map; /* that is being processed from this object */ #ifdef RLD long set_num; /* The set number this object belongs to. */ enum bool user_obj_addr; /* TRUE if the user allocated the object */ /* file's memory (then rld doesn't */ /* deallocate it) */ enum bool from_fat_file; /* TRUE if the object is in a fat file (then */ /* the file's memory is deallocate by */ /* clean_archives_and_fats(). */ #endif #ifndef RLD /* These are for MH_DYLIB files only */ char *module_name; /* module name */ unsigned long nrefsym; /* number of reference symbol table entries */ unsigned long irefsym; /* output index to reference symbol table */ struct reference_map /* Map of external symbols (pointers to merged*/ *reference_maps; /* merged symbols and flag for reference type*/ unsigned long iinit; /* index into mod init section */ unsigned long ninit; /* number of mod init entries */ unsigned long iterm; /* index into mod term section */ unsigned long nterm; /* number of mod term entries */ struct section_map /* the section map for the (__OBJC, */ *objc_module_info; /* __module_info) section if any. */ enum bool init_module_loaded; /* has the module with the library */ /* initialization routine been loaded */ #endif unsigned long imodtab; /* output index to the module table */ unsigned long iextrel; /* index into output external reloc entries */ unsigned long nextrel; /* number of output external reloc entries */ unsigned long ilocrel; /* index into output local reloc entries */ unsigned long nlocrel; /* number of output local reloc entries */ }; /* The number of object_file structrures in object_list */ #ifndef RLD #define NOBJECTS 120 #else #define NOBJECTS 10 #endif /* * The structure to hold a chunk the list of object files actually loaded. */ struct object_list { struct object_file object_files[NOBJECTS]; /* the object_file structures in this chunk */ unsigned long used; /* the number used in this chunk */ struct object_list *next; /* the next chunk (NULL in no more chunks) */ }; /* * The structure for information about each section of an object module. This * gets allocated as an array and the sections in it are in the order that * they appear in the header so that section numbers (minus one) can be used as * indexes into this array. */ struct section_map { struct section *s; /* Pointer to the section structure in the */ /* object file. */ struct merged_section /* Pointer the output section to get the */ *output_section; /* section number this will be in the output */ /* file used in pass2 to rewrite relocation */ /* entries. */ unsigned long offset; /* The offset from the start of the section */ /* that this object file's section will start */ /* at in the output file. */ /* the address the section will be at and is */ /* used in pass2 to do the relocation. */ unsigned long flush_offset; /* The offset from the start of the section */ /* that is to be used by output_flush() that */ /* includes the area before the above offset */ /* for alignment. */ struct fine_reloc /* Map for relocation of literals or other */ *fine_relocs; /* items which are smaller than the section. */ unsigned long nfine_relocs; /* Number of structures in the map */ enum bool no_load_order; /* Not to be scattered, loaded normalily */ unsigned long order; /* order when no_load_order == TRUE */ struct load_order /* Map of symbols used for -sectorder */ *load_orders; unsigned long nload_orders; /* Number of structures in the map */ enum bool start_section; /* There is a symbol at the start of the */ /* section. */ enum bool /* For symbol stub sections if any indirect */ absolute_indirect_defineds; /* symbol is defined as an absolute */ enum bool /* TRUE when the input relocation entries */ input_relocs_already_swapped; /* have been already swapped */ /* * These are set in count_reloc() and tested in output_section() for * internal error checking. */ unsigned long nlocrel; /* number of local reloc entries */ unsigned long nextrel; /* number of external reloc entries */ /* * These next two fields along with the above two fields are used for * output_for_dyld only if this is a non-regular section that will have * external relocation entries (currently only coaleseced sections) */ unsigned long iextrel; /* index into output external reloc entries */ unsigned long ilocrel; /* index into output local reloc entries */ }; /* * This structure is used for relocating items in a section from an input file * when they are scatered in the output file (normally the section is copied * as a whole). The address in the input file and the resulting address of * the section in the output file are also needed to do the relocation. * The two fields indirect_defined and use_contents are used for indirect * sections to indicate if the indirect symbol for the item is defined and if * the item from the object file will be used in the output file. */ struct fine_reloc { unsigned long indirect_defined:1, /* TRUE if the indirect sym is defined */ use_contents:1, /* TRUE if this item is used */ local_symbol:1, /* TRUE if the indirect sym is local */ live:1, /* TRUE if referenced (for -dead_strip) */ refs_marked_live:1, /* TRUE when references marked live */ searched_for_live_refs:1, /* TRUE if searched for live refs */ indirect_symbol_local:1, /* TRUE if this is for an indirect */ /* section with INDIRECT_SYMBOL_LOCAL */ unused_bits:25; unsigned long input_offset; /* offset in the input file for the item */ unsigned long output_offset; /* offset in the output file for the item*/ struct merged_symbol /* the global merged_symbol for the item */ *merged_symbol; /* if any (else NULL) */ }; /* * This structure is used when a section has a -sectorder order file and is used * to set the orders and then build fine_reloc structures for it so it can be * scatter loaded. */ struct load_order { char *name; /* symbol's name */ unsigned long value; /* symbol's value */ unsigned long index; /* symbol's index in symbol table */ unsigned long order; /* order in output, 0 if not assigned yet */ unsigned long line_number; /* line number if specified or zero */ unsigned long input_offset; /* offset in the input file for the item */ unsigned long input_size; /* size of symbol in the input file */ unsigned long output_offset;/* offset in the output file for the item */ struct fine_reloc *fine_reloc; /* the fine_reloc for this load_order */ /* the following is only used in coalesced_section_merge() to know if this load_order struct is for global coalesced symbol */ enum bool global_coalesced_symbol; }; /* * This structure holds pairs of indexes into an object files symbol table and * pointers to merged symbol table structures for each symbol that is an * undefined symbol in an object file. */ struct undefined_map { unsigned long index; /* index of symbol in the object file's symbol table */ struct merged_symbol /* pointer to the merged symbol */ *merged_symbol; }; /* * This structure holds reference type flags and pointers to merged symbol table * structures for each exteranl symbol that is referenced in an object file that * will be part of a MH_DYLIB file. These structures are used to create the * reference table for a MH_DYLIB file. */ struct reference_map { unsigned long flags; /* type of reference made to this symbol */ struct merged_symbol /* pointer to the merged symbol being referenced */ *merged_symbol; }; /* * The head of the object file list and the total count of all object files * in the list. */ __private_extern__ struct object_list *objects; __private_extern__ unsigned long nobjects; /* * A pointer to the current object being processed in pass1 or pass2. */ __private_extern__ struct object_file *cur_obj; /* * A pointer to the base object for an incremental link if not NULL. */ __private_extern__ struct object_file *base_obj; __private_extern__ struct object_file *new_object_file( void); #ifndef RLD __private_extern__ unsigned long object_index( struct object_file *obj); #endif __private_extern__ struct object_file *add_last_object_file( struct object_file *new_object); __private_extern__ void remove_last_object_file( struct object_file *last_object); __private_extern__ void print_obj_name( struct object_file *obj); __private_extern__ unsigned long size_ar_name( struct ar_hdr *ar_hdr); __private_extern__ void print_whatsloaded( void); __private_extern__ enum bool is_dylib_module_loaded( struct dylib_module *dylib_module); __private_extern__ unsigned long fine_reloc_output_offset( struct section_map *map, unsigned long input_offset); __private_extern__ unsigned long fine_reloc_output_address( struct section_map *map, unsigned long input_offset, unsigned long output_base_address); __private_extern__ void fine_reloc_output_ref( struct section_map *map, unsigned long input_offset, struct live_ref *ref); __private_extern__ enum bool fine_reloc_offset_in_output( struct section_map *map, unsigned long input_offset); __private_extern__ enum bool fine_reloc_offset_in_output_for_output_offset( struct section_map *map, unsigned long output_offset); __private_extern__ unsigned long fine_reloc_output_sectnum( struct section_map *map, unsigned long input_offset); __private_extern__ struct fine_reloc *fine_reloc_for_input_offset( struct section_map *map, unsigned long input_offset); #ifdef RLD __private_extern__ void clean_objects( void); __private_extern__ void remove_objects( void); #endif /* RLD */ #ifdef DEBUG __private_extern__ void print_object_list( void); __private_extern__ void print_fine_relocs( struct fine_reloc *fine_relocs, unsigned long nfine_relocs, char *string); #endif /* DEBUG */