2003/09/07 04:31:44
authormegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:04:56 +0000 (07:04 +0000)
committermegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:04:56 +0000 (07:04 +0000)
darcs-hash:20040130070456-2ba56-7683629f2168012e337456e98863ca020fd3da3b.gz

upstream/darwin-linker/patches/include.patch [new file with mode: 0644]
upstream/darwin-linker/patches/ld.patch [new file with mode: 0644]
upstream/darwin-linker/patches/libstuff.patch [new file with mode: 0644]
upstream/darwin-linker/patches/misc.patch [new file with mode: 0644]

diff --git a/upstream/darwin-linker/patches/include.patch b/upstream/darwin-linker/patches/include.patch
new file mode 100644 (file)
index 0000000..75f9ba6
--- /dev/null
@@ -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 <architecture/i386/sel.h>
++#include <architecture/i386/sel.h>
+ /*
+  * 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 <architecture/i386/sel.h>
++#include <architecture/i386/sel.h>
+ /*
+  * 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 <architecture/m88k/reg_help.h>
++#include <architecture/m88k/reg_help.h>
+ /*
+  * 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 <architecture/nrw/reg_help.h>
++#include <architecture/nrw/reg_help.h>
+ /* 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 <architecture/m88k/fp_regs.h>
+-#import <architecture/m88k/reg_help.h>
++#include <architecture/m88k/fp_regs.h>
++#include <architecture/m88k/reg_help.h>
+ /**************************************************************************
+  * 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 <mach/machine/vm_types.h>
+-#import <mach/boolean.h>
++#include <mach/machine/vm_types.h>
++#include <mach/boolean.h>
+ /*
+  *    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 <architecture/byte_order.h>
+-#import <mach/hppa/thread_status.h>
++#include <architecture/byte_order.h>
++#include <mach/hppa/thread_status.h>
+ 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 <architecture/byte_order.h>
+-#import <mach/i860/thread_status.h>
++#include <architecture/byte_order.h>
++#include <mach/i860/thread_status.h>
+ 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 <architecture/byte_order.h>
+-#import <mach/m68k/thread_status.h>
++#include <architecture/byte_order.h>
++#include <mach/m68k/thread_status.h>
+ 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 <architecture/byte_order.h>
+-#import <mach/m88k/thread_status.h>
++#include <architecture/byte_order.h>
++#include <mach/m88k/thread_status.h>
+ 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 <streams/streams.h>
++//~ #include <streams/streams.h>
+ #include <mach-o/loader.h>
+ 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 <architecture/byte_order.h>
+-#import <mach/sparc/thread_status.h>
++#include <architecture/byte_order.h>
++#include <mach/sparc/thread_status.h>
+ 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 <mach-o/kld.h> 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 <mach-o/ppc/reloc.h> 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 <mach-o/ppc/reloc.h>
++  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 <mach-o/nlist.h> 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 <mach-o/loader.h> where "alwasys" should be "always"
++  Radar bug #3198288.
++- Added the prototype for the SPI NSHasModInitObjectFileImage() to
++  <mach-o/dyld.h> .  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 <mach-o/loader.h> .  Radar bug #3193744.
++
++Changes for the 5.12 release (the cctools-462 release):
++- Added the constant:
++    #define NSLINKMODULE_OPTION_TRAILING_PHYS_NAME 0x10
++  to <mach-o/dyld.h> and comments to <mach-o/dyld_gdb.h> .  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 <mach-o/dyld.h> .  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 <mach-o/dyld.h> :
++    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 <cbt/libsyminfo.h>.  Radar bug 3145742.
++
++Changes for the 5.12 release (the cctools-448 release):
++- Added the N_OPT constant to <mach-o/stabs.h> which is emitted with
++  gcc2_compiled and in gcc source.  Radar bug #3104328.
++- Added the _dyld_get_image_header_containing_address() SPI prototype to
++  <mach-o/dyld.h> (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
++  <mach-o/dyld.h>.  Radar bug #3055372.
++
++Changes for the 5.11 release (the cctools-444 release):
++- Added the file <stuff/symbol_list.h> 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 <mach/machine.h>.  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 <mach/mach.h>
++#include <mach/mach.h>
+ #else /* defined(KLD) && defined(__STATIC__) */
+ #include <mach/kern_return.h>
+ #endif /* !(defined(KLD) && defined(__STATIC__)) */
+-#import <mach-o/loader.h>
+-#import <stdarg.h>
+-#import <stddef.h>
++#include <mach-o/loader.h>
++#include <stdarg.h>
++#include <stddef.h>
+ #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 <mach/machine.h>
+-#import <stuff/bytesex.h>
++#include <mach/machine.h>
++#include <stuff/bytesex.h>
+ /*
+  * 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 <mach/machine.h>
+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 <mach-o/fat.h>
+-#import <mach-o/loader.h>
+-#import <mach/m68k/thread_status.h>
+-#import <mach/ppc/thread_status.h>
+-#import <mach/m88k/thread_status.h>
+-#import <mach/i860/thread_status.h>
+-#import <mach/i386/thread_status.h>
+-#import <mach/hppa/thread_status.h>
+-#import <mach/sparc/thread_status.h>
+-#import <mach-o/nlist.h>
+-#import <mach-o/reloc.h>
+-#import <mach-o/ranlib.h>
+-#import "stuff/bool.h"
++#include <mach-o/fat.h>
++#include <mach-o/loader.h>
++#include <mach/m68k/thread_status.h>
++#include <mach/ppc/thread_status.h>
++#include <mach/m88k/thread_status.h>
++#include <mach/i860/thread_status.h>
++#include <mach/i386/thread_status.h>
++#include <mach/hppa/thread_status.h>
++#include <mach/sparc/thread_status.h>
++#include <mach-o/nlist.h>
++#include <mach-o/reloc.h>
++#include <mach-o/ranlib.h>
++#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 <ar.h>
++#include <ar.h>
+ #ifndef AR_EFMT1
+ #define       AR_EFMT1        "#1/"           /* extended format #1 */
+ #endif
+-#import <mach-o/loader.h>
++#include <mach-o/loader.h>
+ #ifdef OFI
+-#import <mach-o/dyld.h>
++#include <mach-o/dyld.h>
+ #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 <stdarg.h>
++#include <stdarg.h>
+ __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 <mach/machine.h>
+-#import "stuff/bool.h"
++#include <mach/machine.h>
++#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 <mach/mach.h>
++#include <mach/mach.h>
+ __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 (file)
index 0000000..8657fd0
--- /dev/null
@@ -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 <mach-o/fat.h> 
+ #include <mach-o/loader.h> 
+-#import <mach/m68k/thread_status.h>
+-#import <mach/ppc/thread_status.h>
+-#import <mach/m88k/thread_status.h>
+-#import <mach/i860/thread_status.h>
+-#import <mach/i386/thread_status.h>
+-#import <mach/hppa/thread_status.h>
+-#import <mach/sparc/thread_status.h>
++#include <mach/m68k/thread_status.h>
++#include <mach/ppc/thread_status.h>
++#include <mach/m88k/thread_status.h>
++#include <mach/i860/thread_status.h>
++#include <mach/i386/thread_status.h>
++#include <mach/hppa/thread_status.h>
++#include <mach/sparc/thread_status.h>
+ #include <mach-o/nlist.h>
+ #include <mach-o/reloc.h>
++
++#include <mach/kern_return.h>
++
+ #if defined(RLD) && !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__))
++typedef void NXStream;
+ #include <mach-o/rld.h>
+-#include <streams/streams.h>
++//~ #include <streams/streams.h>
+ #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 <mach/mach.h>
+ #include <mach/mach_error.h>
+ #include "stuff/seg_addr_table.h"
++#ifndef RLD
++#include "stuff/symbol_list.h"
++#endif
+ #include "make.h"
+ #include <mach/mach_init.h>
+ #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 <mach-o/fat.h>
+ #include <mach-o/nlist.h>
+-#ifdef KLD
++//~ #ifdef KLD
+ #include <mach-o/kld.h>
+-#else /* !defined(KLD) */
++#ifndef KLD
++//~ #else /* !defined(KLD) */
++typedef void NXStream;
+ #include <mach-o/rld.h>
+-#include <streams/streams.h>
++//~ #include <streams/streams.h>
+ #include <objc/zone.h>
+ #endif /* KLD */
+ #include <mach-o/rld_state.h>
+@@ -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 (file)
index 0000000..c6c3ec7
--- /dev/null
@@ -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 <libc.h>
+-#import <ctype.h>
+-#import <sys/types.h>
++#include <libc.h>
++#include <ctype.h>
++#include <sys/types.h>
+ #ifdef __OPENSTEP__
+ #define _POSIX_SOURCE
+ #endif
+-#import <dirent.h>
+-#import <pwd.h>
+-#import "stuff/bool.h"
+-#import "stuff/errors.h"
+-#import "stuff/allocate.h"
+-#import "stuff/SymLoc.h"
++#include <dirent.h>
++#include <pwd.h>
++#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 <string.h>
+ #include <mach-o/fat.h>
+ #include <mach-o/loader.h>
+-#import <mach/m68k/thread_status.h>
+-#import <mach/ppc/thread_status.h>
+-#import <mach/m88k/thread_status.h>
+-#import <mach/i860/thread_status.h>
+-#import <mach/i386/thread_status.h>
+-#import <mach/hppa/thread_status.h>
+-#import <mach/sparc/thread_status.h>
++#include <mach/m68k/thread_status.h>
++#include <mach/ppc/thread_status.h>
++#include <mach/m88k/thread_status.h>
++#include <mach/i860/thread_status.h>
++#include <mach/i386/thread_status.h>
++#include <mach/hppa/thread_status.h>
++#include <mach/sparc/thread_status.h>
+ #include <mach-o/nlist.h>
+ #include <mach-o/reloc.h>
+ #include <mach-o/ranlib.h>
+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 <sys/types.h>
++#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 <libc.h>
+ #include <mach/mach.h>
+ #include "stuff/openstep_mach.h"
++#include <stddef.h>
+ #include <stdarg.h>
+ #include <limits.h>
+ #include <errno.h>
+@@ -35,12 +36,12 @@
+ #include <sys/file.h>
+ #include <mach-o/fat.h>
+ #include <mach-o/loader.h>
+-#import <mach/m68k/thread_status.h>
+-#import <mach/ppc/thread_status.h>
+-#import <mach/m88k/thread_status.h>
+-#import <mach/i860/thread_status.h>
+-#import <mach/i386/thread_status.h>
+-#import <mach/sparc/thread_status.h>
++#include <mach/m68k/thread_status.h>
++#include <mach/ppc/thread_status.h>
++#include <mach/m88k/thread_status.h>
++#include <mach/i860/thread_status.h>
++#include <mach/i386/thread_status.h>
++#include <mach/sparc/thread_status.h>
+ #include <mach-o/nlist.h>
+ #include <mach-o/reloc.h>
+ #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 <stdio.h>
+-#import "stuff/print.h"
++#include <stdio.h>
++#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 <mach-o/loader.h>
+-#import <mach/m68k/thread_status.h>
+-#import <mach/ppc/thread_status.h>
+-#import <mach/m88k/thread_status.h>
+-#import <mach/i860/thread_status.h>
+-#import <mach/i386/thread_status.h>
+-#import <mach/hppa/thread_status.h>
+-#import <mach/sparc/thread_status.h>
++#include <mach/m68k/thread_status.h>
++#include <mach/ppc/thread_status.h>
++#include <mach/m88k/thread_status.h>
++#include <mach/i860/thread_status.h>
++#include <mach/i386/thread_status.h>
++#include <mach/hppa/thread_status.h>
++#include <mach/sparc/thread_status.h>
+ #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 (file)
index 0000000..a9efdc9
--- /dev/null
@@ -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 <mach-o/reloc.h>
+ #include <mach-o/nlist.h>
+ #include <mach-o/stab.h>
+-#include <stuff/breakout.h>
+-#include <stuff/allocate.h>
+-#include <stuff/errors.h>
+-#include <stuff/round.h>
++#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 <file> argument.
+  * remove_symbols is the names of the symbols from the -R <file> 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