From 4ccee83e6c66f35aa714d987002d0fd6377bf917 Mon Sep 17 00:00:00 2001 From: megacz Date: Fri, 30 Jan 2004 07:04:56 +0000 Subject: [PATCH 1/1] 2003/09/07 04:31:44 darcs-hash:20040130070456-2ba56-7683629f2168012e337456e98863ca020fd3da3b.gz --- upstream/darwin-linker/patches/include.patch | 1119 +++++++ upstream/darwin-linker/patches/ld.patch | 4325 +++++++++++++++++++++++++ upstream/darwin-linker/patches/libstuff.patch | 1085 +++++++ upstream/darwin-linker/patches/misc.patch | 952 ++++++ 4 files changed, 7481 insertions(+) create mode 100644 upstream/darwin-linker/patches/include.patch create mode 100644 upstream/darwin-linker/patches/ld.patch create mode 100644 upstream/darwin-linker/patches/libstuff.patch create mode 100644 upstream/darwin-linker/patches/misc.patch diff --git a/upstream/darwin-linker/patches/include.patch b/upstream/darwin-linker/patches/include.patch new file mode 100644 index 0000000..75f9ba6 --- /dev/null +++ b/upstream/darwin-linker/patches/include.patch @@ -0,0 +1,1119 @@ +Only in include: 2.0Compat +Only in include/: CVS +diff -ubr include/Makefile include/Makefile +--- include/Makefile Fri Sep 6 18:27:31 2002 ++++ include/Makefile Mon Aug 25 12:12:28 2003 +@@ -11,7 +11,7 @@ + mach-o/nlist.h mach-o/stab.h mach-o/loader.h mach-o/fat.h \ + mach-o/dyld_debug.h mach-o/arch.h mach-o/gmon.h mach-o/ranlib.h \ + mach-o/swap.h mach-o/getsect.h mach-o/i386/swap.h mach-o/dyld_gdb.h \ +- mach-o/ppc/swap.h mach-o/ppc/reloc.h \ ++ mach-o/ppc/swap.h mach-o/ppc/reloc.h + + LOCFILES = mach-o/rld_state.h mach-o/rld.h mach-o/sarld.h mach-o/kld.h \ + mach-o/redo_prebinding.h \ +@@ -19,7 +19,8 @@ + mach-o/hppa/swap.h mach-o/hppa/reloc.h \ + mach-o/m88k/swap.h mach-o/m88k/reloc.h \ + mach-o/m68k/swap.h \ +- mach-o/sparc/swap.h mach-o/sparc/reloc.h ++ mach-o/sparc/swap.h mach-o/sparc/reloc.h \ ++ cbt/libsyminfo.h + + # Note that OTHER_SRCS do NOT get installed + OTHER_SRCS = notes gnu/symseg.h \ +@@ -30,7 +31,8 @@ + stuff/print.h stuff/version_number.h stuff/crc32.h sys/gmon.h \ + stuff/openstep_mach.h stuff/seg_addr_table.h stuff/dylib_table.h \ + stuff/SymLoc.h stuff/dylib_roots.h stuff/guess_short_name.h \ +- stuff/macosx_deployment_target.h ++ stuff/macosx_deployment_target.h stuff/symbol_list.h ++ + ENCUMBERED_SRCS = gnu/a.out.h gnu/exec.h + + # Note that MISSING_SRCS are those may not be on all build machines +@@ -78,6 +80,7 @@ + ENCUMBERED_SRC_FILES = $(SRC_FILES) $(ENCUMBERED_SRCS) + + installsrc: ++ echo installsrc + $(MKDIRS) $(SRCROOT) + chmod 755 $(SRCROOT) + gnutar cf - $(ENCUMBERED_SRC_FILES) | (cd $(SRCROOT); gnutar xf -) +@@ -126,6 +129,9 @@ + cd stuff; \ + install -c -m 444 ${IFLAGS} bool.h \ + ${DSTROOT}${$(RC_OS)_LOCINCDIR}/dyld ++ cd cbt; \ ++ install -c -m 444 ${IFLAGS} libsyminfo.h \ ++ ${DSTROOT}${$(RC_OS)_LOCINCDIR}/cbt + + dirs: + $(MKDIRS) ${DSTROOT}${$(RC_OS)_INCDIR}/mach-o/i386 +@@ -136,6 +142,7 @@ + $(MKDIRS) ${DSTROOT}${$(RC_OS)_LOCINCDIR}/mach-o/i860 + $(MKDIRS) ${DSTROOT}${$(RC_OS)_LOCINCDIR}/mach-o/m88k + $(MKDIRS) ${DSTROOT}${$(RC_OS)_LOCINCDIR}/dyld ++ $(MKDIRS) ${DSTROOT}${$(RC_OS)_LOCINCDIR}/cbt + + depend: + +Only in include/architecture: CVS +Only in include/architecture/i386: CVS +diff -ubr include/architecture/i386/fpu.h include/architecture/i386/fpu.h +--- include/architecture/i386/fpu.h Tue Apr 30 00:37:18 2002 ++++ include/architecture/i386/fpu.h Mon Aug 25 12:56:22 2003 +@@ -121,7 +121,7 @@ + :3; + } fp_control_t; + +-#import ++#include + + /* + * Floating point 'environment' +diff -ubr include/architecture/i386/frame.h include/architecture/i386/frame.h +--- include/architecture/i386/frame.h Tue Apr 30 00:37:18 2002 ++++ include/architecture/i386/frame.h Mon Aug 25 12:56:22 2003 +@@ -63,7 +63,7 @@ + } pgfault; + } err_code_t; + +-#import ++#include + + /* + * The actual hardware exception frame +Only in include/architecture/m88k: CVS +diff -ubr include/architecture/m88k/fp_regs.h include/architecture/m88k/fp_regs.h +--- include/architecture/m88k/fp_regs.h Tue Jan 14 23:35:23 2003 ++++ include/architecture/m88k/fp_regs.h Mon Aug 25 12:56:22 2003 +@@ -37,7 +37,7 @@ + #ifndef _ARCH_M88K_FP_REGS_H_ + #define _ARCH_M88K_FP_REGS_H_ + +-#import ++#include + + /* + * m88k_xrf_t -- data types that MAY be in extended register file +diff -ubr include/architecture/m88k/reg_help.h include/architecture/m88k/reg_help.h +--- include/architecture/m88k/reg_help.h Tue Jan 14 23:35:23 2003 ++++ include/architecture/m88k/reg_help.h Mon Aug 25 12:56:22 2003 +@@ -37,7 +37,7 @@ + #ifndef _ARCH_M88K_REG_HELP_H_ + #define _ARCH_M88K_REG_HELP_H_ + +-#import ++#include + + /* Stack pointer must always be a multiple of 16 */ + #define STACK_INCR 16 +Only in include/architecture/nrw: CVS +Only in include/architecture: ppc +Only in include/architecture/sparc: CVS +Only in include: cbt +Only in include/gnu: CVS +Only in include: gpul_notes +Only in include/mach: CVS +Only in include/mach/hppa: CVS +Only in include/mach: i386 +Only in include/mach/i860: CVS +Only in include/mach/m68k: CVS +Only in include/mach/m88k: CVS +diff -ubr include/mach/m88k/thread_status.h include/mach/m88k/thread_status.h +--- include/mach/m88k/thread_status.h Tue Jan 14 23:35:24 2003 ++++ include/mach/m88k/thread_status.h Mon Aug 25 12:56:22 2003 +@@ -45,8 +45,8 @@ + #ifndef _MACH_M88K_THREAD_STATE_ + #define _MACH_M88K_THREAD_STATE_ + +-#import +-#import ++#include ++#include + + /************************************************************************** + * Data Typedefs used by thread_getstatus() and thread_setstatus() * +Only in include/mach: m98k +diff -ubr include/mach/machine.h include/mach/machine.h +--- include/mach/machine.h Tue Jan 14 23:35:24 2003 ++++ include/mach/machine.h Mon Aug 25 12:56:22 2003 +@@ -81,8 +81,8 @@ + #ifndef _MACH_MACHINE_H_ + #define _MACH_MACHINE_H_ + +-#import +-#import ++#include ++#include + + /* + * For each host, there is a maximum possible number of +@@ -355,6 +355,7 @@ + #define CPU_SUBTYPE_POWERPC_750 ((cpu_subtype_t) 9) + #define CPU_SUBTYPE_POWERPC_7400 ((cpu_subtype_t) 10) + #define CPU_SUBTYPE_POWERPC_7450 ((cpu_subtype_t) 11) ++#define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100) + + /* + * VEO subtypes +Only in include/mach/ppc: CVS +Only in include/mach/sparc: CVS +Only in include/mach-o: CVS +diff -ubr include/mach-o/dyld.h include/mach-o/dyld.h +--- include/mach-o/dyld.h Fri Sep 6 18:27:36 2002 ++++ include/mach-o/dyld.h Mon Aug 25 12:56:22 2003 +@@ -48,7 +48,7 @@ + * The high level NS... API. + */ + +-/* Object file image api */ ++/* Object file image API */ + typedef enum { + NSObjectFileImageFailure, /* for this a message is printed on stderr */ + NSObjectFileImageSuccess, +@@ -75,41 +75,39 @@ + extern enum DYLD_BOOL NSDestroyObjectFileImage( + NSObjectFileImage objectFileImage); + /* +- * Need api on NSObjectFileImage's for: ++ * API on NSObjectFileImage's for: + * "for Each Symbol Definition In Object File Image" (for Dynamic Bundles) +- * Could have the same thing for references ++ * and the same thing for references + */ +-/* not yet implemented */ + extern unsigned long NSSymbolDefinitionCountInObjectFileImage( + NSObjectFileImage objectFileImage); +-/* not yet implemented */ + extern const char * NSSymbolDefinitionNameInObjectFileImage( + NSObjectFileImage objectFileImage, + unsigned long ordinal); +-/* not yet implemented */ + extern unsigned long NSSymbolReferenceCountInObjectFileImage( + NSObjectFileImage objectFileImage); +-/* not yet implemented */ + extern const char * NSSymbolReferenceNameInObjectFileImage( + NSObjectFileImage objectFileImage, + unsigned long ordinal, + enum DYLD_BOOL *tentative_definition); /* can be NULL */ + /* +- * Other needed api on NSObjectFileImage: ++ * API on NSObjectFileImage: + * "does Object File Image define symbol name X" (using sorted symbol table) +- * a way to get the named objective-C section ++ * and a way to get the named objective-C section + */ +-/* not yet implemented */ + extern enum DYLD_BOOL NSIsSymbolDefinedInObjectFileImage( + NSObjectFileImage objectFileImage, + const char *symbolName); +-/* not yet implemented */ + extern void * NSGetSectionDataInObjectFileImage( + NSObjectFileImage objectFileImage, + const char *segmentName, +- const char *sectionName); ++ const char *sectionName, ++ unsigned long *size); /* can be NULL */ ++/* SPI first appeared in Mac OS X 10.3 */ ++extern enum DYLD_BOOL NSHasModInitObjectFileImage( ++ NSObjectFileImage objectFileImage); + +-/* module api */ ++/* module API */ + typedef void * NSModule; + extern const char * NSNameOfModule( + NSModule m); +@@ -125,6 +123,8 @@ + #define NSLINKMODULE_OPTION_BINDNOW 0x1 + #define NSLINKMODULE_OPTION_PRIVATE 0x2 + #define NSLINKMODULE_OPTION_RETURN_ON_ERROR 0x4 ++#define NSLINKMODULE_OPTION_DONT_CALL_MOD_INIT_ROUTINES 0x8 ++#define NSLINKMODULE_OPTION_TRAILING_PHYS_NAME 0x10 + + /* limited implementation, only modules loaded with NSLinkModule() can be + unlinked */ +@@ -141,7 +141,7 @@ + NSObjectFileImage newObjectFileImage, + unsigned long options); + +-/* symbol api */ ++/* symbol API */ + typedef void * NSSymbol; + extern enum DYLD_BOOL NSIsSymbolNameDefined( + const char *symbolName); +@@ -174,7 +174,7 @@ + extern NSModule NSModuleForSymbol( + NSSymbol symbol); + +-/* error handling api */ ++/* error handling API */ + typedef enum { + NSLinkEditFileAccessError, + NSLinkEditFileFormatError, +@@ -216,7 +216,7 @@ + extern void NSInstallLinkEditErrorHandlers( + NSLinkEditErrorHandlers *handlers); + +-/* other api */ ++/* other API */ + extern enum DYLD_BOOL NSAddLibrary( + const char *pathName); + extern enum DYLD_BOOL NSAddLibraryWithSearching( +@@ -273,10 +273,18 @@ + void *objc_module); + extern enum DYLD_BOOL _dyld_bind_fully_image_containing_address( + unsigned long *address); ++extern enum DYLD_BOOL _dyld_image_containing_address( ++ unsigned long address); ++/* SPI first appeared in Mac OS X 10.3 */ ++extern struct mach_header * _dyld_get_image_header_containing_address( ++ unsigned long address); + + extern void _dyld_moninit( + void (*monaddition)(char *lowpc, char *highpc)); + extern enum DYLD_BOOL _dyld_launched_prebound( ++ void); ++/* SPI first appeared in Mac OS X 10.3 */ ++extern enum DYLD_BOOL _dyld_all_twolevel_modules_prebound( + void); + + extern void _dyld_lookup_and_bind( +diff -ubr include/mach-o/dyld_gdb.h include/mach-o/dyld_gdb.h +--- include/mach-o/dyld_gdb.h Tue Apr 30 00:37:19 2002 ++++ include/mach-o/dyld_gdb.h Mon Aug 25 12:56:22 2003 +@@ -9,7 +9,7 @@ + /* + * gdb_dyld_version is the version of gdb interface that dyld is currently + * exporting. For the interface described in this header file gdb_dyld_version +- * is 1. As the gdb/dyld interface changes this number will be incremented and ++ * is 2. As the gdb/dyld interface changes this number will be incremented and + * comments will be added as to what are the are changes for the various + * versions. + */ +@@ -48,12 +48,21 @@ + * start with a structure containing the following fields: + * + * struct image { +- * char *name; image name for reporting errors ++ * char *physical_name; physical image name (file name) + * unsigned long vmaddr_slide; the slide from the staticly linked address + * struct mach_header *mh; address of the mach header of the image + * unsigned long valid; TRUE if this is struct is valid ++ * char *name; image name for reporting errors + * ... + * }; ++ * ++ * In gdb_dyld_version 1 the first field was "name". In gdb_dyld_version 2 the ++ * first field was changed to "physical_name" and a new fifth field "name" was ++ * added. These two fields are set to the same values except in the case of ++ * zero-link. In zero-link the NSLinkModule() option ++ * NSLINKMODULE_OPTION_TRAILING_PHYS_NAME is used and then the physical_name is ++ * the file name of the module zero-link loaded that is part of the logical ++ * image "name". + */ + + /* object_images is the global object_images structure */ +Only in include/mach-o/hppa: CVS +diff -ubr include/mach-o/hppa/swap.h include/mach-o/hppa/swap.h +--- include/mach-o/hppa/swap.h Tue Apr 30 00:37:19 2002 ++++ include/mach-o/hppa/swap.h Mon Aug 25 12:56:22 2003 +@@ -21,8 +21,8 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#import +-#import ++#include ++#include + + extern void swap_hppa_integer_thread_state( + struct hp_pa_integer_thread_state *regs, +Only in include/mach-o/i386: CVS +Only in include/mach-o/i860: CVS +diff -ubr include/mach-o/i860/swap.h include/mach-o/i860/swap.h +--- include/mach-o/i860/swap.h Tue Apr 30 00:37:19 2002 ++++ include/mach-o/i860/swap.h Mon Aug 25 12:56:22 2003 +@@ -21,8 +21,8 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#import +-#import ++#include ++#include + + extern void swap_i860_thread_state_regs( + struct i860_thread_state_regs *cpu, +diff -ubr include/mach-o/kld.h include/mach-o/kld.h +--- include/mach-o/kld.h Tue Apr 30 00:37:19 2002 ++++ include/mach-o/kld.h Mon Aug 25 12:56:22 2003 +@@ -51,11 +51,6 @@ + __private_extern__ long kld_load_basefile( + const char *base_filename); + +-__private_extern__ long kld_load_basefile_from_memory( +- const char *base_filename, +- char *base_addr, +- long base_size); +- + /* Note: this takes only one object file name */ + __private_extern__ long kld_load( + struct mach_header **header_addr, +@@ -71,7 +66,7 @@ + #endif /* __DYNAMIC__ */ + + /* +- * This two are only in libkld.a use by /mach_kernel (kernel code compiled with ++ * This one is only in libkld.a use by /mach_kernel (kernel code compiled with + * -static). + */ + #ifdef __STATIC__ +@@ -83,6 +78,11 @@ + long object_size); + #endif /* __STATIC__ */ + ++__private_extern__ long kld_load_basefile_from_memory( ++ const char *base_filename, ++ char *base_addr, ++ long base_size); ++ + __private_extern__ long kld_unload_all( + long deallocate_sets); + +@@ -95,5 +95,11 @@ + + __private_extern__ void kld_address_func( + unsigned long (*func)(unsigned long size, unsigned long headers_size)); ++ ++#define KLD_STRIP_ALL 0x00000000 ++#define KLD_STRIP_NONE 0x00000001 ++ ++__private_extern__ void kld_set_link_options( ++ unsigned long link_options); + + #endif /* _MACHO_KLD_H_ */ +diff -ubr include/mach-o/loader.h include/mach-o/loader.h +--- include/mach-o/loader.h Tue Jan 14 23:35:24 2003 ++++ include/mach-o/loader.h Mon Aug 25 12:56:22 2003 +@@ -92,9 +92,11 @@ + #define MH_FVMLIB 0x3 /* fixed VM shared library file */ + #define MH_CORE 0x4 /* core file */ + #define MH_PRELOAD 0x5 /* preloaded executable file */ +-#define MH_DYLIB 0x6 /* dynamicly bound shared library file*/ ++#define MH_DYLIB 0x6 /* dynamically bound shared library */ + #define MH_DYLINKER 0x7 /* dynamic link editor */ +-#define MH_BUNDLE 0x8 /* dynamicly bound bundle file */ ++#define MH_BUNDLE 0x8 /* dynamically bound bundle file */ ++#define MH_DYLIB_STUB 0x9 /* shared library stub for static */ ++ /* linking only, no section contents */ + + /* Constants for the flags field of the mach_header */ + #define MH_NOUNDEFS 0x1 /* the object file has no undefined +@@ -123,7 +125,7 @@ + #define MH_NOMULTIDEFS 0x200 /* this umbrella guarantees no multiple + defintions of symbols in its + sub-images so the two-level namespace +- hints can alwasys be used. */ ++ hints can always be used. */ + #define MH_NOFIXPREBINDING 0x400 /* do not have dyld notify the + prebinding agent about this + executable */ +@@ -171,11 +173,11 @@ + #define LC_FVMFILE 0x9 /* fixed VM file inclusion (internal use) */ + #define LC_PREPAGE 0xa /* prepage command (internal use) */ + #define LC_DYSYMTAB 0xb /* dynamic link-edit symbol table info */ +-#define LC_LOAD_DYLIB 0xc /* load a dynamicly linked shared library */ +-#define LC_ID_DYLIB 0xd /* dynamicly linked shared lib identification */ ++#define LC_LOAD_DYLIB 0xc /* load a dynamically linked shared library */ ++#define LC_ID_DYLIB 0xd /* dynamically linked shared lib ident */ + #define LC_LOAD_DYLINKER 0xe /* load a dynamic linker */ + #define LC_ID_DYLINKER 0xf /* dynamic linker identification */ +-#define LC_PREBOUND_DYLIB 0x10 /* modules prebound for a dynamicly */ ++#define LC_PREBOUND_DYLIB 0x10 /* modules prebound for a dynamically */ + /* linked shared library */ + #define LC_ROUTINES 0x11 /* image routines */ + #define LC_SUB_FRAMEWORK 0x12 /* sub framework */ +@@ -184,7 +186,10 @@ + #define LC_SUB_LIBRARY 0x15 /* sub library */ + #define LC_TWOLEVEL_HINTS 0x16 /* two-level namespace lookup hints */ + #define LC_PREBIND_CKSUM 0x17 /* prebind checksum */ +-/* load a dynamicly linked shared library that is allowed to be missing (weak)*/ ++/* ++ * load a dynamically linked shared library that is allowed to be missing ++ * (all symbols are weak imported). ++ */ + #define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) + + /* +@@ -438,9 +443,9 @@ + }; + + /* +- * A dynamicly linked shared library (filetype == MH_DYLIB in the mach header) ++ * A dynamically linked shared library (filetype == MH_DYLIB in the mach header) + * contains a dylib_command (cmd == LC_ID_DYLIB) to identify the library. +- * An object that uses a dynamicly linked shared library also contains a ++ * An object that uses a dynamically linked shared library also contains a + * dylib_command (cmd == LC_LOAD_DYLIB or cmd == LC_LOAD_WEAK_DYLIB) for each + * library it uses. + */ +@@ -522,7 +527,7 @@ + }; + + /* +- * A program (filetype == MH_EXECUTE) or bundle (filetype == MH_BUNDLE) that is ++ * A program (filetype == MH_EXECUTE) that is + * prebound to its dynamic libraries has one of these for each library that + * the static linker used in prebinding. It contains a bit vector for the + * modules in the library. The bits indicate which modules are bound (1) and +@@ -618,7 +623,7 @@ + + /* + * This is the second set of the symbolic information which is used to support +- * the data structures for the dynamicly link editor. ++ * the data structures for the dynamically link editor. + * + * The original set of symbolic information in the symtab_command which contains + * the symbol and string tables must also be present when this load command is +@@ -639,7 +644,7 @@ + * reference symbol table + * indirect symbol table + * The first three tables above (the table of contents, module table and +- * reference symbol table) are only present if the file is a dynamicly linked ++ * reference symbol table) are only present if the file is a dynamically linked + * shared library. For executable and object modules, which are files + * containing only one module, the information that would be in these three + * tables is determined as follows: +@@ -648,7 +653,7 @@ + * file is part of the module. + * reference symbol table - is the defined and undefined external symbols + * +- * For dynamicly linked shared library files this load command also contains ++ * For dynamically linked shared library files this load command also contains + * offsets and sizes to the pool of relocation entries for all sections + * separated into two groups: + * external relocation entries +@@ -673,7 +678,7 @@ + * + * The last two groups are used by the dynamic binding process to do the + * binding (indirectly through the module table and the reference symbol +- * table when this is a dynamicly linked shared library file). ++ * table when this is a dynamically linked shared library file). + */ + unsigned long ilocalsym; /* index to local symbols */ + unsigned long nlocalsym; /* number of local symbols */ +@@ -688,7 +693,7 @@ + * For the for the dynamic binding process to find which module a symbol + * is defined in the table of contents is used (analogous to the ranlib + * structure in an archive) which maps defined external symbols to modules +- * they are defined in. This exists only in a dynamicly linked shared ++ * they are defined in. This exists only in a dynamically linked shared + * library file. For executable and object modules the defined external + * symbols are sorted by name and is use as the table of contents. + */ +@@ -700,7 +705,7 @@ + * table must reflect the modules that the file was created from. This is + * done by having a module table that has indexes and counts into the merged + * tables for each module. The module structure that these two entries +- * refer to is described below. This exists only in a dynamicly linked ++ * refer to is described below. This exists only in a dynamically linked + * shared library file. For executable and object modules the file only + * contains one module so everything in the file belongs to the module. + */ +@@ -712,7 +717,7 @@ + * indicates the external references (defined and undefined) each module + * makes. For each module there is an offset and a count into the + * reference symbol table for the symbols that the module references. +- * This exists only in a dynamicly linked shared library file. For ++ * This exists only in a dynamically linked shared library file. For + * executable and object modules the defined external symbols and the + * undefined external symbols indicates the external references. + */ +Only in include/mach-o/m68k: CVS +diff -ubr include/mach-o/m68k/swap.h include/mach-o/m68k/swap.h +--- include/mach-o/m68k/swap.h Tue Apr 30 00:37:19 2002 ++++ include/mach-o/m68k/swap.h Mon Aug 25 12:56:22 2003 +@@ -21,8 +21,8 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#import +-#import ++#include ++#include + + extern void swap_m68k_thread_state_regs( + struct m68k_thread_state_regs *cpu, +Only in include/mach-o/m88k: CVS +diff -ubr include/mach-o/m88k/swap.h include/mach-o/m88k/swap.h +--- include/mach-o/m88k/swap.h Tue Apr 30 00:37:19 2002 ++++ include/mach-o/m88k/swap.h Mon Aug 25 12:56:22 2003 +@@ -21,8 +21,8 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#import +-#import ++#include ++#include + + extern void swap_m88k_thread_state_grf_t( + m88k_thread_state_grf_t *cpu, +diff -ubr include/mach-o/nlist.h include/mach-o/nlist.h +--- include/mach-o/nlist.h Tue Jan 14 23:35:24 2003 ++++ include/mach-o/nlist.h Mon Aug 25 12:56:22 2003 +@@ -198,15 +198,24 @@ + * undefined references from module defined in another use the same nlist struct + * an in that case SELF_LIBRARY_ORDINAL is used as the library ordinal. For + * defined symbols in all images they also must have the library ordinal set to +- * SELF_LIBRARY_ORDINAL. The EXECUTABLE_ORDINAL is refers to the executable ++ * SELF_LIBRARY_ORDINAL. The EXECUTABLE_ORDINAL refers to the executable + * image for references from plugins that refer to the executable that loads + * them. ++ * ++ * The DYNAMIC_LOOKUP_ORDINAL is for undefined symbols in a two-level namespace ++ * image that are looked up by the dynamic linker with flat namespace semantics. ++ * This ordinal was added as a feature in Mac OS X 10.3 by reducing the ++ * value of MAX_LIBRARY_ORDINAL by one. So it is legal for existing binaries ++ * or binaries built with older tools to have 0xfe (254) dynamic libraries. In ++ * this case the ordinal value 0xfe (254) must be treated as a library ordinal ++ * for compatibility. + */ + #define GET_LIBRARY_ORDINAL(n_desc) (((n_desc) >> 8) & 0xff) + #define SET_LIBRARY_ORDINAL(n_desc,ordinal) \ + (n_desc) = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8)) + #define SELF_LIBRARY_ORDINAL 0x0 +-#define MAX_LIBRARY_ORDINAL 0xfe ++#define MAX_LIBRARY_ORDINAL 0xfd ++#define DYNAMIC_LOOKUP_ORDINAL 0xfe + #define EXECUTABLE_ORDINAL 0xff + + /* +Only in include/mach-o/ppc: CVS +diff -ubr include/mach-o/ppc/reloc.h include/mach-o/ppc/reloc.h +--- include/mach-o/ppc/reloc.h Tue Apr 30 00:37:19 2002 ++++ include/mach-o/ppc/reloc.h Mon Aug 25 12:56:22 2003 +@@ -27,7 +27,14 @@ + * above and their r_type is RELOC_VANILLA. The rest of the relocation types + * are for instructions. Since they are for instructions the r_address field + * indicates the 32 bit instruction that the relocation is to be preformed on. +- * The fields r_pcrel and r_length are ignored for non-RELOC_VANILLA r_types. ++ * The fields r_pcrel and r_length are ignored for non-RELOC_VANILLA r_types ++ * except for PPC_RELOC_BR14. ++ * ++ * For PPC_RELOC_BR14 if the r_length is the unused value 3, then the branch was ++ * statically predicted setting or clearing the Y-bit based on the sign of the ++ * displacement or the opcode. If this is the case the static linker must flip ++ * the value of the Y-bit if the sign of the displacement changes for non-branch ++ * always conditions. + */ + enum reloc_type_ppc + { +@@ -45,12 +52,13 @@ + */ + PPC_RELOC_LO14, /* Same as the LO16 except that the low 2 bits are not + * stored in the instruction and are always zero. This +- * is used for in double word load/store instructons. ++ * is used in double word load/store instructions. + */ + PPC_RELOC_SECTDIFF, /* a PAIR follows with subtract symbol value */ + PPC_RELOC_PB_LA_PTR,/* prebound lazy pointer */ + PPC_RELOC_HI16_SECTDIFF, /* section difference forms of above. a PAIR */ + PPC_RELOC_LO16_SECTDIFF, /* follows these with subtract symbol value */ + PPC_RELOC_HA16_SECTDIFF, +- PPC_RELOC_JBSR ++ PPC_RELOC_JBSR, ++ PPC_RELOC_LO14_SECTDIFF + }; +diff -ubr include/mach-o/rld.h include/mach-o/rld.h +--- include/mach-o/rld.h Fri Sep 6 18:27:39 2002 ++++ include/mach-o/rld.h Mon Aug 25 12:56:22 2003 +@@ -28,7 +28,7 @@ + #ifndef _MACHO_RLD_H_ + #define _MACHO_RLD_H_ + +-#include ++//~ #include + #include + + extern long rld_load( +Only in include/mach-o/sparc: CVS +diff -ubr include/mach-o/sparc/swap.h include/mach-o/sparc/swap.h +--- include/mach-o/sparc/swap.h Tue Apr 30 00:37:19 2002 ++++ include/mach-o/sparc/swap.h Mon Aug 25 12:56:22 2003 +@@ -21,8 +21,8 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#import +-#import ++#include ++#include + + void swap_sparc_thread_state_regs( + struct sparc_thread_state_regs *cpu, +diff -ubr include/mach-o/stab.h include/mach-o/stab.h +--- include/mach-o/stab.h Tue Jan 14 23:35:24 2003 ++++ include/mach-o/stab.h Mon Aug 25 12:56:22 2003 +@@ -91,6 +91,7 @@ + #define N_STSYM 0x26 /* static symbol: name,,n_sect,type,address */ + #define N_LCSYM 0x28 /* .lcomm symbol: name,,n_sect,type,address */ + #define N_BNSYM 0x2e /* begin nsect sym: 0,,n_sect,0,address */ ++#define N_OPT 0x3c /* emitted with gcc2_compiled and in gcc source */ + #define N_RSYM 0x40 /* register sym: name,,NO_SECT,type,register */ + #define N_SLINE 0x44 /* src line: 0,,n_sect,linenumber,address */ + #define N_ENSYM 0x4e /* end nsect sym: 0,,n_sect,0,address */ +diff -ubr include/notes include/notes +--- include/notes Tue Jan 14 23:35:23 2003 ++++ include/notes Mon Aug 25 12:12:28 2003 +@@ -1,3 +1,96 @@ ++Changes for the 5.12 release (the cctools-477 release): ++- Changed to make kld_load_basefile_from_memory() available for ++ both __DYNAMIC__ and __STATIC__ and added kld_set_link_options() as well as ++ the constants to use with it. Radar bug #3270588. ++ ++Changes for the 5.12 release (the cctools-468 release): ++- Added some comments to to describe the new use of the ++ previously unused value 3 for r_length to mean that the conditional branch was ++ predicted using the Y-bit and the sign of the displacement and opcode. ++ Radar bug #3223045. ++ ++Changes for the 5.12 release (the cctools-467 release): ++- Added the PPC_RELOC_LO14_SECTDIFF relocation type to ++ to match the PPC_RELOC_LO14 relocation type for load and store double ++ instructions using a section difference expression. Radar bug #3218027. ++ ++Changes for the 5.12 release (the cctools-466 release): ++- Added the DYNAMIC_LOOKUP_ORDINAL to and reduced the value of ++ MAX_LIBRARY_ORDINAL by one. This is to allow dynamic flat namespace lookups ++ in twolevel namespace images. Radar bug #3210803. ++ ++Changes for the 5.12 release (the cctools-464 release): ++- Fixed a spelling error in where "alwasys" should be "always" ++ Radar bug #3198288. ++- Added the prototype for the SPI NSHasModInitObjectFileImage() to ++ . Radar bug #3196951. ++- Made changes to build cleanly with gcc3.3 ++ - Change the prototype for round() in "stuff/round.h" to used unsigned long ++ in the two places it use long. ++ ++Changes for the 5.12 release (the cctools-463 release): ++- Changed the prototype of NSGetSectionDataInObjectFileImage() from ++ /* not yet implemented */ ++ extern void * NSGetSectionDataInObjectFileImage( ++ NSObjectFileImage objectFileImage, ++ const char *segmentName, ++ const char *sectionName); ++ to the now implemented prototype: ++ extern void * NSGetSectionDataInObjectFileImage( ++ NSObjectFileImage objectFileImage, ++ const char *segmentName, ++ unsigned long *size); /* can be NULL */ ++ Radar bug #3194204. ++- Added the constant: ++ #define MH_DYLIB_STUB 0x9 /* shared library stub for static */ ++ /* linking only, no section contents */ ++ to . Radar bug #3193744. ++ ++Changes for the 5.12 release (the cctools-462 release): ++- Added the constant: ++ #define NSLINKMODULE_OPTION_TRAILING_PHYS_NAME 0x10 ++ to and comments to . Radar bug #3190599. ++ ++Changes for the 5.12 release (the cctools-461 release): ++- Added the constant: ++ #define NSLINKMODULE_OPTION_DONT_CALL_MOD_INIT_ROUTINES 0x8 ++ to . Radar bug #3183011. ++ ++Changes for the 5.12 release (the cctools-460 release): ++- Removed the /* not yet implemented */ comment off of the following prototypes ++ in : ++ NSSymbolDefinitionCountInObjectFileImage ++ NSSymbolDefinitionNameInObjectFileImage ++ NSSymbolReferenceCountInObjectFileImage ++ NSSymbolReferenceNameInObjectFileImage ++ NSIsSymbolDefinedInObjectFileImage ++ As there are now implemented. Radar bug #3179011. ++ ++Changes for the 5.12 release (the cctools-457 release): ++- Added ofile_map_from_memory() to "stuff/ofile.h". This is needed so the ++ NSCreateObjectFileImageFromMemory() api can be implemented. Radar bug ++ #3131622. ++ ++Changes for the 5.12 release (the cctools-456 release): ++- Picked up the header file . Radar bug 3145742. ++ ++Changes for the 5.12 release (the cctools-448 release): ++- Added the N_OPT constant to which is emitted with ++ gcc2_compiled and in gcc source. Radar bug #3104328. ++- Added the _dyld_get_image_header_containing_address() SPI prototype to ++ (also added the missing _dyld_image_containing_address() ++ prototype). Radar bug #2967928. ++ ++Changes for the 5.12 release (the cctools-447 release): ++- Added the _dyld_all_twolevel_modules_prebound() SPI prototype to ++ . Radar bug #3055372. ++ ++Changes for the 5.11 release (the cctools-444 release): ++- Added the file which contains the interface for the ++ symbol lists code taken from strip.c. Now also used by ld(1)'s ++ -exported_symbols_list and -unexported_symbols_list options. Radar bug ++ #3083844. ++ + Changes for the 5.11 release (the cctools-439 release): + - Added the VEO cputype and its subtypes to . Radar bug + #3068161. +Only in include/standalone: CVS +diff -ubr include/standalone/libsa.h include/standalone/libsa.h +--- include/standalone/libsa.h Tue Apr 30 00:37:19 2002 ++++ include/standalone/libsa.h Mon Aug 25 12:56:22 2003 +@@ -23,13 +23,13 @@ + */ + /* Exported API for standalone library */ + #if !(defined(KLD) && defined(__STATIC__)) +-#import ++#include + #else /* defined(KLD) && defined(__STATIC__) */ + #include + #endif /* !(defined(KLD) && defined(__STATIC__)) */ +-#import +-#import +-#import ++#include ++#include ++#include + + #ifndef bcopy + #ifdef __OPENSTEP__ +Only in include/stuff: CVS +diff -ubr include/stuff/allocate.h include/stuff/allocate.h +--- include/stuff/allocate.h Tue Apr 30 00:37:19 2002 ++++ include/stuff/allocate.h Mon Aug 25 13:08:44 2003 +@@ -21,8 +21,10 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#if defined(__MWERKS__) && !defined(__private_extern__) ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) + #define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern + #endif + + /* defined in allocate.c */ +diff -ubr include/stuff/arch.h include/stuff/arch.h +--- include/stuff/arch.h Fri Sep 6 18:27:41 2002 ++++ include/stuff/arch.h Mon Aug 25 13:10:15 2003 +@@ -24,15 +24,17 @@ + #ifndef _STUFF_ARCH_H_ + #define _STUFF_ARCH_H_ + +-#if defined(__MWERKS__) && !defined(__private_extern__) ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) + #define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern + #endif + /* + * This file contains the current known set of flags and constants for the + * known architectures. + */ +-#import +-#import ++#include ++#include + + /* + * The structure describing an architecture flag with the string of the flag +diff -ubr include/stuff/best_arch.h include/stuff/best_arch.h +--- include/stuff/best_arch.h Tue Apr 30 00:37:19 2002 ++++ include/stuff/best_arch.h Mon Aug 25 13:10:13 2003 +@@ -21,8 +21,10 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#if defined(__MWERKS__) && !defined(__private_extern__) ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) + #define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern + #endif + + #include +diff -ubr include/stuff/bool.h include/stuff/bool.h +--- include/stuff/bool.h Tue Apr 30 00:37:19 2002 ++++ include/stuff/bool.h Mon Aug 25 12:56:22 2003 +@@ -25,6 +25,9 @@ + #ifndef ENUM_DYLD_BOOL + #define ENUM_DYLD_BOOL + ++#define _STDBOOL_H ++#undef bool ++ + #define DYLD_BOOL bool + + #undef FALSE +diff -ubr include/stuff/breakout.h include/stuff/breakout.h +--- include/stuff/breakout.h Fri Sep 6 18:27:42 2002 ++++ include/stuff/breakout.h Mon Aug 25 13:10:12 2003 +@@ -21,11 +21,13 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#if defined(__MWERKS__) && !defined(__private_extern__) ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) + #define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern + #endif + +-#import "stuff/ofile.h" ++#include "stuff/ofile.h" + + /* + * The input files are broken out in to their object files and then placed in +diff -ubr include/stuff/bytesex.h include/stuff/bytesex.h +--- include/stuff/bytesex.h Fri Sep 6 18:27:42 2002 ++++ include/stuff/bytesex.h Mon Aug 25 13:10:10 2003 +@@ -25,23 +25,25 @@ + #ifndef _STUFF_BYTESEX_H_ + #define _STUFF_BYTESEX_H_ + +-#if defined(__MWERKS__) && !defined(__private_extern__) ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) + #define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern + #endif + +-#import +-#import +-#import +-#import +-#import +-#import +-#import +-#import +-#import +-#import +-#import +-#import +-#import "stuff/bool.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "stuff/bool.h" + + enum byte_sex { + UNKNOWN_BYTE_SEX, +diff -ubr include/stuff/errors.h include/stuff/errors.h +--- include/stuff/errors.h Tue Apr 30 00:37:19 2002 ++++ include/stuff/errors.h Mon Aug 25 13:09:00 2003 +@@ -21,11 +21,13 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#if defined(__MWERKS__) && !defined(__private_extern__) ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) + #define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern + #endif + +-#import "mach/mach.h" ++#include "mach/mach.h" + + /* user defined (imported) */ + __private_extern__ char *progname; +diff -ubr include/stuff/execute.h include/stuff/execute.h +--- include/stuff/execute.h Tue Apr 30 00:37:19 2002 ++++ include/stuff/execute.h Mon Aug 25 13:10:04 2003 +@@ -21,8 +21,10 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#if defined(__MWERKS__) && !defined(__private_extern__) ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) + #define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern + #endif + + /* +diff -ubr include/stuff/hash_string.h include/stuff/hash_string.h +--- include/stuff/hash_string.h Tue Apr 30 00:37:19 2002 ++++ include/stuff/hash_string.h Mon Aug 25 13:10:32 2003 +@@ -21,8 +21,10 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#if defined(__MWERKS__) && !defined(__private_extern__) ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) + #define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern + #endif + + __private_extern__ long hash_string( +diff -ubr include/stuff/hppa.h include/stuff/hppa.h +--- include/stuff/hppa.h Tue Apr 30 00:37:19 2002 ++++ include/stuff/hppa.h Mon Aug 25 13:10:40 2003 +@@ -21,8 +21,10 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#if defined(__MWERKS__) && !defined(__private_extern__) ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) + #define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern + #endif + + __private_extern__ void calc_hppa_HILO( +diff -ubr include/stuff/ofile.h include/stuff/ofile.h +--- include/stuff/ofile.h Fri Sep 6 18:27:42 2002 ++++ include/stuff/ofile.h Mon Aug 25 13:10:51 2003 +@@ -25,21 +25,23 @@ + #ifndef _STUFF_OFILE_H_ + #define _STUFF_OFILE_H_ + +-#if defined(__MWERKS__) && !defined(__private_extern__) ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) + #define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern + #endif + +-#import ++#include + #ifndef AR_EFMT1 + #define AR_EFMT1 "#1/" /* extended format #1 */ + #endif +-#import ++#include + #ifdef OFI +-#import ++#include + #endif +-#import "stuff/bytesex.h" +-#import "stuff/bool.h" +-#import "stuff/arch.h" ++#include "stuff/bytesex.h" ++#include "stuff/bool.h" ++#include "stuff/arch.h" + + enum ofile_type { + OFILE_UNKNOWN, +@@ -114,6 +116,18 @@ + #else + __private_extern__ enum bool ofile_map( + #endif ++ const char *file_name, ++ const struct arch_flag *arch_flag, /* can be NULL */ ++ const char *object_name, /* can be NULL */ ++ struct ofile *ofile, ++ enum bool archives_with_fat_objects); ++#ifdef OFI ++__private_extern__ NSObjectFileImageReturnCode ofile_map_from_memory( ++#else ++__private_extern__ enum bool ofile_map_from_memory( ++#endif ++ char *addr, ++ unsigned long size, + const char *file_name, + const struct arch_flag *arch_flag, /* can be NULL */ + const char *object_name, /* can be NULL */ +diff -ubr include/stuff/print.h include/stuff/print.h +--- include/stuff/print.h Tue Apr 30 00:37:19 2002 ++++ include/stuff/print.h Mon Aug 25 13:10:58 2003 +@@ -21,11 +21,13 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#if defined(__MWERKS__) && !defined(__private_extern__) ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) + #define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern + #endif + +-#import ++#include + + __private_extern__ void print( + const char *format, ...) +diff -ubr include/stuff/reloc.h include/stuff/reloc.h +--- include/stuff/reloc.h Tue Apr 30 00:37:19 2002 ++++ include/stuff/reloc.h Mon Aug 25 13:11:02 2003 +@@ -21,12 +21,14 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#if defined(__MWERKS__) && !defined(__private_extern__) ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) + #define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern + #endif + +-#import +-#import "stuff/bool.h" ++#include ++#include "stuff/bool.h" + + __private_extern__ unsigned long reloc_pair_r_type( + cpu_type_t cputype); +diff -ubr include/stuff/round.h include/stuff/round.h +--- include/stuff/round.h Tue Apr 30 00:37:19 2002 ++++ include/stuff/round.h Mon Aug 25 13:11:06 2003 +@@ -21,13 +21,15 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#if defined(__MWERKS__) && !defined(__private_extern__) ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) + #define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern + #endif + + /* + * round() rounds v to a multiple of r. + */ +-__private_extern__ long round( +- long v, ++__private_extern__ unsigned long round( ++ unsigned long v, + unsigned long r); +Only in include/stuff: symbol_list.h +diff -ubr include/stuff/vm_flush_cache.h include/stuff/vm_flush_cache.h +--- include/stuff/vm_flush_cache.h Tue Apr 30 00:37:19 2002 ++++ include/stuff/vm_flush_cache.h Mon Aug 25 13:11:15 2003 +@@ -21,11 +21,13 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#if defined(__MWERKS__) && !defined(__private_extern__) ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) + #define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern + #endif + +-#import ++#include + __private_extern__ kern_return_t vm_flush_cache( + mach_port_t target_task, + vm_address_t address, +Only in include/sys: CVS diff --git a/upstream/darwin-linker/patches/ld.patch b/upstream/darwin-linker/patches/ld.patch new file mode 100644 index 0000000..8657fd0 --- /dev/null +++ b/upstream/darwin-linker/patches/ld.patch @@ -0,0 +1,4325 @@ +Only in ld: CVS +diff -ubr ld/Makefile ld/Makefile +--- ld/Makefile Fri Sep 6 18:27:43 2002 ++++ ld/Makefile Mon Aug 25 23:04:37 2003 +@@ -9,10 +9,10 @@ + -DKERNEL -DKERNEL_PRIVATE -DAPPLE -DNeXT -DLIBSA_PRIVATE + + +-MIG = $(NEXT_ROOT)/usr/bin/mig ++MIG = mig + + ifeq "macos" "$(RC_OS)" +- X_CFLAGS := $(shell if [ "$(RC_RELEASE)" != "Beaker" ] && \ ++ X_CFLAGS := $(shell if [ `uname` != "Linux" ] && [ "$(RC_RELEASE)" != "Beaker" ] && \ + [ "$(RC_RELEASE)" != "Bunsen" ] && \ + [ "$(RC_RELEASE)" != "Gonzo" ] && \ + [ "$(RC_RELEASE)" != "Kodiak" ]; then \ +@@ -21,10 +21,19 @@ + endif + + ifneq "mwccppc" "$(notdir $(CC))" +- GCC_FLAGS = -Wall -Wno-precomp $(X_CFLAGS) ++ ifeq "Linux" "$(shell uname)" ++ GCC_FLAGS = -Wall $(X_CFLAGS) -D__ppc__ -I/usr/include -I../../../macosx-include ++ else ++ GCC_FLAGS = -Wall $(X_CFLAGS) ++ endif + endif + +-USE_DEPENDENCY_FILE := $(shell if [ "$(notdir $(CC))" != "mwccppc" ]; then \ ++# Hack: Add ../misc to the path because it contains seg_hack and ver_string ++ifneq ($(findstring ../misc,$(PATH)),../misc) ++ PATH:=../misc:../../misc:$(PATH) ++endif ++ ++USE_DEPENDENCY_FILE := $(shell if [ `uname` != "Linux" ] && [ "$(notdir $(CC))" != "mwccppc" ]; then \ + echo YES ; else echo NO ; \ + fi; ) + +@@ -78,7 +87,7 @@ + fvmlibs.c layout.c specs.c pass2.c generic_reloc.c rld.c sets.c \ + 4byte_literals.c 8byte_literals.c literal_pointers.c dylibs.c \ + indirect_sections.c mod_sections.c i860_reloc.c ppc_reloc.c \ +- m88k_reloc.c hppa_reloc.c sparc_reloc.c coalesced_sections.c ++ m88k_reloc.c hppa_reloc.c sparc_reloc.c coalesced_sections.c fake-mach.c + OBJS = $(CFILES:.c=.o) + INSTALL_FILES = $(CFILES) $(HFILES) Makefile notes \ + make.defs make_defs.h librld.ofileList +@@ -107,12 +116,12 @@ + OFILE_DIR=. SRCROOT=.. RC_CFLAGS="$(RC_CFLAGS)" \ + LIBSTUFF="-L../../libstuff -lstuff" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" \ +- MAKEINCDIR=`pwd` COPTS="-DDEBUG" CC="$(CC)"; \ ++ MAKEINCDIR="`pwd`" COPTS="-DDEBUG" CC="$(CC)"; \ + else \ + cd $(OBJROOT)/ld_dir; $(MAKE) -f $(SRCROOT)/Makefile ld.NEW \ + VPATH=$(SRCROOT) OFILE_DIR=$(OBJROOT)/ld_dir \ + SYMROOT=$(SYMROOT)/ld_dir SRCROOT=$(SRCROOT) \ +- MAKEINCDIR=`pwd` COPTS="-DDEBUG" \ ++ MAKEINCDIR="`pwd`" COPTS="-DDEBUG" \ + LIBSTUFF="-L$(SYMROOT)/../libstuff -lstuff" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" \ + RC_CFLAGS="$(RC_CFLAGS)" CC="$(CC)"; \ +@@ -120,19 +129,19 @@ + + ld_g_build: ld_g_dir + cd ld_g_dir; $(MAKE) -f ../Makefile ld_g.NEW VPATH=.. OFILE_DIR=. \ +- SRCROOT=.. MAKEINCDIR=`pwd` COPTS="-DDEBUG" OFLAG="" \ ++ SRCROOT=.. MAKEINCDIR="`pwd`" COPTS="-DDEBUG" OFLAG="" \ + LIBSTUFF="-L../../libstuff -lstuff" + + ld_p_build: ld_p_dir + cd ld_p_dir; $(MAKE) -f ../Makefile ld.NEW VPATH=.. OFILE_DIR=. \ +- SRCROOT=.. MAKEINCDIR=`pwd` COPTS="-pg -DDEBUG" \ ++ SRCROOT=.. MAKEINCDIR="`pwd`" COPTS="-pg -DDEBUG" \ + LIBSTUFF="-L../../libstuff -lstuff_p" + + shlib_ofiles: $(OBJROOT)/shlib_obj $(SYMROOT)/ld_dir + @if [ $(SRCROOT) = . ]; \ + then \ + (cd shlib_obj; $(MAKE) -f ../Makefile librld.o VPATH=.. \ +- MAKEINCDIR=`pwd` OFILE_DIR=. SRCROOT=.. \ ++ MAKEINCDIR="`pwd`" OFILE_DIR=. SRCROOT=.. \ + COPTS="-static -DRLD -DSHLIB -I/LocalDeveloper/Headers/libsys" \ + LIBSTUFF="-L../../libstuff -lstuff_s" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" CC="$(CC)" \ +@@ -147,7 +156,7 @@ + COPTS="-static -DRLD -DSHLIB -I/LocalDeveloper/Headers/libsys" \ + LIBSTUFF="-L$(SYMROOT)/../libstuff -lstuff_s" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" \ +- MAKEINCDIR=`pwd` RC_ARCHS="$(RC_ARCHS)"); \ ++ MAKEINCDIR="`pwd`" RC_ARCHS="$(RC_ARCHS)"); \ + rm -f $(OBJROOT)/shlib_obj/librld.ofileList; \ + cp librld.ofileList $(OBJROOT)/shlib_obj; \ + fi +@@ -156,7 +165,7 @@ + @if [ $(SRCROOT) = . ]; \ + then \ + (cd ptmp_obj; $(MAKE) -f ../Makefile librld_pg.a VPATH=.. \ +- MAKEINCDIR=`pwd` OFILE_DIR=. SRCROOT=.. \ ++ MAKEINCDIR="`pwd`" OFILE_DIR=. SRCROOT=.. \ + LIBSTUFF="-L../../libstuff -lstuff_p" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" CC="$(CC)" \ + RC_CFLAGS="$(RC_CFLAGS)" COPTS="-dynamic -DRLD -pg"); \ +@@ -173,7 +182,7 @@ + RC_CFLAGS="$(RC_CFLAGS)" CC="$(CC)" \ + LIBSTUFF="-L$(SYMROOT)/../libstuff -lstuff_p" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" \ +- MAKEINCDIR=`pwd` COPTS="-dynamic -DRLD -pg"); \ ++ MAKEINCDIR="`pwd`" COPTS="-dynamic -DRLD -pg"); \ + rm -f $(OBJROOT)/profile_obj/librld.o; \ + rm -f $(OBJROOT)/profile_obj/librld.ofileList; \ + cp $(OBJROOT)/ptmp_obj/librld.o $(OBJROOT)/profile_obj/librld.o; \ +@@ -186,7 +195,7 @@ + @if [ $(SRCROOT) = . ]; \ + then \ + (cd otmp_obj; $(MAKE) -f ../Makefile librld_static.a VPATH=.. \ +- MAKEINCDIR=`pwd` OFILE_DIR=. SRCROOT=.. \ ++ MAKEINCDIR="`pwd`" OFILE_DIR=. SRCROOT=.. \ + LIBSTUFF="-L../../libstuff -lstuff" CC="$(CC)" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" \ + RC_CFLAGS="$(RC_CFLAGS)" COPTS="-static -DRLD"); \ +@@ -204,7 +213,7 @@ + RC_CFLAGS="$(RC_CFLAGS)" CC="$(CC)" \ + LIBSTUFF="-L$(SYMROOT)/../libstuff -lstuff" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" \ +- MAKEINCDIR=`pwd` COPTS="-static -DRLD"); \ ++ MAKEINCDIR="`pwd`" COPTS="-static -DRLD"); \ + rm -f $(OBJROOT)/optimized_obj/librld.o; \ + rm -f $(OBJROOT)/optimized_obj/librld.ofileList; \ + cp $(OBJROOT)/otmp_obj/librld.o $(OBJROOT)/optimized_obj/librld.o;\ +@@ -217,7 +226,7 @@ + @if [ $(SRCROOT) = . ]; \ + then \ + (cd dtmp_obj; $(MAKE) -f ../Makefile librld.a VPATH=.. \ +- MAKEINCDIR=`pwd` OFILE_DIR=. SRCROOT=.. \ ++ MAKEINCDIR="`pwd`" OFILE_DIR=. SRCROOT=.. \ + LIBSTUFF="-L../../libstuff -lstuff" CC="$(CC)" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" \ + RC_CFLAGS="$(RC_CFLAGS)" COPTS="-dynamic -DRLD"); \ +@@ -232,7 +241,7 @@ + RC_CFLAGS="$(RC_CFLAGS)" CC="$(CC)" \ + LIBSTUFF="-L$(SYMROOT)/../libstuff -lstuff" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" \ +- MAKEINCDIR=`pwd` COPTS="-dynamic -DRLD"); \ ++ MAKEINCDIR="`pwd`" COPTS="-dynamic -DRLD"); \ + rm -f $(OBJROOT)/dynamic_obj/librld.o; \ + rm -f $(OBJROOT)/dynamic_obj/librld.ofileList; \ + cp $(OBJROOT)/dtmp_obj/librld.o $(OBJROOT)/dynamic_obj/librld.o;\ +@@ -243,7 +252,7 @@ + @if [ $(SRCROOT) = . ]; \ + then \ + cd sarld_dir; $(MAKE) -f ../Makefile libsarld.a VPATH=.. \ +- MAKEINCDIR=`pwd` OFILE_DIR=. SRCROOT=.. \ ++ MAKEINCDIR="`pwd`" OFILE_DIR=. SRCROOT=.. \ + COPTS="-static -DRLD -DSA_RLD" CC="$(CC)" \ + LIBSTUFF="-L../../libstuff -lstuff" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" \ +@@ -255,14 +264,14 @@ + COPTS="-static -DRLD -DSA_RLD" RC_CFLAGS="$(RC_CFLAGS)" \ + LIBSTUFF="-L$(SYMROOT)/../libstuff -lstuff" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" \ +- MAKEINCDIR=`pwd` RC_ARCHS="$(RC_ARCHS)"; \ ++ MAKEINCDIR="`pwd`" RC_ARCHS="$(RC_ARCHS)"; \ + fi + + kld_build: $(OBJROOT)/dynamic_kld $(OBJROOT)/static_kld $(SYMROOT)/ld_dir + @if [ $(SRCROOT) = . ]; \ + then \ + cd dynamic_kld; $(MAKE) -f ../Makefile libkld.dylib VPATH=.. \ +- MAKEINCDIR=`pwd` OFILE_DIR=. SRCROOT=.. \ ++ MAKEINCDIR="`pwd`" OFILE_DIR=. SRCROOT=.. \ + COPTS="-DRLD -DKLD" CC="$(CC)" \ + LIBSTUFF="-L../../libstuff -lstuff" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" \ +@@ -274,12 +283,12 @@ + COPTS="-DRLD -DKLD" RC_CFLAGS="$(RC_CFLAGS)" \ + LIBSTUFF="-L$(SYMROOT)/../libstuff -lstuff" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" \ +- MAKEINCDIR=`pwd` RC_ARCHS="$(RC_ARCHS)"; \ ++ MAKEINCDIR="`pwd`" RC_ARCHS="$(RC_ARCHS)"; \ + fi + @if [ $(SRCROOT) = . ]; \ + then \ + cd static_kld; $(MAKE) -f ../Makefile libkld.a VPATH=.. \ +- MAKEINCDIR=`pwd` OFILE_DIR=. SRCROOT=.. \ ++ MAKEINCDIR="`pwd`" OFILE_DIR=. SRCROOT=.. \ + COPTS="-static -DRLD -DKLD $(KERN)" CC="$(CC)" \ + LIBSTUFF="-L../../libstuff -lstuff" PRIVATE_IFLAG="" \ + LIBMACHO="-L../../libmacho/otmp_obj -lmacho_static" \ +@@ -293,7 +302,7 @@ + LIBSTUFF="-L$(SYMROOT)/../libstuff -lstuff" \ + LIBMACHO="-L$(SYMROOT)/../libmacho -lmacho_static" \ + VERS_STRING_FLAGS="$(VERS_STRING_FLAGS)" PRIVATE_IFLAG="" \ +- MAKEINCDIR=`pwd` RC_ARCHS="$(RC_ARCHS)"; \ ++ MAKEINCDIR="`pwd`" RC_ARCHS="$(RC_ARCHS)"; \ + fi + + ld.NEW: $(OBJS) ld_vers.o makeUser.o +@@ -341,8 +350,9 @@ + makeUser.c ld.c: make.h + + make.h makeUser.c: make.defs +- $(MIG) $(MIG_FLAGS) $(SRCROOT)/make.defs +- rm -f makeServer.c ++ #~ $(MIG) $(MIG_FLAGS) $(SRCROOT)/make.defs ++ #~ rm -f makeServer.c ++ cp $(SRCROOT)/makeUser.c . + + ld_vers.o: ld_vers.c + ifeq "mwccppc" "$(notdir $(CC))" +diff -ubr ld/coalesced_sections.c ld/coalesced_sections.c +--- ld/coalesced_sections.c Tue Jan 14 23:35:24 2003 ++++ ld/coalesced_sections.c Mon Aug 25 22:11:47 2003 +@@ -579,15 +579,15 @@ + /* + * The number of relocation entries in the output file is based + * on one of three different cases: +- * The output file is a dynamic shared library file ++ * The output file is a multi module dynamic shared library + * The output file has a dynamic linker load command + * The output does not have a dynamic linker load command + */ +- if(filetype == MH_DYLIB){ ++ if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ + /* +- * For dynamic shared library files the modules are kept +- * separate so external relocation entries on input will be +- * external relocation entries on output. For local ++ * For a multi module dynamic shared library the modules are ++ * kept separate so external relocation entries on input ++ * will be external relocation entries on output. For local + * relocation entries only non-position-independent local + * relocation entries are kept. Modules of dylibs are not + * linked together and can only be slid keeping all sections +diff -ubr ld/dylibs.c ld/dylibs.c +--- ld/dylibs.c Fri Sep 6 18:27:43 2002 ++++ ld/dylibs.c Mon Aug 25 22:11:47 2003 +@@ -116,7 +116,8 @@ + */ + __private_extern__ + void +-merge_dylibs(void) ++merge_dylibs( ++enum bool force_weak) + { + unsigned long i; + struct mach_header *mh; +@@ -142,7 +143,9 @@ + * file. Only record the library itself. + */ + if((lc->cmd != LC_LOAD_DYLIB && +- lc->cmd != LC_LOAD_WEAK_DYLIB) || mh->filetype != MH_DYLIB){ ++ lc->cmd != LC_LOAD_WEAK_DYLIB) || ++ (mh->filetype != MH_DYLIB && ++ mh->filetype != MH_DYLIB_STUB) ){ + dl = (struct dylib_command *)lc; + mdl = lookup_merged_dylib(dl); + if(filetype == MH_DYLIB && dylib_install_name != NULL && +@@ -151,6 +154,7 @@ + "same install_name (%s) as the output", + dylib_install_name); + p = add_dynamic_lib(DYLIB, dl, cur_obj); ++ p->force_weak_dylib = force_weak; + mdl->dynamic_library = p; + } + } +diff -ubr ld/dylibs.h ld/dylibs.h +--- ld/dylibs.h Fri Sep 6 18:27:43 2002 ++++ ld/dylibs.h Mon Aug 25 12:12:28 2003 +@@ -55,7 +55,7 @@ + __private_extern__ void create_dylib_id_command( + void); + __private_extern__ void merge_dylibs( +- void); ++ enum bool force_weak); + __private_extern__ void add_dylib_segment( + struct segment_command *sg, + char *dylib_name, +Only in ld: dynamic_profile_obj +Only in ld: fake-mach.c +diff -ubr ld/generic_reloc.c ld/generic_reloc.c +--- ld/generic_reloc.c Tue Jan 14 23:35:24 2003 ++++ ld/generic_reloc.c Mon Aug 25 22:11:47 2003 +@@ -351,13 +351,13 @@ + /* + * If the symbol is undefined (or common) or a global coalesced + * symbol where we need to force an external relocation entry +- * and we are not prebinding no relocation is done. +- * Or if the output file is MH_DYLIB no relocation is done ++ * and we are not prebinding no relocation is done. Or if the ++ * output file is a multi module MH_DYLIB no relocation is done + * unless the symbol is a private extern or we are prebinding. + */ + if(((merged_symbol->nlist.n_type & N_TYPE) == N_UNDF) || + (force_extern_reloc == TRUE && prebinding == FALSE) || +- (filetype == MH_DYLIB && ++ ((filetype == MH_DYLIB && multi_module_dylib == TRUE) && + (((merged_symbol->nlist.n_type & N_PEXT) != N_PEXT) && + prebinding == FALSE) ) ) + value = 0; +@@ -728,18 +728,19 @@ + * For external relocation entries that the symbol is + * defined (not undefined or common) but not when we are + * forcing an external relocation entry for a global +- * coalesced symbol and if the output file is not MH_DYLIB +- * or the symbol is a private extern it is changed to a +- * local relocation entry using the section that symbol is +- * defined in. If still undefined or forcing an external +- * relocation entry for a global coalesced symbol then the +- * index of the symbol in the output file is set into +- * r_symbolnum. ++ * coalesced symbol and if the output file is not a multi ++ * module MH_DYLIB or the symbol is a private extern, it is ++ * changed to a local relocation entry using the section ++ * that symbol is defined in. If still undefined or forcing ++ * an external relocation entry for a global coalesced ++ * symbol, then the index of the symbol in the output file ++ * is set into r_symbolnum. + */ + else if((merged_symbol->nlist.n_type & N_TYPE) != N_UNDF && + (merged_symbol->nlist.n_type & N_TYPE) != N_PBUD && + force_extern_reloc == FALSE && +- (filetype != MH_DYLIB || ++ ((filetype != MH_DYLIB || ++ multi_module_dylib == FALSE) || + (merged_symbol->nlist.n_type & N_PEXT) == N_PEXT)){ + reloc->r_extern = 0; + /* +diff -ubr ld/hppa_reloc.c ld/hppa_reloc.c +--- ld/hppa_reloc.c Tue Jan 14 23:35:24 2003 ++++ ld/hppa_reloc.c Mon Aug 25 22:11:47 2003 +@@ -384,13 +384,13 @@ + /* + * If the symbol is undefined (or common) or a global coalesced + * symbol where we need to force an external relocation entry +- * and we are not prebinding no relocation is done. +- * Or if the output file is MH_DYLIB no relocation is done ++ * and we are not prebinding no relocation is done. Or if the ++ * output file is a multi module MH_DYLIB no relocation is done + * unless the symbol is a private extern or we are prebinding. + */ + if(((merged_symbol->nlist.n_type & N_TYPE) == N_UNDF) || + (force_extern_reloc == TRUE && prebinding == FALSE) || +- (filetype == MH_DYLIB && ++ ((filetype == MH_DYLIB && multi_module_dylib == TRUE) && + (((merged_symbol->nlist.n_type & N_PEXT) != N_PEXT) && + prebinding == FALSE) ) ) + value = 0; +@@ -807,7 +807,9 @@ + section_map, r_address) + + 8; + if(save_reloc == 0 && +- (filetype != MH_DYLIB || (r_extern == 1 && ++ ((filetype != MH_DYLIB || ++ multi_module_dylib == FALSE) || ++ (r_extern == 1 && + (merged_symbol->nlist.n_type & N_PEXT) == + N_PEXT)) && + (output_for_dyld == FALSE || r_extern == 0 || +@@ -1001,7 +1003,8 @@ + r_address) + + 8); + if(save_reloc == 0 && +- (filetype != MH_DYLIB || (r_extern == 1 && ++ ((filetype != MH_DYLIB || multi_module_dylib == FALSE) || ++ (r_extern == 1 && + (merged_symbol->nlist.n_type & N_PEXT) == N_PEXT)) && + (output_for_dyld == FALSE || r_extern == 0 || + (merged_symbol->nlist.n_type & N_TYPE) != N_UNDF) && +@@ -1054,18 +1057,19 @@ + * For external relocation entries that the symbol is + * defined (not undefined or common) but not when we are + * forcing an external relocation entry for a global +- * coalesced symbol and if the output file is not MH_DYLIB +- * or the symbol is a private extern it is changed to a +- * local relocation entry using the section that symbol is +- * defined in. If still undefined or forcing an external +- * relocation entry for a global coalesced symbol then the +- * index of the symbol in the output file is set into +- * r_symbolnum. ++ * coalesced symbol and if the output file is not a multi ++ * module MH_DYLIB or the symbol is a private extern, it is ++ * changed to a local relocation entry using the section ++ * that symbol is defined in. If still undefined or forcing ++ * an external relocation entry for a global coalesced ++ * symbol, then the index of the symbol in the output file ++ * is set into r_symbolnum. + */ + else if((merged_symbol->nlist.n_type & N_TYPE) != N_UNDF && + (merged_symbol->nlist.n_type & N_TYPE) != N_PBUD && + force_extern_reloc == FALSE && +- (filetype != MH_DYLIB || ++ ((filetype != MH_DYLIB || ++ multi_module_dylib == FALSE) || + (merged_symbol->nlist.n_type & N_PEXT) == N_PEXT)){ + reloc->r_extern = 0; + /* +diff -ubr ld/i860_reloc.c ld/i860_reloc.c +--- ld/i860_reloc.c Tue Jan 14 23:35:24 2003 ++++ ld/i860_reloc.c Mon Aug 25 22:11:47 2003 +@@ -370,13 +370,13 @@ + /* + * If the symbol is undefined (or common) or a global coalesced + * symbol where we need to force an external relocation entry +- * and we are not prebinding no relocation is done. +- * Or if the output file is MH_DYLIB no relocation is done ++ * and we are not prebinding no relocation is done. Or if the ++ * output file is a multi module MH_DYLIB no relocation is done + * unless the symbol is a private extern or we are prebinding. + */ + if(((merged_symbol->nlist.n_type & N_TYPE) == N_UNDF) || + (force_extern_reloc == TRUE && prebinding == FALSE) || +- (filetype == MH_DYLIB && ++ ((filetype == MH_DYLIB && multi_module_dylib == TRUE) && + (((merged_symbol->nlist.n_type & N_PEXT) != N_PEXT) && + prebinding == FALSE) ) ) + value = 0; +@@ -762,19 +762,21 @@ + * For external relocation entries that the symbol is + * defined (not undefined or common) but not when we are + * forcing an external relocation entry for a global +- * coalesced symbol and if the output file is not MH_DYLIB +- * or the symbol is a private extern it is changed to a +- * local relocation entry using the section that symbol is +- * defined in. If still undefined or forcing an external +- * relocation entry for a global coalesced symbol then the +- * index of the symbol in the output file is set into +- * r_symbolnum. ++ * coalesced symbol and if the output file is not a multi ++ * module MH_DYLIB or the symbol is a private extern, it is ++ * changed to a local relocation entry using the section ++ * that symbol is defined in. If still undefined or forcing ++ * an external relocation entry for a global coalesced ++ * symbol, then the index of the symbol in the output file ++ * is set into r_symbolnum. + */ + if((merged_symbol->nlist.n_type & N_TYPE) != N_UNDF && + (merged_symbol->nlist.n_type & N_TYPE) != N_PBUD && + force_extern_reloc == FALSE && +- (filetype != MH_DYLIB || ++ ((filetype != MH_DYLIB || ++ multi_module_dylib == FALSE) || + (merged_symbol->nlist.n_type & N_PEXT) == N_PEXT)){ ++ reloc->r_extern = 0; + reloc->r_extern = 0; + /* + * If this symbol was in the base file then no futher +diff -ubr ld/indirect_sections.c ld/indirect_sections.c +--- ld/indirect_sections.c Tue Jan 14 23:35:24 2003 ++++ ld/indirect_sections.c Mon Aug 25 22:11:47 2003 +@@ -370,11 +370,13 @@ + (merged_symbol->definition_object->section_maps[ + merged_symbol->nlist.n_sect - 1]. + s->flags & SECTION_TYPE) == S_COALESCED){ +- if(output_for_dyld && has_dynamic_linker_command && ++ if((output_for_dyld && has_dynamic_linker_command && + (((merged_symbol->nlist.n_desc & N_WEAK_DEF) != + N_WEAK_DEF) || + ((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT && +- keep_private_externs == FALSE) ) ) ++ keep_private_externs == FALSE) ) ) || ++ (filetype == MH_DYLIB && multi_module_dylib == FALSE && ++ (merged_symbol->nlist.n_type & N_PEXT) == N_PEXT) ) + fine_relocs[i].indirect_defined = TRUE; + else + fine_relocs[i].indirect_defined = FALSE; +@@ -386,7 +388,7 @@ + if((merged_symbol->nlist.n_type & N_TYPE) == N_ABS) + section_map->absolute_indirect_defineds = TRUE; + +- if(filetype == MH_DYLIB || ++ if((filetype == MH_DYLIB && multi_module_dylib == TRUE) || + section_type == S_NON_LAZY_SYMBOL_POINTERS || + fine_relocs[i].indirect_defined == FALSE){ + fine_relocs[i].output_offset = lookup_indirect_item( +@@ -685,15 +687,16 @@ + merged_symbol = (struct merged_symbol *) + merged_symbol->nlist.n_value; + /* +- * For dynamic shared library format files the merged sections +- * that could have had external relocation entries must be +- * resolved to private extern symbols. This is because for +- * MH_DYLIB files all modules share the merged sections and the +- * entire section gets relocated when the library is mapped in. +- * So the above restriction assures the merged section will get +- * relocated properly and can be shared amoung library modules. ++ * For multi module dynamic shared library format files the ++ * merged sections that could have had external relocation ++ * entries must be resolved to private extern symbols. This is ++ * because for multi module MH_DYLIB files all modules share the ++ * merged sections and the entire section gets relocated when ++ * the library is mapped in. So the above restriction assures ++ * the merged section will get relocated properly and can be ++ * shared amoung library modules. + */ +- if(filetype == MH_DYLIB){ ++ if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ + /* + * If the symbol is undefined or not a private extern it is + * an error for in this section for a MH_DYLIB file. +@@ -704,19 +707,20 @@ + merged_symbol->defined_in_dylib == TRUE)){ + if(merged_symbol->error_flagged_for_dylib == 0){ + error_with_cur_obj("illegal undefined reference " +- "for MH_DYLIB output file to symbol: %s from " +- "section (%.16s,%.16s) relocation entry: %lu", +- merged_symbol->nlist.n_un.n_name, +- s->segname, s->sectname, i); ++ "for multi module MH_DYLIB output file to " ++ "symbol: %s from section (%.16s,%.16s) " ++ "relocation entry: %lu", ++ merged_symbol->nlist.n_un.n_name, s->segname, ++ s->sectname, i); + merged_symbol->error_flagged_for_dylib = 1; + } + } + else if((merged_symbol->nlist.n_type & N_PEXT) != N_PEXT){ + if(merged_symbol->error_flagged_for_dylib == 0){ + error_with_cur_obj("illegal external reference for " +- "MH_DYLIB output file to symbol: %s (not a " +- "private extern symbol) from section (%.16s," +- "%.16s) relocation entry: %lu", ++ "multi module MH_DYLIB output file to symbol: " ++ "%s (not a private extern symbol) from section " ++ "(%.16s,%.16s) relocation entry: %lu", + merged_symbol->nlist.n_un.n_name, + s->segname, s->sectname, i); + merged_symbol->error_flagged_for_dylib = 1; +@@ -760,18 +764,19 @@ + /* + * The number of relocation entries in the output file is based + * on one of three different cases: +- * The output file is a dynamic shared library file ++ * The output file is a multi module dynamic shared library + * The output file has a dynamic linker load command + * The output does not have a dynamic linker load command + */ +- if(filetype == MH_DYLIB){ ++ if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ + /* +- * For dynamic shared library files there are no external +- * relocation entries that will be left as external as +- * checked above. Only non-position-independent local +- * relocation entries are kept. Modules of dylibs are not +- * linked together and can only be slid keeping all sections +- * relative to each other the same. ++ * For multi module dynamic shared library files there are ++ * no external relocation entries that will be left as ++ * external as checked above. Only non-position-independent ++ * local relocation entries are kept. Modules of multi ++ * module dylibs are not linked together and can only be ++ * slid keeping all sections relative to each other the ++ * same. + */ + if(pic == FALSE) + ms->nlocrel += 1 + pair; +@@ -884,7 +889,7 @@ + #if defined(DEBUG) && defined(PROBE_COUNT) + data->nprobes++; + #endif +- hashval = ((long)merged_symbol) % INDIRECT_SECTION_HASHSIZE; ++ hashval = ((unsigned long)merged_symbol) % INDIRECT_SECTION_HASHSIZE; + for(bp = data->hashtable[hashval]; bp; bp = bp->next){ + #if defined(DEBUG) && defined(PROBE_COUNT) + data->nprobes++; +@@ -1296,7 +1301,7 @@ + if(nindirectsyms == 0) + return; + if(strip_level == STRIP_ALL) +- fatal("can't use -s with input files containg indirect symbols " ++ fatal("can't use -s with input files containing indirect symbols " + "(output file must contain at least global symbols, for " + "maximum stripping use -x)"); + indirect_symbols = (unsigned long *)(output_addr + +diff -ubr ld/layout.c ld/layout.c +--- ld/layout.c Tue Jan 14 23:35:24 2003 ++++ ld/layout.c Mon Aug 25 23:22:05 2003 +@@ -42,18 +42,22 @@ + #include "stuff/openstep_mach.h" + #include + #include +-#import +-#import +-#import +-#import +-#import +-#import +-#import ++#include ++#include ++#include ++#include ++#include ++#include ++#include + #include + #include ++ ++#include ++ + #if defined(RLD) && !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) ++typedef void NXStream; + #include +-#include ++//~ #include + #endif /* defined(RLD) && !defined(SA_RLD) && + !(defined(KLD) && defined(__STATIC__)) */ + #include "stuff/arch.h" +@@ -73,6 +77,15 @@ + #include "mach-o/sarld.h" + #include "indirect_sections.h" + ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) ++#define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern ++#endif ++ ++/** gcc on Linux defines powerpc, if we are compiling on a powerpc. */ ++#undef powerpc ++ + #ifdef RLD + __private_extern__ long RLD_DEBUG_OUTPUT_FILENAME_flag; + #endif +@@ -213,8 +226,11 @@ + if(filetype == MH_EXECUTE || + filetype == MH_BUNDLE || + filetype == MH_DYLIB || +- filetype == MH_DYLINKER) ++ filetype == MH_DYLINKER){ + setup_link_editor_symbols(); ++ if(undefined_flag == UNDEFINED_DEFINE_A_WAY) ++ define_undefined_symbols_a_way(); ++ } + if(filetype == MH_PRELOAD) + define_link_editor_preload_symbols(TRUE); + #endif /* !defined(RLD) */ +@@ -644,6 +660,7 @@ + if(strip_level != STRIP_ALL) + linkedit_segment.sg.filesize += + (nmerged_symbols ++ - nstripped_merged_symbols + + nlocal_symbols + - nmerged_symbols_referenced_only_from_dylibs) * + sizeof(struct nlist) + +@@ -998,6 +1015,7 @@ + if(strip_level != STRIP_ALL){ + output_symtab_info.symtab_command.nsyms = + nmerged_symbols ++ - nstripped_merged_symbols + + nlocal_symbols + - nmerged_symbols_referenced_only_from_dylibs; + output_symtab_info.symtab_command.strsize = +@@ -1301,20 +1319,21 @@ + + #ifdef RLD + /* +- * For rld() the output format is MH_OBJECT and only the contents of the +- * segment (the entire vmsize not just the filesize) without headers is +- * allocated and the address the segment is linked to is the address of +- * this memory. ++ * For rld() the output format is MH_OBJECT and the contents of the ++ * first segment (the entire vmsize not just the filesize), if it exists, ++ * plus headers are allocated and the address the segment is linked to ++ * is the address of this memory. + */ + output_size = 0; +- if(first_msg != NULL){ + #ifndef SA_RLD + kern_return_t r; + #endif + unsigned long allocate_size; + + headers_size = round(headers_size, max_align); +- output_size = headers_size + first_msg->sg.vmsize; ++ output_size = headers_size; ++ if(first_msg != NULL) ++ output_size += first_msg->sg.vmsize; + allocate_size = output_size; + if(strip_level != STRIP_ALL) + allocate_size += output_symtab_info.symtab_command.nsyms * +@@ -1346,6 +1365,8 @@ + #endif /* RLD_VM_ALLOC_DEBUG */ + sets[cur_set].output_addr = output_addr; + sets[cur_set].output_size = output_size; ++ ++ if(first_msg != NULL){ + if(address_func != NULL){ + if(RLD_DEBUG_OUTPUT_FILENAME_flag) + first_msg->sg.vmaddr = +@@ -2194,12 +2215,18 @@ + (unsigned int)(ms->s.addr + + fine_relocs[k].output_offset), + (unsigned int) +- (k == object_file->section_maps[j]. +- nfine_relocs - 1 ? +- object_file->section_maps[j].s->size - +- fine_relocs[k].input_offset : +- fine_relocs[k + 1].input_offset - +- fine_relocs[k].input_offset)); ++ (k == (unsigned int) ++ ((object_file->section_maps[j]. ++ nfine_relocs) - ++ (unsigned int)1) ? ++ (unsigned int) ++ (object_file->section_maps[j].s->size) - ++ (unsigned int)(fine_relocs[k]. ++ input_offset) : ++ (unsigned int)(fine_relocs[k + 1]. ++ input_offset) - ++ (unsigned int)(fine_relocs[k]. ++ input_offset))); + print_obj_name(object_file); + print("\n"); + } +diff -ubr ld/ld.c ld/ld.c +--- ld/ld.c Tue Jan 14 23:35:24 2003 ++++ ld/ld.c Mon Aug 25 22:11:47 2003 +@@ -50,6 +50,9 @@ + #include + #include + #include "stuff/seg_addr_table.h" ++#ifndef RLD ++#include "stuff/symbol_list.h" ++#endif + #include "make.h" + #include + #if defined(__OPENSTEP__) || defined(__GONZO_BUNSEN_BEAKER__) +@@ -91,8 +94,11 @@ + __private_extern__ char *outputfile = NULL; + /* type of output file */ + __private_extern__ unsigned long filetype = MH_EXECUTE; ++/* multi or single module dylib output */ ++__private_extern__ enum bool multi_module_dylib = TRUE; + #ifndef RLD + static enum bool filetype_specified = FALSE; ++static enum bool moduletype_specified = FALSE; + /* if the -A flag is specified use to set the object file type */ + static enum bool Aflag_specified = FALSE; + #endif /* !defined(RLD) */ +@@ -190,6 +196,19 @@ + /* Strip the base file symbols (the -A argument's symbols) */ + __private_extern__ enum bool strip_base_symbols = FALSE; + ++#ifndef RLD ++/* ++ * Data structures to perform selective exporting of global symbols. ++ * save_symbols is the names of the symbols from -exported_symbols_list ++ * remove_symbols is the names of the symbols from -unexported_symbols_list ++ */ ++__private_extern__ struct symbol_list *save_symbols = NULL; ++__private_extern__ unsigned long nsave_symbols = 0; ++__private_extern__ struct symbol_list *remove_symbols = NULL; ++__private_extern__ unsigned long nremove_symbols = 0; ++#endif /* RLD */ ++ ++ + /* The list of symbols to be traced */ + __private_extern__ char **trace_syms = NULL; + __private_extern__ unsigned long ntrace_syms = 0; +@@ -251,6 +270,7 @@ + static enum bool read_only_reloc_flag_specified = FALSE; + static enum bool sect_diff_reloc_flag_specified = FALSE; + static enum bool weak_reference_mismatches_specified = FALSE; ++static enum bool prebind_all_twolevel_modules_specified = FALSE; + #endif + + /* True if -m is specified to allow multiply symbols, as a warning */ +@@ -418,7 +438,8 @@ + char *argv[], + char *envp[]) + { +- unsigned long i, j, symbols_created, objects_specified, sections_created; ++ int i; ++ unsigned long j, symbols_created, objects_specified, sections_created; + unsigned long table_size; + int fd; + char *p, *symbol_name, *indr_symbol_name, *endp, *file_name; +@@ -438,11 +459,16 @@ + enum weak_reference_mismatches_handling new_weak_reference_mismatches; + enum bool is_framework; + char *has_suffix; ++ struct symbol_list *sp; ++ char *exported_symbols_list, *unexported_symbols_list; ++ enum bool missing_syms; + + #ifdef __MWERKS__ + char **dummy; + dummy = envp; + #endif ++ exported_symbols_list = NULL; ++ unexported_symbols_list = NULL; + + progname = argv[0]; + #ifndef BINARY_COMPARE +@@ -487,6 +513,8 @@ + p = &(argv[i][1]); + switch(*p){ + case 'l': ++ if(p[1] == '\0') ++ fatal("-l: argument missing"); + /* path searched abbrevated file name, processed in the + next pass of parsing arguments */ + break; +@@ -559,7 +587,13 @@ + prebind_allow_overlap = TRUE; + } + else if(strcmp(p, "prebind_all_twolevel_modules") == 0){ ++ if(prebind_all_twolevel_modules_specified == TRUE && ++ prebind_all_twolevel_modules == FALSE) ++ fatal("both -prebind_all_twolevel_modules and " ++ "-noprebind_all_twolevel_modules can't be " ++ "specified"); + prebind_all_twolevel_modules = TRUE; ++ prebind_all_twolevel_modules_specified = TRUE; + } + else if(strcmp(p, "private_bundle") == 0){ + private_bundle = TRUE; +@@ -808,6 +842,15 @@ + else if(strcmp(p, "nomultidefs") == 0){ + nomultidefs = TRUE; + } ++ else if(strcmp(p, "noprebind_all_twolevel_modules") == 0){ ++ if(prebind_all_twolevel_modules_specified == TRUE && ++ prebind_all_twolevel_modules == TRUE) ++ fatal("both -prebind_all_twolevel_modules and " ++ "-noprebind_all_twolevel_modules can't be " ++ "specified"); ++ prebind_all_twolevel_modules = FALSE; ++ prebind_all_twolevel_modules_specified = TRUE; ++ } + else + goto unknown_flag; + break; +@@ -882,6 +925,9 @@ + static_specified = TRUE; + twolevel_namespace = FALSE; + } ++ else if(strcmp(p, "search_paths_first") == 0){ ++ search_paths_first = TRUE; ++ } + /* + * Flags for specifing information about sections. + */ +@@ -1225,6 +1271,15 @@ + sub_librarys[nsub_librarys++] = argv[i+1]; + i += 1; + } ++ /* -single_module for MH_DYLIB output */ ++ else if(strcmp(p, "single_module") == 0){ ++ if(moduletype_specified == TRUE && ++ multi_module_dylib == TRUE) ++ fatal("can't specify both -single_module and " ++ "-multi_module"); ++ moduletype_specified = TRUE; ++ multi_module_dylib = FALSE; ++ } + else + goto unknown_flag; + break; +@@ -1409,6 +1464,16 @@ + new_multiply_defined_unused_flag; + break; + } ++ /* -multi_module for MH_DYLIB output */ ++ else if(strcmp(p, "multi_module") == 0){ ++ if(moduletype_specified == TRUE && ++ multi_module_dylib == FALSE) ++ fatal("can't specify both -single_module and " ++ "-multi_module"); ++ moduletype_specified = TRUE; ++ multi_module_dylib = TRUE; ++ break; ++ } + /* treat multiply defined symbols as a warning not a + hard error */ + if(p[1] != '\0') +@@ -1426,6 +1491,10 @@ + new_undefined_flag = UNDEFINED_WARNING; + else if(strcmp(argv[i], "suppress") == 0) + new_undefined_flag = UNDEFINED_SUPPRESS; ++ else if(strcmp(argv[i], "dynamic_lookup") == 0) ++ new_undefined_flag = UNDEFINED_DYNAMIC_LOOKUP; ++ else if(strcmp(argv[i], "define_a_way") == 0) ++ new_undefined_flag = UNDEFINED_DEFINE_A_WAY; + else{ + fatal("-undefined: unknown argument: %s", argv[i]); + new_undefined_flag = UNDEFINED_ERROR; +@@ -1450,6 +1519,17 @@ + i += 1; + break; + } ++ else if(strcmp(p, "unexported_symbols_list") == 0){ ++ if(i + 1 >= argc) ++ fatal("%s: argument missing", argv[i]); ++ if(remove_symbols != NULL) ++ fatal("%s: multiply specified", argv[i]); ++ setup_symbol_list(argv[i+1], &remove_symbols, ++ &nremove_symbols); ++ unexported_symbols_list = argv[i+1]; ++ i += 1; ++ break; ++ } + if(p[1] != '\0') + goto unknown_flag; + /* cause the specified symbol name to be undefined */ +@@ -1467,6 +1547,17 @@ + filetype = MH_EXECUTE; + break; + } ++ else if(strcmp(p, "exported_symbols_list") == 0){ ++ if(i + 1 >= argc) ++ fatal("%s: argument missing", argv[i]); ++ if(save_symbols != NULL) ++ fatal("%s: multiply specified", argv[i]); ++ setup_symbol_list(argv[i+1], &save_symbols, ++ &nsave_symbols); ++ exported_symbols_list = argv[i+1]; ++ i += 1; ++ break; ++ } + /* specify the entry point, the symbol who's value to be + used as the program counter in the unix thread */ + if(p[1] != '\0') +@@ -1526,6 +1617,26 @@ + new_weak_reference_mismatches; + break; + } ++ else if(strcmp(p, "weak_library") == 0){ ++ if(i + 1 >= argc) ++ fatal("-weak_library: argument missing"); ++ /* object file argv[i] processed in the next pass of ++ parsing arguments */ ++ i += 1; ++ } ++ else if(strncmp(p, "weak-l", sizeof("weak-l") - 1) == 0){ ++ if(p[sizeof("weak-l") - 1] == '\0') ++ fatal("-weak-l: argument missing"); ++ /* path searched abbrevated file name, processed in the ++ next pass of parsing arguments */ ++ } ++ else if(strcmp(p, "weak_framework") == 0){ ++ if(i + 1 >= argc) ++ fatal("-weak_framework: argument missing"); ++ /* path searched abbrevated framework name, processed ++ in the next pass of parsing arguments */ ++ i += 1; ++ } + else + goto unknown_flag; + break; +@@ -1664,7 +1775,7 @@ + rc_trace_dylibs = TRUE; + if(getenv("RC_TRACE_PREBINDING_DISABLED") != NULL) + rc_trace_prebinding_disabled = TRUE; +- if(getenv("XBS_TRACE_BUNDLE_LOADER") != NULL && ++ if(getenv("LD_TRACE_BUNDLE_LOADER") != NULL && + bundle_loader != NULL) + print("[Logging for XBS] Referenced bundle loader: %s\n", + bundle_loader); +@@ -1702,7 +1813,8 @@ + } + if(getenv("LD_PREBIND_ALLOW_OVERLAP") != NULL) + prebind_allow_overlap = TRUE; +- if(getenv("LD_PREBIND_ALL_TWOLEVEL_MODULES") != NULL) ++ if(prebind_all_twolevel_modules_specified == FALSE && ++ getenv("LD_PREBIND_ALL_TWOLEVEL_MODULES") != NULL) + prebind_all_twolevel_modules = TRUE; + + /* +@@ -1765,6 +1877,31 @@ + if(save_reloc && strip_base_symbols == TRUE) + fatal("can't use -b with -r (resulting file would not be " + "relocatable)"); ++ if(keep_private_externs == TRUE){ ++ if(save_symbols != NULL) ++ fatal("can't use both -keep_private_externs and " ++ "-exported_symbols_list"); ++ if(remove_symbols != NULL) ++ fatal("can't use both -keep_private_externs and " ++ "-unexported_symbols_list"); ++ } ++ if(save_symbols != NULL && remove_symbols != NULL){ ++ for(j = 0; j < nremove_symbols ; j++){ ++ sp = bsearch(remove_symbols[j].name, ++ save_symbols, nsave_symbols, ++ sizeof(struct symbol_list), ++ (int (*)(const void *, const void *)) ++ symbol_list_bsearch); ++ if(sp != NULL){ ++ error("symbol name: %s is listed in both " ++ "-exported_symbols_list and -unexported_symbols_list " ++ "(can't be both exported and unexported)", ++ remove_symbols[j].name); ++ } ++ } ++ if(errors != 0) ++ ld_exit(1); ++ } + if(filetype_specified == TRUE && filetype == MH_OBJECT){ + if(dynamic == TRUE) + fatal("incompatible to specifiy -object when -dynamic is used " +@@ -2032,6 +2169,9 @@ + if(nallowable_clients != 0) + fatal("-allowable_client flags can only be used when -dylib " + "is also specified"); ++ if(moduletype_specified == TRUE) ++ fatal("-single_module or -multi_module flags can only be used " ++ "when -dylib is also specified"); + } + if(filetype == MH_BUNDLE){ + if(dynamic == FALSE) +@@ -2094,9 +2234,26 @@ + warning("flag: -init %s ignored (-dylib was not specified", + init_name); + } +- if(twolevel_namespace == TRUE && undefined_flag != UNDEFINED_ERROR){ +- fatal("-undefined error must be used when -twolevel_namespace is " +- "in effect"); ++ if(twolevel_namespace == TRUE && ++ undefined_flag != UNDEFINED_ERROR && ++ undefined_flag != UNDEFINED_DYNAMIC_LOOKUP && ++ undefined_flag != UNDEFINED_DEFINE_A_WAY){ ++ if(macosx_deployment_target >=MACOSX_DEPLOYMENT_TARGET_10_3) ++ fatal("-undefined error, -undefined dynamic_lookup or " ++ "-undefined define_a_way must be used when " ++ "-twolevel_namespace is in effect"); ++ else ++ fatal("-undefined error or -undefined define_a_way must be " ++ "used when -twolevel_namespace is in effect"); ++ } ++ if(undefined_flag == UNDEFINED_DYNAMIC_LOOKUP){ ++ if(dynamic == FALSE) ++ fatal("incompatible flag -undefined dynamic_lookup used (must " ++ "specify \"-dynamic\" to be used)"); ++ if(macosx_deployment_target < MACOSX_DEPLOYMENT_TARGET_10_3) ++ fatal("flag: -undefined dynamic_lookup can't be used with " ++ "MACOSX_DEPLOYMENT_TARGET environment variable set to: " ++ "%s", macosx_deployment_target_name); + } + if(twolevel_namespace == TRUE && nundef_syms != 0){ + fatal("can't use -U flags when -twolevel_namespace is in effect"); +@@ -2181,10 +2338,9 @@ + * can have one. + */ + if(seglinkedit_specified == FALSE){ +- if((filetype == MH_EXECUTE || filetype == MH_BUNDLE || ++ if(filetype == MH_EXECUTE || filetype == MH_BUNDLE || + filetype == MH_FVMLIB || +- filetype == MH_DYLIB || filetype == MH_DYLINKER) && +- strip_level != STRIP_ALL) ++ filetype == MH_DYLIB || filetype == MH_DYLINKER) + seglinkedit = TRUE; + else + seglinkedit = FALSE; +@@ -2215,12 +2371,12 @@ + * output force the bundle_loader to be loaded first. + */ + if(bundle_loader != NULL && twolevel_namespace == FALSE){ +- pass1(bundle_loader, FALSE, FALSE, FALSE, TRUE); ++ pass1(bundle_loader, FALSE, FALSE, FALSE, TRUE, FALSE); + } + for(i = 1 ; i < argc ; i++){ + if(*argv[i] != '-'){ + /* just a normal object file name */ +- pass1(argv[i], FALSE, FALSE, FALSE, FALSE); ++ pass1(argv[i], FALSE, FALSE, FALSE, FALSE, FALSE); + objects_specified++; + } + else{ +@@ -2234,20 +2390,20 @@ + * loaded first above. + */ + if(twolevel_namespace == TRUE) +- pass1(argv[i+1], FALSE, FALSE, FALSE, TRUE); ++ pass1(argv[i+1], FALSE, FALSE, FALSE, TRUE, FALSE); + i++; + break; + } + break; + case 'l': + /* path searched abbrevated file name */ +- pass1(argv[i], TRUE, FALSE, FALSE, FALSE); ++ pass1(argv[i], TRUE, FALSE, FALSE, FALSE, FALSE); + objects_specified++; + break; + case 'A': + if(base_obj != NULL) + fatal("only one -A argument can be specified"); +- pass1(argv[++i], FALSE, TRUE, FALSE, FALSE); ++ pass1(argv[++i], FALSE, TRUE, FALSE, FALSE, FALSE); + objects_specified++; + break; + case 'f': +@@ -2255,7 +2411,7 @@ + if(dynamic == FALSE) + fatal("incompatible flag -framework used (must " + "specify \"-dynamic\" to be used)"); +- pass1(argv[++i], FALSE, FALSE, TRUE, FALSE); ++ pass1(argv[++i], FALSE, FALSE, TRUE, FALSE, FALSE); + objects_specified++; + } + if(strcmp(p, "filelist") == 0){ +@@ -2296,7 +2452,8 @@ + file_name = mkstr(dirname, "/", + file_name, NULL); + } +- pass1(file_name, FALSE, FALSE, FALSE, FALSE); ++ pass1(file_name, FALSE, FALSE, FALSE, FALSE, ++ FALSE); + objects_specified++; + file_name = addr + j + 1; + } +@@ -2314,7 +2471,8 @@ + break; + case 'u': + if(strcmp(p, "undefined") == 0 || +- strcmp(p, "umbrella") == 0){ ++ strcmp(p, "umbrella") == 0 || ++ strcmp(p, "unexported_symbols_list") == 0){ + i++; + break; + } +@@ -2421,6 +2579,23 @@ + case 'w': + if(strcmp(p, "weak_reference_mismatches") == 0) + i++; ++ else if(strcmp(p, "weak_library") == 0){ ++ pass1(argv[++i], FALSE, FALSE, FALSE, FALSE, TRUE); ++ objects_specified++; ++ } ++ else if(strncmp(p, "weak-l", sizeof("weak-l") - 1) == 0){ ++ /* path searched abbrevated file name */ ++ pass1(argv[i] + sizeof("weak"), TRUE, FALSE, FALSE, ++ FALSE, TRUE); ++ objects_specified++; ++ } ++ else if(strcmp(p, "weak_framework") == 0){ ++ if(dynamic == FALSE) ++ fatal("incompatible flag -weak_framework used (must" ++ " specify \"-dynamic\" to be used)"); ++ pass1(argv[++i], FALSE, FALSE, TRUE, FALSE, TRUE); ++ objects_specified++; ++ } + break; + } + } +@@ -2511,6 +2686,38 @@ + layout(); + + /* ++ * Check to that the exported or unexported symbols listed were seen. ++ */ ++ if(save_symbols != NULL){ ++ missing_syms = FALSE; ++ for(j = 0; j < nsave_symbols ; j++){ ++ if(save_symbols[j].seen == FALSE){ ++ if(missing_syms == FALSE){ ++ error("symbols names listed in " ++ "-exported_symbols_list: %s not in linked " ++ "objects", exported_symbols_list); ++ missing_syms = TRUE; ++ } ++ printf("%s\n", save_symbols[j].name); ++ } ++ } ++ } ++ if(remove_symbols != NULL){ ++ missing_syms = FALSE; ++ for(j = 0; j < nremove_symbols ; j++){ ++ if(remove_symbols[j].seen == FALSE){ ++ if(missing_syms == FALSE){ ++ error("symbols names listed in " ++ "-unexported_symbols_list: %s not in linked " ++ "objects", unexported_symbols_list); ++ missing_syms = TRUE; ++ } ++ printf("%s\n", remove_symbols[j].name); ++ } ++ } ++ } ++ ++ /* + * If there were any errors from layout() then don't continue. + */ + if(errors != 0) +@@ -2718,7 +2925,9 @@ + int dummy; + dummy = sig; + #endif +- cleanup(); ++ if(output_addr != NULL) ++ unlink(outputfile); ++ _exit(1); + } + + /* +diff -ubr ld/ld.h ld/ld.h +--- ld/ld.h Tue Jan 14 23:35:24 2003 ++++ ld/ld.h Mon Aug 25 12:12:29 2003 +@@ -41,6 +41,7 @@ + STRIP_L_SYMBOLS, + STRIP_DEBUG, + STRIP_NONGLOBALS, ++ STRIP_DYNAMIC_EXECUTABLE, + STRIP_ALL + }; + +@@ -48,7 +49,9 @@ + enum undefined_check_level { + UNDEFINED_ERROR, + UNDEFINED_WARNING, +- UNDEFINED_SUPPRESS ++ UNDEFINED_SUPPRESS, ++ UNDEFINED_DYNAMIC_LOOKUP, ++ UNDEFINED_DEFINE_A_WAY + }; + + /* The error level check for (twolevel namespace) multiply defined symbols */ +@@ -96,6 +99,8 @@ + __private_extern__ char *outputfile; + /* type of output file */ + __private_extern__ unsigned long filetype; ++/* multi or single module dylib output */ ++__private_extern__ enum bool multi_module_dylib; + + /* + * The architecture of the output file as specified by -arch and the cputype +@@ -161,6 +166,18 @@ + __private_extern__ enum strip_levels strip_level; + /* Strip the base file symbols (the -A argument's symbols) */ + __private_extern__ enum bool strip_base_symbols; ++ ++#ifndef RLD ++/* ++ * Data structures to perform selective exporting of global symbols. ++ * save_symbols is the names of the symbols from -exported_symbols_list ++ * remove_symbols is the names of the symbols from -unexported_symbols_list ++ */ ++__private_extern__ struct symbol_list *save_symbols; ++__private_extern__ unsigned long nsave_symbols; ++__private_extern__ struct symbol_list *remove_symbols; ++__private_extern__ unsigned long nremove_symbols; ++#endif /* RLD */ + + /* The list of symbols to be traced */ + __private_extern__ char **trace_syms; +diff -ubr ld/literal_pointers.c ld/literal_pointers.c +--- ld/literal_pointers.c Tue Jan 14 23:35:25 2003 ++++ ld/literal_pointers.c Mon Aug 25 22:11:47 2003 +@@ -149,8 +149,8 @@ + */ + fine_relocs = allocate(nliterals * sizeof(struct fine_reloc)); + memset(fine_relocs, '\0', nliterals * sizeof(struct fine_reloc)); +- for(i = 0; i < nliterals; i++){ +- fine_relocs[i].output_offset = -1; ++ for(j = 0; j < nliterals; j++){ ++ fine_relocs[j].output_offset = -1; + } + section_map->fine_relocs = fine_relocs; + section_map->nfine_relocs = nliterals; +@@ -374,15 +374,16 @@ + continue; + } + /* +- * For dynamic shared library format files the merged sections that +- * could have had external relocation entries must be resolved to +- * private extern symbols. This is because for MH_DYLIB files all +- * modules share the merged sections and the entire section gets +- * relocated when the library is mapped in. So the above +- * restriction assures the merged section will get relocated +- * properly and can be shared amoung library modules. ++ * For multi module dynamic shared library format files the ++ * merged sections that could have had external relocation ++ * entries must be resolved to private extern symbols. This is ++ * because for multi module MH_DYLIB files all modules share the ++ * merged sections and the entire section gets relocated when ++ * the library is mapped in. So the above restriction assures ++ * the merged section will get relocated properly and can be ++ * shared amoung library modules. + */ +- if(filetype == MH_DYLIB){ ++ if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ + /* + * If the symbol is undefined or not a private extern it is an + * error for in this section for a MH_DYLIB file. +@@ -390,21 +391,22 @@ + if(merged_symbol->nlist.n_type == (N_EXT | N_UNDF)){ + if(merged_symbol->error_flagged_for_dylib == 0){ + error_with_cur_obj("illegal undefined reference for " +- "MH_DYLIB output file to symbol: %s from a literal " +- "pointer section (section (%.16s,%.16s) relocation " +- "entry: %lu)", merged_symbol->nlist.n_un.n_name, +- s->segname, s->sectname, i); ++ "multi module MH_DYLIB output file to symbol: %s " ++ "from a literal pointer section (section (%.16s," ++ "%.16s) relocation entry: %lu)", ++ merged_symbol->nlist.n_un.n_name, s->segname, ++ s->sectname, i); + merged_symbol->error_flagged_for_dylib = 1; + } + } + else if((merged_symbol->nlist.n_type & N_PEXT) != N_PEXT){ + if(merged_symbol->error_flagged_for_dylib == 0){ + error_with_cur_obj("illegal external reference for " +- "MH_DYLIB output file to symbol: %s (not a private " +- "extern symbol) from a literal pointer section " +- "(section (%.16s,%.16s) relocation entry: %lu)", +- merged_symbol->nlist.n_un.n_name, s->segname, +- s->sectname, i); ++ "multi module MH_DYLIB output file to symbol: %s " ++ "(not a private extern symbol) from a literal " ++ "pointer section (section (%.16s,%.16s) relocation " ++ "entry: %lu)", merged_symbol->nlist.n_un.n_name, ++ s->segname, s->sectname, i); + merged_symbol->error_flagged_for_dylib = 1; + } + } +@@ -567,7 +569,7 @@ + * for this literal does not have an output_offset of -1 it is an error + * because we have seen it before. + */ +- if(fine_relocs[r_address/4].output_offset != -1){ ++ if((int)(fine_relocs[r_address/4].output_offset) != -1){ + error_with_cur_obj("more than one relocation entry for literal " + "pointer at address 0x%x (r_address 0x%x) in section " + "(%.16s,%.16s)", (unsigned int)(s->addr + r_address), +@@ -606,16 +608,16 @@ + /* + * The number of relocation entries in the output file is based + * on one of three different cases: +- * The output file is a dynamic shared library file ++ * The output file is a multi module dynamic shared library + * The output file has a dynamic linker load command + * The output does not have a dynamic linker load command + */ +- if(filetype == MH_DYLIB){ ++ if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ + /* +- * For dynamic shared library files there are no external +- * relocation entries that will be left as external as +- * checked above. Only non-sectdiff local relocation +- * entries are kept. Modules of dylibs are not linked ++ * For a multi module dynamic shared library there are no ++ * external relocation entries that will be left as external as ++ * checked above. Only non-sectdiff local relocation entries ++ * are kept. Modules of multi module dylibs are not linked + * together and can only be slid keeping all sections + * relative to each other the same. + */ +diff -ubr ld/m88k_reloc.c ld/m88k_reloc.c +--- ld/m88k_reloc.c Tue Jan 14 23:35:25 2003 ++++ ld/m88k_reloc.c Mon Aug 25 22:11:47 2003 +@@ -373,13 +373,13 @@ + /* + * If the symbol is undefined (or common) or a global coalesced + * symbol where we need to force an external relocation entry +- * and we are not prebinding no relocation is done. +- * Or if the output file is MH_DYLIB no relocation is done ++ * and we are not prebinding no relocation is done. Or if the ++ * output file is a multi module MH_DYLIB no relocation is done + * unless the symbol is a private extern or we are prebinding. + */ + if(((merged_symbol->nlist.n_type & N_TYPE) == N_UNDF) || + (force_extern_reloc == TRUE && prebinding == FALSE) || +- (filetype == MH_DYLIB && ++ ((filetype == MH_DYLIB && multi_module_dylib == TRUE) && + (((merged_symbol->nlist.n_type & N_PEXT) != N_PEXT) && + prebinding == FALSE) ) ) + value = 0; +@@ -910,18 +910,19 @@ + * For external relocation entries that the symbol is + * defined (not undefined or common) but not when we are + * forcing an external relocation entry for a global +- * coalesced symbol and if the output file is not MH_DYLIB +- * or the symbol is a private extern it is changed to a +- * local relocation entry using the section that symbol is +- * defined in. If still undefined or forcing an external +- * relocation entry for a global coalesced symbol then the +- * index of the symbol in the output file is set into +- * r_symbolnum. ++ * coalesced symbol and if the output file is not a multi ++ * module MH_DYLIB or the symbol is a private extern, it is ++ * changed to a local relocation entry using the section ++ * that symbol is defined in. If still undefined or forcing ++ * an external relocation entry for a global coalesced ++ * symbol, then the index of the symbol in the output file ++ * is set into r_symbolnum. + */ + else if((merged_symbol->nlist.n_type & N_TYPE) != N_UNDF && + (merged_symbol->nlist.n_type & N_TYPE) != N_PBUD && + force_extern_reloc == FALSE && +- (filetype != MH_DYLIB || ++ ((filetype != MH_DYLIB || ++ multi_module_dylib == FALSE) || + (merged_symbol->nlist.n_type & N_PEXT) == N_PEXT)){ + reloc->r_extern = 0; + /* +Only in ld: make.h +Only in ld: makeUser.c +diff -ubr ld/mod_sections.c ld/mod_sections.c +--- ld/mod_sections.c Tue Jan 14 23:35:25 2003 ++++ ld/mod_sections.c Mon Aug 25 22:11:47 2003 +@@ -56,8 +56,8 @@ + */ + static struct merged_section *dylib_ms_init = NULL; + static struct merged_section *dylib_ms_term = NULL; +-static unsigned long ninit = 0; +-static unsigned long nterm = 0; ++__private_extern__ unsigned long ninit = 0; ++__private_extern__ unsigned long nterm = 0; + #endif /* !defined(RLD) */ + + /* +diff -ubr ld/mod_sections.h ld/mod_sections.h +--- ld/mod_sections.h Tue Apr 30 00:37:20 2002 ++++ ld/mod_sections.h Mon Aug 25 12:12:29 2003 +@@ -28,6 +28,8 @@ + /* + * Global types, variables and routines declared in the file modinit_sections.c. + */ ++__private_extern__ unsigned long ninit; ++__private_extern__ unsigned long nterm; + + __private_extern__ void mod_section_merge( + void *data, +diff -ubr ld/notes ld/notes +--- ld/notes Tue Jan 14 23:35:25 2003 ++++ ld/notes Mon Aug 25 12:12:29 2003 +@@ -23,6 +23,420 @@ + - For m68k builds -finline-functions crashes the compiler (used in the Makefile + on the ld_build target). + ++Changes for the 5.12 release (the cctools-477 release): ++- Picked up changes to kld interfaces. Changes in rld.c and layout.c . ++ Radar bug #3270588. ++ ++Changes for the 5.12 release (the cctools-473 release): ++- Fixed a bug with the use of a modulus operator on a signed value which caused ++ a crash. The fix was to cast to unsigned long not long. The problem was in ++ lookup_indirect_item() in indirect_sections.c when it used the modulus ++ operator to come up with a hash value. Radar bug #3255992. ++ ++Changes for the 5.12 release (the cctools-472 release): ++- Moved the #ifndef RLD in output_local_symbols() in symbols.c down so that ++ the call to swap_nlist() is not ifdef'ed out. This allows cross building of ++ a kernel's symbol file with kld. Radar bug #3251273. ++ ++Changes for the 5.12 release (the cctools-471 release): ++- Backed out the change to call to _exit() in ld_exit() in ld.c in Radar bug ++ #3237013 as it does not flush the stdio buffers. Then changed the handler() ++ routine in ld.c used for signals to not call ld_exit() and instead unlink(2) ++ the output file if one was created and call _exit(1). Radar bug #3245341. ++- Fixed a problem in the kld libraries where the code that was not ignoring the ++ alignment of non-regular non-zerofill sections from the base file. A missing ++ #ifdef KLD and test of the base file was needed on one more place in ++ merge_sections() in sections.c . Radar bug #3245534. ++ ++Changes for the 5.12 release (the cctools-470 release): ++- Changed the call to exit() in ld_exit() in ld.c to _exit as it was causing a ++ hang in dyld when used with signal handlers. Radar bug #3237013. ++- Added the flag -search_paths_first to cause -lx flags to search each path ++ for .dylib then .a before searching next path. Radar bug #3176974. ++ - Added the enum bool variable search_paths_first to pass1.c and pass1.h and ++ code to parse out the option and set variable in main() in ld.c . ++ - The new static routines search_paths_for_lname() and search_path_for_lname() ++ were added to pass1.c . ++ - In pass1() in pass1.c a test of the new search_paths_first variable is done ++ and if TRUE then search_paths_for_lname() is called. ++ ++Changes for the 5.12 release (the cctools-468 release): ++- Added support to force a dynamic library to be marked weak in the output. ++ This can be done using these three flags: ++ -weak_framework Foo ++ -weak-lx ++ -weak_library library_filename ++ Radar bug #3069758. ++ - Added parsing out "-weak_framework", "-weak-lx"and "-weak_library" to ++ ld.c and calling pass1() with the force_weak parameter as TRUE. ++ - Added the new boolean parameter force_weak to pass1() in pass1.c and ++ pass1.h . Changed the existing calls to pass1() in ld.c to pass the new ++ boolean parameter force_weak as FALSE. ++ - Added the new boolean parameter force_weak to pass1_fat(), pass1_archive() ++ and pass1_object() in pass1.c . Propagated the passing of this new ++ parameter down through the calls. And passed it as FALSE in call to ++ pass1_fat() and pass1_object() from open_dylib(). ++ - Added the new boolean parameter force_weak to merge() in pass1.c . And ++ passed this as the parameter force_weak parameter or FALSE in the existing ++ calls. ++ - Added the new boolean parameter force_weak to merge_dylibs() in dylibs.c and ++ dylibs.h . After the call to add_dynamic_lib() the parameter force_weak is ++ set into the field force_weak_dylib in the dynamic_library struct. ++ - Added the boolean field force_weak_dylib to the dynamic_library structure ++ in pass1.h . ++ - Changed merge_dylib_module_symbols() in symbols.c to test the ++ force_weak_dylib field of the dynamic_library structure and if TRUE set the ++ N_WEAK_REF bit on the merged symbol to mark the symbol as a weak reference. ++ ++Changes for the 5.12 release (the cctools-468 release): ++- Added support for the new use of the previously unused value 3 for r_length ++ to mean that the conditional branch was predicted using the Y-bit and the ++ sign of the displacement and opcode. Radar bug #3223045. ++ - Changed ppc_reloc() in ppc_reloc.c to correctly flip the Y-bit for ++ PPC_RELOC_BR14 r_types with an r_length value of 3 for branch conditions ++ that are not branch always and the sign of the displacement is different ++ after relocation. ++- Fixed a problem when linking against stub libraries that the dependencies of ++ the stub libraries were getting recored in the output file. This caused them ++ to have LC_LOAD_DYLIB load commands which inturn messed up the recorded ++ library ordinals. The fix is in merge_dylibs() in dylibs.c to add a check ++ that the object's file type was not MH_DYLIB_STUB. Radar bug #3220772. ++ ++Changes for the 5.12 release (the cctools-467 release): ++- Added support for the PPC_RELOC_LO14_SECTDIFF relocation type used with ++ double word load/store instructions. Radar bug #3218027. ++ - Changed ppc_reloc() in ppc_reloc.c treat a PPC_RELOC_LO14_SECTDIFF as it ++ other PowerPC section difference relocation entries and expect it to have ++ a pair. And added cases for PPC_RELOC_LO14_SECTDIFF to relocate it as it ++ would for PPC_RELOC_LO14. ++ ++Changes for the 5.12 release (the cctools-466 release): ++- Added the new treatment of "-undefined define_a_way" to define all undefined ++ symbols as private extern symbols. This is a temporary work around to not ++ having dead-code stripping that also strips the undefined references from ++ dead code. Radar bug 3216770. ++ - Added the undefined_check_level enum UNDEFINED_DEFINE_A_WAY to ld.h . ++ - Added parsing out "-undefined define_a_way" in main() in ld.c and modified ++ checks to allow its use with -twolevel_namespace. ++ - Added the define_a_way bit field in the merged_symbol struct in symbols.h . ++ - Added the define_undefined_symbols_a_way() routine to symbols.c and ++ symbols.h . This routines sets up the undefined symbols to be defined and ++ sets the define_a_way bit field in the merged_symbol. ++ - Added code at the end of define_link_editor_dylib_symbols() in symbols.c to ++ loop through the symbol table and set the address of the symbols with the ++ define_a_way bit field set. ++ - In layout() in layout.c after it sets up the link editor defined symbols ++ a check of the undefined_flag for UNDEFINED_DEFINE_A_WAY is made and if so ++ a call to define_undefined_symbols_a_way() is made. ++- Fixed the incorrect casts on the comparison of the nlist struct's n_strx field ++ where the value being compared to was casted to a long. The correct fix was ++ to cast n_strx to an unsigned long. ++- Added the "-undefined dynamic_lookup" option for use in two-level namespace ++ images to all undefined symbols to be looked up dynamically with flat ++ namespace semantics. Radar bug #3210803. ++ - Added the undefined_check_level enum UNDEFINED_DYNAMIC_LOOKUP to ld.h . ++ - Added parsing out "-undefined dynamic_lookup" in main() in ld.c and modified ++ checks to allow its use with -twolevel_namespace. Also added checks when ++ "-undefined dynamic_lookup" is not allowed for -static and when ++ MACOSX_DEPLOYMENT_TARGET is less than 10.3 . ++ - Changed process_undefineds() in symbols.c to changed its check of ++ undefined_flag != UNDEFINED_SUPPRESS ++ to ++ (undefined_flag == UNDEFINED_ERROR || ++ undefined_flag == UNDEFINED_WARNING) ++ and added an else cause to that if to check if undefined_flag is ++ UNDEFINED_DYNAMIC_LOOKUP and then set the library ordinal to ++ DYNAMIC_LOOKUP_ORDINAL if -r is not used and two-level namespace is in ++ effect. ++ - Changed check_symbol() in symbols.c to not treat a symbol with the library ++ ordinal DYNAMIC_LOOKUP_ORDINAL as an error. ++ - Changed merge_dylib_module_symbols() in symbols.c in the second loop that ++ loops through the symbols referenced by the dylib module when it is doing ++ symbol tracing to check the library_ordinal for DYNAMIC_LOOKUP_ORDINAL. ++ And if it is DYNAMIC_LOOKUP_ORDINAL not use it as a library ordinal and ++ let it just get printed as an unbounded reference. ++ - Changed merge_dylib_module_symbols() in symbols.c in the second loop where ++ it resolves the undefined references and changed the logic where it selects ++ how to resolve the symbol. It now sets a new boolean, resolve_flat, based ++ on the old logic plus looking at library_ordinal for DYNAMIC_LOOKUP_ORDINAL. ++ - Changed search_dynamic_libs() in pass1.c when it is has an undefined symbol ++ from a two-level namespace image to check the library ordinal for ++ DYNAMIC_LOOKUP_ORDINAL and if so treat it an internal error. Since the ++ above change to merge_dylib_module_symbols() should never let this happen. ++ - Also added this same check as above and internal error message to ++ process_undefineds() in symbols.c in two places. Also added a missing ++ check in the loop looking for previous undefined two-level namespace symbols ++ that did not check the twolevel_reference field before using the ++ library_ordinal. And added a check for DYNAMIC_LOOKUP_ORDINAL in the ++ loop the prints the references in the -Y loop. ++ ++Changes for the 5.12 release (the cctools-464 release): ++- Changed the they way N_BINCL stabs with non-zero n_value fields are handled so ++ the n_value is not changed. Radar bug #3201935. ++ - Added field input_N_BINCL_n_value to the struct localsym_block in symbols.h ++ - In merged_symbols() in symbols.c when a new N_BINCL is found the n_value ++ of the N_BINCL nlist is saved in the input_N_BINCL_n_value field. And if ++ not zero the variable sum is set to that value. Later when a new symbol in ++ the group in encountered if input_N_BINCL_n_value is not zero then the ++ string for that symbol is not sum'ed. ++ ++Changes for the 5.12 release (the cctools-464 release): ++- Made changes to build cleanly with gcc3.3 ++ - Removed -Wno-precomp from the Makefile ++ - Fixed warnings for "comparison between signed and unsigned" in ld.c, ++ layout.c, pass2.c, literal_pointers.c, pass1.c, rld.c and sets.c . ++ ++Changes for the 5.12 release (the cctools-463 release): ++- Added support for linking against MH_DYLIB_STUB libraries. Radar bug #3193744. ++ - Added a check for the MH_DYLIB_STUB filetype along with MH_DYLIB in ++ merge_symbols() in symbols.c . ++ - Added the testing of the filetype not being MH_DYLIB_STUB along with ++ testing of the section type not being S_ZEROFILL before checking the size ++ and offset of the section contents in check_cur_obj() in pass1.c . ++ - Added the testing for MH_DYLIB_STUB along with MH_DYLIB in a few places ++ in check_cur_obj() in pass1.c for various error checks. ++ - Changed the setting of cur_obj->dylib in check_cur_obj() in pass1.c to ++ include the MH_DYLIB_STUB filetype. ++ ++Changes for the 5.12 release (the cctools-462 release): ++- Fixed a bug in the displacement overflow checking of a PPC_RELOC_BR14 ++ relocation entry. The mask that was used was 0xfffe0000 which should ++ have been 0xffff8000 in the PPC_RELOC_BR14 cases in ppc_reloc.c . ++ Radar bug #3190434. ++ ++Changes for the 5.12 release (the cctools-457 release): ++- For the -single_module dylib case the symbol stubs for coalesced private ++ extern symbols were not being removed when they could be. The change is in ++ indirect_section_merge() in indirect_sections.c after the test if the ++ merged symbol is a coalesced symbol the if statement on line 373. An ++ additional case was added to the if expression such that if the output file ++ is a dylib and not multi-module and the symbol is private extern then the ++ expression is TRUE and indirect_defined is set to TRUE. Radar bug #3163714. ++ ++Changes for the 5.12 release (the cctools-456 release): ++- Changed XBS_TRACE_BUNDLE_LOADER to LD_TRACE_BUNDLE_LOADER in ld.c. Radar bug ++ #3152604. ++ ++Changes for the 5.12 release (the cctools-454 release): ++- Fixed a bug when using the -m flag and having a multiple definition of a ++ private extern symbol. The problem was in merge_symbols the counts of ++ private exterals are first incremented. Then after multiply_defined() is ++ called a check was needed to see if allow_multiply_defined_symbols is TRUE ++ (the -m flag specified) and the counts for private exterals needed to be ++ decremented. Radar bug #3143764. ++- Fixed a bug when creating an indirect symbol when the referenced symbol is ++ a private extern symbol that causes an internal overlap error. Radar bug ++ #3134759. ++ - Added code in reduce_indr_symbols() in symbols.c so the N_PEXT bit is ++ checked and then the counts of private exterals (nmerged_private_symbols) ++ and the object's count (nprivatesym) are incremented. ++ - Changed assign_output_symbol_indexes() in symbols.c to check the N_PEXT ++ bit of the indirect symbol if the symbol is N_INDR to correctly determine ++ if the symbol is a private extern symbol in the two places it checks this ++ bit. ++ ++Changes for the 5.12 release (the cctools-450 release): ++- Added some double quotes in the Makefile around uses of `pwd` to be "`pwd`" so ++ if this were in a directory with a space it would work. Radar bug #3114622. ++- Changed is_output_local_symbol() in symbols.c to strip symbols in sections ++ with the S_ATTR_STRIP_STATIC_SYMS attribute. To do this n_ssect and the ++ object struct that the symbol came from is passed to is_output_local_symbol(). ++ Radar bug #3114458. ++- Changed the -x flag to strip private externs that will be local symbols in the ++ output file. Radar bug #3114182. ++ - Changed is_output_local_symbol() in symbols.c for the STRIP_NONGLOBALS case ++ (the -x flag) to return FALSE causing all local symbols to be stripped. ++ This strips private externs that were local symbols in the input object ++ files. ++ - Changed assign_output_symbol_indexes() in symbols.c to rebuild the merged ++ string table if we are stripping non-globals and we are not keeping private ++ externs and we have some private externs in the merged symbol table, and the ++ output is not a multi-module dylib. Then if this is the case the number of ++ private externs in each object is added to nstripped_merged_symbols so those ++ symbols are not counted. ++ - Changed output_merged_symbols() in symbols.c to check the strip_level for ++ STRIP_NONGLOBALS, and the output is not a multi-module dylib and not put ou ++ private externs in this case. ++ ++Changes for the 5.12 release (the cctools-447 release): ++- Fixed a problem with -x not stripping STABS with the P_EXT bit on them. The ++ odd stab: ++ 00000000 - 00 0000 3c gcc2_compiled. ++ was not stripped because of a bug in is_output_local_symbol() in symbols.c in ++ the STRIP_NONGLOBALS because it did not first check for N_STAB bits in n_type. ++ Radar bug #3104019. ++- Added the -noprebind_all_twolevel_modules flag that overrides the setting ++ of the environment variable LD_PREBIND_ALL_TWOLEVEL_MODULES. The changes are ++ in ld.c . Radar bug #3055372. ++- Fixed a bug that was causing dynamic libraries that had nothing referenced in ++ them that also were used indirectly that did have symbols indirectly ++ referenced in them to be LC_LOAD_WEAK_DYLIB. The problem was that references ++ from dylibs that were were causing the some_symbols_referenced field to be ++ set for the dylib. The fix was to merge_dylib_module_symbols() symbols.c ++ where it sets some_symbols_referenced. Radar bug #3094497. ++- Removed the const off of link_edit_common_object in symbols.[ch] to get rid ++ of warnings and since it is now written on. ++ ++Changes for the 5.11 release (the cctools-446 release): ++- Changed it so that when -s is used on a dynamic dynamic executable it rebuilds ++ the string table in assign_output_symbol_indexes() in symbols.c so that the ++ symbol names for the discarded symbols don't end up in the string table. ++ Radar bug #3089997. ++- Fixed a bug when using an export list and not listing a common symbol would ++ cause an internal overlap error. Radar bug #3088916. ++ - Changed define_common_symbols() in symbols.c right after ++ exports_list_processing() is called to check the N_PEXT bit and increment ++ the counts of private exterals. Both the object's count (nprivatesym) and ++ the global count (nmerged_private_symbols). ++ - Changed assign_output_symbol_indexes() in symbols.c to add the ++ link_edit_common_object object to the list of objects before counting ++ and assigning indexes to private extern symbols. Then at the end of the ++ loop copying back the updated object and taking it back off the list. ++ ++Changes for the 5.11 release (the cctools-445 release): ++- Changed the semantics of -s on dynamic executables to do the same stripping ++ as strip(1) with no arguments. That is only save undefined symbols and ++ global symbols marked referenced dynamically. Radar bug #2545288. ++ - Added the STRIP_DYNAMIC_EXECUTABLE enum value to strip_levels in ld.h . ++ - Added the variable nstripped_merged_symbols to symbols.c and symbols.h to ++ set to the number of merged symbol being stripped out. This is non-zero ++ when the strip_level is STRIP_DYNAMIC_EXECUTABLE. ++ - Changed assign_output_symbol_indexes() in symbols.c so that if strip_level ++ is STRIP_ALL and has_dynamic_linker_command is set to change strip_level ++ to STRIP_DYNAMIC_EXECUTABLE; ++ - Changed assign_output_symbol_indexes() to assign indexes to only undefined ++ symbols and global symbols marked referenced dynamically and add up the ++ number of merged symbol being stripped out into nstripped_merged_symbols. ++ - Added the case label for STRIP_DYNAMIC_EXECUTABLE in ++ is_output_local_symbol() in symbols.c to also return FALSE. ++ - Changed output_merged_symbols() in symbols.c to check the strip_level for ++ STRIP_DYNAMIC_EXECUTABLE and the REFERENCED_DYNAMICALLY of the symbol ++ and not put out those symbols in that case. ++ - Changed layout_segments() in layout.c when setting the ++ linkedit_segment.sg.filesize and output_symtab_info.symtab_command.nsyms ++ to subtract nstripped_merged_symbols. ++ - Fixed a typo in an error message in output_indirect_symbols() in ++ indirect_sections.c (changed "containg" to "containing"). ++ ++Changes for the 5.11 release (the cctools-444 release): ++- Added the -exported_symbols_list and -unexported_symbols_list flags. Radar ++ bug #3083844. ++ - Changes in ld.c and ld.h for adding the save_symbols and remove_symbols ++ variables and parsing and checking the flags. As well as checking to see ++ that the symbols were seen after pass1. ++ - Changed merge_symbol() in symbols.c to check if the symbol is on the ++ save_symbols or remove_symbols list and set the N_PEXT bit as needed. ++- Fixed a problem with ppc JSR's and doing an ld -r where the JBSR has an ++ external relocation entry and the symbol is not defined in the output. ++ The code in ppc_reloc.c was: ++ if(r_extern){ ++ value += offset; ++ other_half = value; ++ } ++ else{ ++ value += other_half; ++ other_half = value; ++ } ++ And in the case of an external relocation entry where the symbol was ++ undefined 'offset' was not set. For JBSR external relocation entries the ++ offset part of "symbol+offset" is stored in the PAIR relocation entry in ++ 'other_half'. This is because the displacement of the bl instruction is for ++ the branch island. So the correct code works out to be the same as the ++ non-extern case and was changed to just this: ++ value += other_half; ++ other_half = value; ++ Radar bug #3054747. ++ ++Changes for the 5.11 release (the cctools-443 release): ++- Added the -single_module and -multi_module flags. Radar bug #3080780. ++ - Changes in ld.c and ld.h for adding the boolean multi_module_dylib and ++ parsing and checking the flags. ++ - Changed one place in coalesced_sections.c in coalesced_section_merge() ++ where the number of relocation is determined. The MH_DYLIB case was changed ++ to include multi_module_dylib == TRUE. ++ - Changed two places in the relocation routines in generic_reloc.c, ++ i860_reloc.c, m88k_reloc.c, sparc_reloc.c, hppa_reloc.c and ppc_reloc.c. ++ For external relocation entries where the symbol is defined, if the output ++ file is a multi_module dylib no relocation is done unless the symbol is a ++ private extern or we are prebinding. In this case the relocation entry is ++ left as extern. For single_module dylibs the relocation is done and the ++ relocation entry turned into a local relocation entry. ++ - Changed two places in the relocation routines in hppa_reloc.c and ++ ppc_reloc.c for JBSR relocations. The JBSR relocation code does not do ++ relocation if multi_module dylib. but will do it for a single_module dylib. ++ - Changed indirect_sections.c in indirect_section_merge() in three places: ++ - The fine relocation entry for defined external symbols are kept in dylibs ++ if it is a multi_module dylib (not kept for single_module dylibs). ++ - The check external relocation entries resolving to private extern being is ++ flagged as an error is only done for multi_module dylibs. ++ - The code that counts up the relocation entries, was changed in the dylib ++ case to include multi_module_dylib == TRUE. ++ - Changed literal_pointers.c in two places: ++ - In literal_pointer_merge() the check external relocation entries resolving ++ to private extern being is flagged as an error is only done for ++ multi_module dylibs. ++ - In the static count_reloc() routine where the number of relocation is ++ determined, the MH_DYLIB case was changed to include ++ multi_module_dylib == TRUE. ++ - Changed objects.c in three places: ++ - In object_index() zero is returned when multi_module_dylib == FALSE. ++ - In fine_reloc_output_address() if the reloc is in a symbol stub section ++ and the symbol is defined and it is not in a multi_module dylib then ++ the merge symbol value from the fine_reloc is used. ++ - In fine_reloc_output_sectnum() if the reloc is in a symbol stub section ++ and the symbol is defined and it is not in a multi_module dylib then ++ the merge symbol section number from the fine_reloc is used. ++ - Changed sections.c in three places: ++ - In layout_relocs_for_dyld() the check that merged sections don't have ++ any external relocation entries in dylibs had multi_module_dylib == TRUE ++ added to it. ++ - In count_relocs() the dylib case for the code counting the number of ++ relocation entries had multi_module_dylib == TRUE added to it. ++ - In reloc_output_for_dyld() a matching change for the above change to ++ count_relocs() was made for the dylib case addin multi_module_dylib ==TRUE ++ to it. ++ - Changed many places in symbols.c: ++ - In the routine merge_symbols() ++ - The number of defined externals is now only counted in the multi ++ module dylib case (need to be able allocate the reference maps). ++ - For a merged symbol that is a weak definition that is discarded, the ++ symbol counts for the reference map are adjusted and the reference ++ flags are updated only in the multi_module dylib case. ++ - The reference map flags are only set in the multi_module dylib case. ++ - In the routine command_line_symbol() and command_line_indr_symbol() the ++ reference map flags are set only in the multi_module dylib case. ++ - In the routine merge_dylib_module_symbols() and ++ merge_bundle_loader_symbols() for a merged symbol that is a weak ++ definition that is discarded, the symbol counts for the reference map are ++ adjusted and the reference flags are updated only in the multi_module ++ dylib case. ++ - In define_common_symbols() a check for multi_module dylib is made and ++ it is an error if there is a common symbol to define. Also the traceing ++ of commons is not done in dylib if multi_module_dylib == TRUE. ++ - In setup_link_editor_symbols() the code is not changed for the one place ++ that MH_DYLIB is used. As the reference table will be ignored and ++ output_dysymtab_info.dysymtab_command.nextrefsyms will be reset ++ layout_dylib_tables() for single module dylibs. ++ - In output_merged_symbols() the N_INDR symbols are set to the defining ++ symbol if it is a multi_module dylib and defined in the same object or ++ in a single module dylib. ++ - In layout_dylib_tables() the existing code for the reference table and ++ module table where placed in if statements with multi_module_dylib == TRUE ++ and new code was added for the single module case. For the reference ++ table its size is reset based on the defined and undefined merged symbols. ++ The module table size is one and a variable, dylib_single_module_name, was ++ added to save the pointer to the module name in the merged symbol table. ++ - In output_dylib_tables() the existing code for the reference table and ++ module table where placed in if statements with multi_module_dylib == TRUE ++ and new code was added for the single module case. For the reference ++ table its is built from the merged symbol table's defined and undefined ++ symbols. The one module table entry is built from the a variable, ++ dylib_single_module_name, which is a pointer to the module name in the ++ merged symbol table and the values in output_dysymtab_info. ++ -Changed mod_sections.c and mod_sections.h so that ninit and nterm were ++ __private_extern__ so that output_dylib_tables() in symbols.c could use ++ them for the single module dylib module table entry. ++ + Changes for the 5.11 release (the cctools-440 release): + - Fixed the warnings about extra tokens at end of #endif directive in + 4byte_literals.c, 8byte_literals.c, coalesced_sections.c, cstring_literals.c, +diff -ubr ld/objects.c ld/objects.c +--- ld/objects.c Tue Jan 14 23:35:25 2003 ++++ ld/objects.c Mon Aug 25 22:11:47 2003 +@@ -110,7 +110,7 @@ + /* + * object_index() returns the index into the module table for a object file + * structure. It is only used in the creation of the table of contents entries +- * in a MH_DYLIB file. ++ * in a multi module MH_DYLIB file. + */ + __private_extern__ + unsigned long +@@ -121,6 +121,8 @@ + struct object_list *object_list, **p; + struct object_file *cmp_obj; + ++ if(multi_module_dylib == FALSE) ++ return(0); + index = 0; + for(p = &objects; *p; p = &(object_list->next)){ + object_list = *p; +@@ -417,6 +419,7 @@ + else if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS && + fine_reloc->indirect_defined == TRUE){ + if(filetype != MH_DYLIB || ++ (filetype == MH_DYLIB && multi_module_dylib == FALSE) || + (cur_obj == fine_reloc->merged_symbol->definition_object && + input_offset - fine_reloc->input_offset == 0)){ + if(cur_obj == fine_reloc->merged_symbol->definition_object) +@@ -559,7 +562,7 @@ + } + else if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS && + fine_reloc->indirect_defined == TRUE && +- filetype != MH_DYLIB){ ++ (filetype != MH_DYLIB || multi_module_dylib == FALSE)){ + merged_symbol = (struct merged_symbol *)fine_reloc->output_offset; + if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR) + merged_symbol = (struct merged_symbol *) +diff -ubr ld/pass1.c ld/pass1.c +--- ld/pass1.c Tue Jan 14 23:35:25 2003 ++++ ld/pass1.c Mon Aug 25 22:11:47 2003 +@@ -71,6 +71,9 @@ + #include "sets.h" + + #ifndef RLD ++/* TRUE if -search_paths_first was specified */ ++__private_extern__ enum bool search_paths_first = FALSE; ++ + /* the user specified directories to search for -lx names, and the number + of them */ + __private_extern__ char **search_dirs = NULL; +@@ -156,6 +159,15 @@ + char *name, + char **file_name, + int *fd); ++static void search_paths_for_lname( ++ const char *lname_argument, ++ char **file_name, ++ int *fd); ++static void search_path_for_lname( ++ const char *dir, ++ const char *lname_argument, ++ char **file_name, ++ int *fd); + #endif /* !defined(RLD) */ + + static void pass1_fat( +@@ -164,7 +176,8 @@ + unsigned long file_size, + enum bool base_name, + enum bool dylib_only, +- enum bool bundle_loader); ++ enum bool bundle_loader, ++ enum bool force_weak); + + static void pass1_archive( + char *file_name, +@@ -172,7 +185,8 @@ + unsigned long file_size, + enum bool base_name, + enum bool from_fat_file, +- enum bool bundle_loader); ++ enum bool bundle_loader, ++ enum bool force_weak); + + static enum bool check_archive_arch( + char *file_name, +@@ -192,7 +206,8 @@ + enum bool base_name, + enum bool from_fat_file, + enum bool dylib_only, +- enum bool bundle_loader); ++ enum bool bundle_loader, ++ enum bool force_weak); + + #ifndef RLD + static void load_init_dylib_module( +@@ -295,7 +310,8 @@ + enum bool lname, + enum bool base_name, + enum bool framework_name, +-enum bool bundle_loader) ++enum bool bundle_loader, ++enum bool force_weak) + { + int fd; + char *file_name; +@@ -335,13 +351,22 @@ + } + else{ + if(dynamic == TRUE){ ++ if(search_paths_first == TRUE){ ++ search_paths_for_lname(&name[2], &file_name, &fd); ++ } ++ else{ + p = mkstr("lib", &name[2], ".dylib", NULL); + search_for_file(p, &file_name, &fd); +- } + if(fd == -1){ + p = mkstr("lib", &name[2], ".a", NULL); + search_for_file(p, &file_name, &fd); + } ++ } ++ } ++ else{ ++ p = mkstr("lib", &name[2], ".a", NULL); ++ search_for_file(p, &file_name, &fd); ++ } + if(fd == -1) + fatal("can't locate file for: %s", name); + free(p); +@@ -444,15 +469,15 @@ + new_archive_or_fat(file_name, file_addr, file_size); + #endif /* RLD */ + pass1_fat(file_name, file_addr, file_size, base_name, FALSE, +- bundle_loader); ++ bundle_loader, force_weak); + } + else if(file_size >= SARMAG && strncmp(file_addr, ARMAG, SARMAG) == 0){ + pass1_archive(file_name, file_addr, file_size, base_name, FALSE, +- bundle_loader); ++ bundle_loader, force_weak); + } + else{ + pass1_object(file_name, file_addr, file_size, base_name, FALSE, +- FALSE, bundle_loader); ++ FALSE, bundle_loader, force_weak); + } + #ifdef VM_SYNC_DEACTIVATE + vm_msync(mach_task_self(), (vm_address_t)file_addr, +@@ -524,6 +549,65 @@ + } + } + } ++ ++/* ++ * search_paths_for_lname() takes the argument to a -lx option and and trys to ++ * open a file with the name libx.dylib or libx.a. This routine is only used ++ * when the -search_paths_first option is specified and -dynamic is in effect. ++ * And looks for a file name ending in .dylib then .a in each directory before ++ * looking in the next directory. The list of the -L search directories and in ++ * the standard directories are searched in that order. If this is sucessful ++ * it returns a pointer to the file name indirectly through file_name and the ++ * open file descriptor indirectly through fd. ++ */ ++static ++void ++search_paths_for_lname( ++const char *lname_argument, ++char **file_name, ++int *fd) ++{ ++ unsigned long i; ++ ++ *fd = -1; ++ for(i = 0; i < nsearch_dirs ; i++){ ++ search_path_for_lname(search_dirs[i], lname_argument, file_name,fd); ++ if(*fd != -1) ++ return; ++ } ++ for(i = 0; standard_dirs[i] != NULL ; i++){ ++ search_path_for_lname(standard_dirs[i],lname_argument,file_name,fd); ++ if(*fd != -1) ++ return; ++ } ++} ++ ++/* ++ * search_path_for_lname() takes the argument to a -lx option and and trys to ++ * open a file with the name libx.dylib then libx.a in the specified directory ++ * name. This routine is only used when the -search_paths_first option is ++ * specified and -dynamic is in effect. If this is sucessful it returns a ++ * pointer to the file name indirectly through file_name and the open file ++ * descriptor indirectly through fd. ++ */ ++static ++void ++search_path_for_lname( ++const char *dir, ++const char *lname_argument, ++char **file_name, ++int *fd) ++{ ++ *file_name = mkstr(dir, "/", "lib", lname_argument, ".dylib", NULL); ++ if((*fd = open(*file_name, O_RDONLY)) != -1) ++ return; ++ free(*file_name); ++ ++ *file_name = mkstr(dir, "/", "lib", lname_argument, ".a", NULL); ++ if((*fd = open(*file_name, O_RDONLY)) != -1) ++ return; ++ free(*file_name); ++} + #endif /* !defined(RLD) */ + + #ifndef RLD +@@ -549,7 +633,8 @@ + unsigned long file_size, + enum bool base_name, + enum bool dylib_only, +-enum bool bundle_loader) ++enum bool bundle_loader, ++enum bool force_weak) + { + struct fat_header *fat_header; + #ifdef __LITTLE_ENDIAN__ +@@ -671,11 +756,11 @@ + goto pass1_fat_return; + } + pass1_archive(file_name, arch_addr, arch_size, +- base_name, TRUE, bundle_loader); ++ base_name, TRUE, bundle_loader, force_weak); + } + else{ + pass1_object(file_name, arch_addr, arch_size, base_name, TRUE, +- dylib_only, bundle_loader); ++ dylib_only, bundle_loader, force_weak); + } + goto pass1_fat_return; + } +@@ -697,11 +782,11 @@ + goto pass1_fat_return; + } + pass1_archive(file_name, arch_addr, arch_size, base_name, TRUE, +- bundle_loader); ++ bundle_loader, force_weak); + } + else{ + pass1_object(file_name, arch_addr, arch_size, base_name, TRUE, +- dylib_only, bundle_loader); ++ dylib_only, bundle_loader, force_weak); + } + goto pass1_fat_return; + } +@@ -729,11 +814,11 @@ + goto pass1_fat_return; + } + pass1_archive(file_name, arch_addr, arch_size, +- base_name, TRUE, bundle_loader); ++ base_name, TRUE, bundle_loader, force_weak); + } + else{ + pass1_object(file_name, arch_addr, arch_size, base_name, TRUE, +- dylib_only, bundle_loader); ++ dylib_only, bundle_loader, force_weak); + } + goto pass1_fat_return; + } +@@ -867,7 +952,8 @@ + unsigned long file_size, + enum bool base_name, + enum bool from_fat_file, +-enum bool bundle_loader) ++enum bool bundle_loader, ++enum bool force_weak) + { + unsigned long i, j, offset; + #ifndef RLD +@@ -1153,7 +1239,7 @@ + print_obj_name(cur_obj); + print("loaded because of -all_load flag\n"); + } +- merge(FALSE, FALSE); ++ merge(FALSE, FALSE, force_weak); + length = round(ar_size + ar_name_size, sizeof(short)); + offset = (offset - ar_name_size) + length; + } +@@ -1271,7 +1357,7 @@ + if(toc_byte_sex != host_byte_sex) + swap_ranlib(ranlibs, nranlibs, host_byte_sex); + for(i = 0; i < nranlibs; i++){ +- if(ranlibs[i].ran_un.ran_strx >= (long)string_size){ ++ if(ranlibs[i].ran_un.ran_strx >= string_size){ + error("malformed table of contents in: %s (ranlib struct %lu " + "has bad string index, can't load from it)", file_name,i); + return; +@@ -1383,7 +1469,7 @@ + print("loaded because of -ObjC flag to get symbol: %s\n", + bsearch_strings + ranlibs[i].ran_un.ran_strx); + } +- merge(FALSE, FALSE); ++ merge(FALSE, FALSE, force_weak); + } + free(loaded_offsets); + } +@@ -1515,7 +1601,7 @@ + undefined->merged_symbol->nlist.n_un.n_name); + } + +- merge(FALSE, FALSE); ++ merge(FALSE, FALSE, force_weak); + + /* make sure this symbol got defined */ + if(errors == 0 && +@@ -1613,7 +1699,7 @@ + merged_symbol->nlist.n_un.n_name); + } + +- merge(FALSE, FALSE); ++ merge(FALSE, FALSE, force_weak); + + /* make sure this symbol got defined */ + if(errors == 0 && +@@ -1829,7 +1915,8 @@ + enum bool base_name, + enum bool from_fat_file, + enum bool dylib_only, +-enum bool bundle_loader) ++enum bool bundle_loader, ++enum bool force_weak) + { + #ifdef __MWERKS__ + enum bool dummy; +@@ -1855,7 +1942,7 @@ + base_obj = cur_obj; + #endif /* !defined(RLD) */ + +- merge(dylib_only, bundle_loader); ++ merge(dylib_only, bundle_loader, force_weak); + + #ifndef RLD + /* +@@ -2349,6 +2436,18 @@ + undefined->merged_symbol->nlist.n_desc); + if(library_ordinal == SELF_LIBRARY_ORDINAL) + p = undefined->merged_symbol->referencing_library; ++ /* ++ * Note that if library_ordinal was DYNAMIC_LOOKUP_ORDINAL then ++ * merge_dylib_module_symbols() in symbols.c would not have ++ * set the twolevel_reference field to TRUE in the merged_symbol ++ * and if we get here it with this it is an internal error. ++ */ ++ else if(library_ordinal == DYNAMIC_LOOKUP_ORDINAL) ++ fatal("internal error: search_dynamic_libs() with a " ++ "merged_symbol (%s) on the undefined list with " ++ "twolevel_reference == TRUE and library_ordinal == " ++ "DYNAMIC_LOOKUP_ORDINAL", undefined->merged_symbol-> ++ nlist.n_un.n_name); + else + p = undefined->merged_symbol->referencing_library-> + dependent_images[library_ordinal - 1]; +@@ -2615,7 +2714,7 @@ + undefined->merged_symbol->nlist.n_un.n_name); + } + +- merge(FALSE, FALSE); ++ merge(FALSE, FALSE, FALSE); + + /* make sure this symbol got defined */ + if(errors == 0 && +@@ -2688,7 +2787,7 @@ + undefined->merged_symbol->nlist.n_un.n_name); + } + +- merge(FALSE, FALSE); ++ merge(FALSE, FALSE, FALSE); + + /* make sure this symbol got defined */ + if(errors == 0 && +@@ -3464,11 +3563,12 @@ + if(fat_header->magic == SWAP_LONG(FAT_MAGIC)) + #endif /* __LITTLE_ENDIAN__ */ + { +- pass1_fat(file_name, file_addr, file_size, FALSE, TRUE, FALSE); ++ pass1_fat(file_name, file_addr, file_size, FALSE, TRUE, FALSE, ++ FALSE); + } + else{ + pass1_object(file_name, file_addr, file_size, FALSE, FALSE, TRUE, +- FALSE); ++ FALSE, FALSE); + } + if(errors) + return(FALSE); +@@ -3800,7 +3900,8 @@ + void + merge( + enum bool dylib_only, +-enum bool bundle_loader) ++enum bool bundle_loader, ++enum bool force_weak) + { + unsigned long previous_errors; + +@@ -3857,7 +3958,7 @@ + /* if this object has any dynamic shared library stuff merge it */ + if(cur_obj->dylib_stuff){ + #ifndef RLD +- merge_dylibs(); ++ merge_dylibs(force_weak); + if(errors) + goto merge_return; + if(cur_obj->dylib) +@@ -3898,9 +3999,9 @@ + * the dysymtab field, the section_maps and nsection_maps fields (this routine + * allocates the section_map structures and fills them in too), the fvmlib_ + * stuff field is set if any SG_FVMLIB segments or LC_LOADFVMLIB commands are +- * seen and the dylib_stuff field is set if the file is a MH_DYLIB type and +- * has a LC_ID_DYLIB command or a LC_LOAD_DYLIB or LC_LOAD_WEAK_DLIB command is +- * seen. ++ * seen and the dylib_stuff field is set if the file is a MH_DYLIB or ++ * MH_DYLIB_STUB type and has a LC_ID_DYLIB command or a LC_LOAD_DYLIB or ++ * LC_LOAD_WEAK_DLIB command is seen. + */ + static + void +@@ -4161,17 +4262,20 @@ + return; + } + if((mh->flags & MH_DYLDLINK) != 0 && +- (mh->filetype != MH_DYLIB && mh->filetype != MH_DYLINKER) && ++ (mh->filetype != MH_DYLIB && ++ mh->filetype != MH_DYLIB_STUB && ++ mh->filetype != MH_DYLINKER) && + bundle_loader == FALSE){ + error_with_cur_obj("is input for the dynamic link editor, is not " + "relocatable by the static link editor again"); + return; + } + /* +- * If this is a MH_DYLIB file then a single LC_ID_DYLIB command must be +- * seen to identify the library. ++ * If this is a MH_DYLIB or MH_DYLIB_STUB file then a single LC_ID_DYLIB ++ * command must be seen to identify the library. + */ +- cur_obj->dylib = (enum bool)(mh->filetype == MH_DYLIB); ++ cur_obj->dylib = (enum bool)(mh->filetype == MH_DYLIB || ++ mh->filetype == MH_DYLIB_STUB); + dlid = NULL; + dylib_id_name = NULL; + if(cur_obj->dylib == TRUE && dynamic == FALSE){ +@@ -4348,7 +4452,8 @@ + return; + } + /* check the size and offset of the contents if it has any*/ +- if(section_type != S_ZEROFILL){ ++ if(mh->filetype != MH_DYLIB_STUB && ++ section_type != S_ZEROFILL){ + check_size_offset_sect(s->size, s->offset, sizeof(char), + "size", "offset", i, j, s->segname, s->sectname); + if(errors) +@@ -4569,14 +4674,16 @@ + filetype == MH_FVMLIB ? "MH_FVMLIB" : "MH_DYLINKER"); + return; + } +- if(mh->filetype != MH_DYLIB){ ++ if(mh->filetype != MH_DYLIB && mh->filetype != MH_DYLIB_STUB){ + error_with_cur_obj("LC_ID_DYLIB load command in non-" +- "MH_DYLIB filetype"); ++ "%s filetype", mh->filetype == MH_DYLIB ? "MH_DYLIB" : ++ "MH_DYLIB_STUB"); + return; + } + if(dlid != NULL){ + error_with_cur_obj("malformed object (more than one " +- "LC_ID_DYLIB load command in MH_DYLIB file)"); ++ "LC_ID_DYLIB load command in %s file)", mh->filetype == ++ MH_DYLIB ? "MH_DYLIB" : "MH_DYLIB_STUB"); + return; + } + dl = (struct dylib_command *)lc; +@@ -4655,14 +4762,17 @@ + filetype == MH_FVMLIB ? "MH_FVMLIB" : "MH_DYLINKER"); + return; + } +- if(mh->filetype != MH_DYLIB){ ++ if(mh->filetype != MH_DYLIB && mh->filetype != MH_DYLIB_STUB){ + error_with_cur_obj("LC_SUB_FRAMEWORK load command in non-" +- "MH_DYLIB filetype"); ++ "%s filetype", mh->filetype == MH_DYLIB ? "MH_DYLIB" : ++ "MH_DYLIB_STUB"); + return; + } + if(sub != NULL){ + error_with_cur_obj("malformed object (more than one " +- "LC_SUB_FRAMEWORK load command in MH_DYLIB file)"); ++ "LC_SUB_FRAMEWORK load command in %s file)", ++ mh->filetype == MH_DYLIB ? "MH_DYLIB" : ++ "MH_DYLIB_STUB"); + return; + } + sub = (struct sub_framework_command *)lc; +@@ -4699,9 +4809,10 @@ + filetype == MH_FVMLIB ? "MH_FVMLIB" : "MH_DYLINKER"); + return; + } +- if(mh->filetype != MH_DYLIB){ ++ if(mh->filetype != MH_DYLIB && mh->filetype != MH_DYLIB_STUB){ + error_with_cur_obj("LC_SUB_UMBRELLA load command in non-" +- "MH_DYLIB filetype"); ++ "%s filetype", mh->filetype == MH_DYLIB ? "MH_DYLIB" : ++ "MH_DYLIB_STUB"); + return; + } + usub = (struct sub_umbrella_command *)lc; +@@ -4738,9 +4849,10 @@ + filetype == MH_FVMLIB ? "MH_FVMLIB" : "MH_DYLINKER"); + return; + } +- if(mh->filetype != MH_DYLIB){ ++ if(mh->filetype != MH_DYLIB && mh->filetype != MH_DYLIB_STUB){ + error_with_cur_obj("LC_SUB_LIBRARY load command in non-" +- "MH_DYLIB filetype"); ++ "%s filetype", mh->filetype == MH_DYLIB ? "MH_DYLIB" : ++ "MH_DYLIB_STUB"); + return; + } + lsub = (struct sub_library_command *)lc; +@@ -4777,9 +4889,10 @@ + filetype == MH_FVMLIB ? "MH_FVMLIB" : "MH_DYLINKER"); + return; + } +- if(mh->filetype != MH_DYLIB){ ++ if(mh->filetype != MH_DYLIB && mh->filetype != MH_DYLIB_STUB){ + error_with_cur_obj("LC_SUB_CLIENT load command in non-" +- "MH_DYLIB filetype"); ++ "%s filetype", mh->filetype == MH_DYLIB ? "MH_DYLIB" : ++ "MH_DYLIB_STUB"); + return; + } + csub = (struct sub_client_command *)lc; +@@ -5092,12 +5205,14 @@ + } + } + /* +- * If this is a MH_DYLIB file then a single LC_ID_DYLIB command must be +- * seen to identify the library. ++ * If this is a MH_DYLIB or MH_DYLIB_STUB file then a single ++ * LC_ID_DYLIB command must be seen to identify the library. + */ +- if(mh->filetype == MH_DYLIB && dlid == NULL){ ++ if((mh->filetype == MH_DYLIB || mh->filetype == MH_DYLIB_STUB) && ++ dlid == NULL){ + error_with_cur_obj("malformed object (no LC_ID_DYLIB load command " +- "in MH_DYLIB file)"); ++ "in %s file)", mh->filetype == MH_DYLIB ? ++ "MH_DYLIB" : "MH_DYLIB_STUB"); + return; + } + /* +diff -ubr ld/pass1.h ld/pass1.h +--- ld/pass1.h Tue Jan 14 23:35:25 2003 ++++ ld/pass1.h Mon Aug 25 12:12:29 2003 +@@ -33,6 +33,9 @@ + */ + + #ifndef RLD ++/* TRUE if -search_paths_first was specified */ ++__private_extern__ enum bool search_paths_first; ++ + /* the user specified directories to search for -lx filenames, and the number + of them */ + __private_extern__ char **search_dirs; +@@ -84,6 +87,7 @@ + enum bool indirect_twolevel_ref_flagged; + enum bool some_non_weak_refs; + enum bool some_symbols_referenced; ++ enum bool force_weak_dylib; + struct object_file *definition_obj; + char *dylib_file; /* argument to -dylib_file "install_name:file_name" */ + struct dylib_table_of_contents *tocs; +@@ -125,10 +129,12 @@ + enum bool lname, + enum bool base_name, + enum bool framework_name, +- enum bool bundle_loader); ++ enum bool bundle_loader, ++ enum bool force_weak); + __private_extern__ void merge( + enum bool dylib_only, +- enum bool bundle_loader); ++ enum bool bundle_loader, ++ enum bool force_weak); + __private_extern__ void check_fat( + char *file_name, + unsigned long file_size, +diff -ubr ld/pass2.c ld/pass2.c +--- ld/pass2.c Tue Jan 14 23:35:25 2003 ++++ ld/pass2.c Mon Aug 25 22:11:47 2003 +@@ -336,7 +336,7 @@ + /* + * Write the entire object file. + */ +- if(write(fd, output_addr, output_size) != output_size) ++ if(write(fd, output_addr, output_size) != (int)output_size) + system_fatal("can't write output file"); + + if((r = vm_deallocate(mach_task_self(), (vm_address_t)output_addr, +@@ -858,7 +858,8 @@ + write_offset, write_size); + #endif /* DEBUG */ + lseek(fd, write_offset, L_SET); +- if(write(fd, output_addr + write_offset, write_size) != write_size) ++ if(write(fd, output_addr + write_offset, write_size) != ++ (int)write_size) + system_fatal("can't write to output file"); + if((r = vm_deallocate(mach_task_self(), (vm_address_t)(output_addr + + write_offset), write_size)) != KERN_SUCCESS) +@@ -919,7 +920,8 @@ + write_offset, write_size); + #endif /* DEBUG */ + lseek(fd, write_offset, L_SET); +- if(write(fd, output_addr + write_offset, write_size) != write_size) ++ if(write(fd, output_addr + write_offset, write_size) != ++ (int)write_size) + system_fatal("can't write to output file"); + if((r = vm_deallocate(mach_task_self(), (vm_address_t)(output_addr + + write_offset), write_size)) != KERN_SUCCESS) +diff -ubr ld/ppc_reloc.c ld/ppc_reloc.c +--- ld/ppc_reloc.c Tue Jan 14 23:35:25 2003 ++++ ld/ppc_reloc.c Mon Aug 25 22:11:47 2003 +@@ -242,6 +242,7 @@ + else if(r_type == PPC_RELOC_SECTDIFF || + r_type == PPC_RELOC_HI16_SECTDIFF || + r_type == PPC_RELOC_LO16_SECTDIFF || ++ r_type == PPC_RELOC_LO14_SECTDIFF || + r_type == PPC_RELOC_HA16_SECTDIFF){ + if(r_scattered != 1){ + error_with_cur_obj("relocation entry (%lu) in section " +@@ -390,13 +391,13 @@ + /* + * If the symbol is undefined (or common) or a global coalesced + * symbol where we need to force an external relocation entry +- * and we are not prebinding no relocation is done. +- * Or if the output file is MH_DYLIB no relocation is done ++ * and we are not prebinding no relocation is done. Or if the ++ * output file is a multi module MH_DYLIB no relocation is done + * unless the symbol is a private extern or we are prebinding. + */ + if(((merged_symbol->nlist.n_type & N_TYPE) == N_UNDF) || + (force_extern_reloc == TRUE && prebinding == FALSE) || +- (filetype == MH_DYLIB && ++ ((filetype == MH_DYLIB && multi_module_dylib == TRUE) && + (((merged_symbol->nlist.n_type & N_PEXT) != N_PEXT) && + prebinding == FALSE) ) ) + value = 0; +@@ -512,6 +513,7 @@ + if(r_type == PPC_RELOC_SECTDIFF || + r_type == PPC_RELOC_HI16_SECTDIFF || + r_type == PPC_RELOC_LO16_SECTDIFF || ++ r_type == PPC_RELOC_LO14_SECTDIFF || + r_type == PPC_RELOC_HA16_SECTDIFF){ + pair_local_map = + &(cur_obj->section_maps[pair_r_symbolnum - 1]); +@@ -523,6 +525,7 @@ + if(r_type == PPC_RELOC_SECTDIFF || + r_type == PPC_RELOC_HI16_SECTDIFF || + r_type == PPC_RELOC_LO16_SECTDIFF || ++ r_type == PPC_RELOC_LO14_SECTDIFF || + r_type == PPC_RELOC_HA16_SECTDIFF){ + value = - local_map->s->addr + + (local_map->output_section->s.addr + +@@ -609,6 +612,7 @@ + other_half; + break; + case PPC_RELOC_LO14: ++ case PPC_RELOC_LO14_SECTDIFF: + value = (other_half << 16) | + (instruction & 0xfffc); + break; +@@ -634,6 +638,7 @@ + if(r_type == PPC_RELOC_SECTDIFF || + r_type == PPC_RELOC_HI16_SECTDIFF || + r_type == PPC_RELOC_LO16_SECTDIFF || ++ r_type == PPC_RELOC_LO14_SECTDIFF || + r_type == PPC_RELOC_HA16_SECTDIFF){ + /* + * For PPC_RELOC_SECTDIFF's the item to be +@@ -788,6 +793,7 @@ + ((value >> 16) & 0xffff); + break; + case PPC_RELOC_LO14: ++ case PPC_RELOC_LO14_SECTDIFF: + if((value & 0x3) != 0) + error_with_cur_obj("relocation error " + "for relocation entry %lu in section " +@@ -808,8 +814,8 @@ + "multiple of 4 bytes)", i, + section_map->s->segname, + section_map->s->sectname); +- if((value & 0xfffe0000) != 0xfffe0000 && +- (value & 0xfffe0000) != 0x00000000) ++ if((value & 0xffff8000) != 0xffff8000 && ++ (value & 0xffff8000) != 0x00000000) + error_with_cur_obj("relocation overflow " + "for relocation entry %lu in section " + "(%.16s,%.16s) (displacement too large)" +@@ -817,6 +823,19 @@ + section_map->s->sectname); + instruction = (instruction & 0xffff0003) | + (value & 0xfffc); ++ /* ++ * If this is a predicted branch conditional ++ * (r_length is 3) where the branch condition ++ * is not branch always and the sign of the ++ * displacement is different after relocation ++ * then flip the Y-bit to preserve the sense of ++ * the branch prediction. ++ */ ++ if(r_length == 3 && ++ (instruction & 0xfc000000) == 0x40000000 && ++ (instruction & 0x03e00000) != 0x02800000 && ++ (instruction & 0x00008000) != br14_disp_sign) ++ instruction ^= (1 << 21); + break; + case PPC_RELOC_BR24: + if((value & 0x3) != 0) +@@ -847,7 +866,9 @@ + + fine_reloc_output_offset( + section_map, r_address); + if(save_reloc == 0 && +- (filetype != MH_DYLIB || (r_extern == 1 && ++ ((filetype != MH_DYLIB || ++ multi_module_dylib == FALSE) || ++ (r_extern == 1 && + (merged_symbol->nlist.n_type & N_PEXT) == + N_PEXT)) && + (output_for_dyld == FALSE || r_extern == 0 || +@@ -968,6 +989,7 @@ + other_half = immediate & 0xffff; + break; + case PPC_RELOC_LO14: ++ case PPC_RELOC_LO14_SECTDIFF: + immediate = (other_half << 16) | + (instruction & 0xfffc); + immediate += value; +@@ -991,14 +1013,28 @@ + "entry %lu in section (%.16s,%.16s) (displacement " + "not a multiple of 4 bytes)", i, + section_map->s->segname, section_map->s->sectname); +- if((immediate & 0xfffe0000) != 0xfffe0000 && +- (immediate & 0xfffe0000) != 0x00000000) ++ if((immediate & 0xffff8000) != 0xffff8000 && ++ (immediate & 0xffff8000) != 0x00000000) + error_with_cur_obj("relocation overflow for relocation " + "entry %lu in section (%.16s,%.16s) (displacement " + "too large)", i, section_map->s->segname, + section_map->s->sectname); + instruction = (instruction & 0xffff0003) | + (immediate & 0xfffc); ++ /* ++ * If this is a predicted branch conditional ++ * (r_length is 3) where the branch condition ++ * is not branch always and the sign of the ++ * displacement is different after relocation ++ * then flip the Y-bit to preserve the sense of ++ * the branch prediction. ++ */ ++ if(r_length == 3 && ++ (instruction & 0xfc000000) == 0x40000000 && ++ (instruction & 0x03e00000) != 0x02800000 && ++ (instruction & 0x00008000) != br14_disp_sign) ++ instruction ^= (1 << 21); ++ break; + break; + case PPC_RELOC_BR24: + immediate = instruction & 0x03fffffc; +@@ -1020,14 +1056,8 @@ + (immediate & 0x03fffffc); + break; + case PPC_RELOC_JBSR: +- if(r_extern){ +- value += offset; +- other_half = value; +- } +- else{ + value += other_half; + other_half = value; +- } + if(section_map->nfine_relocs == 0) + value += - (section_map->output_section->s.addr + + section_map->offset + r_address); +@@ -1036,7 +1066,8 @@ + fine_reloc_output_offset(section_map, + r_address)); + if(save_reloc == 0 && +- (filetype != MH_DYLIB || (r_extern == 1 && ++ ((filetype != MH_DYLIB || multi_module_dylib == FALSE) || ++ (r_extern == 1 && + (merged_symbol->nlist.n_type & N_PEXT) == N_PEXT)) && + (output_for_dyld == FALSE || r_extern == 0 || + (merged_symbol->nlist.n_type & N_TYPE) != N_UNDF) && +@@ -1087,18 +1118,19 @@ + * For external relocation entries that the symbol is + * defined (not undefined or common) but not when we are + * forcing an external relocation entry for a global +- * coalesced symbol and if the output file is not MH_DYLIB +- * or the symbol is a private extern it is changed to a +- * local relocation entry using the section that symbol is +- * defined in. If still undefined or forcing an external +- * relocation entry for a global coalesced symbol then the +- * index of the symbol in the output file is set into +- * r_symbolnum. ++ * coalesced symbol and if the output file is not a multi ++ * module MH_DYLIB or the symbol is a private extern, it is ++ * changed to a local relocation entry using the section ++ * that symbol is defined in. If still undefined or forcing ++ * an external relocation entry for a global coalesced ++ * symbol, then the index of the symbol in the output file ++ * is set into r_symbolnum. + */ + else if((merged_symbol->nlist.n_type & N_TYPE) != N_UNDF && + (merged_symbol->nlist.n_type & N_TYPE) != N_PBUD && + force_extern_reloc == FALSE && +- (filetype != MH_DYLIB || ++ ((filetype != MH_DYLIB || ++ multi_module_dylib == FALSE) || + (merged_symbol->nlist.n_type & N_PEXT) == N_PEXT)){ + reloc->r_extern = 0; + /* +@@ -1251,6 +1283,7 @@ + if(r_type == PPC_RELOC_SECTDIFF || + r_type == PPC_RELOC_HI16_SECTDIFF || + r_type == PPC_RELOC_LO16_SECTDIFF || ++ r_type == PPC_RELOC_LO14_SECTDIFF || + r_type == PPC_RELOC_HA16_SECTDIFF){ + /* + * For PPC_RELOC_SECTDIFF relocation entries (which +@@ -1269,6 +1302,7 @@ + pair_local_map->output_section->s.addr); + if(r_type == PPC_RELOC_HI16_SECTDIFF || + r_type == PPC_RELOC_LO16_SECTDIFF || ++ r_type == PPC_RELOC_LO14_SECTDIFF || + r_type == PPC_RELOC_HA16_SECTDIFF) + spair_reloc->r_address = other_half; + } +diff -ubr ld/rld.c ld/rld.c +--- ld/rld.c Tue Jan 14 23:35:25 2003 ++++ ld/rld.c Mon Aug 25 22:11:47 2003 +@@ -56,11 +56,13 @@ + #include "stuff/openstep_mach.h" + #include + #include +-#ifdef KLD ++//~ #ifdef KLD + #include +-#else /* !defined(KLD) */ ++#ifndef KLD ++//~ #else /* !defined(KLD) */ ++typedef void NXStream; + #include +-#include ++//~ #include + #include + #endif /* KLD */ + #include +@@ -104,6 +106,9 @@ + unsigned long (*address_func)(unsigned long size, unsigned long headers_size) = + NULL; + ++static ++enum strip_levels kld_requested_strip_level = STRIP_ALL; ++ + #if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) + /* + * The function pointer passed to moninitrld() to do profiling of rld loaded +@@ -198,12 +203,12 @@ + long base_size); + #endif /* !defined(SA_RLD) && !defined(KLD) */ + +-#if defined(KLD) && !defined(__STATIC__) ++#if defined(KLD) + static long internal_kld_load_basefile( + const char *base_filename, + char *base_addr, + long base_size); +-#endif /* defined(KLD) && !defined(__STATIC__) */ ++#endif /* defined(KLD) */ + + #if !defined(SA_RLD) && !defined(KLD) + /* +@@ -413,7 +418,7 @@ + if(output_filename != NULL) + strip_level = STRIP_NONE; + else +- strip_level = STRIP_ALL; ++ strip_level = kld_requested_strip_level; + + /* This must be cleared for each call to rld() */ + errors = 0; +@@ -522,7 +527,8 @@ + #if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) + if(file_name == NULL){ + for(i = 0; object_filenames[i] != NULL; i++) +- pass1((char *)object_filenames[i], FALSE, FALSE, FALSE, FALSE); ++ pass1((char *)object_filenames[i], FALSE, FALSE, FALSE, FALSE, ++ FALSE); + } + else + #endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */ +@@ -533,7 +539,7 @@ + cur_obj->user_obj_addr = TRUE; + cur_obj->obj_addr = (char *)obj_addr; + cur_obj->obj_size = obj_size; +- merge(FALSE, FALSE); ++ merge(FALSE, FALSE, FALSE); + } + + if(errors){ +@@ -612,7 +618,7 @@ + * Write the entire output file. + */ + if(write(fd, output_addr, output_size + symbol_size) != +- output_size + symbol_size){ ++ (int)(output_size + symbol_size)){ + system_error("can't write output file: %s",output_filename); + #ifdef KLD + internal_kld_unload(TRUE); +@@ -635,8 +641,14 @@ + * Deallocate the pages of memory for the symbol table if there are + * any whole pages. + */ ++ if (strip_level == STRIP_ALL) + deallocate_size = round(output_size + symbol_size, host_pagesize) - + round(output_size, host_pagesize); ++ else { ++ deallocate_size = 0; ++ sets[cur_set].output_size += symbol_size; ++ } ++ + if(deallocate_size > 0){ + if((r = vm_deallocate(mach_task_self(), + (vm_address_t)(output_addr + +@@ -777,18 +789,20 @@ + return(1); + } + +-#if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) ++#if !defined(SA_RLD) + /* + * rld_load_basefile() loads a base file from an object file rather than just + * picking up the link edit segment from this program. + */ + #if defined(KLD) ++#if !defined(__STATIC__) + long + kld_load_basefile( + const char *base_filename) + { + return(internal_kld_load_basefile(base_filename, NULL, 0)); + } ++#endif /* !defined(__STATIC__) */ + + long + kld_load_basefile_from_memory( +@@ -824,7 +838,8 @@ + char *base_addr, + long base_size) + { +- long size; ++#if !(defined(KLD) && defined(__STATIC__)) ++ unsigned long size; + char *addr; + int fd; + struct stat stat_buf; +@@ -834,13 +849,14 @@ + struct fat_header struct_fat_header; + #endif /* __LITTLE_ENDIAN__ */ + struct fat_arch *fat_archs, *best_fat_arch; +-#if !(defined(KLD) && defined(__STATIC__)) + struct arch_flag host_arch_flag; +-#endif /* !(defined(KLD) && defined(__STATIC__)) */ + enum bool from_fat_file; + + size = 0; + from_fat_file = FALSE; ++ ++#endif /* !(defined(KLD) && defined(__STATIC__)) */ ++ + #ifndef KLD + error_stream = stream; + #endif /* !defined(KLD) */ +@@ -898,6 +914,8 @@ + base_name = allocate(strlen(base_filename) + 1); + strcpy(base_name, base_filename); + ++#if !(defined(KLD) && defined(__STATIC__)) ++ + /* + * If there is to be an output file then save the symbols. Only the + * symbols from the current set will be placed in the output file. The +@@ -976,7 +994,7 @@ + #endif /* __LITTLE_ENDIAN__ */ + + if(sizeof(struct fat_header) + fat_header->nfat_arch * +- sizeof(struct fat_arch) > size){ ++ sizeof(struct fat_arch) > (unsigned long)size){ + error("fat file: %s truncated or malformed (fat_arch " + "structs would extend past the end of the file)", + base_name); +@@ -1042,7 +1060,9 @@ + base_obj = cur_obj; + } + } +- else{ ++ else ++#endif /* !(defined(KLD) && defined(__STATIC__)) */ ++ { + cur_obj = new_object_file(); + cur_obj->file_name = base_name; + cur_obj->obj_addr = base_addr; +@@ -1054,7 +1074,7 @@ + /* + * Now that the file is mapped in merge it as the base file. + */ +- merge(FALSE, FALSE); ++ merge(FALSE, FALSE, FALSE); + + if(errors){ + #ifdef KLD +@@ -1071,6 +1091,7 @@ + */ + clean_objects(); + clean_archives_and_fats(); ++#if !(defined(KLD) && defined(__STATIC__)) + if(from_fat_file == TRUE){ + if((r = vm_deallocate(mach_task_self(), (vm_address_t)addr, + (vm_size_t)size)) != KERN_SUCCESS) +@@ -1088,8 +1109,11 @@ + */ + rld_maintain_states = FALSE; + ++#endif /* !(defined(KLD) && defined(__STATIC__)) */ ++ + return(1); + ++#if !(defined(KLD) && defined(__STATIC__)) + rld_load_basefile_error_return: + if((r = vm_deallocate(mach_task_self(), (vm_address_t)addr, + (vm_size_t)size)) != KERN_SUCCESS) +@@ -1106,6 +1130,7 @@ + free(fat_archs); + #endif /* __LITTLE_ENDIAN__ */ + return(0); ++#endif /* !(defined(KLD) && defined(__STATIC__)) */ + } + + #ifndef KLD +@@ -1638,7 +1663,7 @@ + * Write the entire output file. + */ + if(write(fd, output_addr, output_size + symbol_size) != +- output_size + symbol_size){ ++ (int)(output_size + symbol_size)){ + system_error("can't write output file: %s",output_filename); + (void)unlink(output_filename); + return_value = 0; +@@ -1768,6 +1793,23 @@ + { + address_func = func; + } ++ ++/* ++ * kld_set_link_options() . ++ */ ++void ++#ifdef KLD ++kld_set_link_options( ++#else /* !defined(KLD) */ ++rld_set_link_options( ++#endif /* KLD */ ++unsigned long link_options) ++{ ++ if(KLD_STRIP_NONE & link_options) ++ kld_requested_strip_level = STRIP_NONE; ++ else ++ kld_requested_strip_level = STRIP_ALL; ++} + #endif /* !defined(SA_RLD) */ + + /* +@@ -1793,6 +1835,7 @@ + { + if(error_stream != NULL) + NXVPrintf(error_stream, format, ap); ++NXVPrintf(error_stream, format, ap); + } + #endif /* !defined(SA_RLD) && !defined(KLD) */ + +diff -ubr ld/sections.c ld/sections.c +--- ld/sections.c Tue Jan 14 23:35:25 2003 ++++ ld/sections.c Mon Aug 25 22:11:47 2003 +@@ -324,6 +324,13 @@ + error_with_cur_obj("literal section (%.16s,%.16s) " + "not allowed in I860 cputype objects", + ms->s.segname, ms->s.sectname); ++#ifdef KLD ++ /* ++ * For KLD the section's alignment from the base file is NOT ++ * picked up. ++ */ ++ if(cur_obj != base_obj) ++#endif /* KLD */ + if(s->align > ms->s.align) + ms->s.align = s->align; + if(dynamic != TRUE) +@@ -2724,16 +2731,16 @@ + /* + * It is an error if one of these types of merged sections + * has an external relocation entry and the output is a +- * dynamic library. As no library module will "own" it and +- * it will never get used by the dynamic linker and the +- * item relocated. ++ * multi module dynamic library. As in a multi module dylib ++ * no library module will "own" it and it will never get ++ * used by the dynamic linker and the item relocated. + */ + if(ms->nextrel != 0){ +- if(filetype == MH_DYLIB) ++ if(filetype == MH_DYLIB && multi_module_dylib == TRUE) + fatal("internal error: layout_relocs_for_dyld() " + "called with external relocation entries for " +- "merged section (%.16s,%.16s) for MH_DYLIB " +- "output", ms->s.segname, ms->s.sectname); ++ "merged section (%.16s,%.16s) for multi module " ++ "MH_DYLIB output", ms->s.segname, ms->s.sectname); + /* TODO: can this ever get here? even if not MH_DYLIB? */ + ms->iextrel = nextrel; + nextrel += ms->nextrel; +@@ -3036,18 +3043,19 @@ + /* + * The number of relocation entries in the output file is based on + * one of three different cases: +- * The output file is a dynamic shared library file ++ * The output file is a multi module dynamic shared library + * The output file has a dynamic linker load command + * The output does not have a dynamic linker load command + */ +- if(filetype == MH_DYLIB){ ++ if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ + /* +- * For dynamic shared library files all external relocations are +- * kept as external relocation entries except for references to +- * private externs (which are kept as locals) and all non- +- * position-independent local relocation entries are kept. +- * Modules of dylibs are not linked together and can only be +- * slid keeping all sections relative to each other the same. ++ * For multi module dynamic shared library files all external ++ * relocations are kept as external relocation entries except ++ * for references to private externs (which are kept as locals) ++ * and all non-position-independent local relocation entries ++ * are kept. Modules of multi module dylibs are not linked ++ * together and can only be slid keeping all sections relative ++ * to each other the same. + */ + if(r_extern && (merged_symbol->nlist.n_type & N_PEXT) == 0){ + (*nextrel) += 1 + pair; +@@ -3953,19 +3961,19 @@ + /* + * The relocation entries in the output file is based on one of + * three different cases: +- * The output file is a dynamic shared library file ++ * The output file is a multi module dynamic shared library + * The output file has a dynamic linker load command + * The output does not have a dynamic linker load command + */ +- if(filetype == MH_DYLIB){ ++ if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ + /* +- * For dynamic shared library files all external relocations are +- * kept as external relocation entries except for references to +- * private externs (which are have been turned into locals and +- * kept as locals) and all non-position-independent local +- * relocation entrie are kept. Modules of dylibs are not linked +- * together and can only be slid keeping all sections relative +- * to each other the same. ++ * For multi module dynamic shared library files all external ++ * relocations are kept as external relocation entries except ++ * for references to private externs (which are have been turned ++ * into locals and kept as locals) and all non-position- ++ * independent local relocation entrie are kept. Modules of ++ * multi module dylibs are not linked together and can only be ++ * slid keeping all sections relative to each other the same. + */ + if(r_extern){ + reloc->r_address += addr_adjust; +diff -ubr ld/sets.c ld/sets.c +--- ld/sets.c Tue Jan 14 23:35:25 2003 ++++ ld/sets.c Mon Aug 25 22:11:47 2003 +@@ -134,7 +134,7 @@ + clean_archives_and_fats(void) + { + #ifndef SA_RLD +- long i; ++ unsigned long i; + kern_return_t r; + char *file_addr, *file_name; + long file_size; +diff -ubr ld/sparc_reloc.c ld/sparc_reloc.c +--- ld/sparc_reloc.c Tue Jan 14 23:35:25 2003 ++++ ld/sparc_reloc.c Mon Aug 25 22:11:47 2003 +@@ -385,13 +385,13 @@ + /* + * If the symbol is undefined (or common) or a global coalesced + * symbol where we need to force an external relocation entry +- * and we are not prebinding no relocation is done. +- * Or if the output file is MH_DYLIB no relocation is done ++ * and we are not prebinding no relocation is done. Or if the ++ * output file is a multi module MH_DYLIB no relocation is done + * unless the symbol is a private extern or we are prebinding. + */ + if(((merged_symbol->nlist.n_type & N_TYPE) == N_UNDF) || + (force_extern_reloc == TRUE && prebinding == FALSE) || +- (filetype == MH_DYLIB && ++ ((filetype == MH_DYLIB && multi_module_dylib == TRUE) && + (((merged_symbol->nlist.n_type & N_PEXT) != N_PEXT) && + prebinding == FALSE) ) ) + value = 0; +@@ -915,18 +915,19 @@ + * For external relocation entries that the symbol is + * defined (not undefined or common) but not when we are + * forcing an external relocation entry for a global +- * coalesced symbol and if the output file is not MH_DYLIB +- * or the symbol is a private extern it is changed to a +- * local relocation entry using the section that symbol is +- * defined in. If still undefined or forcing an external +- * relocation entry for a global coalesced symbol then the +- * index of the symbol in the output file is set into +- * r_symbolnum. ++ * coalesced symbol and if the output file is not a multi ++ * module MH_DYLIB or the symbol is a private extern, it is ++ * changed to a local relocation entry using the section ++ * that symbol is defined in. If still undefined or forcing ++ * an external relocation entry for a global coalesced ++ * symbol, then the index of the symbol in the output file ++ * is set into r_symbolnum. + */ + else if((merged_symbol->nlist.n_type & N_TYPE) != N_UNDF && + (merged_symbol->nlist.n_type & N_TYPE) != N_PBUD && + force_extern_reloc == FALSE && +- (filetype != MH_DYLIB || ++ ((filetype != MH_DYLIB || ++ multi_module_dylib == FALSE) || + (merged_symbol->nlist.n_type & N_PEXT) == N_PEXT)){ + reloc->r_extern = 0; + /* +diff -ubr ld/symbols.c ld/symbols.c +--- ld/symbols.c Tue Jan 14 23:35:25 2003 ++++ ld/symbols.c Mon Aug 25 22:11:47 2003 +@@ -47,6 +47,9 @@ + #include "stuff/bool.h" + #include "stuff/bytesex.h" + #include "stuff/macosx_deployment_target.h" ++#ifndef RLD ++#include "stuff/symbol_list.h" ++#endif + + #include "ld.h" + #include "specs.h" +@@ -59,6 +62,7 @@ + #include "sets.h" + #include "hash_string.h" + #include "dylibs.h" ++#include "mod_sections.h" + + #ifdef RLD + __private_extern__ char *base_name; +@@ -77,6 +81,12 @@ + __private_extern__ unsigned long nmerged_symbols_referenced_only_from_dylibs =0; + + /* ++ * nstripped_merged_symbols is set to the number of merged symbol being stripped ++ * out when the strip_level is STRIP_DYNAMIC_EXECUTABLE. ++ */ ++__private_extern__ unsigned long nstripped_merged_symbols = 0; ++ ++/* + * This is set by lookup_symbol() and used by enter_symbol(). When a symbol + * is not found in the symbol_list by lookup_symbol() it returns a pointer + * to a hash_table entry in a merged_symbol_list. The merged_symbol_list that +@@ -205,6 +215,10 @@ + static struct object_file *link_edit_symbols_object = NULL; + static void setup_link_edit_symbols_object( + void); ++ ++static void exports_list_processing( ++ char *symbol_name, ++ struct nlist *symbol); + #endif /* !defined(RLD) */ + + /* +@@ -263,9 +277,6 @@ + #endif /* !defined(RLD) */ + + __private_extern__ +-#if defined(RLD) && !defined(__DYNAMIC__) +-const +-#endif + struct object_file link_edit_common_object = { + "\"link editor\"", /* file_name */ + 0, /* obj_addr */ +@@ -408,7 +419,7 @@ + + /* check the n_strx field of this symbol */ + if(symbol->n_un.n_strx < 0 || +- symbol->n_un.n_strx >= (long)(cur_obj->symtab->strsize)){ ++ (unsigned long)symbol->n_un.n_strx >= cur_obj->symtab->strsize){ + error_with_cur_obj("bad string table index (%ld) for symbol %lu", + symbol->n_un.n_strx, index); + return; +@@ -440,6 +451,8 @@ + ((struct mach_header *)(cur_obj->obj_addr))->filetype != + MH_BUNDLE) || + (library_ordinal != SELF_LIBRARY_ORDINAL && ++ (library_ordinal != DYNAMIC_LOOKUP_ORDINAL || ++ cur_obj->nload_dylibs != DYNAMIC_LOOKUP_ORDINAL) && + library_ordinal-1 >= cur_obj->nload_dylibs) ){ + error_with_cur_obj("undefined symbol %lu (%s) has bad " + "library oridinal %lu", index, +@@ -835,7 +848,9 @@ + cur_obj->symtab->symoff); + object_strings = (char *)(cur_obj->obj_addr + cur_obj->symtab->stroff); + if(cur_obj->swapped && +- ((struct mach_header *)cur_obj->obj_addr)->filetype != MH_DYLIB) ++ (((struct mach_header *)cur_obj->obj_addr)->filetype != MH_DYLIB || ++ ((struct mach_header *)cur_obj->obj_addr)->filetype != ++ MH_DYLIB_STUB)) + swap_nlist(object_symbols, cur_obj->symtab->nsyms, host_byte_sex); + + +@@ -867,6 +882,18 @@ + object_undefineds++; + /* TODO coalesce symbols may need to be accounted for depending on how they are + referenced */ ++#ifndef RLD ++ /* ++ * If we have an -export_symbols_list or -unexport_symbol_list ++ * option set the private extern bit on symbols that are not to ++ * be exported for global symbols that are not undefined. ++ */ ++ if((object_symbols[i].n_type & N_EXT) == N_EXT && ++ object_symbols[i].n_type != (N_EXT | N_UNDF)) ++ exports_list_processing(object_strings + ++ object_symbols[i].n_un.n_strx, ++ object_symbols + i); ++#endif /* !defined(RLD) */ + /* + * If this is a private external increment the count of + * private exterals for this object and the total in the +@@ -887,12 +914,12 @@ + + #ifndef RLD + /* +- * If the output file type is a dynamic shared library then count the +- * number of defined externals. And using this count, the count of +- * undefined symbols and the count of private externs the reference map, +- * to build the reference table, is allocated. ++ * If the output file type is a multi module dynamic shared library then ++ * count the number of defined externals. And using this count, the ++ * count of undefined symbols and the count of private externs then ++ * reference map, to build the reference table, is allocated. + */ +- if(filetype == MH_DYLIB){ ++ if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ + /* TODO coalesce symbols that are discarded need to be accounted for as + undefined references */ + for(i = 0; i < cur_obj->symtab->nsyms; i++){ +@@ -1205,11 +1232,12 @@ + } + #ifndef RLD + /* +- * If the output file is a MH_DYLIB type reset the +- * reference map for the merged external symbol that +- * is being discarded. ++ * If the output file is a multi module MH_DYLIB type ++ * reset the reference map for the merged external ++ * symbol that is being discarded. + */ + if(filetype == MH_DYLIB && ++ multi_module_dylib == TRUE && + merged_symbol->defined_in_dylib == FALSE){ + /* + * Discared coalesced symbols are referenced as +@@ -1292,9 +1320,24 @@ + printf("symbol: %s is coalesced\n", merged_symbol->nlist.n_un.n_name); + #endif + } +- else ++ else{ + multiply_defined(merged_symbol, &(object_symbols[i]), + object_strings); ++ if(allow_multiply_defined_symbols == TRUE){ ++ /* ++ * If this is a private external then decrement ++ * the previous incremented the count of private ++ * exterals for this object and the total in the ++ * output file since we are going to ignore this ++ * this multiply defined symbol. ++ */ ++ if((object_symbols[i].n_type & N_EXT) && ++ (object_symbols[i].n_type & N_PEXT)){ ++ cur_obj->nprivatesym--; ++ nmerged_private_symbols--; ++ } ++ } ++ } + } + /* + * If this symbol was undefined or a common in this object +@@ -1313,10 +1356,10 @@ + } + #ifndef RLD + /* +- * If the output file is a MH_DYLIB type set the reference map +- * for this external symbol. ++ * If the output file is a multi module MH_DYLIB type set the ++ * reference map for this external symbol. + */ +- if(filetype == MH_DYLIB){ ++ if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ + cur_obj->reference_maps[nrefsym].merged_symbol = + merged_symbol; + /* +@@ -1353,6 +1396,7 @@ + } + else if(strip_level != STRIP_DUP_INCLS && + is_output_local_symbol(object_symbols[i].n_type, ++ object_symbols[i].n_sect, cur_obj, + object_symbols[i].n_un.n_strx == 0 ? "" : + object_strings + object_symbols[i].n_un.n_strx)){ + cur_obj->nlocalsym++; +@@ -1427,6 +1471,10 @@ + localsym_block->index = i; + localsym_block->state = PARSE_SYMBOLS; + localsym_block->count = 1; ++ localsym_block->input_N_BINCL_n_value = ++ object_symbols[i].n_value; ++ if(localsym_block->input_N_BINCL_n_value != 0) ++ sum = localsym_block->input_N_BINCL_n_value; + + /* insert the first block in the list */ + localsym_block->next = *next_localsym_block; +@@ -1506,7 +1554,8 @@ + if((object_symbols[j].n_type & N_STAB) != 0){ + cur_localsym_block->count++; + +- if(object_symbols[j].n_un.n_strx != 0){ ++ if(localsym_block->input_N_BINCL_n_value == 0 && ++ object_symbols[j].n_un.n_strx != 0){ + stab_string = object_strings + + object_symbols[j].n_un.n_strx; + for( ; *stab_string != '\0'; stab_string++){ +@@ -1687,6 +1736,55 @@ + + #ifndef RLD + /* ++ * exports_list_processing() takes a symbol_name and a defined symbol from an ++ * object file and sets the private extern bit is it is not to be exported. And ++ * also marks the symbol in the list as seen. ++ */ ++static ++void ++exports_list_processing( ++char *symbol_name, ++struct nlist *symbol) ++{ ++ struct symbol_list *sp; ++ ++ if(save_symbols != NULL){ ++ sp = bsearch(symbol_name, save_symbols, nsave_symbols, ++ sizeof(struct symbol_list), ++ (int (*)(const void *, const void *)) ++ symbol_list_bsearch); ++ if(sp != NULL){ ++ sp->seen = TRUE; ++ } ++ else{ ++ if(symbol->n_desc & REFERENCED_DYNAMICALLY){ ++ warning("symbol: %s referenced dynamically and must be " ++ "exported", symbol_name); ++ } ++ else{ ++ symbol->n_type |= N_PEXT; ++ } ++ } ++ } ++ if(remove_symbols != NULL){ ++ sp = bsearch(symbol_name, remove_symbols, nremove_symbols, ++ sizeof(struct symbol_list), ++ (int (*)(const void *, const void *)) ++ symbol_list_bsearch); ++ if(sp != NULL){ ++ sp->seen = TRUE; ++ if(symbol->n_desc & REFERENCED_DYNAMICALLY){ ++ warning("symbol: %s referenced dynamically and must be " ++ "exported", symbol_name); ++ } ++ else{ ++ symbol->n_type |= N_PEXT; ++ } ++ } ++ } ++} ++ ++/* + * command_line_symbol() looks up a symbol name that comes from a command line + * argument (like -u symbol_name) and returns a pointer to the merged symbol + * table entry for it. If the symbol doesn't exist it enters an undefined +@@ -1725,7 +1823,7 @@ + */ + merged_symbol = enter_symbol(hash_pointer, &(undefined_symbol), + symbol_name, command_line_object); +- if(filetype == MH_DYLIB){ ++ if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ + command_line_object->reference_maps = + reallocate(command_line_object->reference_maps, + (command_line_object->nrefsym + 1) * +@@ -1910,7 +2008,7 @@ + } + merged_symbol->nlist.n_value = (unsigned long)merged_indr_symbol; + +- if(filetype == MH_DYLIB){ ++ if(filetype == MH_DYLIB && multi_module_dylib == TRUE){ + command_line_object->nextdefsym = 1; + command_line_object->reference_maps = + reallocate(command_line_object->reference_maps, +@@ -1951,7 +2049,7 @@ + struct nlist *symbols, *fake_trace_symbol; + struct dylib_reference *refs; + unsigned long flags; +- enum bool was_traced; ++ enum bool was_traced, resolve_flat; + struct merged_symbol **hash_pointer, *merged_symbol; + struct object_file *obj; + struct dylib_table_of_contents *toc; +@@ -2031,11 +2129,12 @@ + } + } + /* +- * If the output file is a MH_DYLIB type reset the +- * reference map for the merged external symbol that ++ * If the output file is a multi module MH_DYLIB type reset ++ * the reference map for the merged external symbol that + * is being discarded. + */ + if(filetype == MH_DYLIB && ++ multi_module_dylib == TRUE && + merged_symbol->defined_in_dylib == FALSE){ + /* + * Discared coalesced symbols are referenced as +@@ -2208,6 +2307,13 @@ + merged_symbol->defined_in_dylib = TRUE; + merged_symbol->definition_library = dynamic_library; + /* ++ * If this shared library is being forced to be weak linked then ++ * set N_WEAK_REF to make this symbol a weak reference. ++ */ ++ if(dynamic_library->force_weak_dylib && ++ merged_symbol->referenced_in_non_dylib == TRUE) ++ merged_symbol->nlist.n_desc |= N_WEAK_REF; ++ /* + * If the merged symbol we are resolving is not a weak reference + * and it is referenced from a non-dylib then set + * some_non_weak_refs to TRUE. +@@ -2215,6 +2321,7 @@ + if((merged_symbol->nlist.n_desc & N_WEAK_REF) == 0 && + merged_symbol->referenced_in_non_dylib == TRUE) + dynamic_library->some_non_weak_refs = TRUE; ++ if(merged_symbol->referenced_in_non_dylib == TRUE) + dynamic_library->some_symbols_referenced = TRUE; + if((symbols[j].n_type & N_TYPE) == N_INDR){ + merged_symbol->nlist.n_type = N_INDR | N_EXT; +@@ -2295,7 +2402,8 @@ + print_obj_name(cur_obj); + library_ordinal = GET_LIBRARY_ORDINAL(symbols[ + refs[j].isym].n_desc); +- if(library_ordinal != 0){ ++ if(library_ordinal != 0 && ++ library_ordinal != DYNAMIC_LOOKUP_ORDINAL){ + dep = dynamic_library->dependent_images[ + library_ordinal - 1]; + if(dep->umbrella_name != NULL) +@@ -2316,13 +2424,32 @@ + } + } + /* +- * If -force_flat_namespace is TRUE or this dylib is not a +- * two-level namespace dylib then use flat semantics to resolve +- * the undefined symbols from this dylib module. ++ * Determine how this reference will be resolved. If ++ * -force_flat_namespace is TRUE it will be resolved flat. ++ * If this dylib is not a two-level namespace dylib it will ++ * also be resolved flat. It it is a two-level dylib then ++ * if the library_ordinal is DYNAMIC_LOOKUP_ORDINAL it will be ++ * resolved flat. If it is a two-level namespace dylib and ++ * the library_ordinal is not DYNAMIC_LOOKUP_ORDINAL it will ++ * be resolved with two-level namespace semantics. + */ +- if(force_flat_namespace == TRUE || +- (((struct mach_header *)(cur_obj->obj_addr))->flags & +- MH_TWOLEVEL) != MH_TWOLEVEL){ ++ if(force_flat_namespace == TRUE) ++ resolve_flat = TRUE; ++ else{ ++ if((((struct mach_header *)(cur_obj->obj_addr))-> ++ flags & MH_TWOLEVEL) == MH_TWOLEVEL){ ++ library_ordinal = GET_LIBRARY_ORDINAL( ++ symbols[refs[j].isym].n_desc); ++ if(library_ordinal == DYNAMIC_LOOKUP_ORDINAL) ++ resolve_flat = TRUE; ++ else ++ resolve_flat = FALSE; ++ } ++ else{ ++ resolve_flat = TRUE; ++ } ++ } ++ if(resolve_flat == TRUE){ + /* lookup the symbol and see if it has already been seen */ + hash_pointer = lookup_symbol(symbol_name); + if(*hash_pointer == NULL){ +@@ -2505,11 +2632,12 @@ + } + } + /* +- * If the output file is a MH_DYLIB type reset the +- * reference map for the merged external symbol that ++ * If the output file is a multi module MH_DYLIB type reset ++ * the reference map for the merged external symbol that + * is being discarded. + */ + if(filetype == MH_DYLIB && ++ multi_module_dylib == TRUE && + merged_symbol->defined_in_dylib == FALSE){ + /* + * Discared coalesced symbols are referenced as +@@ -2686,13 +2814,17 @@ + + /* + * is_output_local_symbol() returns TRUE or FALSE depending if the local symbol +- * type and name passed to it will be in the output file's symbol table based +- * on the level of symbol stripping. ++ * type, section, object and name passed to it will be in the output file's ++ * symbol table based on the level of symbol stripping. The obj passed must be ++ * be the object this symbol came from so that the the section can be checked ++ * for the S_ATTR_STRIP_STATIC_SYMS attribute flag. + */ + __private_extern__ + enum bool + is_output_local_symbol( + unsigned char n_type, ++unsigned char n_sect, ++struct object_file *obj, + char *symbol_name) + { + switch(strip_level){ +@@ -2700,14 +2832,15 @@ + case STRIP_DUP_INCLS: + return(TRUE); + case STRIP_ALL: +- return(FALSE); ++ case STRIP_DYNAMIC_EXECUTABLE: + case STRIP_NONGLOBALS: +- if(n_type & N_PEXT) +- return(TRUE); + return(FALSE); + case STRIP_DEBUG: + if(n_type & N_STAB || +- (*symbol_name == 'L' && (n_type & N_STAB) == 0)) ++ (*symbol_name == 'L' && (n_type & N_STAB) == 0) || ++ ((n_type & N_TYPE) == N_SECT && ++ (obj->section_maps[n_sect - 1].s->flags & ++ S_ATTR_STRIP_STATIC_SYMS) == S_ATTR_STRIP_STATIC_SYMS)) + return(FALSE); + else + return(TRUE); +@@ -3340,13 +3473,12 @@ + error("common symbols not allowed with MH_FVMLIB " + "output format"); + /* +- * If the output format is MH_DYLIB then commons are not +- * allowed because each symbol can only be defined in at +- * most one module. ++ * If the output format is multi module MH_DYLIB then * commons are not allowed because each symbol can only be ++ * defined in at most one module. + */ +- if(filetype == MH_DYLIB) ++ if(filetype == MH_DYLIB && multi_module_dylib == TRUE) + error("common symbols not allowed with MH_DYLIB " +- "output format"); ++ "output format with the -multi_module option"); + commons_exist = TRUE; + #ifndef RLD + if(sect_spec != NULL && sect_spec->order_filename != NULL){ +@@ -3461,7 +3593,8 @@ + * formats so trace each one. An error message for this + * has been printed above. + */ +- if(filetype == MH_FVMLIB || filetype == MH_DYLIB) ++ if(filetype == MH_FVMLIB || ++ (filetype == MH_DYLIB && multi_module_dylib == TRUE)) + trace_merged_symbol(merged_symbol); + /* determine the alignment of this symbol */ + common_size = merged_symbol->nlist.n_value; +@@ -3497,6 +3630,22 @@ + &link_edit_common_object; + /* Create the space for this symbol */ + link_edit_common_section.size += common_size; ++ /* ++ * If we have an -export_symbols_list or ++ * -unexport_symbol_list option set the private extern bit ++ * on the symbol if it is not to be exported. ++ */ ++ exports_list_processing(merged_symbol->nlist.n_un.n_name, ++ &(merged_symbol->nlist)); ++ /* ++ * If this common symbol got made into a private extern with ++ * the processing of the exports list increment the count of ++ * private exterals. ++ */ ++ if((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT){ ++ link_edit_common_object.nprivatesym++; ++ nmerged_private_symbols++; ++ } + #endif /* RLD */ + /* + * Do the trace of this symbol if specified now that it has +@@ -3557,6 +3706,58 @@ + } + + #ifndef RLD ++/* ++ * define_undefined_symbols_a_way() is called to setup defining all remaining ++ * undefined symbols as private externs. Their final value gets set by ++ * define_link_editor_dylib_symbols(). ++ */ ++__private_extern__ ++void ++define_undefined_symbols_a_way( ++void) ++{ ++ unsigned long i; ++ struct merged_symbol_list **p, *merged_symbol_list; ++ struct merged_symbol *merged_symbol; ++ ++ for(p = &merged_symbol_lists; *p; p = &(merged_symbol_list->next)){ ++ merged_symbol_list = *p; ++ for(i = 0; i < merged_symbol_list->used; i++){ ++ merged_symbol = &(merged_symbol_list->merged_symbols[i]); ++ if(merged_symbol->nlist.n_type == (N_EXT | N_UNDF) && ++ merged_symbol->nlist.n_value == 0){ ++ if(dynamic == TRUE && ++ filetype != MH_EXECUTE && ++ merged_segments != NULL){ ++ define_link_editor_symbol( ++ merged_symbol->nlist.n_un.n_name, ++ N_SECT | N_PEXT | N_EXT, /* n_type */ ++ 1, /* n_sect */ ++ 0, /* n_desc */ ++ 0); /* n_value */ ++ } ++ else{ ++ define_link_editor_symbol( ++ merged_symbol->nlist.n_un.n_name, ++ N_ABS | N_PEXT | N_EXT, /* n_type */ ++ NO_SECT, /* n_sect */ ++ 0, /* n_desc */ ++ 0); /* n_value */ ++ } ++ /* ++ * This symbol got made into a private extern so increment ++ * the count of private exterals. ++ */ ++ if((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT){ ++ link_edit_symbols_object->nprivatesym++; ++ nmerged_private_symbols++; ++ } ++ merged_symbol->define_a_way = 1; ++ } ++ } ++ } ++} ++ + static + void + setup_link_edit_symbols_object( +@@ -3741,6 +3942,8 @@ + { + char *symbol_name; + struct merged_symbol *merged_symbol; ++ struct merged_symbol_list **p, *merged_symbol_list; ++ unsigned long i; + + if(filetype == MH_BUNDLE) + symbol_name = _MH_BUNDLE_SYM; +@@ -3762,6 +3965,24 @@ + else + merged_symbol->nlist.n_value = header_address - + link_edit_symbols_object->section_maps[0].output_section->s.addr; ++ ++ /* set the correct values of the undefined symbols defined a way */ ++ if(undefined_flag == UNDEFINED_DEFINE_A_WAY){ ++ for(p = &merged_symbol_lists; *p; p = &(merged_symbol_list->next)){ ++ merged_symbol_list = *p; ++ for(i = 0; i < merged_symbol_list->used; i++){ ++ merged_symbol = &(merged_symbol_list->merged_symbols[i]); ++ if(merged_symbol->define_a_way == 1){ ++ if(merged_symbol->nlist.n_sect == NO_SECT) ++ merged_symbol->nlist.n_value = header_address; ++ else ++ merged_symbol->nlist.n_value = header_address - ++ link_edit_symbols_object->section_maps[0]. ++ output_section->s.addr; ++ } ++ } ++ } ++ } + } + #endif /* !defined(RLD) */ + +@@ -3942,6 +4163,16 @@ + merged_symbol->nlist.n_value = value; + merged_symbol->definition_object = link_edit_symbols_object; + ++#ifndef RLD ++ /* ++ * If we have an -export_symbols_list or ++ * -unexport_symbol_list option set the private extern bit ++ * on the symbol if it is not to be exported. ++ */ ++ exports_list_processing(merged_symbol->nlist.n_un.n_name, ++ &(merged_symbol->nlist)); ++#endif ++ + /* + * Do the trace of this symbol if specified now that it has + * been defined. +@@ -4057,6 +4288,16 @@ + for(j = 0; j < indr_depth; j++){ + indr_symbols[j]->nlist.n_value = + (unsigned long)indr_symbol; ++ /* ++ * If this indirect symbol is pointing to a ++ * private extern then increment the count of ++ * private exterals. ++ */ ++ if((indr_symbol->nlist.n_type & N_PEXT) == N_PEXT){ ++ indr_symbols[j]->definition_object-> ++ nprivatesym++; ++ nmerged_private_symbols++; ++ } + } + } + } +@@ -4142,6 +4383,7 @@ + object_symbols[i].n_sect == nsect && + (strip_level == STRIP_NONE || + is_output_local_symbol(object_symbols[i].n_type, ++ object_symbols[i].n_sect, cur_obj, + object_symbols[i].n_un.n_strx == 0 ? "" : + object_strings + + object_symbols[i].n_un.n_strx))){ +@@ -4383,6 +4625,7 @@ + if((object_symbols[i].n_type & N_EXT) == 0 && + (strip_level == STRIP_NONE || strip_level == STRIP_DUP_INCLS || + is_output_local_symbol(object_symbols[i].n_type, ++ object_symbols[i].n_sect, cur_obj, + object_symbols[i].n_un.n_strx == 0 ? "" : + object_strings + object_symbols[i].n_un.n_strx))){ + +@@ -4433,11 +4676,11 @@ + cur_obj->symtab->strsize); + output_symtab_info.output_local_strsize += cur_obj->symtab->strsize; + } +-#ifndef RLD + if(host_byte_sex != target_byte_sex){ + nlist = (struct nlist *)(output_addr + flush_symbol_offset); + swap_nlist(nlist, output_nsyms, target_byte_sex); + } ++#ifndef RLD + output_flush(flush_symbol_offset, output_nsyms * sizeof(struct nlist)); + output_flush(flush_string_offset, output_symtab_info. + output_local_strsize - +@@ -4503,6 +4746,7 @@ + if((object_symbols[i].n_type & N_EXT) == 0 && + (strip_level == STRIP_NONE || + is_output_local_symbol(object_symbols[i].n_type, ++ object_symbols[i].n_sect, obj, + object_symbols[i].n_un.n_strx == 0 ? "" : + object_strings + object_symbols[i].n_un.n_strx))){ + +@@ -4609,6 +4853,7 @@ + if(indr_symbol->nlist.n_type != (N_EXT | N_UNDF) && + indr_symbol->nlist.n_type != (N_EXT | N_PBUD) && + (filetype != MH_DYLIB || ++ (filetype == MH_DYLIB && multi_module_dylib == FALSE) || + merged_symbol->definition_object == + indr_symbol->definition_object)){ + merged_symbol->nlist.n_type = indr_symbol->nlist.n_type; +@@ -4640,7 +4885,10 @@ + * the output file is the private externs if they are not to be kept + * (that is they are to be made static and not kept as global symbols). + */ +- if(nmerged_private_symbols != 0 && keep_private_externs == FALSE){ ++ if(nmerged_private_symbols != 0 && ++ keep_private_externs == FALSE && ++ (strip_level != STRIP_NONGLOBALS || ++ (filetype == MH_DYLIB && multi_module_dylib == TRUE)) ){ + for(p = &merged_symbol_lists; *p; p = &(merged_symbol_list->next)){ + merged_symbol_list = *p; + for(i = 0; i < merged_symbol_list->used; i++){ +@@ -4654,6 +4902,11 @@ + if(merged_symbol->definition_object->set_num != cur_set) + continue; + #endif /* RLD */ ++ if(strip_level == STRIP_DYNAMIC_EXECUTABLE && ++ (merged_symbol->nlist.n_desc & REFERENCED_DYNAMICALLY) != ++ REFERENCED_DYNAMICALLY) ++ continue; ++ + if(merged_symbol->nlist.n_type & N_PEXT){ + /* + * Place this symbol with the local symbols for the +@@ -5020,7 +5273,8 @@ + if(allowed_undef == FALSE) + noundefs = FALSE; + if(save_reloc == FALSE && +- undefined_flag != UNDEFINED_SUPPRESS){ ++ (undefined_flag == UNDEFINED_ERROR || ++ undefined_flag == UNDEFINED_WARNING)){ + if(allowed_undef == FALSE || prebound_undef == TRUE){ + if(printed_undef == FALSE){ + if(undefined_flag == UNDEFINED_WARNING) +@@ -5047,6 +5301,12 @@ + print("%s\n", merged_symbol->nlist.n_un.n_name); + } + } ++ else if(save_reloc == FALSE && ++ undefined_flag == UNDEFINED_DYNAMIC_LOOKUP && ++ twolevel_namespace == TRUE){ ++ SET_LIBRARY_ORDINAL(merged_symbol->nlist.n_desc, ++ DYNAMIC_LOOKUP_ORDINAL); ++ } + } + #ifndef RLD + else { +@@ -5177,6 +5437,8 @@ + } + + #ifndef RLD ++ lib = NULL; ++ prev_lib = NULL; + /* + * There can be two-level references left on the undefined list. These + * are "fake" merged symbols as they are not entered in the symbol +@@ -5198,6 +5460,18 @@ + undefined->merged_symbol->nlist.n_desc); + if(library_ordinal == SELF_LIBRARY_ORDINAL) + lib = undefined->merged_symbol->referencing_library; ++ /* ++ * Note that if library_ordinal was DYNAMIC_LOOKUP_ORDINAL then ++ * merge_dylib_module_symbols() in symbols.c would not have ++ * set the twolevel_reference field to TRUE in the merged_symbol ++ * and if we get here it with this it is an internal error. ++ */ ++ else if(library_ordinal == DYNAMIC_LOOKUP_ORDINAL) ++ fatal("internal error: process_undefineds() 1 with a " ++ "merged_symbol (%s) on the undefined list with " ++ "twolevel_reference == TRUE and library_ordinal == " ++ "DYNAMIC_LOOKUP_ORDINAL", undefined->merged_symbol-> ++ nlist.n_un.n_name); + else + lib = undefined->merged_symbol->referencing_library-> + dependent_images[library_ordinal - 1]; +@@ -5205,10 +5479,25 @@ + for(prevs = undefined_list.next; + prevs != undefined; + prevs = prevs->next){ ++ if(prevs->merged_symbol->twolevel_reference == FALSE) ++ continue; + library_ordinal = GET_LIBRARY_ORDINAL( + prevs->merged_symbol->nlist.n_desc); + if(library_ordinal == SELF_LIBRARY_ORDINAL) + prev_lib = prevs->merged_symbol->referencing_library; ++ /* ++ * Note that if library_ordinal was DYNAMIC_LOOKUP_ORDINAL ++ * then merge_dylib_module_symbols() in symbols.c would not ++ * have set the twolevel_reference field to TRUE in the ++ * merged_symbol and if we get here it with this it is an ++ * internal error. ++ */ ++ else if(library_ordinal == DYNAMIC_LOOKUP_ORDINAL) ++ fatal("internal error: process_undefineds() 2 with a " ++ "merged_symbol (%s) on the undefined list with " ++ "twolevel_reference == TRUE and library_ordinal " ++ "== DYNAMIC_LOOKUP_ORDINAL", ++ prevs->merged_symbol->nlist.n_un.n_name); + else + prev_lib = prevs->merged_symbol->referencing_library-> + dependent_images[library_ordinal - 1]; +@@ -5277,9 +5566,10 @@ + "weak " : "", + merged_symbol->nlist.n_un.n_name); + #ifndef RLD +- if(merged_symbol->twolevel_reference == TRUE){ + library_ordinal = GET_LIBRARY_ORDINAL( + merged_symbol->nlist.n_desc); ++ if(merged_symbol->twolevel_reference == TRUE && ++ library_ordinal != DYNAMIC_LOOKUP_ORDINAL){ + if(library_ordinal == SELF_LIBRARY_ORDINAL) + lib = merged_symbol->referencing_library; + else +@@ -5419,13 +5709,54 @@ + assign_output_symbol_indexes( + void) + { +- unsigned long index, i, nextdefsym, nundefsym; ++ unsigned long index, i, nextdefsym, nundefsym, n_pext; + struct merged_symbol_list **p, *merged_symbol_list; +- struct merged_symbol *merged_symbol; ++ struct merged_symbol *merged_symbol, *indr_symbol; + struct object_list *object_list, **q; ++ struct object_file *last_object; ++ enum bool rebuild_merged_string_table; + +- if(strip_level == STRIP_ALL) ++ rebuild_merged_string_table = FALSE; ++ if(strip_level == STRIP_ALL){ ++ if(has_dynamic_linker_command){ ++ strip_level = STRIP_DYNAMIC_EXECUTABLE; ++ /* ++ * In order to not put out strings for merged symbols that will ++ * be discared we need to rebuild the merged string table for ++ * only the symbols not stripped. ++ */ ++ merged_string_blocks = NULL; ++ merged_string_size = 0; ++ rebuild_merged_string_table = TRUE; ++ } ++ else{ ++ seglinkedit = FALSE; + return; ++ } ++ } ++ /* ++ * If we are stripping non-globals and we are not keeping private ++ * externs and we have some private externs in the merged symbol table, ++ * and the output is not a multi-module dylib, then in order to not put ++ * out strings for them we also need to rebuild the merged string table ++ * without these symbols. ++ */ ++ else if(strip_level == STRIP_NONGLOBALS && ++ keep_private_externs == FALSE && ++ nmerged_private_symbols != 0 && ++ (filetype != MH_DYLIB || multi_module_dylib == FALSE)){ ++ merged_string_blocks = NULL; ++ merged_string_size = 0; ++ rebuild_merged_string_table = TRUE; ++ } ++ ++ /* ++ * Add a copy of the object file for the common symbols that the link ++ * editor allocated into the object file list. Since it is possible ++ * that some of the common symbols are not on the export list they could ++ * have been made into private externs. ++ */ ++ last_object = add_last_object_file(&link_edit_common_object); + + /* + * Private exterals are always kept when any symbols are kept. The +@@ -5467,7 +5798,12 @@ + if(keep_private_externs == FALSE){ + cur_obj->iprivatesym = index; + cur_obj->cprivatesym = index; ++ if(strip_level != STRIP_DYNAMIC_EXECUTABLE && ++ (strip_level != STRIP_NONGLOBALS || ++ (filetype == MH_DYLIB && multi_module_dylib == TRUE))) + index += cur_obj->nprivatesym; ++ else ++ nstripped_merged_symbols += cur_obj->nprivatesym; + } + } + } +@@ -5476,12 +5812,21 @@ + */ + if((keep_private_externs == TRUE && index != nlocal_symbols) || + (keep_private_externs == FALSE && index != nlocal_symbols + +- nmerged_private_symbols)) ++ nmerged_private_symbols - nstripped_merged_symbols)) + fatal("internal error: assign_output_symbol_indexes() " + "inconsistent local symbol counts"); + output_dysymtab_info.dysymtab_command.nlocalsym = index; + + /* ++ * Copy the values that got set in the above loop back into the ++ * object file for the the common symbols. Then remove the copy of ++ * the object file from the object file list. ++ */ ++ link_edit_common_object = *last_object; ++ remove_last_object_file(last_object); ++ ++ ++ /* + * Count the number of undefined symbols and defined external symbols. + * Private exterals are counted as defined externals if + * keep_private_externs is TRUE. +@@ -5504,11 +5849,36 @@ + if(merged_symbol->nlist.n_type == (N_EXT | N_UNDF) || + merged_symbol->nlist.n_type == (N_EXT | N_PBUD) || + (merged_symbol->nlist.n_type == (N_EXT | N_INDR) && +- merged_symbol->defined_in_dylib == TRUE)) ++ merged_symbol->defined_in_dylib == TRUE)){ + nundefsym++; +- else if(keep_private_externs == TRUE || +- (merged_symbol->nlist.n_type & N_PEXT) == 0) ++ if(rebuild_merged_string_table == TRUE) ++ merged_symbol->nlist.n_un.n_name = ++ enter_string(merged_symbol->nlist.n_un.n_name); ++ } ++ else{ ++ if(merged_symbol->nlist.n_type == (N_EXT | N_INDR)){ ++ indr_symbol = (struct merged_symbol *) ++ (merged_symbol->nlist.n_value); ++ n_pext = indr_symbol->nlist.n_type & N_PEXT; ++ } ++ else{ ++ n_pext = merged_symbol->nlist.n_type & N_PEXT; ++ } ++ if(keep_private_externs == TRUE || n_pext == 0){ ++ if(strip_level != STRIP_DYNAMIC_EXECUTABLE || ++ (merged_symbol->nlist.n_desc & ++ REFERENCED_DYNAMICALLY) == REFERENCED_DYNAMICALLY){ + nextdefsym++; ++ if(rebuild_merged_string_table == TRUE) ++ merged_symbol->nlist.n_un.n_name = ++ enter_string(merged_symbol-> ++ nlist.n_un.n_name); ++ } ++ else{ ++ nstripped_merged_symbols++; ++ } ++ } ++ } + } + } + +@@ -5543,11 +5913,25 @@ + (merged_symbol->nlist.n_type == (N_EXT | N_INDR) && + merged_symbol->defined_in_dylib == TRUE)) + undefsyms_order[nundefsym++] = merged_symbol; +- else if(keep_private_externs == TRUE || +- (merged_symbol->nlist.n_type & N_PEXT) == 0) ++ else{ ++ if(merged_symbol->nlist.n_type == (N_EXT | N_INDR)){ ++ indr_symbol = (struct merged_symbol *) ++ (merged_symbol->nlist.n_value); ++ n_pext = indr_symbol->nlist.n_type & N_PEXT; ++ } ++ else{ ++ n_pext = merged_symbol->nlist.n_type & N_PEXT; ++ } ++ if(keep_private_externs == TRUE || n_pext == 0){ ++ if(strip_level != STRIP_DYNAMIC_EXECUTABLE || ++ (merged_symbol->nlist.n_desc & ++ REFERENCED_DYNAMICALLY) == REFERENCED_DYNAMICALLY){ + extdefsyms_order[nextdefsym++] = merged_symbol; + } + } ++ } ++ } ++ } + #ifndef SA_RLD + /* + * Sort the defined symbols by module for MH_DYLIB formats and by +@@ -5688,6 +6072,12 @@ + + #ifndef RLD + /* ++ * This is a pointer to the module name saved in the merged string table for ++ * the one module table entry for a single module dylib. ++ */ ++char *dylib_single_module_name; ++ ++/* + * layout_dylib_tables() sizes and readys the tables for a dynamic library file. + * The merged symbol indexes have already been assigned before this is called. + * There are three tables: +@@ -5705,10 +6095,12 @@ + struct object_list *object_list, **q; + char *p; + ++ if(multi_module_dylib == TRUE){ + /* +- * The reference table was sized as the symbols were merged. All that +- * is left to do for the reference table is to adjust the flags for +- * undefined references that ended up referencing private externs. ++ * For multi module dylibs the reference table was sized as the ++ * symbols were merged. All that is left to do for the reference ++ * table is to adjust the flags for undefined references that ended ++ * up referencing private externs. + */ + for(q = &objects; *q; q = &(object_list->next)){ + object_list = *q; +@@ -5721,7 +6113,8 @@ + if(cur_obj->dylinker) + continue; + for(j = 0; j < cur_obj->nrefsym; j++){ +- merged_symbol = cur_obj->reference_maps[j].merged_symbol; ++ merged_symbol = ++ cur_obj->reference_maps[j].merged_symbol; + if(merged_symbol->nlist.n_type & N_PEXT){ + flags = cur_obj->reference_maps[j].flags; + if(flags == REFERENCE_FLAG_UNDEFINED_NON_LAZY) +@@ -5735,27 +6128,43 @@ + /* + * The merged symbol is not a private extern. So it + * might be a non-weak symbol that is being used and +- * some weak private externs refs were discarded. If +- * so we need to make the refs non-weak. ++ * some weak private externs refs were discarded. ++ * If so we need to make the refs non-weak. + */ + flags = cur_obj->reference_maps[j].flags; +- if(flags == REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY) ++ if(flags == ++ REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY) + cur_obj->reference_maps[j].flags = + REFERENCE_FLAG_UNDEFINED_NON_LAZY; +- else if(flags == REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY) ++ else if(flags == ++ REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY) + cur_obj->reference_maps[j].flags = + REFERENCE_FLAG_UNDEFINED_LAZY; + } + } + } + } +- ++ } ++ else{ + /* +- * The module table is sized from the number of modules loaded. The +- * module_name of each module in the dynamic shared library is set from +- * base name or archive member name of the object loaded. The string +- * for the module_name is then saved with the merged strings so that it +- * can be converted to a string table index on output. ++ * For single module dylibs the reference table size is reset here ++ * from the defined and undefined merged symbols. The contents of ++ * the reference table for single module dylibs will be filled in ++ * output_dylib_tables() from the merged symbol table. ++ */ ++ output_dysymtab_info.dysymtab_command.nextrefsyms = ++ output_dysymtab_info.dysymtab_command.nextdefsym + ++ output_dysymtab_info.dysymtab_command.nundefsym; ++ } ++ ++ if(multi_module_dylib == TRUE){ ++ /* ++ * For multi module dylibs the module table is sized from the number ++ * of modules loaded. The module_name of each module in the dynamic ++ * shared library is set from base name or archive member name of ++ * the object loaded. The string for the module_name is then saved ++ * with the merged strings so that it can be converted to a string ++ * table index on output. + */ + output_dysymtab_info.dysymtab_command.nmodtab = 0; + for(q = &objects; *q; q = &(object_list->next)){ +@@ -5786,6 +6195,17 @@ + } + } + } ++ } ++ else{ ++ /* ++ * For single module dylibs there is one module table entry. ++ * The module_name is set to "single module". The string for the ++ * module_name is then saved with the merged strings so that it can ++ * be converted to a string table index on output. ++ */ ++ output_dysymtab_info.dysymtab_command.nmodtab = 1; ++ dylib_single_module_name = enter_string("single module"); ++ } + + /* + * The table of contents is sized from the number of defined external +@@ -5815,6 +6235,7 @@ + struct merged_symbol_list **p, *merged_symbol_list; + struct merged_symbol *merged_symbol; + struct dylib_table_of_contents *tocs, *toc; ++ struct merged_section *ms; + + /* + * Output the reference table. +@@ -5822,6 +6243,11 @@ + flush_offset = output_dysymtab_info.dysymtab_command.extrefsymoff; + refs = (struct dylib_reference *)(output_addr + flush_offset); + ref = refs; ++ if(multi_module_dylib == TRUE){ ++ /* ++ * For multi module dylibs there is a reference table for each ++ * object loaded built from the reference_maps. ++ */ + for(q = &objects; *q; q = &(object_list->next)){ + object_list = *q; + for(i = 0; i < object_list->used; i++){ +@@ -5840,6 +6266,35 @@ + } + } + } ++ } ++ else{ ++ /* ++ * For single module dylibs there is one reference table and it is ++ * built from the merged symbol table. ++ */ ++ for(p = &merged_symbol_lists; *p; p = &(merged_symbol_list->next)){ ++ merged_symbol_list = *p; ++ for(i = 0; i < merged_symbol_list->used; i++){ ++ merged_symbol = &(merged_symbol_list->merged_symbols[i]); ++ if(merged_symbol->referenced_in_non_dylib == FALSE) ++ continue; ++ if(merged_symbol->nlist.n_type == (N_EXT | N_UNDF) || ++ merged_symbol->nlist.n_type == (N_EXT | N_PBUD) || ++ (merged_symbol->nlist.n_type == (N_EXT | N_INDR) && ++ merged_symbol->defined_in_dylib == TRUE)){ ++ ref->isym = merged_symbol_output_index(merged_symbol); ++ ref->flags = merged_symbol->nlist.n_desc & ++ REFERENCE_TYPE; ++ ref++; ++ } ++ else if((merged_symbol->nlist.n_type & N_PEXT) == 0){ ++ ref->isym = merged_symbol_output_index(merged_symbol); ++ ref->flags = REFERENCE_FLAG_DEFINED; ++ ref++; ++ } ++ } ++ } ++ } + if(host_byte_sex != target_byte_sex){ + swap_dylib_reference(refs, + output_dysymtab_info.dysymtab_command.nextrefsyms, +@@ -5855,6 +6310,11 @@ + flush_offset = output_dysymtab_info.dysymtab_command.modtaboff; + mods = (struct dylib_module *)(output_addr + flush_offset); + mod = mods; ++ if(multi_module_dylib == TRUE){ ++ /* ++ * For multi module dylibs there is a module table for each ++ * object loaded built from the info saved in the object struct. ++ */ + for(q = &objects; *q; q = &(object_list->next)){ + object_list = *q; + for(i = 0; i < object_list->used; i++){ +@@ -5873,7 +6333,7 @@ + mod->nlocalsym = cur_obj->nlocalsym + cur_obj->nprivatesym; + mod->iextrel = cur_obj->iextrel; + mod->nextrel = cur_obj->nextrel; +- mod->iinit_iterm = (cur_obj->iterm << 16) | cur_obj->iinit ; ++ mod->iinit_iterm = (cur_obj->iterm << 16) | cur_obj->iinit; + mod->ninit_nterm = (cur_obj->nterm << 16) | cur_obj->ninit; + if(cur_obj->objc_module_info != NULL){ + mod->objc_module_info_addr = +@@ -5887,6 +6347,39 @@ + mod->objc_module_info_size = 0; + } + mod++; ++ } ++ } ++ } ++ else{ ++ /* ++ * For single module dylibs there is one module table entry. ++ */ ++ mod->module_name = STRING_SIZE_OFFSET + ++ merged_symbol_string_index(dylib_single_module_name); ++ mod->iextdefsym = ++ output_dysymtab_info.dysymtab_command.iextdefsym; ++ mod->nextdefsym = ++ output_dysymtab_info.dysymtab_command.nextdefsym; ++ mod->irefsym = 0; ++ mod->nrefsym = ++ output_dysymtab_info.dysymtab_command.nextrefsyms; ++ mod->ilocalsym = ++ output_dysymtab_info.dysymtab_command.ilocalsym; ++ mod->nlocalsym = ++ output_dysymtab_info.dysymtab_command.nlocalsym; ++ mod->iextrel = 0; ++ mod->nextrel = ++ output_dysymtab_info.dysymtab_command.nextrel; ++ mod->iinit_iterm = 0; ++ mod->ninit_nterm = (nterm << 16) | ninit; ++ ms = lookup_merged_section(SEG_OBJC, SECT_OBJC_MODULES); ++ if(ms != NULL){ ++ mod->objc_module_info_addr = ms->s.addr; ++ mod->objc_module_info_size = ms->s.size; ++ } ++ else{ ++ mod->objc_module_info_addr = 0; ++ mod->objc_module_info_size = 0; + } + } + if(host_byte_sex != target_byte_sex){ +diff -ubr ld/symbols.h ld/symbols.h +--- ld/symbols.h Tue Jan 14 23:35:25 2003 ++++ ld/symbols.h Mon Aug 25 12:12:29 2003 +@@ -78,7 +78,8 @@ + /* only in the undefined list as a two- */ + /* level namespace reference from a dylib.*/ + weak_reference_mismatch:1, /* seen both a weak and non-weak reference */ +- reserved:1, ++ define_a_way:1, /* set if this symbol was defined as a */ ++ /* result of -undefined define_a_way */ + output_index:23; /* the symbol table index this symbol will */ + /* have in the output file. */ + int undef_order; /* if the symbol was undefined the order it */ +@@ -184,6 +185,12 @@ + __private_extern__ unsigned long nmerged_symbols_referenced_only_from_dylibs; + + /* ++ * nstripped_merged_symbols is set to the number of merged symbol being stripped ++ * out when the strip_level is STRIP_DYNAMIC_EXECUTABLE. ++ */ ++__private_extern__ unsigned long nstripped_merged_symbols; ++ ++/* + * The head of the list of the blocks that store the strings for the merged + * symbols and the total size of all the strings. The size of the strings for + * the private externals is included in the the merge string size. +@@ -210,9 +217,6 @@ + * The object file that is created for the common symbols to be allocated in. + */ + __private_extern__ +-#if defined(RLD) && !defined(__DYNAMIC__) +-const +-#endif + struct object_file link_edit_common_object; + + /* +@@ -255,6 +259,7 @@ + unsigned long index; + unsigned long count; + enum localsym_block_state state; ++ unsigned long input_N_BINCL_n_value; + unsigned long sum; + struct localsym_block *next; + }; +@@ -323,6 +328,8 @@ + void); + __private_extern__ void define_common_symbols( + void); ++__private_extern__ void define_undefined_symbols_a_way( ++ void); + __private_extern__ void define_link_editor_execute_symbols( + unsigned long header_address); + __private_extern__ void setup_link_editor_symbols( +@@ -369,6 +376,8 @@ + #endif /* defined(RLD) && !defined(SA_RLD) */ + __private_extern__ enum bool is_output_local_symbol( + unsigned char n_type, ++ unsigned char n_sect, ++ struct object_file *obj, + char *symbol_name); + __private_extern__ unsigned long merged_symbol_output_index( + struct merged_symbol *merged_symbol); diff --git a/upstream/darwin-linker/patches/libstuff.patch b/upstream/darwin-linker/patches/libstuff.patch new file mode 100644 index 0000000..c6c3ec7 --- /dev/null +++ b/upstream/darwin-linker/patches/libstuff.patch @@ -0,0 +1,1085 @@ +Only in libstuff: CVS +diff -ubr libstuff/Makefile libstuff/Makefile +--- libstuff/Makefile Fri Sep 6 18:27:55 2002 ++++ libstuff/Makefile Mon Aug 25 21:54:30 2003 +@@ -1,7 +1,7 @@ + RC_OS = macos + OFLAG = -O + ifeq "macos" "$(RC_OS)" +- X_CFLAGS := $(shell if [ "$(RC_RELEASE)" != "Beaker" ] && \ ++ X_CFLAGS := $(shell if [ `uname` != "Linux" ] && [ "$(RC_RELEASE)" != "Beaker" ] && \ + [ "$(RC_RELEASE)" != "Bunsen" ] && \ + [ "$(RC_RELEASE)" != "Gonzo" ] && \ + [ "$(RC_RELEASE)" != "Kodiak" ]; then \ +@@ -10,14 +10,18 @@ + endif + + +-USE_DEPENDENCY_FILE := $(shell if [ "$(notdir $(CC))" != "mwccppc" ]; then \ ++USE_DEPENDENCY_FILE := $(shell if [ `uname` != "Linux" ] && [ "$(notdir $(CC))" != "mwccppc" ]; then \ + echo YES ; else echo NO ; \ + fi; ) + + ifeq "mwccppc" "$(notdir $(CC))" + CFLAGS = $(OFLAG) -g -gccinc -I$(SRCROOT)/../include + else +- CFLAGS = $(OFLAG) -g -I$(SRCROOT)/../include -Wall -Wno-precomp $(X_CFLAGS) ++ ifeq "Linux" "$(shell uname)" ++ CFLAGS = $(OFLAG) -g -I$(SRCROOT)/../include -Wall $(X_CFLAGS) -D__ppc__ -I/usr/include -I../../../macosx-include ++ else ++ CFLAGS = $(OFLAG) -g -I$(SRCROOT)/../include -Wall $(X_CFLAGS) ++ endif + endif + + ifneq "" "$(wildcard /bin/mkdirs)" +@@ -40,7 +44,8 @@ + set_arch_flag_name.c seg_addr_table.c dylib_table.c \ + breakout.c writeout.c checkout.c fatal_arch.c ofile_get_word.c \ + vm_flush_cache.c hash_string.c dylib_roots.c guess_short_name.c \ +- SymLoc.c get_arch_from_host.c crc32.c macosx_deployment_target.c ++ SymLoc.c get_arch_from_host.c crc32.c macosx_deployment_target.c \ ++ symbol_list.c fake-mach.c + OBJS = $(CFILES:.c=.o) + INSTALL_FILES = $(CFILES) Makefile notes + +@@ -90,7 +95,7 @@ + OFILE_DIR=. \ + SRCROOT=.. \ + SYMROOT=.. \ +- COPTS="-dynamic" \ ++ COPTS="" \ + OFLAG="$(OFLAG)" \ + CFILES="$(CFILES)" \ + RC_CFLAGS="$(RC_CFLAGS)" \ +@@ -103,7 +108,7 @@ + OFILE_DIR=$(OBJROOT)/dynamic_obj \ + SRCROOT=$(SRCROOT) \ + SYMROOT=$(SYMROOT) \ +- COPTS="-dynamic" \ ++ COPTS="" \ + OFLAG="$(OFLAG)" \ + CFILES="$(CFILES)" \ + RC_CFLAGS="$(RC_CFLAGS)" \ +@@ -120,7 +125,7 @@ + OFILE_DIR=. \ + SRCROOT=.. \ + SYMROOT=.. \ +- COPTS="-dynamic -pg" \ ++ COPTS="-pg" \ + OFLAG="$(OFLAG)" \ + RC_CFLAGS="$(RC_CFLAGS)" \ + RC_ARCHS="$(RC_ARCHS)"; \ +@@ -132,7 +137,7 @@ + OFILE_DIR=$(OBJROOT)/profile_obj \ + SRCROOT=$(SRCROOT) \ + SYMROOT=$(SYMROOT) \ +- COPTS="-dynamic -pg" \ ++ COPTS="-pg" \ + OFLAG="$(OFLAG)" \ + RC_CFLAGS="$(RC_CFLAGS)" \ + RC_ARCHS="$(RC_ARCHS)"; \ +@@ -167,7 +172,8 @@ + fi + + $(PRODUCT): $(OFILE_DIR) $(SYMROOT) $(OBJS) +- libtool -static -o $(SYMROOT)/$(PRODUCT) $(OBJS) ++ ar r $(SYMROOT)/$(PRODUCT) $(OBJS) ++ ranlib $(SYMROOT)/$(PRODUCT) + + ifeq "NO" "$(USE_DEPENDENCY_FILE)" + .c.o: +diff -ubr libstuff/SymLoc.c libstuff/SymLoc.c +--- libstuff/SymLoc.c Fri Sep 6 18:27:55 2002 ++++ libstuff/SymLoc.c Mon Aug 25 13:17:40 2003 +@@ -1,15 +1,15 @@ +-#import +-#import +-#import ++#include ++#include ++#include + #ifdef __OPENSTEP__ + #define _POSIX_SOURCE + #endif +-#import +-#import +-#import "stuff/bool.h" +-#import "stuff/errors.h" +-#import "stuff/allocate.h" +-#import "stuff/SymLoc.h" ++#include ++#include ++#include "stuff/bool.h" ++#include "stuff/errors.h" ++#include "stuff/allocate.h" ++#include "stuff/SymLoc.h" + + const char * + symLocForDylib(const char *installName, const char *releaseName, +@@ -101,6 +101,7 @@ + system_error("symLocForDylib(): Can't opendir %s", buf); + return NULL; + } ++ c = NULL; + + // read DylibProjects entries + *buf = '\0'; +diff -ubr libstuff/arch.c libstuff/arch.c +--- libstuff/arch.c Tue Jan 14 23:35:27 2003 ++++ libstuff/arch.c Mon Aug 25 13:17:40 2003 +@@ -60,11 +60,13 @@ + { "ppc750", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_750 }, + { "ppc7400",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7400 }, + { "ppc7450",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7450 }, ++ { "ppc970", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_970 }, + { "i486", CPU_TYPE_I386, CPU_SUBTYPE_486 }, + { "i486SX", CPU_TYPE_I386, CPU_SUBTYPE_486SX }, + { "pentium",CPU_TYPE_I386, CPU_SUBTYPE_PENT }, /* same as i586 */ + { "i586", CPU_TYPE_I386, CPU_SUBTYPE_586 }, +- { "pentpro", CPU_TYPE_I386, CPU_SUBTYPE_PENTPRO }, ++ { "pentpro", CPU_TYPE_I386, CPU_SUBTYPE_PENTPRO }, /* same as i686 */ ++ { "i686", CPU_TYPE_I386, CPU_SUBTYPE_PENTPRO }, + { "pentIIm3",CPU_TYPE_I386, CPU_SUBTYPE_PENTII_M3 }, + { "pentIIm5",CPU_TYPE_I386, CPU_SUBTYPE_PENTII_M5 }, + { "m68030", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68030_ONLY }, +@@ -269,7 +271,8 @@ + const struct arch_flag *flag) + { + if(flag->cputype == CPU_TYPE_POWERPC || +- flag->cputype == CPU_TYPE_VEO) ++ flag->cputype == CPU_TYPE_VEO || ++ flag->cputype == CPU_TYPE_I386) + return(0x1000); /* 4K */ + else + return(0x2000); /* 8K */ +diff -ubr libstuff/best_arch.c libstuff/best_arch.c +--- libstuff/best_arch.c Tue Jan 14 23:35:27 2003 ++++ libstuff/best_arch.c Mon Aug 25 13:17:40 2003 +@@ -44,7 +44,8 @@ + struct fat_arch *fat_archs, + unsigned long nfat_archs) + { +- unsigned long i, lowest_family, lowest_model, lowest_index; ++ unsigned long i; ++ long lowest_family, lowest_model, lowest_index; + + /* + * Look for the first exact match. +@@ -183,14 +184,21 @@ + * An exact match as not found. So for all the PowerPC subtypes + * pick the subtype from the following order starting from a subtype + * that will work (contains altivec if needed): +- * 7450, 7400, 750, 604e, 604, 603ev, 603e, 603, ALL ++ * 790, 7450, 7400, 750, 604e, 604, 603ev, 603e, 603, ALL + * Note the 601 is NOT in the list above. It is only picked via + * an exact match. For an unknown subtype pick only the ALL type if + * it exists. + */ + switch(cpusubtype){ ++ case CPU_SUBTYPE_POWERPC_970: + case CPU_SUBTYPE_POWERPC_7450: + case CPU_SUBTYPE_POWERPC_7400: ++ for(i = 0; i < nfat_archs; i++){ ++ if(fat_archs[i].cputype != cputype) ++ continue; ++ if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_970) ++ return(fat_archs + i); ++ } + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +diff -ubr libstuff/bytesex.c libstuff/bytesex.c +--- libstuff/bytesex.c Fri Sep 6 18:27:56 2002 ++++ libstuff/bytesex.c Mon Aug 25 13:17:40 2003 +@@ -25,13 +25,13 @@ + #include + #include + #include +-#import +-#import +-#import +-#import +-#import +-#import +-#import ++#include ++#include ++#include ++#include ++#include ++#include ++#include + #include + #include + #include +diff -ubr libstuff/checkout.c libstuff/checkout.c +--- libstuff/checkout.c Fri Sep 6 18:27:57 2002 ++++ libstuff/checkout.c Mon Aug 25 13:17:40 2003 +@@ -132,9 +132,11 @@ + } + lc = (struct load_command *)((char *)lc + lc->cmdsize); + } +- if(object->mh->filetype == MH_DYLIB && dl_id == NULL) ++ if((object->mh->filetype == MH_DYLIB || ++ object->mh->filetype == MH_DYLIB_STUB) && dl_id == NULL) + fatal_arch(arch, member, "malformed file (no LC_ID_DYLIB load " +- "command in MH_DYLIB file): "); ++ "command in %s file): ", object->mh->filetype == MH_DYLIB ? ++ "MH_DYLIB" : "MH_DYLIB_STUB"); + if(object->hints_cmd != NULL){ + if(object->dyst == NULL && object->hints_cmd->nhints != 0) + fatal_arch(arch, member, "malformed file (LC_TWOLEVEL_HINTS " +@@ -161,7 +163,8 @@ + * and a relocatable object file. Since it has a dynamic symbol + * table command it could have an indirect symbol table. + */ +- if(object->mh->filetype == MH_DYLIB){ ++ if(object->mh->filetype == MH_DYLIB /* || ++ object->mh->filetype == MH_DYLIB_STUB */ ){ + /* + * This is a dynamic shared library. + * The order of the symbolic info is: +@@ -172,10 +175,10 @@ + * undefined symbols + * two-level namespace hints + * external relocation entries ++ * indirect symbol table + * table of contents + * module table + * reference table +- * indirect symbol table + * string table + * strings for external symbols + * strings for local symbols +diff -ubr libstuff/crc32.c libstuff/crc32.c +--- libstuff/crc32.c Fri Sep 6 18:27:57 2002 ++++ libstuff/crc32.c Mon Aug 25 13:19:21 2003 +@@ -35,6 +35,12 @@ + */ + #include + ++#if ( defined(__MWERKS__) && !defined(__private_extern__) ) ++#define __private_extern__ __declspec(private_extern) ++#elif ( defined(__linux__) && !defined(__private_extern__) ) ++#define __private_extern__ extern ++#endif ++ + static const u_int32_t crctab[] = { + 0x0, + 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, +diff -ubr libstuff/dylib_roots.c libstuff/dylib_roots.c +--- libstuff/dylib_roots.c Fri Sep 6 18:27:58 2002 ++++ libstuff/dylib_roots.c Mon Aug 25 13:17:40 2003 +@@ -21,7 +21,7 @@ + enum bool check_result; + }; + +-static void check_for_install_name( ++static void check_for_dylib( + struct ofile *ofile, + char *arch_name, + void *cookie); +@@ -77,7 +77,7 @@ + } + } + ofile_process(image_file_name, NULL, 0, TRUE, +- TRUE, TRUE, FALSE, check_for_install_name, &block); ++ TRUE, TRUE, FALSE, check_for_dylib, &block); + if(block.check_result == TRUE) + return(image_file_name); + free(image_file_name); +@@ -148,14 +148,14 @@ + #endif + /* + * Now that we found a file with the same base_name in the root +- * check to see that it is a dynamic library with the correct +- * install name. Assume it is an if it is not then the +- * routine check_for_install_name() will reset the check_result +- * in the block passed to it back to FALSE. ++ * check to see that it is a dynamic library. Assume it is an ++ * if it is not then the routine check_for_dylib() will ++ * reset the check_result in the block passed to ++ * it back to FALSE. + */ + block.check_result = TRUE; + ofile_process(ftsent->fts_path, NULL, 0, TRUE, +- TRUE, TRUE, FALSE, check_for_install_name,&block); ++ TRUE, TRUE, FALSE, check_for_dylib,&block); + if(block.check_result == TRUE){ + image_file_name = allocate(ftsent->fts_pathlen + 1); + strcpy(image_file_name, ftsent->fts_path); +@@ -189,7 +189,7 @@ + + static + void +-check_for_install_name( ++check_for_dylib( + struct ofile *ofile, + char *arch_name, + void *cookie) +@@ -197,11 +197,9 @@ + unsigned long i; + struct check_block *block; + struct load_command *lc; +- struct dylib_command *dl; +- char *name; + + #ifdef BIG_DEBUG +- printf("In check_for_install_name() ofile->file_name = %s", ++ printf("In check_for_dylib() ofile->file_name = %s", + ofile->file_name); + if(arch_name != NULL) + printf(" arch_name = %s\n", arch_name); +@@ -218,13 +216,6 @@ + lc = ofile->load_commands; + for(i = 0; i < ofile->mh->ncmds; i++){ + if(lc->cmd == LC_ID_DYLIB){ +- dl = (struct dylib_command *)lc; +- name = (char *)lc + dl->dylib.name.offset; +- if(strncmp(name, "@executable_path/", +- sizeof("@executable_path") - 1) == 0) +- return; +- if(strcmp(name, block->install_name) != 0) +- block->check_result = FALSE; + return; + } + lc = (struct load_command *)((char *)lc + lc->cmdsize); +Only in libstuff: fake-mach.c +diff -ubr libstuff/get_arch_from_host.c libstuff/get_arch_from_host.c +--- libstuff/get_arch_from_host.c Tue Jan 14 23:35:27 2003 ++++ libstuff/get_arch_from_host.c Mon Aug 25 13:17:40 2003 +@@ -181,6 +181,14 @@ + if(specific_arch_flag != NULL) + specific_arch_flag->name = "ppc7450"; + return(1); ++ case CPU_SUBTYPE_POWERPC_970: ++ if(family_arch_flag != NULL){ ++ family_arch_flag->name = "ppc"; ++ family_arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL; ++ } ++ if(specific_arch_flag != NULL) ++ specific_arch_flag->name = "ppc970"; ++ return(1); + default: + if(family_arch_flag != NULL){ + family_arch_flag->name = "ppc"; +Only in libstuff: gpul_notes +diff -ubr libstuff/notes libstuff/notes +--- libstuff/notes Tue Jan 14 23:35:27 2003 ++++ libstuff/notes Mon Aug 25 12:12:33 2003 +@@ -5,6 +5,69 @@ + TODO: + - Deal with LC_PREPAGE and unknown load commands that don't need to be swapped. + ++Changes for the 5.12 release (the cctools-469 release): ++- Fixed a problem with the added checks of the of the dylib_module struct in ++ ofile.c made in cctools-466 for Radar bug #3208399 where it did not work if ++ the file was not in host byte sex. The fix was to copy the struct and byte ++ swap it if needed before doing the checks on the copy of the struct in ++ check_dylib_module() in ofile.c . Radar bug #3228664. ++ ++Changes for the 5.12 release (the cctools-467 release): ++- Added support for the PPC_RELOC_LO14_SECTDIFF relocation type used with ++ double word load/store instructions. Radar bug #3218027. ++ - Added tests for PPC_RELOC_LO14_SECTDIFF in both reloc_has_pair() and ++ reloc_is_sectdiff() in reloc.c . ++ ++Changes for the 5.12 release (the cctools-466 release): ++- Fixed the incorrect casts on the comparison of the nlist struct's n_strx field ++ where the value being compared to was casted to a long. The correct fix was ++ to cast n_strx to an unsigned long. ++- Added the missing checking of the dylib_module struct in ofile.c so that it ++ would not return an ofile struct with a bad dylib_module. Also fixed a number ++ of places the routine Mach_O_error() was called to print an error message but ++ the code failed to return a failure status. Radar bug #3208399. ++ ++Changes for the 5.12 release (the cctools-464 release): ++- Made changes to build cleanly with gcc3.3 ++ - Removed -Wno-precomp from the Makefile ++ - Fixed warnings for "comparison between signed and unsigned" in writeout.c, ++ symbol_list.c, ofile_get_word.c, round.c, ofile.c, and best_arch.c . ++ ++Changes for the 5.12 release (the cctools-462 release): ++- Added support for MH_DYLIB_STUB libraries. Radar bug #3193744. ++ - Did NOT change writeout() in writeout.c to handle the timestamp in ++ MH_DYLIB_STUB filetypes like MH_DYLIB filetypes as the timestamp should ++ not be changed or else this would mess up building prebound. ++ - Changed the routines in ofile.c to handle MH_DYLIB_STUB filetypes like ++ MH_DYLIB filetypes. ++ - Changed check_object() in checkout.c to handle MH_DYLIB_STUB filetypes like ++ MH_DYLIB filetypes. ++ ++Changes for the 5.12 release (the cctools-457 release): ++- Changed ofile_map() added ofile_map_from_memory() which is everything from ++ the original ofile_map() except mapping the file. This is needed so the ++ NSCreateObjectFileImageFromMemory() api can be implemented. Radar bug ++ #3131622. ++ ++Changes for the 5.12 release (the cctools-455 release): ++- Changed the code in dylib_roots.c to remove the check that the actual path of ++ a binary equals the install name of the dynamic library. Radar bug #3147668. ++ ++Changes for the 5.12 release (the cctools-450 release): ++- Changed get_segalign_from_flag() in arch.c to have 4K returned for i386 also. ++ Radar bug #3120579. ++ ++Changes for the 5.12 release (the cctools-449 release): ++- Added the arch flag i686 to be the same as pentpro in arch.c. Radar bug ++ #3111977. ++ ++Changes for the 5.11 release (the cctools-444 release): ++- Added the file symbol_list.c which contains the code from strip.c for the ++ symbol lists. Now also used by ld(1)'s -exported_symbols_list and ++ -unexported_symbols_list options. Radar bug #3083844. ++- Picked up fix to LocForDylib() in SymLoc.c that was crashing when the ++ DylibProjects directory was empty. Radar bug #3079374. ++ + Changes for the 5.11 release (the cctools-440 release): + - Fixed the warnings about extra tokens at end of #endif directive in ofile.c + (Radar bug #3072042). +diff -ubr libstuff/ofile.c libstuff/ofile.c +--- libstuff/ofile.c Tue Jan 14 23:35:27 2003 ++++ libstuff/ofile.c Mon Aug 25 23:49:59 2003 +@@ -27,6 +27,7 @@ + #include + #include + #include "stuff/openstep_mach.h" ++#include + #include + #include + #include +@@ -35,12 +36,12 @@ + #include + #include + #include +-#import +-#import +-#import +-#import +-#import +-#import ++#include ++#include ++#include ++#include ++#include ++#include + #include + #include + #include "stuff/bool.h" +@@ -91,6 +92,12 @@ + unsigned long *member_name_size); + static enum check_type check_Mach_O( + struct ofile *ofile); ++static enum check_type check_dylib_module( ++ struct ofile *ofile, ++ struct symtab_command *st, ++ struct dysymtab_command *dyst, ++ char *strings, ++ unsigned long module_index); + + #ifndef OFI + /* +@@ -229,7 +236,8 @@ + else if(process_non_objects == TRUE || + ofile.arch_type == OFILE_Mach_O){ + if(ofile.arch_type == OFILE_Mach_O && +- ofile.mh->filetype == MH_DYLIB){ ++ (ofile.mh->filetype == MH_DYLIB || ++ ofile.mh->filetype == MH_DYLIB_STUB)){ + if(dylib_flat == TRUE){ + processor(&ofile, arch_name, cookie); + } +@@ -349,7 +357,8 @@ + else if(process_non_objects == TRUE || + ofile.arch_type == OFILE_Mach_O){ + if(ofile.arch_type == OFILE_Mach_O && +- ofile.mh->filetype == MH_DYLIB){ ++ (ofile.mh->filetype == MH_DYLIB || ++ ofile.mh->filetype == MH_DYLIB_STUB)){ + if(dylib_flat == TRUE){ + processor(&ofile, NULL, cookie); + } +@@ -445,7 +454,8 @@ + else if(process_non_objects == TRUE || + ofile.arch_type == OFILE_Mach_O){ + if(ofile.arch_type == OFILE_Mach_O && +- ofile.mh->filetype == MH_DYLIB){ ++ (ofile.mh->filetype == MH_DYLIB || ++ ofile.mh->filetype == MH_DYLIB_STUB)){ + if(dylib_flat == TRUE){ + processor(&ofile, ofile.arch_flag.name, cookie); + } +@@ -557,9 +567,9 @@ + } + #ifdef OTOOL + if(ofile.mh->magic == SWAP_LONG(MH_MAGIC)){ +- if(SWAP_LONG(ofile.mh->cputype) == ++ if((cpu_type_t)SWAP_LONG(ofile.mh->cputype) == + arch_flags[i].cputype && +- (SWAP_LONG(ofile.mh->cpusubtype) == ++ ((cpu_subtype_t)SWAP_LONG(ofile.mh->cpusubtype) == + arch_flags[i].cpusubtype || + family == TRUE)){ + arch_found = TRUE; +@@ -580,7 +590,8 @@ + if(arch_found == FALSE) + return; + } +- if(ofile.mh->filetype == MH_DYLIB){ ++ if(ofile.mh->filetype == MH_DYLIB || ++ ofile.mh->filetype == MH_DYLIB_STUB){ + if(dylib_flat == TRUE){ + processor(&ofile, NULL, cookie); + } +@@ -658,19 +669,15 @@ + { + int fd; + struct stat stat_buf; +- unsigned long i, size, magic; ++ unsigned long size, magic; + kern_return_t r; + char *addr; +- enum byte_sex host_byte_sex; +- struct arch_flag host_arch_flag; +- enum bool family; +- const struct arch_flag *family_arch_flag; + + magic = 0; /* to shut up the compiler warning message */ + memset(ofile, '\0', sizeof(struct ofile)); + + /* Open the file and map it in */ +- if((fd = open(file_name, O_RDONLY)) == -1){ ++ if((fd = open(file_name, O_RDWR)) == -1){ + #ifdef OFI + return(NSObjectFileImageAccess); + #else +@@ -700,6 +707,35 @@ + printf("Modification time = %ld\n", (long int)stat_buf.st_mtime); + #endif /* OTOOL */ + ++ return(ofile_map_from_memory(addr, size, file_name, arch_flag, ++ object_name, ofile, archives_with_fat_objects)); ++} ++ ++/* ++ * ofile_map_from_memory() is the guts of ofile_map() but with an interface ++ * to pass the address and size of the file already mapped in. ++ */ ++__private_extern__ ++#ifdef OFI ++NSObjectFileImageReturnCode ++#else ++enum bool ++#endif ++ofile_map_from_memory( ++char *addr, ++unsigned long size, ++const char *file_name, ++const struct arch_flag *arch_flag, /* can be NULL */ ++const char *object_name, /* can be NULL */ ++struct ofile *ofile, ++enum bool archives_with_fat_objects) ++{ ++ unsigned long i, magic; ++ enum byte_sex host_byte_sex; ++ struct arch_flag host_arch_flag; ++ enum bool family; ++ const struct arch_flag *family_arch_flag; ++ + /* fill in the start of the ofile structure */ + ofile->file_name = savestr(file_name); + if(ofile->file_name == NULL) +@@ -1176,7 +1212,7 @@ + } + + #ifdef OTOOL +- if(addr - ofile->file_addr > ofile->file_size){ ++ if(addr - ofile->file_addr > (ptrdiff_t)ofile->file_size){ + error("fat file: %s offset to architecture %s extends past end " + "of file", ofile->file_name, ofile->arch_flag.name); + return(FALSE); +@@ -1327,7 +1363,7 @@ + return(FALSE); + } + #ifdef OTOOL +- if((addr + SARMAG) - ofile->file_addr > ofile->file_size){ ++ if((addr + SARMAG) - ofile->file_addr > (ptrdiff_t)ofile->file_size){ + archive_error(ofile, "offset to first member extends past the end " + "of the file"); + return(FALSE); +@@ -1832,7 +1868,7 @@ + + /* + * ofile_first_module() set up the ofile structure (the dylib_module field) +- * for the first module of an MH_DYLIB file. ++ * for the first module of an MH_DYLIB or MH_DYLIB_STUB file. + */ + __private_extern__ + enum bool +@@ -1856,7 +1892,8 @@ + + if(ofile->file_type == OFILE_FAT){ + if(ofile->arch_type != OFILE_Mach_O && +- ofile->mh->filetype != MH_DYLIB){ ++ (ofile->mh->filetype != MH_DYLIB && ++ ofile->mh->filetype != MH_DYLIB_STUB)){ + error("ofile_first_module() called on fat file: %s with a " + "non-MH_DYLIB architecture or no architecture selected\n", + ofile->file_name); +@@ -1864,7 +1901,8 @@ + } + } + else if(ofile->arch_type != OFILE_Mach_O && +- ofile->mh->filetype != MH_DYLIB){ ++ (ofile->mh->filetype != MH_DYLIB && ++ ofile->mh->filetype != MH_DYLIB_STUB)){ + error("ofile_first_module() called and file type of %s is " + "non-MH_DYLIB\n", ofile->file_name); + return(FALSE); +@@ -1902,20 +1940,22 @@ + m = *ofile->dylib_module; + if(swapped) + swap_dylib_module(&m, 1, host_byte_sex); ++ if(check_dylib_module(ofile, st, dyst, strings, 0) == CHECK_BAD) ++ return(FALSE); + ofile->dylib_module_name = strings + m.module_name; + return(TRUE); + } + + /* + * ofile_next_module() set up the ofile structure (the dylib_module field) +- * for the next module of an MH_DYLIB file. ++ * for the next module of an MH_DYLIB or MH_DYLIB_STUB file. + */ + __private_extern__ + enum bool + ofile_next_module( + struct ofile *ofile) + { +- unsigned long i; ++ unsigned long i, module_index; + struct symtab_command *st; + struct dysymtab_command *dyst; + struct load_command *lc; +@@ -1926,7 +1966,8 @@ + + if(ofile->file_type == OFILE_FAT){ + if(ofile->arch_type != OFILE_Mach_O && +- ofile->mh->filetype != MH_DYLIB){ ++ (ofile->mh->filetype != MH_DYLIB && ++ ofile->mh->filetype != MH_DYLIB_STUB)){ + error("ofile_next_module() called on fat file: %s with a " + "non-MH_DYLIB architecture or no architecture selected\n", + ofile->file_name); +@@ -1934,7 +1975,8 @@ + } + } + else if(ofile->arch_type != OFILE_Mach_O && +- ofile->mh->filetype != MH_DYLIB){ ++ (ofile->mh->filetype != MH_DYLIB && ++ ofile->mh->filetype != MH_DYLIB_STUB)){ + error("ofile_next_module() called and file type of %s is " + "non-MH_DYLIB\n", ofile->file_name); + return(FALSE); +@@ -1959,7 +2001,8 @@ + return(FALSE); + } + +- if((ofile->dylib_module + 1) - ofile->modtab >= ofile->nmodtab) ++ module_index = (ofile->dylib_module + 1) - ofile->modtab; ++ if(module_index >= ofile->nmodtab) + return(FALSE); + + ofile->dylib_module++; +@@ -1969,13 +2012,17 @@ + m = *ofile->dylib_module; + if(swapped) + swap_dylib_module(&m, 1, host_byte_sex); ++ if(check_dylib_module(ofile, st, dyst, strings, module_index) == ++ CHECK_BAD) ++ return(FALSE); + ofile->dylib_module_name = strings + m.module_name; + return(TRUE); + } + + /* + * ofile_specific_module() set up the ofile structure (the dylib_module fields) +- * for the specified module, module_name, of an MH_DYLIB file. ++ * for the specified module, module_name, of an MH_DYLIB or an MH_DYLIB_STUB ++ * file. + */ + __private_extern__ + enum bool +@@ -2000,7 +2047,8 @@ + + if(ofile->file_type == OFILE_FAT){ + if(ofile->arch_type != OFILE_Mach_O && +- ofile->mh->filetype != MH_DYLIB){ ++ (ofile->mh->filetype != MH_DYLIB && ++ ofile->mh->filetype != MH_DYLIB_STUB)){ + error("ofile_specific_module() called on fat file: %s with a " + "non-MH_DYLIB architecture or no architecture selected\n", + ofile->file_name); +@@ -2008,7 +2056,8 @@ + } + } + else if(ofile->arch_type != OFILE_Mach_O && +- ofile->mh->filetype != MH_DYLIB){ ++ (ofile->mh->filetype != MH_DYLIB && ++ ofile->mh->filetype != MH_DYLIB_STUB)){ + error("ofile_specific_module() called and file type of %s is " + "non-MH_DYLIB\n", ofile->file_name); + return(FALSE); +@@ -2047,8 +2096,10 @@ + m = *p; + if(swapped) + swap_dylib_module(&m, 1, host_byte_sex); +- if(strcmp(module_name, strings + m.module_name) == 0){ + ofile->dylib_module = p; ++ if(check_dylib_module(ofile, st, dyst, strings, i) == CHECK_BAD) ++ return(FALSE); ++ if(strcmp(module_name, strings + m.module_name) == 0){ + ofile->dylib_module_name = strings + m.module_name; + return(TRUE); + } +@@ -2520,10 +2571,12 @@ + return(CHECK_BAD); + } + if(ofile->file_type == OFILE_FAT){ +- if(ofile->fat_archs[ofile->narch].cputype != ofile->mh->cputype) ++ if(ofile->fat_archs[ofile->narch].cputype != ofile->mh->cputype){ + Mach_O_error(ofile, "malformed fat file (fat header " + "architecture: %lu's cputype does not match " + "object file's mach header)", ofile->narch); ++ return(CHECK_BAD); ++ } + } + /* + * Make a pass through the load commands checking them to the level +@@ -3595,55 +3648,73 @@ + } + } + if(st == NULL){ +- if(dyst != NULL) ++ if(dyst != NULL){ + Mach_O_error(ofile, "truncated or malformed object (contains " + "LC_DYSYMTAB load command without a LC_SYMTAB load command)"); ++ return(CHECK_BAD); ++ } + } + else{ + if(dyst != NULL){ + if(dyst->nlocalsym != 0 && +- dyst->ilocalsym > st->nsyms) ++ dyst->ilocalsym > st->nsyms){ + Mach_O_error(ofile, "truncated or malformed object " + "(ilocalsym in LC_DYSYMTAB load command extends past " + "the end of the symbol table)"); ++ return(CHECK_BAD); ++ } + if(dyst->nlocalsym != 0 && +- dyst->ilocalsym + dyst->nlocalsym > st->nsyms) ++ dyst->ilocalsym + dyst->nlocalsym > st->nsyms){ + Mach_O_error(ofile, "truncated or malformed object " + "(ilocalsym plus nlocalsym in LC_DYSYMTAB load command " + "extends past the end of the symbol table)"); ++ return(CHECK_BAD); ++ } + + if(dyst->nextdefsym != 0 && +- dyst->iextdefsym > st->nsyms) ++ dyst->iextdefsym > st->nsyms){ + Mach_O_error(ofile, "truncated or malformed object " + "(iextdefsym in LC_DYSYMTAB load command extends past " + "the end of the symbol table)"); ++ return(CHECK_BAD); ++ } + if(dyst->nextdefsym != 0 && +- dyst->iextdefsym + dyst->nextdefsym > st->nsyms) ++ dyst->iextdefsym + dyst->nextdefsym > st->nsyms){ + Mach_O_error(ofile, "truncated or malformed object " + "(iextdefsym plus nextdefsym in LC_DYSYMTAB load " + "command extends past the end of the symbol table)"); ++ return(CHECK_BAD); ++ } + + if(dyst->nundefsym != 0 && +- dyst->iundefsym > st->nsyms) ++ dyst->iundefsym > st->nsyms){ + Mach_O_error(ofile, "truncated or malformed object " + "(iundefsym in LC_DYSYMTAB load command extends past " + "the end of the symbol table)"); ++ return(CHECK_BAD); ++ } + if(dyst->nundefsym != 0 && +- dyst->iundefsym + dyst->nundefsym > st->nsyms) ++ dyst->iundefsym + dyst->nundefsym > st->nsyms){ + Mach_O_error(ofile, "truncated or malformed object " + "(iundefsym plus nundefsym in LC_DYSYMTAB load command " + "extends past the end of the symbol table)"); ++ return(CHECK_BAD); ++ } + if(rc != NULL){ +- if(rc->init_module > dyst->nmodtab) ++ if(rc->init_module > dyst->nmodtab){ + Mach_O_error(ofile, "malformed object (init_module in " + "LC_ROUTINES load command extends past the end of " + "the module table)"); ++ return(CHECK_BAD); ++ } + } + if(hints != NULL){ +- if(hints->nhints != dyst->nundefsym) ++ if(hints->nhints != dyst->nundefsym){ + Mach_O_error(ofile, "malformed object (nhints in " + "LC_TWOLEVEL_HINTS load command not the same as " + "nundefsym in LC_DYSYMTAB load command)"); ++ return(CHECK_BAD); ++ } + } + } + } +@@ -3655,6 +3726,109 @@ + } + + /* looks good return ok */ ++ return(CHECK_GOOD); ++#endif /* OTOOL */ ++} ++ ++/* ++ * check_dylib_module() checks the object file's dylib_module as referenced ++ * by the dylib_module field in the ofile for correctness. ++ */ ++static ++enum check_type ++check_dylib_module( ++struct ofile *ofile, ++struct symtab_command *st, ++struct dysymtab_command *dyst, ++char *strings, ++unsigned long module_index) ++{ ++#ifdef OTOOL ++ return(CHECK_GOOD); ++#else /* !defined OTOOL */ ++ unsigned long i; ++ enum byte_sex host_byte_sex; ++ enum bool swapped; ++ struct dylib_module m; ++ ++ m = *ofile->dylib_module; ++ host_byte_sex = get_host_byte_sex(); ++ swapped = (enum bool)(host_byte_sex != ofile->object_byte_sex); ++ if(swapped) ++ swap_dylib_module(&m, 1, host_byte_sex); ++ ++ if(m.module_name > st->strsize){ ++ Mach_O_error(ofile, "truncated or malformed object (module_name " ++ "of module table entry %lu past the end of the string table)", ++ module_index); ++ return(CHECK_BAD); ++ } ++ for(i = m.module_name; i < st->strsize && strings[i] != '\0'; i++) ++ ; ++ if(i >= st->strsize){ ++ Mach_O_error(ofile, "truncated or malformed object (module_name " ++ "of module table entry %lu extends past the end of the string " ++ "table)", module_index); ++ return(CHECK_BAD); ++ } ++ ++ if(m.nextdefsym != 0){ ++ if(m.iextdefsym > st->nsyms){ ++ Mach_O_error(ofile, "truncated or malformed object (iextdefsym " ++ "field of module table entry %lu past the end of the " ++ "symbol table", module_index); ++ return(CHECK_BAD); ++ } ++ if(m.iextdefsym + m.nextdefsym > st->nsyms){ ++ Mach_O_error(ofile, "truncated or malformed object (iextdefsym " ++ "field of module table entry %lu plus nextdefsym field " ++ "extends past the end of the symbol table", module_index); ++ return(CHECK_BAD); ++ } ++ } ++ if(m.nlocalsym != 0){ ++ if(m.ilocalsym > st->nsyms){ ++ Mach_O_error(ofile, "truncated or malformed object (ilocalsym " ++ "field of module table entry %lu past the end of the " ++ "symbol table", module_index); ++ return(CHECK_BAD); ++ } ++ if(m.ilocalsym + m.nlocalsym > st->nsyms){ ++ Mach_O_error(ofile, "truncated or malformed object (ilocalsym " ++ "field of module table entry %lu plus nlocalsym field " ++ "extends past the end of the symbol table", module_index); ++ return(CHECK_BAD); ++ } ++ } ++ if(m.nrefsym != 0){ ++ if(m.irefsym > dyst->nextrefsyms){ ++ Mach_O_error(ofile, "truncated or malformed object (irefsym " ++ "field of module table entry %lu past the end of the " ++ "reference table", module_index); ++ return(CHECK_BAD); ++ } ++ if(m.irefsym + m.nrefsym > dyst->nextrefsyms){ ++ Mach_O_error(ofile, "truncated or malformed object (irefsym " ++ "field of module table entry %lu plus nrefsym field " ++ "extends past the end of the reference table",module_index); ++ return(CHECK_BAD); ++ } ++ } ++ if(m.nextrel != 0){ ++ if(m.iextrel > dyst->extreloff){ ++ Mach_O_error(ofile, "truncated or malformed object (iextrel " ++ "field of module table entry %lu past the end of the " ++ "external relocation enrties", module_index); ++ return(CHECK_BAD); ++ } ++ if(m.iextrel + m.nextrel > dyst->extreloff){ ++ Mach_O_error(ofile, "truncated or malformed object (iextrel " ++ "field of module table entry %lu plus nextrel field " ++ "extends past the end of the external relocation enrties", ++ module_index); ++ return(CHECK_BAD); ++ } ++ } + return(CHECK_GOOD); + #endif /* OTOOL */ + } +diff -ubr libstuff/ofile_get_word.c libstuff/ofile_get_word.c +--- libstuff/ofile_get_word.c Fri Sep 6 18:28:00 2002 ++++ libstuff/ofile_get_word.c Mon Aug 25 13:17:40 2003 +@@ -34,7 +34,7 @@ + unsigned long *word, + void *get_word_data /* struct mach_object_file *ofile */ ) + { +- int i, j; ++ unsigned long i, j; + struct load_command *lc; + struct segment_command *sg; + struct section *s; +diff -ubr libstuff/print.c libstuff/print.c +--- libstuff/print.c Tue Apr 30 00:37:20 2002 ++++ libstuff/print.c Mon Aug 25 13:17:40 2003 +@@ -21,8 +21,8 @@ + * + * @APPLE_LICENSE_HEADER_END@ + */ +-#import +-#import "stuff/print.h" ++#include ++#include "stuff/print.h" + + /* + * All printing of all messages for ofile functions goes through this function. +diff -ubr libstuff/reloc.c libstuff/reloc.c +--- libstuff/reloc.c Tue Jan 14 23:35:27 2003 ++++ libstuff/reloc.c Mon Aug 25 13:17:40 2003 +@@ -106,6 +106,7 @@ + r_type == PPC_RELOC_SECTDIFF || + r_type == PPC_RELOC_HI16_SECTDIFF || + r_type == PPC_RELOC_LO16_SECTDIFF || ++ r_type == PPC_RELOC_LO14_SECTDIFF || + r_type == PPC_RELOC_HA16_SECTDIFF || + r_type == PPC_RELOC_JBSR) + return(TRUE); +@@ -164,6 +165,7 @@ + if(r_type == PPC_RELOC_SECTDIFF || + r_type == PPC_RELOC_HI16_SECTDIFF || + r_type == PPC_RELOC_LO16_SECTDIFF || ++ r_type == PPC_RELOC_LO14_SECTDIFF || + r_type == PPC_RELOC_HA16_SECTDIFF) + return(TRUE); + break; +diff -ubr libstuff/round.c libstuff/round.c +--- libstuff/round.c Tue Apr 30 00:37:20 2002 ++++ libstuff/round.c Mon Aug 25 13:17:40 2003 +@@ -26,9 +26,9 @@ + * round() rounds v to a multiple of r. + */ + __private_extern__ +-long ++unsigned long + round( +-long v, ++unsigned long v, + unsigned long r) + { + r--; +diff -ubr libstuff/swap_headers.c libstuff/swap_headers.c +--- libstuff/swap_headers.c Tue Jan 14 23:35:27 2003 ++++ libstuff/swap_headers.c Mon Aug 25 13:17:40 2003 +@@ -22,13 +22,13 @@ + * @APPLE_LICENSE_HEADER_END@ + */ + #include +-#import +-#import +-#import +-#import +-#import +-#import +-#import ++#include ++#include ++#include ++#include ++#include ++#include ++#include + #include "stuff/bool.h" + #include "stuff/bytesex.h" + #include "stuff/errors.h" +Only in libstuff: symbol_list.c +diff -ubr libstuff/writeout.c libstuff/writeout.c +--- libstuff/writeout.c Fri Sep 6 18:28:00 2002 ++++ libstuff/writeout.c Mon Aug 25 13:17:40 2003 +@@ -511,7 +511,7 @@ + write_size = (file + file_size) - p; + else + write_size = WRITE_SIZE; +- if(write(fd, p, write_size) != write_size){ ++ if(write(fd, p, write_size) != (int)write_size){ + system_error("can't write output file: %s", output); + goto cleanup; + } +@@ -560,7 +560,7 @@ + } + else{ + no_throttle: +- if(write(fd, file, file_size) != file_size){ ++ if(write(fd, file, file_size) != (int)file_size){ + system_error("can't write output file: %s", output); + goto cleanup; + } +@@ -807,7 +807,7 @@ + strings_size = object->output_strings_size; + } + for(j = 0; j < nsymbols; j++){ +- if(symbols[j].n_un.n_strx > strings_size) ++ if((unsigned long)symbols[j].n_un.n_strx > strings_size) + continue; + if(toc_symbol(symbols + j, commons_in_toc, + object->sections) == TRUE){ +@@ -998,7 +998,7 @@ + char *output, + enum bool library_warnings) + { +- long i; ++ unsigned long i; + enum bool multiple_defs; + struct member *member; + +@@ -1008,7 +1008,7 @@ + * only once (marked by changing the sign of their ran_off). + */ + multiple_defs = FALSE; +- for(i = 0; i < (long)arch->toc_nranlibs - 1; i++){ ++ for(i = 0; i < arch->toc_nranlibs - 1; i++){ + if(strcmp(arch->toc_ranlibs[i].ran_un.ran_name, + arch->toc_ranlibs[i+1].ran_un.ran_name) == 0){ + if(multiple_defs == FALSE){ diff --git a/upstream/darwin-linker/patches/misc.patch b/upstream/darwin-linker/patches/misc.patch new file mode 100644 index 0000000..a9efdc9 --- /dev/null +++ b/upstream/darwin-linker/patches/misc.patch @@ -0,0 +1,952 @@ +Only in misc: CVS +diff -ubr misc/Makefile misc/Makefile +--- misc/Makefile Tue Jan 14 23:35:29 2003 ++++ misc/Makefile Mon Aug 25 22:06:23 2003 +@@ -2,11 +2,11 @@ + OFLAG = -O + RC_OS = macos + ifeq "macos" "$(RC_OS)" +- X_CFLAGS := $(shell if [ "$(RC_RELEASE)" != "Beaker" ] && \ ++ X_CFLAGS := $(shell if [ `uname` != "Linux" ] && [ "$(RC_RELEASE)" != "Beaker" ] && \ + [ "$(RC_RELEASE)" != "Bunsen" ] && \ + [ "$(RC_RELEASE)" != "Gonzo" ] && \ + [ "$(RC_RELEASE)" != "Kodiak" ]; then \ +- echo -Wno-long-double -no-cpp-precomp; \ ++ echo -Wno-long-double -no-cpp-precomp ; \ + fi; ) + endif + +@@ -14,11 +14,16 @@ + CFLAGS = $(OFLAG) -g \ + -I$(SRCROOT) -I$(SRCROOT)/../include -I$(OFILE_DIR) + else +- CFLAGS = $(OFLAG) -g -Wall -Wno-precomp $(X_CFLAGS) \ ++ ifeq "Linux" "$(shell uname)" ++ CFLAGS = $(OFLAG) -g -Wall $(X_CFLAGS) \ ++ -I$(SRCROOT) -I$(SRCROOT)/../include -I$(OFILE_DIR) -D__ppc__ -I/usr/include -I../../macosx-include ++ else ++ CFLAGS = $(OFLAG) -g -Wall $(X_CFLAGS) \ + -I$(SRCROOT) -I$(SRCROOT)/../include -I$(OFILE_DIR) ++ endif + endif + +-USE_DEPENDENCY_FILE := $(shell if [ "$(notdir $(CC))" != "mwccppc" ]; then \ ++USE_DEPENDENCY_FILE := $(shell if [ `uname` != "Linux" ] && [ "$(notdir $(CC))" != "mwccppc" ]; then \ + echo YES ; else echo NO ; \ + fi; ) + +@@ -44,10 +49,7 @@ + LOCLIBDIR = /usr/local/lib + + CFILES1 = libtool.c +-CFILES2 = main.c lipo.c size.c strings.c nm.c checksyms.c inout.c \ +- indr.c strip.c atom.c segedit.c kern_tool.c cmpdylib.c \ +- dylib_pcsampler.c pagestuff.c redo_prebinding.c seg_addr_table.c \ +- check_dylib.c seg_hack.c check_hints.c install_name_tool.c ++CFILES2 = seg_hack.c strip.c + ifeq "nextstep" "$(RC_OS)" + CFILES3 = file.c ar.c + endif +@@ -56,11 +58,7 @@ + notes + + +-PROGS = lipo.NEW size.NEW strings.NEW nm.NEW \ +- libtool.NEW checksyms.NEW indr.NEW strip.NEW nmedit.NEW \ +- segedit.NEW kern_tool.NEW cmpdylib.NEW \ +- dylib_pcsampler.NEW pagestuff.NEW redo_prebinding.NEW \ +- seg_addr_table.NEW check_dylib.NEW seg_hack.NEW install_name_tool.NEW ++PROGS = seg_hack.NEW strip.NEW + + teflon_all macos_all: $(PROGS) + +@@ -71,7 +69,7 @@ + lib_ofiles: $(OFILE_DIR) $(SYMROOT) libredo_prebinding.a + + vers.c: +- vers_string -c $(VERS_STRING_FLAGS) cctools_misc > $(OFILE_DIR)/$@ ++ ./vers_string -c $(VERS_STRING_FLAGS) cctools_misc > $(OFILE_DIR)/$@ + + ifeq "NO" "$(USE_DEPENDENCY_FILE)" + .c.o: +@@ -222,6 +220,7 @@ + $(OFILE_DIR)/seg_hack.o $(OFILE_DIR)/vers.o $(LIBSTUFF) + $(CC) $(CFLAGS) $(RC_CFLAGS) -o $(SYMROOT)/seg_hack.NEW \ + $(OFILE_DIR)/seg_hack.private.o ++ cp $(SYMROOT)/seg_hack.NEW $(SYMROOT)/seg_hack + + install_name_tool.NEW: install_name_tool.o vers.o + $(CC) $(CFLAGS) $(RC_CFLAGS) -nostdlib -r \ +@@ -331,7 +330,8 @@ + $(SYMROOT)/redo_prebinding.NEW \ + $(SYMROOT)/libredo_prebinding.a \ + $(SYMROOT)/kern_tool.NEW \ +- $(SYMROOT)/cmpdylib.NEW ++ $(SYMROOT)/cmpdylib.NEW \ ++ $(SYMROOT)/seg_hack + + shlib_clean: + -rm -f \ +Only in misc: ar.c +Only in misc: atom.c +Only in misc: check_dylib.c +Only in misc: check_hints.c +Only in misc: checksyms.c +Only in misc: cmpdylib.c +Only in misc: dylib_pcsampler.c +Only in misc: file.c +Only in misc: indr.c +Only in misc: inout.c +Only in misc: install_name_tool.c +Only in misc: kern_tool.c +Only in misc: libtool.c +Only in misc: lipo.c +Only in misc: main.c +Only in misc: nm.c +diff -ubr misc/notes misc/notes +--- misc/notes Tue Jan 14 23:35:29 2003 ++++ misc/notes Mon Aug 25 12:12:34 2003 +@@ -7,6 +7,148 @@ + could have been set otherwise and does not print the next line. + - Maybe add fat support for segedit(1) + ++Changes for the 5.12 release (the cctools-474 release): ++- Fixed a bug in redo_prebinding that was leaking memory if the ++ allow_missing_architectures parameter was used and the fat file did not ++ contain an architecture. The fix was in load_library() in 4 places it ++ checks to see if the missing architecure is allowed to be missing and it now ++ unmap's the ofile before returning. Radar bug #3144803. ++ ++Changes for the 5.12 release (the cctools-472 release): ++- Fixed a bug in seg_addr_table(1) when run with -relayout the <<< Next split ++ address to assign >>> isn't getting set properly. The fix in in main() to add ++ relayout == FALSE to the if() condition for the code that loops and updates ++ the NEXT_SPLIT_ADDRESS_TO_ASSIGN. Radar bug #3245958. ++ ++Changes for the 5.12 release (the cctools-470 release): ++- Added the -c option to strip(1) to strip the section contents of a dynamic ++ shared library and create a stub library. Radar bug #3235093. ++- Changed install_name_tool(1) to not change MH_DYLIB_STUB filetypes. ++ Radar bug #3235093. ++- Added the flag -search_paths_first to cause -lx flags to search each path ++ for .dylib then .a before searching next path to libtool(1). Radar bug ++ #3176974. ++ - Added the enum bool variable search_paths_first to the cmd_flags struct and ++ code to parse out the option, set variable and add it to the ldflags[] in ++ main() . ++ - The new static routines search_paths_for_lname() and search_path_for_lname() ++ were added. ++ - In file_name_from_l_flag() a test of the new search_paths_first variable is ++ done and if TRUE then search_paths_for_lname() is called. ++ ++Changes for the 5.12 release (the cctools-469 release): ++- Added support for the -weak-lx, -weak_library and -weak_framework flags to ++ libtool(1). Radar bug #3069758. ++- Fixed a bug seg_addr_table(1) in next_flat_seg1addr() where the variable i ++ was previously changed to unsigned. The second loop uses this varaiable as ++ signed and thus this change was causing the loop to never terminate. Radar ++ bug 3225931. ++ ++Changes for the 5.12 release (the cctools-466 release): ++- Fixed a bug in libtool(1) for the -static option that caused it to crash if ++ the objects contained no symbols to put in the table of contents. Radar bug ++ #3217471. ++- Fixed the incorrect casts on the comparison of the nlist struct's n_strx field ++ where the value being compared to was casted to a long. The correct fix was ++ to cast n_strx to an unsigned long. ++- Changed print_mach_symbols() in nm.c to print "(dynamically looked up)" for ++ the library ordinal DYNAMIC_LOOKUP_ORDINAL which are looked up dynamically ++ with flat namespace semantics in two-level namespace images. Radar bug ++ #3210803. ++- Changed get_primary_lib() in redo_prebinding.c to check for the library ++ ordinal DYNAMIC_LOOKUP_ORDINAL and return NULL. Radar bug #3210803. ++ ++Changes for the 5.12 release (the cctools-464 release): ++- Made changes to build cleanly with gcc3.3 ++ - Removed -Wno-precomp from the Makefile ++ - Fixed warnings for "comparison between signed and unsigned" in lipo.c, ++ size.c, strings.c, nm.c, libtool.c, checksyms.c, indr.c, strip.c, segedit.c, ++ kern_tool.c, cmpdylib.c, dylib_pcsampler.c, pagestuff.c, redo_prebinding.c, ++ seg_addr_table.c, check_dylib.c, seg_hack.c and install_name_tool.c. ++ ++Changes for the 5.12 release (the cctools-463 release): ++- Added support for MH_DYLIB_STUB libraries. Radar bug #3193744. ++ - Added the testing for MH_DYLIB_STUB along with MH_DYLIB in add_member() ++ in libtool.c . ++ - Added the testing for MH_DYLIB_STUB along with MH_DYLIB in ++ translate_object() in indr.c in the error check. ++ - Added a case for MH_DYLIB_STUB in type_buf() in file.c (note this is the ++ old file(1) command and is no longer used). ++ - Added the testing for MH_DYLIB_STUB along with MH_DYLIB in check_dylib() ++ in cmpdylib.c in 2 places. ++ - Added the testing for MH_DYLIB_STUB along with MH_DYLIB in checksyms() and ++ in check_dynamic_binary() in checksyms.c in 3 places in all. ++ - Added the testing for MH_DYLIB_STUB along with MH_DYLIB in check_hints.c . ++ ++Changes for the 5.12 release (the cctools-461 release): ++- Fixed a bug in install_name_tool(1) that caused it to crash when the new ++ load commands were smaller than the old load commands. Radar bug #3161586. ++ ++Changes for the 5.12 release (the cctools-456 release): ++- Fixed a bug in the redo_prebinding code when the allow_missing_architectures ++ parameter to the redo_prebinding() API is non-zero. In the routine ++ load_library() an extra check is needed to not cause an error if we are ++ allowing missing architectures. The case where this happens is when there ++ is a fat file that the architecture we don't care about depends on a library ++ in another fat file but the time stamps for the libraries don't match. ++ Radar bug #3144552. ++ ++Changes for the 5.12 release (the cctools-455 release): ++- Fixed a bug in the redo_prebinding code in the routine link_library_module() ++ in redo_prebinding.c. The problem was that when a reference to a private ++ extern was found only the module containing it was marked linked. A call ++ to link_library_module() for that module was needed to pull in its ++ dependencies and get those modules marked as LINKED. Radar bug #3126383. ++ ++Changes for the 5.12 release (the cctools-454 release): ++- Fixed a bug where seg_addr_table doesn't catch when an address is assigned in ++ the "alternate" area. seg_addr_table(1) was using the wrong constant to ++ check the validity of newly assigned addresses, the fix is to use the correct ++ constant. Radar bug #3138181. ++ ++Changes for the 5.12 release (the cctools-452 release): ++- Fixed the bug fix done for Radar bug #3124262 below in the redo_prebinding ++ code. The copied code from the above loop was wrong as it changed this: ++ if(libs[i].module_states[j] == LINKED) ++ to this: ++ if(libs[j].module_states[k] == LINKED || ++ (prebind_all_twolevel_modules == TRUE && ++ (libs[j].ofile->mh->flags & MH_TWOLEVEL) == ++ MH_TWOLEVEL)) ++ which should have been this: ++ if(libs[i].module_states[j] == LINKED || ++ (prebind_all_twolevel_modules == TRUE && ++ (libs[i].ofile->mh->flags & MH_TWOLEVEL) == ++ MH_TWOLEVEL)) ++ which used the correct index variables. Radar bug #3133589. ++ ++Changes for the 5.12 release (the cctools-451 release): ++- Fixed a bug in the redo_prebinding code that did not set the all the bits ++ in the linked_modules bit vector for any new LC_PREBOUND_DYLIB load commands ++ when prebind_all_twolevel_modules was TRUE. Radar bug #3124262. ++ ++Changes for the 5.12 release (the cctools-448 release): ++- Added an entry stabnames[] array in nm.c for N_OPT that is emitted with ++ gcc2_compiled and in gcc source. Radar bug #3104328. ++ ++Changes for the 5.12 release (the cctools-447 release): ++- Fixed a bug in add_member() in libtool.c when get_arch_family_from_cputype() ++ returns NULL. ++ ++Changes for the 5.11 release (the cctools-446 release): ++- Added passing -x from libtool to ld. Radar bug #3088301. ++ ++Changes for the 5.11 release (the cctools-444 release): ++- Added passing -exported_symbols_list & -unexported_symbols_list from libtool ++ to ld. Radar bug #3083844. ++- Factored out some of the symbol list stuff out of strip.c into libstuff so ++ ld(1)'s -exported_symbols_list and -unexported_symbols_list options can use ++ it. Radar bug #3083844. ++ ++Changes for the 5.11 release (the cctools-443 release): ++- Added passing -single_module & -multi_module from libtool to ld. Also added ++ passing -u flags. Radar #3080780. ++ + Changes for the 5.11 release (the cctools-440 release): + - Fixed the warnings about extra tokens at end of #endif directive in + check_hints.c, strip.c and make_defs.h (Radar bug #3072042). +Only in misc: pagestuff.c +Only in misc: redo_prebinding.c +Only in misc: seg_addr_table.c +diff -ubr misc/seg_hack.c misc/seg_hack.c +--- misc/seg_hack.c Fri Sep 6 18:28:06 2002 ++++ misc/seg_hack.c Mon Aug 25 12:12:34 2003 +@@ -58,7 +58,7 @@ + char **argv, + char **envp) + { +- unsigned long i; ++ int i; + char *input, *output; + struct arch *archs; + unsigned long narchs; +Only in misc: segedit.c +Only in misc: size.c +Only in misc: strings.c +diff -ubr misc/strip.c misc/strip.c +--- misc/strip.c Tue Jan 14 23:35:30 2003 ++++ misc/strip.c Mon Aug 25 22:02:32 2003 +@@ -38,11 +38,13 @@ + #include + #include + #include +-#include +-#include +-#include +-#include ++#include "stuff/breakout.h" ++#include "stuff/allocate.h" ++#include "stuff/errors.h" ++#include "stuff/round.h" + #include "stuff/reloc.h" ++#include "stuff/reloc.h" ++#include "stuff/symbol_list.h" + + /* These are set from the command line arguments */ + char *progname; /* name of the program for error messages (argv[0]) */ +@@ -62,6 +64,8 @@ + static long Sflag; /* -S strip only debugger symbols N_STAB */ + static long xflag; /* -x strip non-globals */ + static long Xflag; /* -X strip local symbols with 'L' names */ ++static long cflag; /* -c strip section contents from dynamic libraries ++ files to create stub libraries */ + static long strip_all = 1; + /* + * This is set on an object by object basis if the strip_all flag is still set +@@ -76,11 +80,6 @@ + * save_symbols is the names of the symbols from the -s argument. + * remove_symbols is the names of the symbols from the -R argument. + */ +-struct symbol_list { +- char *name; /* name of the global symbol */ +- struct nlist *sym; /* pointer to the nlist structure for this symbol */ +- enum bool seen; /* set if the symbol is seen in the input file */ +-}; + static struct symbol_list *save_symbols = NULL; + static unsigned long nsave_symbols = 0; + static struct symbol_list *remove_symbols = NULL; +@@ -106,12 +105,12 @@ + * and the new counts of local, defined external and undefined symbols. + */ + static struct nlist *new_symbols = NULL; +-static long new_nsyms = 0; ++static unsigned long new_nsyms = 0; + static char *new_strings = NULL; +-static long new_strsize = 0; +-static long new_nlocalsym = 0; +-static long new_nextdefsym = 0; +-static long new_nundefsym = 0; ++static unsigned long new_strsize = 0; ++static unsigned long new_nlocalsym = 0; ++static unsigned long new_nextdefsym = 0; ++static unsigned long new_nundefsym = 0; + + /* + * These hold the new table of contents, reference table and module table for +@@ -169,9 +168,9 @@ + struct member *member, + struct object *object, + struct nlist *symbols, +- long nsyms, ++ unsigned long nsyms, + char *strings, +- long strsize, ++ unsigned long strsize, + struct dylib_table_of_contents *tocs, + unsigned long ntoc, + struct dylib_module *mods, +@@ -202,9 +201,9 @@ + struct member *member, + struct object *object, + struct nlist *symbols, +- long nsyms, ++ unsigned long nsyms, + char *strings, +- long strsize, ++ unsigned long strsize, + struct dylib_table_of_contents *tocs, + unsigned long ntoc, + struct dylib_module *mods, +@@ -213,19 +212,6 @@ + unsigned long nextrefsyms); + #endif /* NMEDIT */ + +-static void setup_symbol_list( +- char *file, +- struct symbol_list **list, +- unsigned long *size); +- +-static int cmp_qsort_name( +- const struct symbol_list *sym1, +- const struct symbol_list *sym2); +- +-static int cmp_bsearch( +- const char *name, +- const struct symbol_list *sym); +- + #ifndef NMEDIT + static void setup_debug_filenames( + char *dfile); +@@ -260,7 +246,8 @@ + char *argv[], + char *envp[]) + { +- unsigned long i, j, args_left, files_specified; ++ int i; ++ unsigned long j, args_left, files_specified; + struct arch_flag *arch_flags; + unsigned long narch_flags; + enum bool all_archs; +@@ -388,6 +375,12 @@ + strip_all = 0; + #endif /* !defined(NMEDIT) */ + break; ++#ifndef NMEDIT ++ case 'c': ++ cflag = 1; ++ strip_all = 0; ++ break; ++#endif /* NMEDIT */ + default: + error("unrecognized option: %s", argv[i]); + usage(); +@@ -421,16 +414,16 @@ + if(Rfile){ + setup_symbol_list(Rfile, &remove_symbols, &nremove_symbols); + if(sfile){ +- for(i = 0; i < nremove_symbols ; i++){ +- sp = bsearch(remove_symbols[i].name, ++ for(j = 0; j < nremove_symbols ; j++){ ++ sp = bsearch(remove_symbols[j].name, + save_symbols, nsave_symbols, + sizeof(struct symbol_list), + (int (*)(const void *, const void *)) +- cmp_bsearch); ++ symbol_list_bsearch); + if(sp != NULL){ + error("symbol name: %s is listed in both -s %s and -R " + "%s files (can't be both saved and removed)", +- remove_symbols[i].name, sfile, Rfile); ++ remove_symbols[j].name, sfile, Rfile); + } + } + if(errors) +@@ -635,7 +628,7 @@ + + /* + * Now this arch[i] has been selected to be processed so process it +- * according to it's type. ++ * according to its type. + */ + if(archs[i].type == OFILE_ARCHIVE){ + for(j = 0; j < archs[i].nmembers; j++){ +@@ -753,7 +746,7 @@ + unsigned long nextrefsyms; + unsigned long *indirectsyms; + unsigned long nindirectsyms; +- long i, j, k; ++ unsigned long i, j, k; + struct load_command *lc; + struct segment_command *sg; + struct section *s; +@@ -780,6 +773,15 @@ + strings = object->object_addr + object->st->stroff; + strsize = object->st->strsize; + ++#ifndef NMEDIT ++ if(object->mh->filetype != MH_DYLIB && cflag) ++ fatal_arch(arch, member, "-c can't be used on non-dynamic " ++ "library: "); ++#endif /* !(NMEDIT) */ ++ if(object->mh->filetype == MH_DYLIB_STUB) ++ fatal_arch(arch, member, "dynamic stub library can't be changed " ++ "once created: "); ++ + if(object->mh->filetype == MH_DYLIB){ + tocs = (struct dylib_table_of_contents *) + (object->object_addr + object->dyst->tocoff); +@@ -795,6 +797,71 @@ + swap_dylib_module(mods, nmodtab, host_byte_sex); + swap_dylib_reference(refs, nextrefsyms, host_byte_sex); + } ++#ifndef NMEDIT ++ /* ++ * In the -c flag is specified then strip the section contents of ++ * this dynamic library and change it into a stub library. When ++ * creating a stub library the timestamp is not changed. ++ */ ++ if(cflag){ ++ object->mh->filetype = MH_DYLIB_STUB; ++ arch->dont_update_LC_ID_DYLIB_timestamp = TRUE; ++ ++ lc = object->load_commands; ++ for(i = 0; i < object->mh->ncmds; i++){ ++ if(lc->cmd == LC_SEGMENT){ ++ sg = (struct segment_command *)lc; ++ if(strcmp(sg->segname, SEG_LINKEDIT) != 0){ ++ /* ++ * Zero out the section offset, reloff, and size ++ * fields as the section contents are being removed. ++ */ ++ s = (struct section *)&sg[1]; ++ for(j = 0; j < sg->nsects; j++){ ++ /* ++ * For section types with indirect tables we ++ * do not zero out the section size in a stub ++ * library. As the section size is needed to ++ * know now many indirect table entries the ++ * section has. This is a bit odd but programs ++ * dealing with MH_DYLIB_STUB filetypes special ++ * case this. ++ */ ++ section_type = s[j].flags & SECTION_TYPE; ++ if(section_type != S_SYMBOL_STUBS && ++ section_type != S_LAZY_SYMBOL_POINTERS && ++ section_type != S_NON_LAZY_SYMBOL_POINTERS){ ++ s[j].size = 0; ++ } ++ s[j].addr = 0; ++ s[j].offset = 0; ++ s[j].reloff = 0; ++ } ++ /* zero out file offset and size in the segment */ ++ sg->fileoff = 0; ++ sg->filesize = 0; ++ } ++ } ++ lc = (struct load_command *)((char *)lc + lc->cmdsize); ++ } ++ /* ++ * To get the right amount of the file copied out by writeout() ++ * for the case when we are stripping out the section contents ++ * we reduce the object size by the size of the section contents ++ * including the padding after the load commands. Then this ++ * size minus the size of the input symbolic information is ++ * copied out. ++ */ ++ object->object_size -= (object->seg_linkedit->fileoff - ++ (sizeof(struct mach_header) + object->mh->sizeofcmds)); ++ /* ++ * Set the file offset to the link edit information to be right ++ * after the load commands. ++ */ ++ object->seg_linkedit->fileoff = ++ sizeof(struct mach_header) + object->mh->sizeofcmds; ++ } ++#endif /* !(NMEDIT) */ + } + else{ + tocs = NULL; +@@ -877,7 +944,12 @@ + + } + +- if(object->mh->filetype == MH_DYLIB){ ++ /* ++ * If the -c option is specified the object's filetype will ++ * have been changed from MH_DYLIB to MH_DYLIB_STUB above. ++ */ ++ if(object->mh->filetype == MH_DYLIB || ++ object->mh->filetype == MH_DYLIB_STUB){ + object->output_tocs = new_tocs; + object->output_ntoc = new_ntoc; + #ifdef NMEDIT +@@ -910,9 +982,20 @@ + object->dyst->ntoc * sizeof(struct dylib_table_of_contents)+ + object->dyst->nmodtab * sizeof(struct dylib_module) + + object->dyst->nextrefsyms * sizeof(struct dylib_reference); ++#ifndef NMEDIT ++ /* ++ * When stripping out the section contents to create a ++ * dynamic library stub the relocation info also gets ++ * stripped. ++ */ ++ if(!cflag) ++#endif /* !(NMEDIT) */ ++ { + object->output_sym_info_size += + object->dyst->nlocrel * sizeof(struct relocation_info) + +- object->dyst->nextrel * sizeof(struct relocation_info) + ++ object->dyst->nextrel * sizeof(struct relocation_info); ++ } ++ object->output_sym_info_size += + object->dyst->nindirectsyms * sizeof(unsigned long) + + new_ntoc * sizeof(struct dylib_table_of_contents)+ + object->dyst->nmodtab * sizeof(struct dylib_module) + +@@ -961,10 +1044,24 @@ + if(object->dyst->nlocrel != 0){ + object->output_loc_relocs = (struct relocation_info *) + (object->object_addr + object->dyst->locreloff); ++#ifndef NMEDIT ++ /* ++ * When stripping out the section contents to create a ++ * dynamic library stub the relocation info also gets ++ * stripped. ++ */ ++ if(cflag){ ++ object->dyst->nlocrel = 0; ++ object->dyst->locreloff = 0; ++ } ++ else ++#endif /* defined(NMEDIT) */ ++ { + object->dyst->locreloff = offset; + offset += object->dyst->nlocrel * + sizeof(struct relocation_info); + } ++ } + else + object->dyst->locreloff = 0; + +@@ -990,10 +1087,24 @@ + if(object->dyst->nextrel != 0){ + object->output_ext_relocs = (struct relocation_info *) + (object->object_addr + object->dyst->extreloff); ++#ifndef NMEDIT ++ /* ++ * When stripping out the section contents to create a ++ * dynamic library stub the relocation info also gets ++ * stripped. ++ */ ++ if(cflag){ ++ object->dyst->nextrel = 0; ++ object->dyst->extreloff = 0; ++ } ++ else ++#endif /* defined(NMEDIT) */ ++ { + object->dyst->extreloff = offset; + offset += object->dyst->nextrel * + sizeof(struct relocation_info); + } ++ } + else + object->dyst->extreloff = 0; + +@@ -1014,6 +1125,24 @@ + object->dyst->tocoff = 0; + + if(object->dyst->nmodtab != 0){ ++#ifndef NMEDIT ++ /* ++ * When stripping out the section contents to create a ++ * dynamic library stub zero out the fields in the module ++ * table for the sections and relocation information. ++ */ ++ if(cflag){ ++ /* Clear Objective-C address and size from modules. */ ++ for(k = 0; k < object->dyst->nmodtab; k++){ ++ mods[k].iinit_iterm = 0; ++ mods[k].ninit_nterm = 0; ++ mods[k].iextrel = 0; ++ mods[k].nextrel = 0; ++ mods[k].objc_module_info_addr = 0; ++ mods[k].objc_module_info_size = 0; ++ } ++ } ++#endif /* !(NMEDIT) */ + object->dyst->modtaboff = offset; + offset += object->dyst->nmodtab * + sizeof(struct dylib_module); +@@ -1423,120 +1552,6 @@ + } + } + +-/* +- * This is called to setup a symbol list from a file. It reads the file with +- * the strings in it and places them in an array of symbol_list structures and +- * then sorts them by name. +- * +- * The file that contains the symbol names must have symbol names one per line, +- * leading and trailing white space is removed and lines starting with a '#' +- * and lines with only white space are ignored. +- */ +-static +-void +-setup_symbol_list( +-char *file, +-struct symbol_list **list, +-unsigned long *size) +-{ +- int fd, i, j, len, strings_size; +- struct stat stat_buf; +- char *strings, *p, *line; +- +- if((fd = open(file, O_RDONLY)) < 0){ +- system_error("can't open: %s", file); +- return; +- } +- if(fstat(fd, &stat_buf) == -1){ +- system_error("can't stat: %s", file); +- close(fd); +- return; +- } +- strings_size = stat_buf.st_size; +- strings = (char *)allocate(strings_size + 2); +- strings[strings_size] = '\n'; +- strings[strings_size + 1] = '\0'; +- if(read(fd, strings, strings_size) != strings_size){ +- system_error("can't read: %s", file); +- close(fd); +- return; +- } +- /* +- * Change the newlines to '\0' and count the number of lines with +- * symbol names. Lines starting with '#' are comments and lines +- * contain all space characters do not contain symbol names. +- */ +- p = strings; +- line = p; +- for(i = 0; i < strings_size + 1; i++){ +- if(*p == '\n' || *p == '\r'){ +- *p = '\0'; +- if(*line != '#'){ +- while(*line != '\0' && isspace(*line)) +- line++; +- if(*line != '\0') +- (*size)++; +- } +- p++; +- line = p; +- } +- else{ +- p++; +- } +- } +- *list = (struct symbol_list *) +- allocate((*size) * sizeof(struct symbol_list)); +- +- /* +- * Place the strings in the list trimming leading and trailing spaces +- * from the lines with symbol names. +- */ +- p = strings; +- line = p; +- for(i = 0; i < (*size); ){ +- p += strlen(p) + 1; +- if(*line != '#' && *line != '\0'){ +- while(*line != '\0' && isspace(*line)) +- line++; +- if(*line != '\0'){ +- (*list)[i].name = line; +- (*list)[i].seen = FALSE; +- i++; +- len = strlen(line); +- j = len - 1; +- while(j > 0 && isspace(line[j])){ +- j--; +- } +- if(j > 0 && j + 1 < len && isspace(line[j+1])) +- line[j+1] = '\0'; +- } +- } +- line = p; +- } +- +- qsort(*list, *size, sizeof(struct symbol_list), +- (int (*)(const void *, const void *))cmp_qsort_name); +- +- /* remove duplicates on the list */ +- for(i = 0; i < (*size); i++){ +- if(i + 1 < (*size)){ +- if(strcmp((*list)[i].name, (*list)[i+1].name) == 0){ +- for(j = 1; j < ((*size) - i - 1); j++){ +- (*list)[i + j].name = (*list)[i + j + 1].name; +- } +- *size = *size - 1; +- } +- } +- } +- +-#ifdef DEBUG +- printf("symbol list:\n"); +- for(i = 0; i < (*size); i++){ +- printf("0x%x name = %s\n", &((*list)[i]),(*list)[i].name); +- } +-#endif /* DEBUG */ +-} +- + #ifndef NMEDIT + /* + * This is called if there is a -d option specified. It reads the file with +@@ -1609,9 +1624,9 @@ + struct member *member, + struct object *object, + struct nlist *symbols, +-long nsyms, ++unsigned long nsyms, + char *strings, +-long strsize, ++unsigned long strsize, + struct dylib_table_of_contents *tocs, + unsigned long ntoc, + struct dylib_module *mods, +@@ -1621,7 +1636,8 @@ + unsigned long *indirectsyms, + unsigned long nindirectsyms) + { +- long i, j, k, n, inew_syms, save_debug, missing_syms, missing_symbols; ++ unsigned long i, j, k, n, inew_syms, save_debug, missing_syms; ++ unsigned long missing_symbols; + char *p, *q, **pp, *basename; + struct symbol_list *sp; + unsigned long new_ext_strsize, len, *changes, inew_undefsyms; +@@ -1686,7 +1702,7 @@ + for(i = 0; i < nsyms; i++){ + if(symbols[i].n_un.n_strx != 0){ + if(symbols[i].n_un.n_strx < 0 || +- symbols[i].n_un.n_strx > strsize){ ++ (unsigned long)symbols[i].n_un.n_strx > strsize){ + error_arch(arch, member, "bad string index for symbol " + "table entry %ld in: ", i); + return(FALSE); +@@ -1838,7 +1854,7 @@ + save_symbols, nsave_symbols, + sizeof(struct symbol_list), + (int (*)(const void *, const void *)) +- cmp_bsearch); ++ symbol_list_bsearch); + if(sp != NULL){ + if(sp->sym == NULL){ + sp->sym = &(symbols[i]); +@@ -1885,7 +1901,7 @@ + remove_symbols, nremove_symbols, + sizeof(struct symbol_list), + (int (*)(const void *, const void *)) +- cmp_bsearch); ++ symbol_list_bsearch); + if(sp != NULL){ + if((symbols[i].n_type & N_TYPE) == N_UNDF || + (symbols[i].n_type & N_TYPE) == N_PBUD){ +@@ -1960,7 +1976,7 @@ + save_symbols, nsave_symbols, + sizeof(struct symbol_list), + (int (*)(const void *, const void *)) +- cmp_bsearch); ++ symbol_list_bsearch); + if(sp != NULL){ + if(sp->sym != NULL && + (sp->sym->n_type & N_PEXT) != N_PEXT){ +@@ -2467,30 +2483,6 @@ + } + #endif /* !defined(NMEDIT) */ + +-/* +- * Function for qsort for comparing symbol list names. +- */ +-static +-int +-cmp_qsort_name( +-const struct symbol_list *sym1, +-const struct symbol_list *sym2) +-{ +- return(strcmp(sym1->name, sym2->name)); +-} +- +-/* +- * Function for bsearch for finding a symbol. +- */ +-static +-int +-cmp_bsearch( +-const char *name, +-const struct symbol_list *sym) +-{ +- return(strcmp(name, sym->name)); +-} +- + #ifndef NMEDIT + /* + * Function for qsort for comparing object names. +@@ -2525,9 +2517,9 @@ + struct member *member, + struct object *object, + struct nlist *symbols, +-long nsyms, ++unsigned long nsyms, + char *strings, +-long strsize, ++unsigned long strsize, + struct dylib_table_of_contents *tocs, + unsigned long ntoc, + struct dylib_module *mods, +@@ -2667,7 +2659,7 @@ + len = 0; + if(symbols[i].n_un.n_strx != 0){ + if(symbols[i].n_un.n_strx < 0 || +- symbols[i].n_un.n_strx > strsize){ ++ (unsigned long)symbols[i].n_un.n_strx > strsize){ + error_arch(arch, member, "bad string index for symbol " + "table entry %lu in: ", i); + return(FALSE); +@@ -2695,7 +2687,7 @@ + remove_symbols, nremove_symbols, + sizeof(struct symbol_list), + (int (*)(const void *, const void *)) +- cmp_bsearch); ++ symbol_list_bsearch); + if(sp != NULL){ + if(sp->sym != NULL){ + error_arch(arch, member, "more than one " +@@ -2719,7 +2711,7 @@ + save_symbols, nsave_symbols, + sizeof(struct symbol_list), + (int (*)(const void *, const void *)) +- cmp_bsearch); ++ symbol_list_bsearch); + if(sp != NULL){ + if(sp->sym != NULL){ + error_arch(arch, member, "more than one " +@@ -2738,7 +2730,7 @@ + remove_symbols, nremove_symbols, + sizeof(struct symbol_list), + (int (*)(const void *, const void *)) +- cmp_bsearch); ++ symbol_list_bsearch); + if(sp != NULL){ + if(sp->sym != NULL){ + error_arch(arch, member, "more than one symbol " +@@ -2777,7 +2769,7 @@ + save_symbols, nsave_symbols, + sizeof(struct symbol_list), + (int (*)(const void *, const void *)) +- cmp_bsearch); ++ symbol_list_bsearch); + if(sp != NULL){ + if(sp->sym != NULL){ + error_arch(arch, member, "more than one symbol " +@@ -2910,19 +2902,19 @@ + if((global_name[0] == '+' || global_name[0] == '-') && + global_name[1] == '['){ + j = 2; +- while(j + symbols[i].n_un.n_strx < strsize && ++ while(j + (unsigned long)symbols[i].n_un.n_strx < strsize && + global_name[j] != ']') + j++; +- if(j + symbols[i].n_un.n_strx < strsize && ++ if(j + (unsigned long)symbols[i].n_un.n_strx < strsize && + global_name[j] == ']') + j++; + } + else + j = 0; +- while(j + symbols[i].n_un.n_strx < strsize && ++ while(j + (unsigned long)symbols[i].n_un.n_strx < strsize && + global_name[j] != ':') + j++; +- if(j + symbols[i].n_un.n_strx >= strsize){ ++ if(j + (unsigned long)symbols[i].n_un.n_strx >= strsize){ + error_arch(arch, member, "bad N_STAB symbol name for entry " + "%lu (does not contain ':' separating name from type) " + "in: ", i); +@@ -2945,7 +2937,8 @@ + symbols[i].n_sect = (*global_symbol)->n_sect; + symbols[i].n_value = (*global_symbol)->n_value; + symbols[i].n_desc = (*global_symbol)->n_desc; +- if(j + 1 + symbols[i].n_un.n_strx >= strsize || ++ if(j + 1 + (unsigned long)symbols[i].n_un.n_strx >= ++ strsize || + global_name[j+1] != 'G'){ + error_arch(arch, member, "bad N_GSYM symbol name " + "for entry %lu (does not have type 'G' after " +@@ -2955,7 +2948,8 @@ + global_name[j+1] = 'S'; + } + else{ /* symbols[i].n_type == N_FUN */ +- if(j + 1 + symbols[i].n_un.n_strx >= strsize || ++ if(j + 1 + (unsigned long)symbols[i].n_un.n_strx >= ++ strsize || + global_name[j+1] == 'F'){ + global_name[j+1] = 'f'; + } +Only in misc: vers_string -- 1.7.10.4