This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How do I link to a shared lib without having that lib'sdependencies (the way MS link does)


Hi Guys,

  OK, here is my patch to tidy up the linker's handling of unresolved
  symbols.  The patch does most of the things that I mentioned in my
  previous post, except:

    1. It does not add a linker testsuite case to check the behaviour
       - that will come soon.

    2. It does not provide a special mechanism to allow particular
       targets to decide how to handle unresolved symbols if the user
       has not specified how to do so on the command line.

       There is however the SET_SYMBOLS emulation function which is
       called immediately after the command line is parsed and which
       could easily be used for this purpose.
       
    3. It does not provide a way to tell the linker to ignore
       unresolved symbols in object files without also telling it to
       ignore unresolved symbols in shared libraries.  All other
       combinations are supported however.  (ie you change the way the
       linker handles unresolved references in shared libraries
       with *or* without changing how it handles unresolved references
       in object files).

   With this patch applied three new linker command line switches are
   introduced:

`--unresolved-symbols=METHOD'
     Determine how to handle unresolved symbols.  There are four
     possible values for `method':

    `ignore-all'
          Do not report any unresolved symbols.  This is the default
          when creating shared libraries or dynamic executables.

    `report-all'
          Report all unresolved symbols.  This is the default when
          creating static binaries.

    `ignore-in-object-files'
          Report unresolved symbols that are contained in shared
          libraries, but ignore them if they come from regular object
          files.

    `ignore-in-shared-libraries'
          Report unresolved symbols that come from regular object
          files, but ignore them if they come from shared libraries.
          This can be useful when creating a dynamic binary and it is
          known that all the shared libraries that it should be
          referencing are included on the linker's command line.

     The behaviour for shared libraries on their own can also be
     controlled by the `--[no-]allow-shlib-undefined' option.

     Normally the linker will generate an error message for each
     reported unresolved symbol but the option
     `--warn-unresolved-symbols' can change this to a warning.

`--warn-unresolved-symbols'
     If the linker is going to report an unresolved symbol (see the
     option `--unresolved-symbols') it will normally generate an error.
     This option makes it generate a warning instead.

`--error-unresolved-symbols'
     This restores the linker's default behaviour of generating errors
     when it is reporting unresolved symbols.


  The behaviour that Dave was asking for can now be achieved.  Using
  the script in his testcase but changing the last line to

  ../../gcc/xgcc -B ../../gcc/ -o prog prog.c -L. -lA \
    -Wl,--unresolved-symbols=ignore-in-shared-libs

  I can now link against libA.so, get a warning message that libB.so
  cannot be found, and get no errors or warnings about libB_func being
  unresolved.

  Oh - the other benefit of the patch is that it removes some
  duplicated code from the implementations of xxx_relocate_section()
  in the various elfxx-xxxx.c files.  This could probably be extended
  in the future.

  Any comments before I apply the patch ?  (Which will probably be
  tomorrow).
  
Cheers
        Nick

include/ChangeLog                
2003-08-19  Nick Clifton  <nickc@redhat.com>

	* bfdlink.h (enum report_method): New enum.  Describes how to
	report something.
        (struct bfd_link_info): Delete fields 'no_undefined' and
	'allow_shlib_undefined'.  Replace with
	'unresolved_symbols_in_objects' and
	'unresolved_symbols_in_shared_libs'.
        
ld/ChangeLog                
2003-08-19  Nick Clifton  <nickc@redhat.com>

	* ldmain.c: Initialise the new fields in bfd_link_info to
        NOT_YET_SET.
       	* lexsup.c (enum option_values): New enum.  Use this to
        replace the handed coded values for the long switch options.
        (ld_options): Add 'unresolved-symbols',
        'warn-unresolved-symbols' and 'error-unresolved-symbols'.
        (parse_args): Handle the new switches.  Set the values of
        unresolved_symbols_in_objects and
        unresolved_symbols_in_shared_libs appropriately.  If they were
        not initialised by the command line, install default values.
        * emultempl/elf32.em (handle_option): Update OPTION_GROUP and
        -z defs to use the new fields in bfd_link_info.
	* ld.texinfo: Document the new switches.
	* NEWS: Mention this feature.

bfd/ChangeLog                
2003-08-19  Nick Clifton  <nickc@redhat.com>

	* elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): New macro used to
	replace some duplicated code in most elfxx-xxxx.c files.  This
	version uses the new fields in bfd_link_info.

        * elf-m10300.c (mn10300_elf_relocate_section): Use new macro.
        * elf32-arm.h (elf32_arm_relocate_section): Likewise.
        * elf32-cris.c (cris_elf_relocate_section): Likewise.
	* elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
	* elf32-i386.c (elf_i386_relocate_section): Likewise.
	* elf32-ip2k.c (ip2k_elf_relocate_section): Likewise.
	* elf32-iq2000.c (iq2000_elf_relocate_section): Likewise.
	* elf32-m68k.c (elf_m68k_relocate_section): Likewise.
	* elf32-ppc.c (ppc_elf_relocate_section): Likewise.
	* elf32-s390.c (elf_s390_relocate_section): Likewise.
	* elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
	* elf32-vax.c (elf_vax_relocate_section): Likewise.
	* elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
	* elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
	* elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
	* elf64-s390.c (elf_s390_relocate_section): Likewise.
	* elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
	* elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
	* elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise.
        
        * elf-hppa.h (elf_hppa_unmark_useless_dynamic_symbols,
	elf_hppa_remark_useless_dynamic_symbols,
	elf_hppa_relocate_section): Use the new fields in
	bfd_link_info structure.
	* elf32-sh.c (sh_elf_relocate_section): Likewise.
	* elf64-alpha.c (elf64_alpha_check_relocs): Likewise.
	* elf64-hppa.c (elf64_hppa_check_relocs): Likewise.
	* elf64-sh64.c (sh_elf64_relocate_section): Likewise.
	* elfxx-ia64.c (elfNN_ia64_check_relocs): Likewise.
	* elfxx-mips.c (mips_elf_calculate_relocation): Likewise.

	* elflink.h (elf_link_output_extsym): Fix test for reporting
        undefined symbols in shared libraries.  Remove redundant test
        of shlib_undefined when reporting references to forced local
        symbols.

Index: include/bfdlink.h
===================================================================
RCS file: /cvs/src/src/include/bfdlink.h,v
retrieving revision 1.34
diff -c -3 -p -r1.34 bfdlink.h
*** include/bfdlink.h	7 Aug 2003 02:25:49 -0000	1.34
--- include/bfdlink.h	19 Aug 2003 16:41:08 -0000
*************** struct bfd_sym_chain
*** 198,203 ****
--- 198,216 ----
    const char *name;
  };
  
+ /* How to handle unresolved symbols.
+    There are four possibilities which are enumerated below:  */
+ enum report_method
+ {
+   /* This is the initial value when then link_info structure is created.
+      It allows the various stages of the linker to determine whether they
+      allowed to set the value.  */
+   RM_NOT_YET_SET = 0,
+   RM_IGNORE,
+   RM_GENERATE_WARNING,
+   RM_GENERATE_ERROR
+ };
+ 
  /* This structure holds all the information needed to communicate
     between BFD and the linker when doing a link.  */
  
*************** struct bfd_link_info
*** 238,261 ****
       need much more time and therefore must be explicitly selected.  */
    unsigned int optimize: 1;
  
-   /* TRUE if BFD should generate errors for undefined symbols
-      even if generating a shared object.  */
-   unsigned int no_undefined: 1;
- 
-   /* TRUE if BFD should allow undefined symbols in shared objects even
-      when no_undefined is set to disallow undefined symbols.  The net
-      result will be that undefined symbols in regular objects will
-      still trigger an error, but undefined symbols in shared objects
-      will be ignored.  The implementation of no_undefined makes the
-      assumption that the runtime linker will choke on undefined
-      symbols.  However there is at least one system (BeOS) where
-      undefined symbols in shared libraries is normal since the kernel
-      patches them at load time to select which function is most
-      appropriate for the current architecture.  I.E. dynamically
-      select an appropriate memset function.  Apparently it is also
-      normal for HPPA shared libraries to have undefined symbols.  */
-   unsigned int allow_shlib_undefined: 1;
- 
    /* TRUE if ok to have multiple definition.  */
    unsigned int allow_multiple_definition: 1;
  
--- 251,256 ----
*************** struct bfd_link_info
*** 304,309 ****
--- 299,315 ----
    /* TRUE if PT_GNU_STACK segment should be created with PF_R|PF_W
       flags.  */
    unsigned int noexecstack: 1;
+ 
+   /* What to do with unresolved symbols in an object file.
+      When producing static binaries the default is GENERATE_ERROR.
+      When producing dynamic binaries the default is IGNORE.  The
+      assumption with dynamic binaries is that the reference will be
+      resolved at load/execution time.  */
+   enum report_method unresolved_syms_in_objects;
+ 
+   /* What to do with unresolved symbols in a shared library.
+      The same defaults apply.  */
+   enum report_method unresolved_syms_in_shared_libs;
  
    /* Which symbols to strip.  */
    enum bfd_link_strip strip;

Index: ld/ldmain.c
===================================================================
RCS file: /cvs/src/src/ld/ldmain.c,v
retrieving revision 1.73
diff -c -3 -p -r1.73 ldmain.c
*** ld/ldmain.c	12 Aug 2003 16:46:17 -0000	1.73
--- ld/ldmain.c	19 Aug 2003 16:41:18 -0000
*************** main (int argc, char **argv)
*** 289,296 ****
    link_info.static_link = FALSE;
    link_info.traditional_format = FALSE;
    link_info.optimize = FALSE;
!   link_info.no_undefined = FALSE;
!   link_info.allow_shlib_undefined = TRUE;
    link_info.allow_multiple_definition = FALSE;
    link_info.allow_undefined_version = TRUE;
    link_info.keep_memory = TRUE;
--- 289,296 ----
    link_info.static_link = FALSE;
    link_info.traditional_format = FALSE;
    link_info.optimize = FALSE;
!   link_info.unresolved_syms_in_objects = RM_NOT_YET_SET;
!   link_info.unresolved_syms_in_shared_libs = RM_NOT_YET_SET;
    link_info.allow_multiple_definition = FALSE;
    link_info.allow_undefined_version = TRUE;
    link_info.keep_memory = TRUE;
Index: ld/lexsup.c
===================================================================
RCS file: /cvs/src/src/ld/lexsup.c,v
retrieving revision 1.65
diff -c -3 -p -r1.65 lexsup.c
*** ld/lexsup.c	28 Jun 2003 05:28:54 -0000	1.65
--- ld/lexsup.c	19 Aug 2003 16:41:20 -0000
*************** int parsing_defsym = 0;
*** 62,143 ****
  
  /* Codes used for the long options with no short synonyms.  150 isn't
     special; it's just an arbitrary non-ASCII char value.  */
! 
! #define OPTION_ASSERT			150
! #define OPTION_CALL_SHARED		(OPTION_ASSERT + 1)
! #define OPTION_CREF			(OPTION_CALL_SHARED + 1)
! #define OPTION_DEFSYM			(OPTION_CREF + 1)
! #define OPTION_DEMANGLE			(OPTION_DEFSYM + 1)
! #define OPTION_DYNAMIC_LINKER		(OPTION_DEMANGLE + 1)
! #define OPTION_EB			(OPTION_DYNAMIC_LINKER + 1)
! #define OPTION_EL			(OPTION_EB + 1)
! #define OPTION_EMBEDDED_RELOCS		(OPTION_EL + 1)
! #define OPTION_EXPORT_DYNAMIC		(OPTION_EMBEDDED_RELOCS + 1)
! #define OPTION_HELP			(OPTION_EXPORT_DYNAMIC + 1)
! #define OPTION_IGNORE			(OPTION_HELP + 1)
! #define OPTION_MAP			(OPTION_IGNORE + 1)
! #define OPTION_NO_DEMANGLE		(OPTION_MAP + 1)
! #define OPTION_NO_KEEP_MEMORY		(OPTION_NO_DEMANGLE + 1)
! #define OPTION_NO_WARN_MISMATCH		(OPTION_NO_KEEP_MEMORY + 1)
! #define OPTION_NOINHIBIT_EXEC		(OPTION_NO_WARN_MISMATCH + 1)
! #define OPTION_NON_SHARED		(OPTION_NOINHIBIT_EXEC + 1)
! #define OPTION_NO_WHOLE_ARCHIVE		(OPTION_NON_SHARED + 1)
! #define OPTION_OFORMAT			(OPTION_NO_WHOLE_ARCHIVE + 1)
! #define OPTION_RELAX			(OPTION_OFORMAT + 1)
! #define OPTION_RETAIN_SYMBOLS_FILE	(OPTION_RELAX + 1)
! #define OPTION_RPATH			(OPTION_RETAIN_SYMBOLS_FILE + 1)
! #define OPTION_RPATH_LINK		(OPTION_RPATH + 1)
! #define OPTION_SHARED			(OPTION_RPATH_LINK + 1)
! #define OPTION_SONAME			(OPTION_SHARED + 1)
! #define OPTION_SORT_COMMON		(OPTION_SONAME + 1)
! #define OPTION_STATS			(OPTION_SORT_COMMON + 1)
! #define OPTION_SYMBOLIC			(OPTION_STATS + 1)
! #define OPTION_TASK_LINK		(OPTION_SYMBOLIC + 1)
! #define OPTION_TBSS			(OPTION_TASK_LINK + 1)
! #define OPTION_TDATA			(OPTION_TBSS + 1)
! #define OPTION_TTEXT			(OPTION_TDATA + 1)
! #define OPTION_TRADITIONAL_FORMAT	(OPTION_TTEXT + 1)
! #define OPTION_UR			(OPTION_TRADITIONAL_FORMAT + 1)
! #define OPTION_VERBOSE			(OPTION_UR + 1)
! #define OPTION_VERSION			(OPTION_VERBOSE + 1)
! #define OPTION_VERSION_SCRIPT		(OPTION_VERSION + 1)
! #define OPTION_VERSION_EXPORTS_SECTION	(OPTION_VERSION_SCRIPT + 1)
! #define OPTION_WARN_COMMON		(OPTION_VERSION_EXPORTS_SECTION + 1)
! #define OPTION_WARN_CONSTRUCTORS	(OPTION_WARN_COMMON + 1)
! #define OPTION_WARN_FATAL		(OPTION_WARN_CONSTRUCTORS + 1)
! #define OPTION_WARN_MULTIPLE_GP		(OPTION_WARN_FATAL + 1)
! #define OPTION_WARN_ONCE		(OPTION_WARN_MULTIPLE_GP + 1)
! #define OPTION_WARN_SECTION_ALIGN	(OPTION_WARN_ONCE + 1)
! #define OPTION_SPLIT_BY_RELOC		(OPTION_WARN_SECTION_ALIGN + 1)
! #define OPTION_SPLIT_BY_FILE 		(OPTION_SPLIT_BY_RELOC + 1)
! #define OPTION_WHOLE_ARCHIVE		(OPTION_SPLIT_BY_FILE + 1)
! #define OPTION_WRAP			(OPTION_WHOLE_ARCHIVE + 1)
! #define OPTION_FORCE_EXE_SUFFIX		(OPTION_WRAP + 1)
! #define OPTION_GC_SECTIONS		(OPTION_FORCE_EXE_SUFFIX + 1)
! #define OPTION_NO_GC_SECTIONS		(OPTION_GC_SECTIONS + 1)
! #define OPTION_CHECK_SECTIONS		(OPTION_NO_GC_SECTIONS + 1)
! #define OPTION_NO_CHECK_SECTIONS	(OPTION_CHECK_SECTIONS + 1)
! #define OPTION_MPC860C0			(OPTION_NO_CHECK_SECTIONS + 1)
! #define OPTION_NO_UNDEFINED		(OPTION_MPC860C0 + 1)
! #define OPTION_INIT			(OPTION_NO_UNDEFINED + 1)
! #define OPTION_FINI			(OPTION_INIT + 1)
! #define OPTION_SECTION_START		(OPTION_FINI + 1)
! #define OPTION_UNIQUE			(OPTION_SECTION_START + 1)
! #define OPTION_TARGET_HELP		(OPTION_UNIQUE + 1)
! #define OPTION_ALLOW_SHLIB_UNDEFINED	(OPTION_TARGET_HELP + 1)
! #define OPTION_NO_ALLOW_SHLIB_UNDEFINED	(OPTION_ALLOW_SHLIB_UNDEFINED + 1)
! #define OPTION_ALLOW_MULTIPLE_DEFINITION (OPTION_NO_ALLOW_SHLIB_UNDEFINED + 1)
! #define OPTION_NO_UNDEFINED_VERSION	(OPTION_ALLOW_MULTIPLE_DEFINITION + 1)
! #define OPTION_DISCARD_NONE		(OPTION_NO_UNDEFINED_VERSION + 1)
! #define OPTION_SPARE_DYNAMIC_TAGS	(OPTION_DISCARD_NONE + 1)
! #define OPTION_NO_DEFINE_COMMON		(OPTION_SPARE_DYNAMIC_TAGS + 1)
! #define OPTION_NOSTDLIB			(OPTION_NO_DEFINE_COMMON + 1)
! #define OPTION_NO_OMAGIC		(OPTION_NOSTDLIB + 1)
! #define OPTION_STRIP_DISCARDED		(OPTION_NO_OMAGIC + 1)
! #define OPTION_NO_STRIP_DISCARDED	(OPTION_STRIP_DISCARDED + 1)
! #define OPTION_ACCEPT_UNKNOWN_INPUT_ARCH    (OPTION_NO_STRIP_DISCARDED + 1)
! #define OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH (OPTION_ACCEPT_UNKNOWN_INPUT_ARCH + 1)
! #define OPTION_PIE			(OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH + 1)
  
  /* The long options.  This structure is used for both the option
     parsing and the help text.  */
--- 62,148 ----
  
  /* Codes used for the long options with no short synonyms.  150 isn't
     special; it's just an arbitrary non-ASCII char value.  */
! enum option_values
! {
!   OPTION_ASSERT = 150,
!   OPTION_CALL_SHARED,
!   OPTION_CREF,
!   OPTION_DEFSYM,
!   OPTION_DEMANGLE,
!   OPTION_DYNAMIC_LINKER,
!   OPTION_EB,
!   OPTION_EL,
!   OPTION_EMBEDDED_RELOCS,
!   OPTION_EXPORT_DYNAMIC,
!   OPTION_HELP,
!   OPTION_IGNORE,
!   OPTION_MAP,
!   OPTION_NO_DEMANGLE,
!   OPTION_NO_KEEP_MEMORY,
!   OPTION_NO_WARN_MISMATCH,
!   OPTION_NOINHIBIT_EXEC,
!   OPTION_NON_SHARED,
!   OPTION_NO_WHOLE_ARCHIVE,
!   OPTION_OFORMAT,
!   OPTION_RELAX,
!   OPTION_RETAIN_SYMBOLS_FILE,
!   OPTION_RPATH,
!   OPTION_RPATH_LINK,
!   OPTION_SHARED,
!   OPTION_SONAME,
!   OPTION_SORT_COMMON,
!   OPTION_STATS,
!   OPTION_SYMBOLIC,
!   OPTION_TASK_LINK,
!   OPTION_TBSS,
!   OPTION_TDATA,
!   OPTION_TTEXT,
!   OPTION_TRADITIONAL_FORMAT,
!   OPTION_UR,
!   OPTION_VERBOSE,
!   OPTION_VERSION,
!   OPTION_VERSION_SCRIPT,
!   OPTION_VERSION_EXPORTS_SECTION,
!   OPTION_WARN_COMMON,
!   OPTION_WARN_CONSTRUCTORS,
!   OPTION_WARN_FATAL,
!   OPTION_WARN_MULTIPLE_GP,
!   OPTION_WARN_ONCE,
!   OPTION_WARN_SECTION_ALIGN,
!   OPTION_SPLIT_BY_RELOC,
!   OPTION_SPLIT_BY_FILE ,
!   OPTION_WHOLE_ARCHIVE,
!   OPTION_WRAP,
!   OPTION_FORCE_EXE_SUFFIX,
!   OPTION_GC_SECTIONS,
!   OPTION_NO_GC_SECTIONS,
!   OPTION_CHECK_SECTIONS,
!   OPTION_NO_CHECK_SECTIONS,
!   OPTION_MPC860C0,
!   OPTION_NO_UNDEFINED,
!   OPTION_INIT,
!   OPTION_FINI,
!   OPTION_SECTION_START,
!   OPTION_UNIQUE,
!   OPTION_TARGET_HELP,
!   OPTION_ALLOW_SHLIB_UNDEFINED,
!   OPTION_NO_ALLOW_SHLIB_UNDEFINED,
!   OPTION_ALLOW_MULTIPLE_DEFINITION,
!   OPTION_NO_UNDEFINED_VERSION,
!   OPTION_DISCARD_NONE,
!   OPTION_SPARE_DYNAMIC_TAGS,
!   OPTION_NO_DEFINE_COMMON,
!   OPTION_NOSTDLIB,
!   OPTION_NO_OMAGIC,
!   OPTION_STRIP_DISCARDED,
!   OPTION_NO_STRIP_DISCARDED,
!   OPTION_ACCEPT_UNKNOWN_INPUT_ARCH,
!   OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH,
!   OPTION_PIE,
!   OPTION_UNRESOLVED_SYMBOLS,
!   OPTION_WARN_UNRESOLVED_SYMBOLS,
!   OPTION_ERROR_UNRESOLVED_SYMBOLS
! };
  
  /* The long options.  This structure is used for both the option
     parsing and the help text.  */
*************** static const struct ld_option ld_options
*** 334,344 ****
    { {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY},
        '\0', NULL, N_("Use less memory and more disk I/O"), TWO_DASHES },
    { {"no-undefined", no_argument, NULL, OPTION_NO_UNDEFINED},
!      '\0', NULL, N_("Allow no undefined symbols"), TWO_DASHES },
    { {"allow-shlib-undefined", no_argument, NULL, OPTION_ALLOW_SHLIB_UNDEFINED},
!      '\0', NULL, N_("Allow undefined symbols in shared objects (the default)"), TWO_DASHES },
    { {"no-allow-shlib-undefined", no_argument, NULL, OPTION_NO_ALLOW_SHLIB_UNDEFINED},
!      '\0', NULL, N_("Do not allow undefined symbols in shared objects"), TWO_DASHES },
    { {"allow-multiple-definition", no_argument, NULL, OPTION_ALLOW_MULTIPLE_DEFINITION},
       '\0', NULL, N_("Allow multiple definitions"), TWO_DASHES },
    { {"no-undefined-version", no_argument, NULL, OPTION_NO_UNDEFINED_VERSION},
--- 339,349 ----
    { {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY},
        '\0', NULL, N_("Use less memory and more disk I/O"), TWO_DASHES },
    { {"no-undefined", no_argument, NULL, OPTION_NO_UNDEFINED},
!      '\0', NULL, N_("Do not allow unresolved references in object files"), TWO_DASHES },
    { {"allow-shlib-undefined", no_argument, NULL, OPTION_ALLOW_SHLIB_UNDEFINED},
!      '\0', NULL, N_("Allow unresolved references in shared libaries"), TWO_DASHES },
    { {"no-allow-shlib-undefined", no_argument, NULL, OPTION_NO_ALLOW_SHLIB_UNDEFINED},
!      '\0', NULL, N_("Do not allow unresolved references in shared libs"), TWO_DASHES },
    { {"allow-multiple-definition", no_argument, NULL, OPTION_ALLOW_MULTIPLE_DEFINITION},
       '\0', NULL, N_("Allow multiple definitions"), TWO_DASHES },
    { {"no-undefined-version", no_argument, NULL, OPTION_NO_UNDEFINED_VERSION},
*************** static const struct ld_option ld_options
*** 400,405 ****
--- 405,413 ----
        '\0', N_("ADDRESS"), N_("Set address of .data section"), ONE_DASH },
    { {"Ttext", required_argument, NULL, OPTION_TTEXT},
        '\0', N_("ADDRESS"), N_("Set address of .text section"), ONE_DASH },
+   { {"unresolved-symbols=<method>", required_argument, NULL, OPTION_UNRESOLVED_SYMBOLS},
+      '\0', NULL, N_("How to handle unresolved symbols.  <method> is:\n\t\t\t\tignore-all, report-all, ignore-in-object-files,\n\t\t\t\tignore-in-shared-libs"),
+     TWO_DASHES },
    { {"verbose", no_argument, NULL, OPTION_VERBOSE},
        '\0', NULL, N_("Output lots of information during link"), TWO_DASHES },
    { {"dll-verbose", no_argument, NULL, OPTION_VERBOSE}, /* Linux.  */
*************** static const struct ld_option ld_options
*** 422,427 ****
--- 430,439 ----
    { {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN},
        '\0', NULL, N_("Warn if start of section changes due to alignment"),
        TWO_DASHES },
+   { {"warn-unresolved-symbols", no_argument, NULL, OPTION_WARN_UNRESOLVED_SYMBOLS},
+     '\0', NULL, N_("Report unresolved symbols as warnings"), TWO_DASHES },
+   { {"error-unresolved-symbols", no_argument, NULL, OPTION_ERROR_UNRESOLVED_SYMBOLS},
+     '\0', NULL, N_("Report unresolved symbols as errors"), TWO_DASHES },
    { {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL},
       '\0', NULL, N_("Treat warnings as errors"),
       TWO_DASHES },
*************** parse_args (unsigned argc, char **argv)
*** 469,474 ****
--- 481,487 ----
    struct option *longopts;
    struct option *really_longopts;
    int last_optind;
+   enum report_method how_to_report_unresolved_symbols = RM_GENERATE_ERROR;
  
    shortopts = xmalloc (OPTION_COUNT * 3 + 2);
    longopts = xmalloc (sizeof (*longopts) * (OPTION_COUNT + 1));
*************** parse_args (unsigned argc, char **argv)
*** 647,655 ****
--- 660,680 ----
  	  break;
  	case OPTION_CALL_SHARED:
  	  config.dynamic_link = TRUE;
+ 	  /* When linking against shared libraries, the default
+ 	     behaviour is to ignore any unresolved references.  */
+ 	  if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
+ 	    link_info.unresolved_syms_in_objects = RM_IGNORE;
+ 	  if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
+ 	    link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
  	  break;
  	case OPTION_NON_SHARED:
  	  config.dynamic_link = FALSE;
+ 	  /* When linking against static libraries, the default
+ 	     behaviour is to report any unresolved references.  */
+ 	  if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
+ 	    link_info.unresolved_syms_in_objects = how_to_report_unresolved_symbols;
+ 	  if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
+ 	    link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
  	  break;
  	case OPTION_CREF:
  	  command_line.cref = TRUE;
*************** parse_args (unsigned argc, char **argv)
*** 790,803 ****
  	  link_info.keep_memory = FALSE;
  	  break;
  	case OPTION_NO_UNDEFINED:
! 	  link_info.no_undefined = TRUE;
  	  break;
  	case OPTION_ALLOW_SHLIB_UNDEFINED:
! 	  link_info.allow_shlib_undefined = TRUE;
  	  break;
  	case OPTION_NO_ALLOW_SHLIB_UNDEFINED:
! 	  link_info.allow_shlib_undefined = FALSE;
  	  break;
  	case OPTION_ALLOW_MULTIPLE_DEFINITION:
  	  link_info.allow_multiple_definition = TRUE;
  	  break;
--- 815,867 ----
  	  link_info.keep_memory = FALSE;
  	  break;
  	case OPTION_NO_UNDEFINED:
! 	  link_info.unresolved_syms_in_objects = how_to_report_unresolved_symbols;
  	  break;
  	case OPTION_ALLOW_SHLIB_UNDEFINED:
! 	  link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
  	  break;
  	case OPTION_NO_ALLOW_SHLIB_UNDEFINED:
! 	  link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
! 	  break;
! 	case OPTION_UNRESOLVED_SYMBOLS:
! 	  if (strcmp (optarg, "ignore-all") == 0)
! 	    {
! 	      link_info.unresolved_syms_in_objects = RM_IGNORE;
! 	      link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
! 	    }
! 	  else if (strcmp (optarg, "report-all") == 0)
! 	    {
! 	      link_info.unresolved_syms_in_objects = how_to_report_unresolved_symbols;
! 	      link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
! 	    }
! 	  else if (strcmp (optarg, "ignore-in-object-files") == 0)
! 	    {
! 	      link_info.unresolved_syms_in_objects = RM_IGNORE;
! 	      link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
! 	    }
!       	  else if (strcmp (optarg, "ignore-in-shared-libs") == 0)
! 	    {
! 	      link_info.unresolved_syms_in_objects = how_to_report_unresolved_symbols;
! 	      link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
! 	    }
! 	  else
! 	    einfo (_("%P%F: bad --unresolved-symbols option: %s\n"), optarg);
  	  break;
+ 	case OPTION_WARN_UNRESOLVED_SYMBOLS:
+ 	  how_to_report_unresolved_symbols = RM_GENERATE_WARNING;
+ 	  if (link_info.unresolved_syms_in_objects == RM_GENERATE_ERROR)
+ 	    link_info.unresolved_syms_in_objects = RM_GENERATE_WARNING;
+ 	  if (link_info.unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)
+ 	    link_info.unresolved_syms_in_shared_libs = RM_GENERATE_WARNING;
+ 	  break;
+ 	  
+ 	case OPTION_ERROR_UNRESOLVED_SYMBOLS:
+ 	  how_to_report_unresolved_symbols = RM_GENERATE_ERROR;
+ 	  if (link_info.unresolved_syms_in_objects == RM_GENERATE_WARNING)
+ 	    link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
+ 	  if (link_info.unresolved_syms_in_shared_libs == RM_GENERATE_WARNING)
+ 	    link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR;
+ 	  break;	  
  	case OPTION_ALLOW_MULTIPLE_DEFINITION:
  	  link_info.allow_multiple_definition = TRUE;
  	  break;
*************** parse_args (unsigned argc, char **argv)
*** 948,954 ****
  	  break;
  	case OPTION_SHARED:
  	  if (config.has_shared)
! 	    link_info.shared = TRUE;
  	  else
  	    einfo (_("%P%F: -shared not supported\n"));
  	  break;
--- 1012,1026 ----
  	  break;
  	case OPTION_SHARED:
  	  if (config.has_shared)
! 	    {
! 	      link_info.shared = TRUE;
! 	      /* When creating a shared library, the default
! 		 behaviour is to ignore any unresolved references.  */
! 	      if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
! 		link_info.unresolved_syms_in_objects = RM_IGNORE;
! 	      if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
! 		link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
! 	    }
  	  else
  	    einfo (_("%P%F: -shared not supported\n"));
  	  break;
*************** parse_args (unsigned argc, char **argv)
*** 1202,1207 ****
--- 1274,1287 ----
        set_default_dirlist (default_dirlist);
        free (default_dirlist);
      }
+ 
+   if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
+     /* FIXME: Should we allow emulations a chance to set this ?  */
+     link_info.unresolved_syms_in_objects = how_to_report_unresolved_symbols;
+   
+   if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
+     /* FIXME: Should we allow emulations a chance to set this ?  */
+     link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
  }
  
  /* Add the (colon-separated) elements of DIRLIST_PTR to the

Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.103
diff -c -3 -p -r1.103 elf32.em
*** ld/emultempl/elf32.em	4 Aug 2003 11:32:52 -0000	1.103
--- ld/emultempl/elf32.em	19 Aug 2003 16:41:22 -0000
*************** cat >>e${EMULATION_NAME}.c <<EOF
*** 1602,1608 ****
      case OPTION_GROUP:
        link_info.flags_1 |= (bfd_vma) DF_1_GROUP;
        /* Groups must be self-contained.  */
!       link_info.no_undefined = TRUE;
        break;
  
      case 'z':
--- 1602,1609 ----
      case OPTION_GROUP:
        link_info.flags_1 |= (bfd_vma) DF_1_GROUP;
        /* Groups must be self-contained.  */
!       link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
!       link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR;
        break;
  
      case 'z':
*************** cat >>e${EMULATION_NAME}.c <<EOF
*** 1631,1637 ****
  	  link_info.flags_1 |= (bfd_vma) DF_1_ORIGIN;
  	}
        else if (strcmp (optarg, "defs") == 0)
! 	link_info.no_undefined = TRUE;
        else if (strcmp (optarg, "muldefs") == 0)
  	link_info.allow_multiple_definition = TRUE;
        else if (strcmp (optarg, "combreloc") == 0)
--- 1632,1638 ----
  	  link_info.flags_1 |= (bfd_vma) DF_1_ORIGIN;
  	}
        else if (strcmp (optarg, "defs") == 0)
! 	link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
        else if (strcmp (optarg, "muldefs") == 0)
  	link_info.allow_multiple_definition = TRUE;
        else if (strcmp (optarg, "combreloc") == 0)
*************** cat >>e${EMULATION_NAME}.c <<EOF
*** 1684,1690 ****
    fprintf (file, _("  --enable-new-dtags\tEnable new dynamic tags\n"));
    fprintf (file, _("  --eh-frame-hdr\tCreate .eh_frame_hdr section\n"));
    fprintf (file, _("  -z combreloc\t\tMerge dynamic relocs into one section and sort\n"));
!   fprintf (file, _("  -z defs\t\tDisallows undefined symbols\n"));
    fprintf (file, _("  -z execstack\t\tMark executable as requiring executable stack\n"));
    fprintf (file, _("  -z initfirst\t\tMark DSO to be initialized first at runtime\n"));
    fprintf (file, _("  -z interpose\t\tMark object to interpose all DSOs but executable\n"));
--- 1685,1691 ----
    fprintf (file, _("  --enable-new-dtags\tEnable new dynamic tags\n"));
    fprintf (file, _("  --eh-frame-hdr\tCreate .eh_frame_hdr section\n"));
    fprintf (file, _("  -z combreloc\t\tMerge dynamic relocs into one section and sort\n"));
!   fprintf (file, _("  -z defs\t\tReport unresolved symbols in object files.\n"));
    fprintf (file, _("  -z execstack\t\tMark executable as requiring executable stack\n"));
    fprintf (file, _("  -z initfirst\t\tMark DSO to be initialized first at runtime\n"));
    fprintf (file, _("  -z interpose\t\tMark object to interpose all DSOs but executable\n"));

Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.97
diff -c -3 -p -r1.97 ld.texinfo
*** ld/ld.texinfo	15 Aug 2003 09:42:17 -0000	1.97
--- ld/ld.texinfo	19 Aug 2003 16:41:17 -0000
*************** Combines multiple reloc sections and sor
*** 883,889 ****
  lookup caching possible.
  
  @item defs
! Disallows undefined symbols.
  
  @item initfirst
  This option is only meaningful when building a shared object.
--- 883,890 ----
  lookup caching possible.
  
  @item defs
! Disallows undefined symbols in object files.  Undefined symbols in
! shared libaries are still allowed.
  
  @item initfirst
  This option is only meaningful when building a shared object.
*************** for which shared libraries are supported
*** 984,998 ****
  default on such platforms.  The different variants of this option are
  for compatibility with various systems.  You may use this option
  multiple times on the command line: it affects library searching for
! @option{-l} options which follow it.
  
  @kindex -Bgroup
  @item -Bgroup
  Set the @code{DF_1_GROUP} flag in the @code{DT_FLAGS_1} entry in the dynamic
  section.  This causes the runtime linker to handle lookups in this
  object and its dependencies to be performed only inside the group.
! @option{--no-undefined} is implied.  This option is only meaningful on ELF
! platforms which support shared libraries.
  
  @kindex -Bstatic
  @kindex -dn
--- 985,1000 ----
  default on such platforms.  The different variants of this option are
  for compatibility with various systems.  You may use this option
  multiple times on the command line: it affects library searching for
! @option{-l} options which follow it.  This
! option also implies @option{--unresolved-symbols=ignore-all}.
  
  @kindex -Bgroup
  @item -Bgroup
  Set the @code{DF_1_GROUP} flag in the @code{DT_FLAGS_1} entry in the dynamic
  section.  This causes the runtime linker to handle lookups in this
  object and its dependencies to be performed only inside the group.
! @option{--unresolved-symbols=report-all} is implied.  This option is
! only meaningful on ELF platforms which support shared libraries.
  
  @kindex -Bstatic
  @kindex -dn
*************** Do not link against shared libraries.  T
*** 1006,1012 ****
  platforms for which shared libraries are supported.  The different
  variants of this option are for compatibility with various systems.  You
  may use this option multiple times on the command line: it affects
! library searching for @option{-l} options which follow it.
  
  @kindex -Bsymbolic
  @item -Bsymbolic
--- 1008,1015 ----
  platforms for which shared libraries are supported.  The different
  variants of this option are for compatibility with various systems.  You
  may use this option multiple times on the command line: it affects
! library searching for @option{-l} options which follow it.  This
! option also implies @option{--unresolved-symbols=report-all}.
  
  @kindex -Bsymbolic
  @item -Bsymbolic
*************** been assigned to see if there any overla
*** 1025,1031 ****
  perform this check, and if it finds any overlaps it will produce
  suitable error messages.  The linker does know about, and does make
  allowances for sections in overlays.  The default behaviour can be
! restored by using the command line switch @samp{--check-sections}.
  
  @cindex cross reference table
  @kindex --cref
--- 1028,1034 ----
  perform this check, and if it finds any overlaps it will produce
  suitable error messages.  The linker does know about, and does make
  allowances for sections in overlays.  The default behaviour can be
! restored by using the command line switch @option{--check-sections}.
  
  @cindex cross reference table
  @kindex --cref
*************** Print a summary of all target specific o
*** 1146,1152 ****
  @kindex -Map
  @item -Map @var{mapfile}
  Print a link map to the file @var{mapfile}.  See the description of the
! @samp{-M} option, above.
  
  @cindex memory usage
  @kindex --no-keep-memory
--- 1149,1155 ----
  @kindex -Map
  @item -Map @var{mapfile}
  Print a link map to the file @var{mapfile}.  See the description of the
! @option{-M} option, above.
  
  @cindex memory usage
  @kindex --no-keep-memory
*************** while linking a large executable.
*** 1161,1171 ****
  @kindex -z defs
  @item --no-undefined
  @itemx -z defs
! Normally when creating a non-symbolic shared library, undefined symbols
! are allowed and left to be resolved by the runtime loader.  This option
! disallows such undefined symbols if they come from regular object
! files.  The switch @samp{--no-allow-shlib-undefined} controls the
! behaviour for shared objects being linked into the shared library.
  
  @kindex --allow-multiple-definition
  @kindex -z muldefs
--- 1164,1174 ----
  @kindex -z defs
  @item --no-undefined
  @itemx -z defs
! Report unresolved symbol references from regular object files.  This
! is done even if the linker is creating a non-symbolic shared library.
! The switch @option{--[no-]allow-shlib-undefined} controls the
! behaviour for reporting unresolved references found in shared
! libraries being linked in.  
  
  @kindex --allow-multiple-definition
  @kindex -z muldefs
*************** first definition will be used.
*** 1179,1200 ****
  @kindex --no-allow-shlib-undefined
  @item --allow-shlib-undefined
  @itemx --no-allow-shlib-undefined
! Allow (the default) or disallow undefined symbols in shared objects.
! The setting of this switch overrides @samp{--no-undefined} where
! shared objects are concerned.  Thus if @samp{--no-undefined} is set
! but @samp{--no-allow-shlib-undefined} is not, the net result will be
! that undefined symbols in regular object files will trigger an error,
! but undefined symbols in shared objects will be ignored.
! 
! The reason that @samp{--allow-shlib-undefined} is the default is that
! the shared object being specified at link time may not be the same one
! that is available at load time, so the symbols might actually be
  resolvable at load time.  Plus there are some systems, (eg BeOS) where
! undefined symbols in shared libraries is normal since the kernel
! patches them at load time to select which function is most appropriate
! for the current architecture. eg. to dynamically select an appropriate
! memset function.  Apparently it is also normal for HPPA shared
! libraries to have undefined symbols.
  
  @kindex --no-undefined-version
  @item --no-undefined-version
--- 1182,1202 ----
  @kindex --no-allow-shlib-undefined
  @item --allow-shlib-undefined
  @itemx --no-allow-shlib-undefined
! Allows (the default) or disallows undefined symbols in shared libraries.
! This switch is similar to @option{--no-undefined} except that it
! determines the behaviour when the undefined symbols are in a
! shared library rather than a regular object file.  It does not affect
! how undefined symbols in regular object files are handled.
! 
! The reason that @option{--allow-shlib-undefined} is the default is that
! the shared library being specified at link time may not be the same as
! the one that is available at load time, so the symbols might actually be
  resolvable at load time.  Plus there are some systems, (eg BeOS) where
! undefined symbols in shared libraries is normal.  (The kernel patches
! them at load time to select which function is most appropriate 
! for the current architecture.  This is used for example to dynamically
! select an appropriate memset function).  Apparently it is also normal
! for HPPA shared libraries to have undefined symbols.
  
  @kindex --no-undefined-version
  @item --no-undefined-version
*************** sign (``@key{=}''), and @var{org}.
*** 1486,1491 ****
--- 1488,1526 ----
  Same as --section-start, with @code{.bss}, @code{.data} or
  @code{.text} as the @var{sectionname}.
  
+ @kindex --unresolved-symbols
+ @item --unresolved-symbols=@var{method}
+ Determine how to handle unresolved symbols.  There are four possible
+ values for @samp{method}:
+ 
+ @table @samp
+ @item ignore-all
+ Do not report any unresolved symbols.  This is the default when
+ creating shared libraries or dynamic executables.
+ 
+ @item report-all
+ Report all unresolved symbols.  This is the default when creating
+ static binaries.
+ 
+ @item ignore-in-object-files
+ Report unresolved symbols that are contained in shared libraries, but
+ ignore them if they come from regular object files.
+ 
+ @item ignore-in-shared-libs
+ Report unresolved symbols that come from regular object files, but
+ ignore them if they come from shared libraries.  This can be useful
+ when creating a dynamic binary and it is known that all the shared
+ libraries that it should be referencing are included on the linker's
+ command line.
+ @end table
+ 
+ The behaviour for shared libraries on their own can also be controlled
+ by the @option{--[no-]allow-shlib-undefined} option.
+ 
+ Normally the linker will generate an error message for each reported
+ unresolved symbol but the option @option{--warn-unresolved-symbols}
+ can change this to a warning.
+ 
  @kindex --verbose
  @cindex verbose
  @item --dll-verbose
*************** is only meaningful on ELF platforms whic
*** 1508,1517 ****
  @cindex combining symbols, warnings on
  @item --warn-common
  Warn when a common symbol is combined with another common symbol or with
! a symbol definition.  Unix linkers allow this somewhat sloppy practice,
  but linkers on some other operating systems do not.  This option allows
  you to find potential problems from combining global symbols.
! Unfortunately, some C libraries use this practice, so you may get some
  warnings about symbols in the libraries as well as in your programs.
  
  There are three kinds of global symbols, illustrated here by C examples:
--- 1543,1552 ----
  @cindex combining symbols, warnings on
  @item --warn-common
  Warn when a common symbol is combined with another common symbol or with
! a symbol definition.  Unix linkers allow this somewhat sloppy practise,
  but linkers on some other operating systems do not.  This option allows
  you to find potential problems from combining global symbols.
! Unfortunately, some C libraries use this practise, so you may get some
  warnings about symbols in the libraries as well as in your programs.
  
  There are three kinds of global symbols, illustrated here by C examples:
*************** The address will only be changed if it n
*** 1625,1630 ****
--- 1660,1676 ----
  is, if the @code{SECTIONS} command does not specify a start address for
  the section (@pxref{SECTIONS}).
  
+ @kindex --warn-unresolved-symbols
+ @item --warn-unresolved-symbols
+ If the linker is going to report an unresolved symbol (see the option
+ @option{--unresolved-symbols}) it will normally generate an error.
+ This option makes it generate a warning instead.
+ 
+ @kindex --error-unresolved-symbols
+ @item --error-unresolved-symbols
+ This restores the linker's default behaviour of generating errors when
+ it is reporting unresolved symbols.
+ 
  @kindex --whole-archive
  @cindex including an entire archive
  @item --whole-archive
*************** automatically or implicitly exported sym
*** 1871,1877 ****
  The linker will create the file @var{file} which will contain an
  import lib corresponding to the DLL the linker is generating. This
  import lib (which should be called @code{*.dll.a} or @code{*.a}
! may be used to link clients against the generated DLL; this behavior
  makes it possible to skip a separate @code{dlltool} import library
  creation step.
  [This option is specific to the i386 PE targeted port of the linker]
--- 1917,1923 ----
  The linker will create the file @var{file} which will contain an
  import lib corresponding to the DLL the linker is generating. This
  import lib (which should be called @code{*.dll.a} or @code{*.a}
! may be used to link clients against the generated DLL; this behaviour
  makes it possible to skip a separate @code{dlltool} import library
  creation step.
  [This option is specific to the i386 PE targeted port of the linker]
*************** default.
*** 1897,1903 ****
  @item --dll-search-prefix @var{string}
  When linking dynamically to a dll without an import library,
  search for @code{<string><basename>.dll} in preference to 
! @code{lib<basename>.dll}. This behavior allows easy distinction
  between DLLs built for the various "subplatforms": native, cygwin,
  uwin, pw, etc.  For instance, cygwin DLLs typically use
  @code{--dll-search-prefix=cyg}. 
--- 1943,1949 ----
  @item --dll-search-prefix @var{string}
  When linking dynamically to a dll without an import library,
  search for @code{<string><basename>.dll} in preference to 
! @code{lib<basename>.dll}. This behaviour allows easy distinction
  between DLLs built for the various "subplatforms": native, cygwin,
  uwin, pw, etc.  For instance, cygwin DLLs typically use
  @code{--dll-search-prefix=cyg}. 
*************** data type of the exported variable:
*** 1928,1934 ****
  
  One way is to use --enable-runtime-pseudo-reloc switch. This leaves the task
  of adjusting references in your client code for runtime environment, so
! this method works only when runtime environtment supports this feature.
  
  A second solution is to force one of the 'constants' to be a variable -- 
  that is, unknown and un-optimizable at compile time.  For arrays, 
--- 1974,1980 ----
  
  One way is to use --enable-runtime-pseudo-reloc switch. This leaves the task
  of adjusting references in your client code for runtime environment, so
! this method works only when runtime environment supports this feature.
  
  A second solution is to force one of the 'constants' to be a variable -- 
  that is, unknown and un-optimizable at compile time.  For arrays, 
*************** extern_ll -->
*** 1968,1974 ****
  
  A third method of dealing with this difficulty is to abandon
  'auto-import' for the offending symbol and mark it with 
! @code{__declspec(dllimport)}.  However, in practice that
  requires using compile-time #defines to indicate whether you are
  building a DLL, building client code that will link to the DLL, or 
  merely building/linking to a static library.   In making the choice 
--- 2014,2020 ----
  
  A third method of dealing with this difficulty is to abandon
  'auto-import' for the offending symbol and mark it with 
! @code{__declspec(dllimport)}.  However, in practise that
  requires using compile-time #defines to indicate whether you are
  building a DLL, building client code that will link to the DLL, or 
  merely building/linking to a static library.   In making the choice 
*************** functions).
*** 2025,2031 ****
  
  @kindex --disable-auto-import
  @item --disable-auto-import
! Do not attempt to do sophisticalted linking of @code{_symbol} to 
  @code{__imp__symbol} for DATA imports from DLLs.
  [This option is specific to the i386 PE targeted port of the linker]
  
--- 2071,2077 ----
  
  @kindex --disable-auto-import
  @item --disable-auto-import
! Do not attempt to do sophisticated linking of @code{_symbol} to 
  @code{__imp__symbol} for DATA imports from DLLs.
  [This option is specific to the i386 PE targeted port of the linker]
  
*************** subsystem version also.
*** 2083,2089 ****
  
  @c man begin ENVIRONMENT
  
! You can change the behavior of @command{ld} with the environment variables
  @ifclear SingleFormat
  @code{GNUTARGET},
  @end ifclear
--- 2129,2135 ----
  
  @c man begin ENVIRONMENT
  
! You can change the behaviour of @command{ld} with the environment variables
  @ifclear SingleFormat
  @code{GNUTARGET},
  @end ifclear

Index: ld/NEWS
===================================================================
RCS file: /cvs/src/src/ld/NEWS,v
retrieving revision 1.36
diff -c -3 -p -r1.36 NEWS
*** ld/NEWS	25 Jun 2003 06:40:26 -0000	1.36
--- ld/NEWS	19 Aug 2003 16:41:08 -0000
***************
*** 1,5 ****
--- 1,10 ----
  -*- text -*-
  
+ * Improved linker's handling of unresolved symbols.  The switch
+   --unresolved-symbols=<method> has been added to tell the linker when it
+   should report them and the switch --warn-unresolved-symbols has been added to
+   make reports be issued as warning messages rather than errors.
+ 
  * Added support for Xtensa architecture.
  
  * Added --with-sysroot configure switch to specify a target system root, for

Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.109
diff -c -3 -p -r1.109 elf-bfd.h
*** bfd/elf-bfd.h	7 Aug 2003 08:38:06 -0000	1.109
--- bfd/elf-bfd.h	19 Aug 2003 16:39:27 -0000
*************** extern bfd *_bfd_elf64_bfd_from_remote_m
*** 1682,1685 ****
--- 1682,1741 ----
  extern bfd_boolean _sh_elf_set_mach_from_flags
    (bfd *);
  
+ /* This macro is to avoid lots of duplicated code in the body
+    of xxx_relocate_section() in the various elfxx-xxxx.c files.  */
+ #define RELOC_FOR_GLOBAL_SYMBOL(h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned)	\
+   do															\
+     {															\
+       /* It seems this can happen with erroneous or unsupported								\
+ 	 input (mixing a.out and elf in an archive, for example.)  */							\
+       if (sym_hashes == NULL)												\
+ 	return FALSE;													\
+ 															\
+       h = sym_hashes[r_symndx - symtab_hdr->sh_info];									\
+ 															\
+       while (h->root.type == bfd_link_hash_indirect									\
+ 	     || h->root.type == bfd_link_hash_warning)									\
+ 	h = (struct elf_link_hash_entry *) h->root.u.i.link;								\
+ 															\
+       warned = FALSE;													\
+       unresolved_reloc = FALSE;												\
+       relocation = 0;													\
+       if (h->root.type == bfd_link_hash_defined										\
+ 	  || h->root.type == bfd_link_hash_defweak)									\
+ 	{														\
+ 	  sec = h->root.u.def.section;											\
+ 	  if (sec == NULL												\
+ 	      || sec->output_section == NULL)										\
+ 	    /* Set a flag that will be cleared later if we find a							\
+ 	       relocation value for this symbol.  output_section							\
+ 	       is typically NULL for symbols satisfied by a shared							\
+ 	       library.  */												\
+ 	    unresolved_reloc = TRUE;											\
+ 	  else														\
+ 	    relocation = (h->root.u.def.value										\
+ 			  + sec->output_section->vma									\
+ 			  + sec->output_offset);									\
+ 	}														\
+       else if (h->root.type == bfd_link_hash_undefweak)									\
+ 	;														\
+       else if (!info->executable											\
+ 	       && info->unresolved_syms_in_objects == RM_IGNORE								\
+ 	       && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)								\
+ 	;														\
+       else														\
+ 	{														\
+ 	  if (! info->callbacks->undefined_symbol									\
+ 	      (info, h->root.root.string, input_bfd,									\
+ 	       input_section, rel->r_offset,										\
+ 	       ((info->shared && info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)				\
+ 		|| (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR)				\
+ 		|| ELF_ST_VISIBILITY (h->other))									\
+ 	       ))													\
+ 	    return FALSE;												\
+ 	  warned = TRUE;												\
+ 	}														\
+     }															\
+   while (0)
+ 
  #endif /* _LIBELF_H_ */
Index: bfd/elf-hppa.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-hppa.h,v
retrieving revision 1.64
diff -c -3 -p -r1.64 elf-hppa.h
*** bfd/elf-hppa.h	7 Aug 2003 07:25:34 -0000	1.64
--- bfd/elf-hppa.h	19 Aug 2003 16:39:28 -0000
*************** elf_hppa_unmark_useless_dynamic_symbols 
*** 1097,1103 ****
       linker code.  */
    if (! info->relocatable
        && ! (info->shared
! 	    && !info->no_undefined)
        && h->root.type == bfd_link_hash_undefined
        && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0
        && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0)
--- 1097,1103 ----
       linker code.  */
    if (! info->relocatable
        && ! (info->shared
! 	    && info->unresolved_syms_in_shared_libs == RM_IGNORE)
        && h->root.type == bfd_link_hash_undefined
        && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0
        && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0)
*************** elf_hppa_remark_useless_dynamic_symbols 
*** 1132,1138 ****
       linker code.  */
    if (! info->relocatable
        && ! (info->shared
! 	    && !info->no_undefined)
        && h->root.type == bfd_link_hash_undefined
        && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0
        && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
--- 1132,1138 ----
       linker code.  */
    if (! info->relocatable
        && ! (info->shared
! 	    && info->unresolved_syms_in_shared_libs == RM_IGNORE)
        && h->root.type == bfd_link_hash_undefined
        && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0
        && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
*************** elf_hppa_relocate_section (bfd *output_b
*** 1399,1405 ****
  		relocation = 0;
  	    }
  	  /* Allow undefined symbols in shared libraries.  */
! 	  else if (info->shared && !info->no_undefined
  		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
  	    {
  	      if (info->symbolic)
--- 1399,1406 ----
  		relocation = 0;
  	    }
  	  /* Allow undefined symbols in shared libraries.  */
! 	  else if (info->shared
! 		   && info->unresolved_syms_in_shared_libs == RM_IGNORE
  		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
  	    {
  	      if (info->symbolic)
Index: bfd/elf-m10300.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-m10300.c,v
retrieving revision 1.39
diff -c -3 -p -r1.39 elf-m10300.c
*** bfd/elf-m10300.c	7 Aug 2003 08:38:07 -0000	1.39
--- bfd/elf-m10300.c	19 Aug 2003 16:39:32 -0000
*************** mn10300_elf_final_link_relocate (howto, 
*** 1158,1166 ****
  	    }
  
  	  bfd_elf32_swap_reloca_out (output_bfd, &outrel,
! 				     (((Elf32_External_Rela *)
! 				       sreloc->contents)
! 				      + sreloc->reloc_count));
  	  ++sreloc->reloc_count;
  
  	  /* If this reloc is against an external symbol, we do
--- 1158,1165 ----
  	    }
  
  	  bfd_elf32_swap_reloca_out (output_bfd, &outrel,
! 				     (bfd_byte *) (((Elf32_External_Rela *) sreloc->contents)
! 						   + sreloc->reloc_count));
  	  ++sreloc->reloc_count;
  
  	  /* If this reloc is against an external symbol, we do
*************** mn10300_elf_final_link_relocate (howto, 
*** 1295,1303 ****
  	    }
  
  	  bfd_elf32_swap_reloca_out (output_bfd, &outrel,
! 				     (((Elf32_External_Rela *)
! 				       sreloc->contents)
! 				      + sreloc->reloc_count));
  	  ++sreloc->reloc_count;
  
  	  return bfd_reloc_ok;
--- 1294,1302 ----
  	    }
  
  	  bfd_elf32_swap_reloca_out (output_bfd, &outrel,
! 				     (bfd_byte *) (((Elf32_External_Rela *)
! 						    sreloc->contents)
! 						   + sreloc->reloc_count));
  	  ++sreloc->reloc_count;
  
  	  return bfd_reloc_ok;
*************** mn10300_elf_final_link_relocate (howto, 
*** 1480,1488 ****
  		  outrel.r_info = ELF32_R_INFO (0, R_MN10300_RELATIVE);
  		  outrel.r_addend = value;
  		  bfd_elf32_swap_reloca_out (output_bfd, &outrel,
! 					     (((Elf32_External_Rela *)
! 					       srelgot->contents)
! 					      + srelgot->reloc_count));
  		  ++ srelgot->reloc_count;
  		}
  
--- 1479,1487 ----
  		  outrel.r_info = ELF32_R_INFO (0, R_MN10300_RELATIVE);
  		  outrel.r_addend = value;
  		  bfd_elf32_swap_reloca_out (output_bfd, &outrel,
! 					     (bfd_byte *) (((Elf32_External_Rela *)
! 							    srelgot->contents)
! 							   + srelgot->reloc_count));
  		  ++ srelgot->reloc_count;
  		}
  
*************** mn10300_elf_relocate_section (output_bfd
*** 1579,1593 ****
  	}
        else
  	{
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! 	  while (h->root.root.type == bfd_link_hash_indirect
! 		 || h->root.root.type == bfd_link_hash_warning)
! 	    h = (struct elf32_mn10300_link_hash_entry *) h->root.root.u.i.link;
! 	  if (h->root.root.type == bfd_link_hash_defined
  	      || h->root.root.type == bfd_link_hash_defweak)
! 	    {
! 	      sec = h->root.root.u.def.section;
! 	      if (   r_type == R_MN10300_GOTPC32
  		  || r_type == R_MN10300_GOTPC16
  		  || ((   r_type == R_MN10300_PLT32
  		       || r_type == R_MN10300_PLT16)
--- 1578,1597 ----
  	}
        else
  	{
! 	  bfd_boolean unresolved_reloc;
! 	  bfd_boolean warned;
! 	  struct elf_link_hash_entry *hh;
! 
! 	  RELOC_FOR_GLOBAL_SYMBOL (hh, (struct elf_link_hash_entry *) sym_hashes,
! 				   r_symndx, symtab_hdr, relocation,
! 				   sec, unresolved_reloc, info,
! 				   warned);
! 
! 	  h = (struct elf32_mn10300_link_hash_entry *) hh;
! 
! 	  if ((h->root.root.type == bfd_link_hash_defined
  	      || h->root.root.type == bfd_link_hash_defweak)
! 	      && (   r_type == R_MN10300_GOTPC32
  		  || r_type == R_MN10300_GOTPC16
  		  || ((   r_type == R_MN10300_PLT32
  		       || r_type == R_MN10300_PLT16)
*************** mn10300_elf_relocate_section (output_bfd
*** 1615,1655 ****
  			     do anything with them here.  */
  			  || ((input_section->flags & SEC_DEBUGGING) != 0
  			      && (h->root.elf_link_hash_flags
! 				  & ELF_LINK_HASH_DEF_DYNAMIC) != 0))))
! 		{
! 		  /* In these cases, we don't need the relocation
!                      value.  We check specially because in some
!                      obscure cases sec->output_section will be NULL.  */
! 		  relocation = 0;
! 		}
! 	      else if (sec->output_section == NULL)
! 		{
! 		  (*_bfd_error_handler)
! 		    (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
! 		     bfd_get_filename (input_bfd), h->root.root.root.string,
! 		     bfd_get_section_name (input_bfd, input_section));
! 		  relocation = 0;
! 		}
! 	      else	      
! 		relocation = (h->root.root.u.def.value
! 			      + sec->output_section->vma
! 			      + sec->output_offset);
! 	    }
! 	  else if (h->root.root.type == bfd_link_hash_undefweak)
! 	    relocation = 0;
! 	  else if (info->shared && !info->symbolic && !info->no_undefined
! 		   && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
  	    relocation = 0;
! 	  else
! 	    {
! 	      if (! ((*info->callbacks->undefined_symbol)
! 		     (info, h->root.root.root.string, input_bfd,
! 		      input_section, rel->r_offset,
! 		      (!info->shared || info->no_undefined
! 		       || ELF_ST_VISIBILITY (h->root.other)))))
! 		return FALSE;
! 	      relocation = 0;
! 	    }
  	}
  
        r = mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
--- 1619,1635 ----
  			     do anything with them here.  */
  			  || ((input_section->flags & SEC_DEBUGGING) != 0
  			      && (h->root.elf_link_hash_flags
! 				  & ELF_LINK_HASH_DEF_DYNAMIC) != 0)))))
! 	    /* In these cases, we don't need the relocation
! 	       value.  We check specially because in some
! 	       obscure cases sec->output_section will be NULL.  */
  	    relocation = 0;
! 
! 	  else if (unresolved_reloc)
! 	    (*_bfd_error_handler)
! 	      (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
! 	       bfd_get_filename (input_bfd), h->root.root.root.string,
! 	       bfd_get_section_name (input_bfd, input_section));
  	}
  
        r = mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
*************** _bfd_mn10300_elf_finish_dynamic_symbol (
*** 4626,4633 ****
        rel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_JMP_SLOT);
        rel.r_addend = 0;
        bfd_elf32_swap_reloca_out (output_bfd, &rel,
! 				((Elf32_External_Rela *) srel->contents
! 				 + plt_index));
  
        if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
  	/* Mark the symbol as undefined, rather than as defined in
--- 4606,4613 ----
        rel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_JMP_SLOT);
        rel.r_addend = 0;
        bfd_elf32_swap_reloca_out (output_bfd, &rel,
! 				 (bfd_byte *) ((Elf32_External_Rela *) srel->contents
! 					       + plt_index));
  
        if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
  	/* Mark the symbol as undefined, rather than as defined in
*************** _bfd_mn10300_elf_finish_dynamic_symbol (
*** 4673,4680 ****
  	}
  
        bfd_elf32_swap_reloca_out (output_bfd, &rel,
! 				 ((Elf32_External_Rela *) srel->contents
! 				  + srel->reloc_count));
        ++ srel->reloc_count;
      }
  
--- 4653,4660 ----
  	}
  
        bfd_elf32_swap_reloca_out (output_bfd, &rel,
! 				 (bfd_byte *) ((Elf32_External_Rela *) srel->contents
! 					       + srel->reloc_count));
        ++ srel->reloc_count;
      }
  
*************** _bfd_mn10300_elf_finish_dynamic_symbol (
*** 4698,4705 ****
        rel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_COPY);
        rel.r_addend = 0;
        bfd_elf32_swap_reloca_out (output_bfd, &rel,
! 				 ((Elf32_External_Rela *) s->contents
! 				  + s->reloc_count));
        ++ s->reloc_count;
      }
  
--- 4678,4685 ----
        rel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_COPY);
        rel.r_addend = 0;
        bfd_elf32_swap_reloca_out (output_bfd, &rel,
! 				 (bfd_byte *) ((Elf32_External_Rela *) s->contents
! 					       + s->reloc_count));
        ++ s->reloc_count;
      }
  
Index: bfd/elf32-arm.h
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.h,v
retrieving revision 1.109
diff -c -3 -p -r1.109 elf32-arm.h
*** bfd/elf32-arm.h	5 Aug 2003 16:24:12 -0000	1.109
--- bfd/elf32-arm.h	19 Aug 2003 16:39:36 -0000
*************** elf32_arm_relocate_section (output_bfd, 
*** 1963,1981 ****
  	}
        else
  	{
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
  
! 	  while (   h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
! 
! 	  if (   h->root.type == bfd_link_hash_defined
! 	      || h->root.type == bfd_link_hash_defweak)
  	    {
- 	      int relocation_needed = 1;
- 
- 	      sec = h->root.u.def.section;
- 
  	      /* In these cases, we don't need the relocation value.
  	         We check specially because in some obscure cases
  	         sec->output_section will be NULL.  */
--- 1963,1978 ----
  	}
        else
  	{
! 	  bfd_boolean warned;
! 	  bfd_boolean unresolved_reloc;
  
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
! 				   symtab_hdr, relocation,
! 				   sec, unresolved_reloc, info,
! 				   warned);
! 	  
! 	  if (unresolved_reloc || relocation != 0)
  	    {
  	      /* In these cases, we don't need the relocation value.
  	         We check specially because in some obscure cases
  	         sec->output_section will be NULL.  */
*************** elf32_arm_relocate_section (output_bfd, 
*** 1998,2061 ****
  			      && (h->elf_link_hash_flags
  				  & ELF_LINK_HASH_DEF_DYNAMIC) != 0))
  		      )
! 	            relocation_needed = 0;
  		  break;
  
  	        case R_ARM_GOTPC:
! 	          relocation_needed = 0;
  		  break;
  
  	        case R_ARM_GOT32:
  	          if ((WILL_CALL_FINISH_DYNAMIC_SYMBOL
! 		       (elf_hash_table(info)->dynamic_sections_created,
  			info->shared, h))
  		      && (!info->shared
  	                  || (!info->symbolic && h->dynindx != -1)
  	                  || (h->elf_link_hash_flags
  			      & ELF_LINK_HASH_DEF_REGULAR) == 0))
! 	            relocation_needed = 0;
  		  break;
  
  	        case R_ARM_PLT32:
  	          if (h->plt.offset != (bfd_vma)-1)
! 	            relocation_needed = 0;
  		  break;
  
  	        default:
! 		  if (sec->output_section == NULL)
! 		    {
! 		      (*_bfd_error_handler)
! 			(_("%s: warning: unresolvable relocation %d against symbol `%s' from %s section"),
! 			 bfd_archive_filename (input_bfd),
! 			 r_type,
! 			 h->root.root.string,
! 			 bfd_get_section_name (input_bfd, input_section));
! 		      relocation_needed = 0;
! 		    }
  		}
- 
- 	      if (relocation_needed)
- 		relocation = h->root.u.def.value
- 		  + sec->output_section->vma
- 		  + sec->output_offset;
- 	      else
- 		relocation = 0;
- 	    }
- 	  else if (h->root.type == bfd_link_hash_undefweak)
- 	    relocation = 0;
- 	  else if (info->shared && !info->symbolic
- 		   && !info->no_undefined
- 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
- 	    relocation = 0;
- 	  else
- 	    {
- 	      if (!((*info->callbacks->undefined_symbol)
- 		    (info, h->root.root.string, input_bfd,
- 		     input_section, rel->r_offset,
- 		     (!info->shared || info->no_undefined
- 		      || ELF_ST_VISIBILITY (h->other)))))
- 		return FALSE;
- 	      relocation = 0;
  	    }
  	}
  
--- 1995,2033 ----
  			      && (h->elf_link_hash_flags
  				  & ELF_LINK_HASH_DEF_DYNAMIC) != 0))
  		      )
! 	            relocation = 0;
  		  break;
  
  	        case R_ARM_GOTPC:
! 	          relocation = 0;
  		  break;
  
  	        case R_ARM_GOT32:
  	          if ((WILL_CALL_FINISH_DYNAMIC_SYMBOL
! 		       (elf_hash_table (info)->dynamic_sections_created,
  			info->shared, h))
  		      && (!info->shared
  	                  || (!info->symbolic && h->dynindx != -1)
  	                  || (h->elf_link_hash_flags
  			      & ELF_LINK_HASH_DEF_REGULAR) == 0))
! 	            relocation = 0;
  		  break;
  
  	        case R_ARM_PLT32:
  	          if (h->plt.offset != (bfd_vma)-1)
! 	            relocation = 0;
  		  break;
  
  	        default:
! 		  if (unresolved_reloc)
! 		    _bfd_error_handler
! 		      (_("%s: warning: unresolvable relocation %d against symbol `%s' from %s section"),
! 		       bfd_archive_filename (input_bfd),
! 		       r_type,
! 		       h->root.root.string,
! 		       bfd_get_section_name (input_bfd, input_section));
! 		  break;
  		}
  	    }
  	}
  
Index: bfd/elf32-cris.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-cris.c,v
retrieving revision 1.42
diff -c -3 -p -r1.42 elf32-cris.c
*** bfd/elf32-cris.c	25 Jun 2003 06:40:23 -0000	1.42
--- bfd/elf32-cris.c	19 Aug 2003 16:39:38 -0000
*************** cris_elf_relocate_section (output_bfd, i
*** 856,879 ****
  	}
        else
  	{
! 	  /* It seems this can happen with erroneous or unsupported input
! 	     (mixing a.out and elf in an archive, for example.)  */
! 	  if (sym_hashes == NULL)
! 	    return FALSE;
  
! 	  h = sym_hashes [r_symndx - symtab_hdr->sh_info];
! 
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
! 
! 	  symname = h->root.root.string;
! 
! 	  if (h->root.type == bfd_link_hash_defined
! 	      || h->root.type == bfd_link_hash_defweak)
! 	    {
! 	      sec = h->root.u.def.section;
  
  	      /* Perhaps we should detect the cases that
  		 sec->output_section is expected to be NULL like i386 and
  		 m68k, but apparently (and according to elfxx-ia64.c) all
--- 856,867 ----
  	}
        else
  	{
! 	  bfd_boolean warned;
! 	  bfd_boolean unresolved_reloc;
  
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned);
  
+ 	  if (unresolved_reloc
  	      /* Perhaps we should detect the cases that
  		 sec->output_section is expected to be NULL like i386 and
  		 m68k, but apparently (and according to elfxx-ia64.c) all
*************** cris_elf_relocate_section (output_bfd, i
*** 888,933 ****
  		 is *not* dynamically linked against.  Thus this will
  		 automatically remind us so we can see if there are other
  		 valid cases we need to revisit.  */
! 	      if ((sec->output_section == NULL
! 		   && (sec->owner->flags & DYNAMIC) != 0)
! 
! 		  /* Here follow the cases where the relocation value must
! 		     be zero (or when further handling is simplified when
! 		     zero).  I can't claim to understand the various
! 		     conditions and they weren't described in the files
! 		     where I copied them from (elf32-m68k.c and
! 		     elf32-i386.c), but let's mention examples of where
! 		     they happen.  FIXME: Perhaps define and use a
! 		     dynamic_symbol_p function like ia64.
  
! 		     - When creating a shared library, we can have an
! 		     ordinary relocation for a symbol defined in a shared
! 		     library (perhaps the one we create).  We then make
! 		     the relocation value zero, as the value seen now will
! 		     be added into the relocation addend in this shared
! 		     library, but must be handled only at dynamic-link
! 		     time.  FIXME: Not sure this example covers the
! 		     h->elf_link_hash_flags test, though it's there in
! 		     other targets.  */
! 		  || (info->shared
! 		      && ((! info->symbolic && h->dynindx != -1)
! 			  || (h->elf_link_hash_flags
! 			      & ELF_LINK_HASH_DEF_REGULAR) == 0)
! 		      && (input_section->flags & SEC_ALLOC) != 0
! 		      && (r_type == R_CRIS_8
! 			  || r_type == R_CRIS_16
! 			  || r_type == R_CRIS_32
! 			  || r_type == R_CRIS_8_PCREL
! 			  || r_type == R_CRIS_16_PCREL
! 			  || r_type == R_CRIS_32_PCREL)))
  		relocation = 0;
! 	      else if (sec->output_section != NULL)
! 		relocation = (h->root.u.def.value
! 			      + sec->output_section->vma
! 			      + sec->output_offset);
! 	      else
  		{
! 		  (*_bfd_error_handler)
  		    (_("%s: unresolvable relocation %s against symbol `%s' from %s section"),
  		     bfd_archive_filename (input_bfd),
  		     cris_elf_howto_table[r_type].name,
--- 876,920 ----
  		 is *not* dynamically linked against.  Thus this will
  		 automatically remind us so we can see if there are other
  		 valid cases we need to revisit.  */
! 	      && (sec->owner->flags & DYNAMIC) != 0)
! 	    relocation = 0;
  
! 	  else if (h->root.type == bfd_link_hash_defined
! 		   || h->root.type == bfd_link_hash_defweak)
! 	    {
! 	      /* Here follow the cases where the relocation value must
! 		 be zero (or when further handling is simplified when
! 		 zero).  I can't claim to understand the various
! 		 conditions and they weren't described in the files
! 		 where I copied them from (elf32-m68k.c and
! 		 elf32-i386.c), but let's mention examples of where
! 		 they happen.  FIXME: Perhaps define and use a
! 		 dynamic_symbol_p function like ia64.
! 
! 		 - When creating a shared library, we can have an
! 		 ordinary relocation for a symbol defined in a shared
! 		 library (perhaps the one we create).  We then make
! 		 the relocation value zero, as the value seen now will
! 		 be added into the relocation addend in this shared
! 		 library, but must be handled only at dynamic-link
! 		 time.  FIXME: Not sure this example covers the
! 		 h->elf_link_hash_flags test, though it's there in
! 		 other targets.  */
! 	      if (info->shared
! 		  && ((! info->symbolic && h->dynindx != -1)
! 		      || (h->elf_link_hash_flags
! 			  & ELF_LINK_HASH_DEF_REGULAR) == 0)
! 		  && (input_section->flags & SEC_ALLOC) != 0
! 		  && (r_type == R_CRIS_8
! 		      || r_type == R_CRIS_16
! 		      || r_type == R_CRIS_32
! 		      || r_type == R_CRIS_8_PCREL
! 		      || r_type == R_CRIS_16_PCREL
! 		      || r_type == R_CRIS_32_PCREL))
  		relocation = 0;
! 	      else if (unresolved_reloc)
  		{
! 		  _bfd_error_handler
  		    (_("%s: unresolvable relocation %s against symbol `%s' from %s section"),
  		     bfd_archive_filename (input_bfd),
  		     cris_elf_howto_table[r_type].name,
*************** cris_elf_relocate_section (output_bfd, i
*** 936,957 ****
  		  bfd_set_error (bfd_error_bad_value);
  		  return FALSE;
  		}
- 	    }
- 	  else if (h->root.type == bfd_link_hash_undefweak)
- 	    relocation = 0;
- 	  else if (info->shared
- 		   && !info->no_undefined
- 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
- 	    relocation = 0;
- 	  else
- 	    {
- 	      if (!(info->callbacks->undefined_symbol
- 		    (info, symname, input_bfd,
- 		     input_section, rel->r_offset,
- 		     (!info->shared || info->no_undefined
- 		      || ELF_ST_VISIBILITY (h->other)))))
- 		return FALSE;
- 	      relocation = 0;
  	    }
  	}
  
--- 923,928 ----
Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.102
diff -c -3 -p -r1.102 elf32-hppa.c
*** bfd/elf32-hppa.c	7 Aug 2003 08:38:07 -0000	1.102
--- bfd/elf32-hppa.c	19 Aug 2003 16:39:43 -0000
*************** elf32_hppa_size_stubs
*** 2853,2859 ****
  		      else if (hash->elf.root.type == bfd_link_hash_undefined)
  			{
  			  if (! (info->shared
! 				 && !info->no_undefined
  				 && (ELF_ST_VISIBILITY (hash->elf.other)
  				     == STV_DEFAULT)
  				 && hash->elf.type != STT_PARISC_MILLI))
--- 2853,2859 ----
  		      else if (hash->elf.root.type == bfd_link_hash_undefined)
  			{
  			  if (! (info->shared
! 				 && info->unresolved_syms_in_objects == RM_IGNORE
  				 && (ELF_ST_VISIBILITY (hash->elf.other)
  				     == STV_DEFAULT)
  				 && hash->elf.type != STT_PARISC_MILLI))
*************** elf32_hppa_relocate_section (bfd *output
*** 3444,3486 ****
  	}
        else
  	{
! 	  int indx;
  
! 	  /* It's a global; Find its entry in the link hash.  */
! 	  indx = r_symndx - symtab_hdr->sh_info;
! 	  h = ((struct elf32_hppa_link_hash_entry *)
! 	       elf_sym_hashes (input_bfd)[indx]);
! 	  while (h->elf.root.type == bfd_link_hash_indirect
! 		 || h->elf.root.type == bfd_link_hash_warning)
! 	    h = (struct elf32_hppa_link_hash_entry *) h->elf.root.u.i.link;
! 
! 	  relocation = 0;
! 	  if (h->elf.root.type == bfd_link_hash_defined
! 	      || h->elf.root.type == bfd_link_hash_defweak)
! 	    {
! 	      sym_sec = h->elf.root.u.def.section;
! 	      /* If sym_sec->output_section is NULL, then it's a
! 		 symbol defined in a shared library.  */
! 	      if (sym_sec->output_section != NULL)
! 		relocation = (h->elf.root.u.def.value
! 			      + sym_sec->output_offset
! 			      + sym_sec->output_section->vma);
! 	    }
! 	  else if (h->elf.root.type == bfd_link_hash_undefweak)
! 	    ;
! 	  else if (info->shared
! 		   && !info->no_undefined
! 		   && ELF_ST_VISIBILITY (h->elf.other) == STV_DEFAULT
! 		   && h->elf.type != STT_PARISC_MILLI)
! 	    ;
! 	  else
! 	    {
! 	      if (!((*info->callbacks->undefined_symbol)
! 		    (info, h->elf.root.root.string, input_bfd,
! 		     input_section, rel->r_offset, TRUE)))
! 		return FALSE;
! 	      warned_undef = TRUE;
  	    }
  	}
  
        /* Do any required modifications to the relocation value, and
--- 3444,3476 ----
  	}
        else
  	{
! 	  struct elf_link_hash_entry *hh;
! 	  bfd_boolean unresolved_reloc;
  
! 	  RELOC_FOR_GLOBAL_SYMBOL (hh, elf_sym_hashes (input_bfd), r_symndx, symtab_hdr,
! 				   relocation, sym_sec, unresolved_reloc, info,
! 				   warned_undef);
! 
! 	  if (relocation == 0
! 	      && hh->root.type != bfd_link_hash_defined
! 	      && hh->root.type != bfd_link_hash_defweak
! 	      && hh->root.type != bfd_link_hash_undefweak)
! 	    {  
! 	      if (!info->executable
! 		  && info->unresolved_syms_in_objects == RM_IGNORE
! 		  && ELF_ST_VISIBILITY (hh->other) == STV_DEFAULT
! 		  && hh->type == STT_PARISC_MILLI)
! 		{
! 		  if (! info->callbacks->undefined_symbol
! 		      (info, hh->root.root.string, input_bfd,
! 		       input_section, rel->r_offset,
! 		       ((info->shared && info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)
! 			|| (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR))))
! 		    return FALSE;
! 		  warned_undef = TRUE;
! 		}
  	    }
+ 	  h = (struct elf32_hppa_link_hash_entry *) hh;
  	}
  
        /* Do any required modifications to the relocation value, and
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.110
diff -c -3 -p -r1.110 elf32-i386.c
*** bfd/elf32-i386.c	11 Aug 2003 14:26:10 -0000	1.110
--- bfd/elf32-i386.c	19 Aug 2003 16:39:48 -0000
*************** elf_i386_relocate_section (bfd *output_b
*** 2154,2195 ****
  	}
        else
  	{
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
  
! 	  relocation = 0;
! 	  if (h->root.type == bfd_link_hash_defined
! 	      || h->root.type == bfd_link_hash_defweak)
! 	    {
! 	      sec = h->root.u.def.section;
! 	      if (sec->output_section == NULL)
! 		/* Set a flag that will be cleared later if we find a
! 		   relocation value for this symbol.  output_section
! 		   is typically NULL for symbols satisfied by a shared
! 		   library.  */
! 		unresolved_reloc = TRUE;
! 	      else
! 		relocation = (h->root.u.def.value
! 			      + sec->output_section->vma
! 			      + sec->output_offset);
! 	    }
! 	  else if (h->root.type == bfd_link_hash_undefweak)
! 	    ;
! 	  else if (!info->executable
! 		   && !info->no_undefined
! 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
! 	    ;
! 	  else
! 	    {
! 	      if (! ((*info->callbacks->undefined_symbol)
! 		     (info, h->root.root.string, input_bfd,
! 		      input_section, rel->r_offset,
! 		      (info->executable || info->no_undefined
! 		       || ELF_ST_VISIBILITY (h->other)))))
! 		return FALSE;
! 	    }
  	}
  
        switch (r_type)
--- 2154,2162 ----
  	}
        else
  	{
! 	  bfd_boolean warned;
  
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned);
  	}
  
        switch (r_type)
Index: bfd/elf32-ip2k.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ip2k.c,v
retrieving revision 1.9
diff -c -3 -p -r1.9 elf32-ip2k.c
*** bfd/elf32-ip2k.c	25 Jun 2003 06:40:25 -0000	1.9
--- bfd/elf32-ip2k.c	19 Aug 2003 16:39:48 -0000
*************** ip2k_elf_relocate_section (output_bfd, i
*** 1532,1564 ****
  	}
        else
  	{
! 	  h = sym_hashes [r_symndx - symtab_hdr->sh_info];
  
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
  
  	  name = h->root.root.string;
- 
- 	  if (h->root.type == bfd_link_hash_defined
- 	      || h->root.type == bfd_link_hash_defweak)
- 	    {
- 	      sec = h->root.u.def.section;
- 	      relocation = h->root.u.def.value + BASEADDR (sec);
- 	    }
- 
- 	  else if (h->root.type == bfd_link_hash_undefweak)
- 	    relocation = 0;
- 
- 	  else
- 	    {
- 	      if (! ((*info->callbacks->undefined_symbol)
- 		     (info, h->root.root.string, input_bfd,
- 		      input_section, rel->r_offset,
- 		     (! info->shared || info->no_undefined))))
- 		return FALSE;
- 	      relocation = 0;
- 	    }
  	}
  
        /* Finally, the sole IP2K-specific part.  */
--- 1532,1543 ----
  	}
        else
  	{
! 	  bfd_boolean warned;
! 	  bfd_boolean unresolved_reloc;
  
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned);
  
  	  name = h->root.root.string;
  	}
  
        /* Finally, the sole IP2K-specific part.  */
Index: bfd/elf32-iq2000.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-iq2000.c,v
retrieving revision 1.3
diff -c -3 -p -r1.3 elf32-iq2000.c
*** bfd/elf32-iq2000.c	25 Jun 2003 06:40:24 -0000	1.3
--- bfd/elf32-iq2000.c	19 Aug 2003 16:39:48 -0000
*************** iq2000_elf_relocate_section (output_bfd,
*** 618,665 ****
  	}
        else
  	{
! 	  h = sym_hashes [r_symndx];
! 	  
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
  
  	  name = h->root.root.string;
- 	  
- 	  if (h->root.type == bfd_link_hash_defined
- 	      || h->root.type == bfd_link_hash_defweak)
- 	    {
- 	      sec = h->root.u.def.section;
- 	      relocation = (h->root.u.def.value
- 			    + sec->output_section->vma
- 			    + sec->output_offset);
- #ifdef DEBUG
- 	      fprintf (stderr,
- 		       "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
- 		       sec->name, name, h->root.u.def.value,
- 		       sec->output_section->vma, sec->output_offset, relocation);
- #endif
- 	    }
- 	  else if (h->root.type == bfd_link_hash_undefweak)
- 	    {
- #ifdef DEBUG
- 	      fprintf (stderr, "undefined: sec: %s, name: %s\n",
- 		       sec->name, name);
- #endif
- 	      relocation = 0;
- 	    }
- 	  else
- 	    {
- 	      if (! ((*info->callbacks->undefined_symbol)
- 		     (info, h->root.root.string, input_bfd,
- 		      input_section, rel->r_offset,
- 		     (!info->shared || info->no_undefined))))
- 		return FALSE;
- #ifdef DEBUG
- 	      fprintf (stderr, "unknown: name: %s\n", name);
- #endif
- 	      relocation = 0;
- 	    }
  	}
  
        switch (r_type)
--- 618,631 ----
  	}
        else
  	{
! 	  bfd_boolean unresolved_reloc;
! 	  bfd_boolean warned;
! 
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
! 				   symtab_hdr, relocation,
! 				   sec, unresolved_reloc, info, warned);
  
  	  name = h->root.root.string;
  	}
  
        switch (r_type)
Index: bfd/elf32-m68k.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68k.c,v
retrieving revision 1.57
diff -c -3 -p -r1.57 elf32-m68k.c
*** bfd/elf32-m68k.c	25 Jun 2003 06:40:19 -0000	1.57
--- bfd/elf32-m68k.c	19 Aug 2003 16:39:50 -0000
*************** elf_m68k_relocate_section (output_bfd, i
*** 1398,1403 ****
--- 1398,1404 ----
        sym = NULL;
        sec = NULL;
        unresolved_reloc = FALSE;
+ 
        if (r_symndx < symtab_hdr->sh_info)
  	{
  	  sym = local_syms + r_symndx;
*************** elf_m68k_relocate_section (output_bfd, i
*** 1406,1447 ****
  	}
        else
  	{
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
  
! 	  relocation = 0;
! 	  if (h->root.type == bfd_link_hash_defined
! 	      || h->root.type == bfd_link_hash_defweak)
! 	    {
! 	      sec = h->root.u.def.section;
! 	      if (sec->output_section == NULL)
! 		/* Set a flag that will be cleared later if we find a
! 		   relocation value for this symbol.  output_section
! 		   is typically NULL for symbols satisfied by a shared
! 		   library.  */
! 		unresolved_reloc = TRUE;
! 	      else
! 		relocation = (h->root.u.def.value
! 			      + sec->output_section->vma
! 			      + sec->output_offset);
! 	    }
! 	  else if (h->root.type == bfd_link_hash_undefweak)
! 	    ;
! 	  else if (info->shared
! 		   && !info->no_undefined
! 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
! 	    ;
! 	  else
! 	    {
! 	      if (!(info->callbacks->undefined_symbol
! 		    (info, h->root.root.string, input_bfd,
! 		     input_section, rel->r_offset,
! 		     (!info->shared || info->no_undefined
! 		      || ELF_ST_VISIBILITY (h->other)))))
! 		return FALSE;
! 	    }
  	}
  
        switch (r_type)
--- 1407,1415 ----
  	}
        else
  	{
! 	  bfd_boolean warned;
  
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned);
  	}
  
        switch (r_type)
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.99
diff -c -3 -p -r1.99 elf32-ppc.c
*** bfd/elf32-ppc.c	11 Aug 2003 14:26:10 -0000	1.99
--- bfd/elf32-ppc.c	19 Aug 2003 16:39:55 -0000
*************** ppc_elf_relocate_section (bfd *output_bf
*** 4718,4723 ****
--- 4718,4724 ----
        unresolved_reloc = FALSE;
        warned = FALSE;
        r_symndx = ELF32_R_SYM (rel->r_info);
+ 
        if (r_symndx < symtab_hdr->sh_info)
  	{
  	  sym = local_syms + r_symndx;
*************** ppc_elf_relocate_section (bfd *output_bf
*** 4728,4771 ****
  	}
        else
  	{
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
  	  sym_name = h->root.root.string;
- 
- 	  relocation = 0;
- 	  if (h->root.type == bfd_link_hash_defined
- 	      || h->root.type == bfd_link_hash_defweak)
- 	    {
- 	      sec = h->root.u.def.section;
- 	      /* Set a flag that will be cleared later if we find a
- 		 relocation value for this symbol.  output_section
- 		 is typically NULL for symbols satisfied by a shared
- 		 library.  */
- 	      if (sec->output_section == NULL)
- 		unresolved_reloc = TRUE;
- 	      else
- 		relocation = (h->root.u.def.value
- 			      + sec->output_section->vma
- 			      + sec->output_offset);
- 	    }
- 	  else if (h->root.type == bfd_link_hash_undefweak)
- 	    ;
- 	  else if (!info->executable
- 		   && !info->no_undefined
- 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
- 	    ;
- 	  else
- 	    {
- 	      if (! ((*info->callbacks->undefined_symbol)
- 		     (info, h->root.root.string, input_bfd, input_section,
- 		      rel->r_offset, (info->executable
- 				      || info->no_undefined
- 				      || ELF_ST_VISIBILITY (h->other)))))
- 		return FALSE;
- 	      warned = TRUE;
- 	    }
  	}
  
        /* TLS optimizations.  Replace instruction sequences and relocs
--- 4729,4740 ----
  	}
        else
  	{
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
! 				   symtab_hdr, relocation, sec,
! 				   unresolved_reloc, info,
! 				   warned);
! 	  
  	  sym_name = h->root.root.string;
  	}
  
        /* TLS optimizations.  Replace instruction sequences and relocs
*************** ppc_elf_relocate_section (bfd *output_bf
*** 5500,5548 ****
  	      }
  	    else
  	      {
! 		long indx;
! 
! 		indx = r_symndx - symtab_hdr->sh_info;
! 		h = elf_sym_hashes (input_bfd)[indx];
! 		while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 		  h = (struct elf_link_hash_entry *) h->root.u.i.link;
! 
! 		value = 0;
! 		if (h->root.type == bfd_link_hash_defined
! 		    || h->root.type == bfd_link_hash_defweak)
! 		  {
! 		    sym_sec = h->root.u.def.section;
! 
! 		    /* Detect the cases that sym_sec->output_section is
! 		       expected to be NULL -- all cases in which the symbol
! 		       is defined in another shared module.  This includes
! 		       PLT relocs for which we've created a PLT entry and
! 		       other relocs for which we're prepared to create
! 		       dynamic relocations.  */
! 		    /* ??? Just accept it NULL and continue.  */
  
! 		    if (sym_sec->output_section != NULL)
! 		      {
! 			value = (h->root.u.def.value
! 				 + sym_sec->output_section->vma
! 				 + sym_sec->output_offset);
! 		      }
! 		  }
! 		else if (!info->executable
! 			 && !info->no_undefined
! 			 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
! 		  ;
! 		else
! 		  {
! 		    if (! ((*info->callbacks->undefined_symbol)
! 			   (info, h->root.root.string, input_bfd,
! 			    input_section, rel->r_offset,
! 			    (info->executable || info->no_undefined
! 			     || ELF_ST_VISIBILITY (h->other)))))
! 		      return FALSE;
! 		    continue;
! 		  }
  	      }
  	    hit_addr = contents + rel->r_offset;
  	    value += rel->r_addend;
--- 5469,5484 ----
  	      }
  	    else
  	      {
! 		bfd_boolean warned;
! 		bfd_boolean unresolved_reloc;
  
! 		RELOC_FOR_GLOBAL_SYMBOL (h, elf_sym_hashes (input_bfd),
! 					 r_symndx, symtab_hdr,
! 					 value, sym_sec,
! 					 unresolved_reloc, info,
! 					 warned);
! 		if (warned)
! 		  continue;
  	      }
  	    hit_addr = contents + rel->r_offset;
  	    value += rel->r_addend;
Index: bfd/elf32-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-s390.c,v
retrieving revision 1.47
diff -c -3 -p -r1.47 elf32-s390.c
*** bfd/elf32-s390.c	11 Aug 2003 14:26:10 -0000	1.47
--- bfd/elf32-s390.c	19 Aug 2003 16:40:01 -0000
*************** elf_s390_relocate_section (output_bfd, i
*** 2331,2375 ****
  	}
        else
  	{
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
  
! 	  if (h->root.type == bfd_link_hash_defined
! 	      || h->root.type == bfd_link_hash_defweak)
! 	    {
! 	      sec = h->root.u.def.section;
! 	      if (sec->output_section == NULL)
! 		{
! 		  /* Set a flag that will be cleared later if we find a
! 		     relocation value for this symbol.  output_section
! 		     is typically NULL for symbols satisfied by a shared
! 		     library.  */
! 		  unresolved_reloc = TRUE;
! 		  relocation = 0;
! 		}
! 	      else
! 		relocation = (h->root.u.def.value
! 			      + sec->output_section->vma
! 			      + sec->output_offset);
! 	    }
! 	  else if (h->root.type == bfd_link_hash_undefweak)
! 	    relocation = 0;
! 	  else if (!info->executable
! 		   && !info->no_undefined
! 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
! 	    relocation = 0;
! 	  else
! 	    {
! 	      if (! ((*info->callbacks->undefined_symbol)
! 		     (info, h->root.root.string, input_bfd,
! 		      input_section, rel->r_offset,
! 		      (info->executable || info->no_undefined
! 		       || ELF_ST_VISIBILITY (h->other)))))
! 		return FALSE;
! 	      relocation = 0;
! 	    }
  	}
  
        switch (r_type)
--- 2331,2342 ----
  	}
        else
  	{
! 	  bfd_boolean warned ATTRIBUTE_UNUSED;
  
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
! 				   symtab_hdr, relocation, sec,
! 				   unresolved_reloc, info,
! 				   warned);
  	}
  
        switch (r_type)
Index: bfd/elf32-sh.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sh.c,v
retrieving revision 1.90
diff -c -3 -p -r1.90 elf32-sh.c
*** bfd/elf32-sh.c	11 Aug 2003 14:26:10 -0000	1.90
--- bfd/elf32-sh.c	19 Aug 2003 16:40:04 -0000
*************** sh_elf_relocate_section (bfd *output_bfd
*** 4663,4668 ****
--- 4663,4670 ----
  	}
        else
  	{
+ 	  /* FIXME: Ought to make use of the RELOC_FOR_GLOBAL_SYMBOL macro.  */
+ 
  	  /* Section symbol are never (?) placed in the hash table, so
  	     we can just ignore hash relocations when creating a
  	     relocatable object file.  */
*************** sh_elf_relocate_section (bfd *output_bfd
*** 4765,4780 ****
  	  else if (h->root.type == bfd_link_hash_undefweak)
  	    relocation = 0;
  	  else if (! info->executable
! 		   && ! info->no_undefined
  		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
  	    relocation = 0;
  	  else
  	    {
! 	      if (! ((*info->callbacks->undefined_symbol)
! 		     (info, h->root.root.string, input_bfd,
! 		      input_section, rel->r_offset,
! 		      (info->executable || info->no_undefined
! 		       || ELF_ST_VISIBILITY (h->other)))))
  		return FALSE;
  	      relocation = 0;
  	    }
--- 4767,4783 ----
  	  else if (h->root.type == bfd_link_hash_undefweak)
  	    relocation = 0;
  	  else if (! info->executable
! 		   && info->unresolved_syms_in_objects == RM_IGNORE
  		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
  	    relocation = 0;
  	  else
  	    {
! 	      if (! info->callbacks->undefined_symbol
! 		  (info, h->root.root.string, input_bfd,
! 		   input_section, rel->r_offset,
! 		   ((info->shared && info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)
! 		    || (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
! 		    || ELF_ST_VISIBILITY (h->other))))
  		return FALSE;
  	      relocation = 0;
  	    }
Index: bfd/elf32-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sparc.c,v
retrieving revision 1.55
diff -c -3 -p -r1.55 elf32-sparc.c
*** bfd/elf32-sparc.c	11 Aug 2003 14:26:10 -0000	1.55
--- bfd/elf32-sparc.c	19 Aug 2003 16:40:07 -0000
*************** elf32_sparc_relocate_section (output_bfd
*** 2186,2227 ****
  	}
        else
  	{
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
  
! 	  relocation = 0;
! 	  if (h->root.type == bfd_link_hash_defined
! 	      || h->root.type == bfd_link_hash_defweak)
! 	    {
! 	      sec = h->root.u.def.section;
! 	      if (sec->output_section == NULL)
! 		 /* Set a flag that will be cleared later if we find a
! 		   relocation value for this symbol.  output_section
! 		   is typically NULL for symbols satisfied by a shared
! 		   library.  */
! 		unresolved_reloc = TRUE;
! 	      else
! 		relocation = (h->root.u.def.value
! 			      + sec->output_section->vma
! 			      + sec->output_offset);
! 	    }
! 	  else if (h->root.type == bfd_link_hash_undefweak)
! 	    ;
! 	  else if (!info->executable
! 		   && !info->no_undefined
! 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
! 	    ;
! 	  else
! 	    {
! 	      if (! ((*info->callbacks->undefined_symbol)
! 		     (info, h->root.root.string, input_bfd,
! 		      input_section, rel->r_offset,
! 		      (info->executable || info->no_undefined
! 		       || ELF_ST_VISIBILITY (h->other)))))
! 		return FALSE;
! 	    }
  	}
  
        switch (r_type)
--- 2186,2197 ----
  	}
        else
  	{
! 	  bfd_boolean warned ATTRIBUTE_UNUSED;
  
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
! 				   symtab_hdr, relocation, sec,
! 				   unresolved_reloc, info,
! 				   warned);
  	}
  
        switch (r_type)
Index: bfd/elf32-vax.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-vax.c,v
retrieving revision 1.13
diff -c -3 -p -r1.13 elf32-vax.c
*** bfd/elf32-vax.c	25 Jun 2003 06:40:25 -0000	1.13
--- bfd/elf32-vax.c	19 Aug 2003 16:40:09 -0000
*************** elf_vax_relocate_section (output_bfd, in
*** 1487,1501 ****
  	}
        else
  	{
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
! 	  if (h->root.type == bfd_link_hash_defined
  	      || h->root.type == bfd_link_hash_defweak)
! 	    {
! 	      sec = h->root.u.def.section;
! 	      if ((r_type == R_VAX_PLT32
  		   && h->plt.offset != (bfd_vma) -1
  		   && elf_hash_table (info)->dynamic_sections_created)
  		  || (r_type == R_VAX_GOT32
--- 1487,1503 ----
  	}
        else
  	{
! 	  bfd_boolean unresolved_reloc;
! 	  bfd_boolean warned;
! 
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
! 				   symtab_hdr, relocation, sec,
! 				   unresolved_reloc, info,
! 				   warned);
! 	   
! 	  if ((h->root.type == bfd_link_hash_defined
  	      || h->root.type == bfd_link_hash_defweak)
! 	      && ((r_type == R_VAX_PLT32
  		   && h->plt.offset != (bfd_vma) -1
  		   && elf_hash_table (info)->dynamic_sections_created)
  		  || (r_type == R_VAX_GOT32
*************** elf_vax_relocate_section (output_bfd, in
*** 1524,1557 ****
  			  || r_type == R_VAX_32
  			  || r_type == R_VAX_PC8
  			  || r_type == R_VAX_PC16
! 			  || r_type == R_VAX_PC32)))
! 		{
! 		  /* In these cases, we don't need the relocation
! 		     value.  We check specially because in some
! 		     obscure cases sec->output_section will be NULL.  */
! 		  relocation = 0;
! 		}
! 	      else
! 		relocation = (h->root.u.def.value
! 			      + sec->output_section->vma
! 			      + sec->output_offset);
! 	    }
! 	  else if (h->root.type == bfd_link_hash_undefweak)
! 	    relocation = 0;
! 	  else if (info->shared
! 		   && !info->no_undefined
! 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
  	    relocation = 0;
- 	  else
- 	    {
- 	      if (!(info->callbacks->undefined_symbol
- 		    (info, h->root.root.string, input_bfd,
- 		     input_section, rel->r_offset,
- 		     (!info->shared || info->no_undefined
- 		      || ELF_ST_VISIBILITY (h->other)))))
- 		return FALSE;
- 	      relocation = 0;
- 	    }
  	}
  
        switch (r_type)
--- 1526,1536 ----
  			  || r_type == R_VAX_32
  			  || r_type == R_VAX_PC8
  			  || r_type == R_VAX_PC16
! 			  || r_type == R_VAX_PC32))))
! 	    /* In these cases, we don't need the relocation
! 	       value.  We check specially because in some
! 	       obscure cases sec->output_section will be NULL.  */
  	    relocation = 0;
  	}
  
        switch (r_type)
Index: bfd/elf32-xtensa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-xtensa.c,v
retrieving revision 1.10
diff -c -3 -p -r1.10 elf32-xtensa.c
*** bfd/elf32-xtensa.c	7 Aug 2003 08:38:08 -0000	1.10
--- bfd/elf32-xtensa.c	19 Aug 2003 16:40:14 -0000
*************** elf_xtensa_relocate_section (output_bfd,
*** 2009,2053 ****
  	}
        else
  	{
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! 
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
! 
! 	  relocation = 0;
! 	  if (h->root.type == bfd_link_hash_defined
! 	      || h->root.type == bfd_link_hash_defweak)
! 	    {
! 	      sec = h->root.u.def.section;
! 
! 	      if (sec->output_section == NULL)
! 		/* Set a flag that will be cleared later if we find a
! 		   relocation value for this symbol.  output_section
! 		   is typically NULL for symbols satisfied by a shared
! 		   library.  */
! 		unresolved_reloc = TRUE;
! 	      else
! 		relocation = (h->root.u.def.value
! 			      + sec->output_section->vma
! 			      + sec->output_offset);
! 	    }
! 	  else if (h->root.type == bfd_link_hash_undefweak)
  	    is_weak_undef = TRUE;
- 	  else if (info->shared
- 		   && !info->no_undefined
- 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
- 	    ;
- 	  else
- 	    {
- 	      if (! ((*info->callbacks->undefined_symbol)
- 		     (info, h->root.root.string, input_bfd,
- 		      input_section, rel->r_offset,
- 		      (!info->shared || info->no_undefined
- 		       || ELF_ST_VISIBILITY (h->other)))))
- 		return FALSE;
- 	      warned = TRUE;
- 	    }
  	}
  
        if (relaxing_section)
--- 2009,2023 ----
  	}
        else
  	{
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
! 				   symtab_hdr, relocation, sec,
! 				   unresolved_reloc, info,
! 				   warned);
! 
! 	  if (relocation == 0
! 	      && !unresolved_reloc
! 	      && h->root.type == bfd_link_hash_undefweak)
  	    is_weak_undef = TRUE;
  	}
  
        if (relaxing_section)
*************** hash_literal_value (src)
*** 3575,3580 ****
--- 3545,3551 ----
       const literal_value *src;
  {
    unsigned hash_val;
+ 
    if (r_reloc_is_const (&src->r_rel))
      return hash_bfd_vma (src->value);
  
*************** hash_literal_value (src)
*** 3583,3591 ****
    
    /* Now check for the same section and the same elf_hash.  */
    if (r_reloc_is_defined (&src->r_rel))
!     hash_val += hash_bfd_vma ((bfd_vma) r_reloc_get_section (&src->r_rel));
    else
!     hash_val += hash_bfd_vma ((bfd_vma) r_reloc_get_hash_entry (&src->r_rel));
  
    return hash_val;
  }
--- 3554,3562 ----
    
    /* Now check for the same section and the same elf_hash.  */
    if (r_reloc_is_defined (&src->r_rel))
!     hash_val += hash_bfd_vma ((bfd_vma) (unsigned) r_reloc_get_section (&src->r_rel));
    else
!     hash_val += hash_bfd_vma ((bfd_vma) (unsigned) r_reloc_get_hash_entry (&src->r_rel));
  
    return hash_val;
  }
Index: bfd/elf64-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-alpha.c,v
retrieving revision 1.104
diff -c -3 -p -r1.104 elf64-alpha.c
*** bfd/elf64-alpha.c	11 Aug 2003 14:26:10 -0000	1.104
--- bfd/elf64-alpha.c	19 Aug 2003 16:40:19 -0000
*************** elf64_alpha_check_relocs (abfd, info, se
*** 3074,3080 ****
           this may help reduce memory usage and processing time later.  */
        maybe_dynamic = FALSE;
        if (h && ((info->shared
! 		 && (!info->symbolic || info->allow_shlib_undefined))
  		|| ! (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
  		|| h->root.root.type == bfd_link_hash_defweak))
          maybe_dynamic = TRUE;
--- 3074,3080 ----
           this may help reduce memory usage and processing time later.  */
        maybe_dynamic = FALSE;
        if (h && ((info->shared
! 		 && (!info->symbolic || info->unresolved_syms_in_shared_libs == RM_IGNORE))
  		|| ! (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
  		|| h->root.root.type == bfd_link_hash_defweak))
          maybe_dynamic = TRUE;
*************** elf64_alpha_relocate_section (output_bfd
*** 4445,4492 ****
  	}
        else
  	{
! 	  h = alpha_elf_sym_hashes (input_bfd)[r_symndx - symtab_hdr->sh_info];
  
! 	  while (h->root.root.type == bfd_link_hash_indirect
! 		 || h->root.root.type == bfd_link_hash_warning)
! 	    h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
! 
! 	  value = 0;
! 	  if (h->root.root.type == bfd_link_hash_defined
! 	      || h->root.root.type == bfd_link_hash_defweak)
! 	    {
! 	      sec = h->root.root.u.def.section;
  
! 	      /* Detect the cases that sym_sec->output_section is
! 		 expected to be NULL -- all cases in which the symbol
! 		 is defined in another shared module.  This includes
! 		 PLT relocs for which we've created a PLT entry and
! 		 other relocs for which we're prepared to create
! 		 dynamic relocations.  */
! 	      /* ??? Just accept it NULL and continue.  */
! 
! 	      if (sec->output_section != NULL)
! 		value = (h->root.root.u.def.value
! 			 + sec->output_section->vma
! 			      + sec->output_offset);
! 	    }
! 	  else if (h->root.root.type == bfd_link_hash_undefweak)
  	    undef_weak_ref = TRUE;
- 	  else if (!info->executable
- 		   && !info->no_undefined
- 		   && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
- 	    ;
- 	  else
- 	    {
- 	      if (!((*info->callbacks->undefined_symbol)
- 		    (info, h->root.root.root.string, input_bfd,
- 		     input_section, rel->r_offset,
- 		     (info->executable || info->no_undefined
- 		      || ELF_ST_VISIBILITY (h->root.other)))))
- 		return FALSE;
- 	      continue;
- 	    }
  
            dynamic_symbol_p = alpha_elf_dynamic_symbol_p (&h->root, info);
  	  gotent = h->got_entries;
  	}
--- 4445,4469 ----
  	}
        else
  	{
! 	  bfd_boolean warned;
! 	  bfd_boolean unresolved_reloc;
! 	  struct elf_link_hash_entry *hh;
! 	  
! 	  RELOC_FOR_GLOBAL_SYMBOL (hh,
! 				   (struct elf_link_hash_entry *) alpha_elf_sym_hashes (input_bfd),
! 				   r_symndx, symtab_hdr, value,
! 				   sec, unresolved_reloc, info,
! 				   warned);
  
! 	  if (warned)
! 	    continue;
  
! 	  if (value == 0
! 	      && ! unresolved_reloc
! 	      && hh->root.type == bfd_link_hash_undefweak)
  	    undef_weak_ref = TRUE;
  
+ 	  h = (struct alpha_elf_link_hash_entry *) hh;
            dynamic_symbol_p = alpha_elf_dynamic_symbol_p (&h->root, info);
  	  gotent = h->got_entries;
  	}
Index: bfd/elf64-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-hppa.c,v
retrieving revision 1.36
diff -c -3 -p -r1.36 elf64-hppa.c
*** bfd/elf64-hppa.c	30 Jul 2003 02:15:07 -0000	1.36
--- bfd/elf64-hppa.c	19 Aug 2003 16:40:21 -0000
*************** elf64_hppa_check_relocs (abfd, info, sec
*** 710,722 ****
    relend = relocs + sec->reloc_count;
    for (rel = relocs; rel < relend; ++rel)
      {
!       enum {
! 	NEED_DLT = 1,
! 	NEED_PLT = 2,
! 	NEED_STUB = 4,
! 	NEED_OPD = 8,
! 	NEED_DYNREL = 16,
!       };
  
        struct elf_link_hash_entry *h = NULL;
        unsigned long r_symndx = ELF64_R_SYM (rel->r_info);
--- 710,723 ----
    relend = relocs + sec->reloc_count;
    for (rel = relocs; rel < relend; ++rel)
      {
!       enum
! 	{
! 	  NEED_DLT = 1,
! 	  NEED_PLT = 2,
! 	  NEED_STUB = 4,
! 	  NEED_OPD = 8,
! 	  NEED_DYNREL = 16,
! 	};
  
        struct elf_link_hash_entry *h = NULL;
        unsigned long r_symndx = ELF64_R_SYM (rel->r_info);
*************** elf64_hppa_check_relocs (abfd, info, sec
*** 746,752 ****
  	 this may help reduce memory usage and processing time later.  */
        maybe_dynamic = FALSE;
        if (h && ((info->shared
! 		    && (!info->symbolic || info->allow_shlib_undefined) )
  		|| ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
  		|| h->root.type == bfd_link_hash_defweak))
  	maybe_dynamic = TRUE;
--- 747,753 ----
  	 this may help reduce memory usage and processing time later.  */
        maybe_dynamic = FALSE;
        if (h && ((info->shared
! 		 && (!info->symbolic || info->unresolved_syms_in_shared_libs == RM_IGNORE))
  		|| ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
  		|| h->root.type == bfd_link_hash_defweak))
  	maybe_dynamic = TRUE;
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.129
diff -c -3 -p -r1.129 elf64-ppc.c
*** bfd/elf64-ppc.c	16 Aug 2003 13:42:43 -0000	1.129
--- bfd/elf64-ppc.c	19 Aug 2003 16:40:28 -0000
*************** ppc64_elf_relocate_section (bfd *output_
*** 7362,7405 ****
  	}
        else
  	{
! 	  /* It's a global symbol.  */
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
  	  sym_name = h->root.root.string;
- 	  relocation = 0;
- 	  if (h->root.type == bfd_link_hash_defined
- 	      || h->root.type == bfd_link_hash_defweak)
- 	    {
- 	      sec = h->root.u.def.section;
- 	      if (sec->output_section == NULL)
- 		/* Set a flag that will be cleared later if we find a
- 		   relocation value for this symbol.  output_section
- 		   is typically NULL for symbols satisfied by a shared
- 		   library.  */
- 		unresolved_reloc = TRUE;
- 	      else
- 		relocation = (h->root.u.def.value
- 			      + sec->output_section->vma
- 			      + sec->output_offset);
- 	    }
- 	  else if (h->root.type == bfd_link_hash_undefweak)
- 	    ;
- 	  else if (!info->executable
- 		   && !info->no_undefined
- 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
- 	    ;
- 	  else
- 	    {
- 	      if (! ((*info->callbacks->undefined_symbol)
- 		     (info, h->root.root.string, input_bfd, input_section,
- 		      rel->r_offset, (info->executable
- 				      || info->no_undefined
- 				      || ELF_ST_VISIBILITY (h->other)))))
- 		return FALSE;
- 	      warned = TRUE;
- 	    }
  	}
  
        /* TLS optimizations.  Replace instruction sequences and relocs
--- 7362,7372 ----
  	}
        else
  	{
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
! 				   symtab_hdr, relocation, sec,
! 				   unresolved_reloc, info,
! 				   warned);
  	  sym_name = h->root.root.string;
  	}
  
        /* TLS optimizations.  Replace instruction sequences and relocs
Index: bfd/elf64-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-s390.c,v
retrieving revision 1.48
diff -c -3 -p -r1.48 elf64-s390.c
*** bfd/elf64-s390.c	11 Aug 2003 14:26:10 -0000	1.48
--- bfd/elf64-s390.c	19 Aug 2003 16:40:32 -0000
*************** elf_s390_relocate_section (output_bfd, i
*** 2301,2345 ****
  	}
        else
  	{
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
  
! 	  if (h->root.type == bfd_link_hash_defined
! 	      || h->root.type == bfd_link_hash_defweak)
! 	    {
! 	      sec = h->root.u.def.section;
! 	      if (sec->output_section == NULL)
! 		{
! 		  /* Set a flag that will be cleared later if we find a
! 		     relocation value for this symbol.  output_section
! 		     is typically NULL for symbols satisfied by a shared
! 		     library.  */
! 		  unresolved_reloc = TRUE;
! 		  relocation = 0;
! 		}
! 	      else
! 		relocation = (h->root.u.def.value
! 			      + sec->output_section->vma
! 			      + sec->output_offset);
! 	    }
! 	  else if (h->root.type == bfd_link_hash_undefweak)
! 	    relocation = 0;
! 	  else if (!info->executable
! 		   && !info->no_undefined
! 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
! 	    relocation = 0;
! 	  else
! 	    {
! 	      if (! ((*info->callbacks->undefined_symbol)
! 		     (info, h->root.root.string, input_bfd,
! 		      input_section, rel->r_offset,
! 		      (info->executable || info->no_undefined
! 		       || ELF_ST_VISIBILITY (h->other)))))
! 		return FALSE;
! 	      relocation = 0;
! 	    }
  	}
  
        switch (r_type)
--- 2301,2312 ----
  	}
        else
  	{
! 	  bfd_boolean warned ATTRIBUTE_UNUSED;
  
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
! 				   symtab_hdr, relocation, sec,
! 				   unresolved_reloc, info,
! 				   warned);
  	}
  
        switch (r_type)
Index: bfd/elf64-sh64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-sh64.c,v
retrieving revision 1.34
diff -c -3 -p -r1.34 elf64-sh64.c
*** bfd/elf64-sh64.c	7 Aug 2003 08:38:08 -0000	1.34
--- bfd/elf64-sh64.c	19 Aug 2003 16:40:35 -0000
*************** sh_elf64_relocate_section (bfd *output_b
*** 1610,1615 ****
--- 1610,1617 ----
  	}
        else
  	{
+ 	  /* ??? Could we use the RELOC_FOR_GLOBAL_SYMBOL macro here ?  */
+ 
  	  /* Section symbols are never (?) placed in the hash table, so
  	     we can just ignore hash relocations when creating a
  	     relocatable object file.  */
*************** sh_elf64_relocate_section (bfd *output_b
*** 1699,1705 ****
  	    }
  	  else if (h->root.type == bfd_link_hash_undefweak)
  	    relocation = 0;
! 	  else if (info->shared && !info->symbolic && !info->no_undefined)
  	    relocation = 0;
  	  else
  	    {
--- 1701,1709 ----
  	    }
  	  else if (h->root.type == bfd_link_hash_undefweak)
  	    relocation = 0;
! 	  else if (info->shared
! 		   && !info->symbolic
! 		   && info->unresolved_syms_in_objects == RM_IGNORE)
  	    relocation = 0;
  	  else
  	    {
Index: bfd/elf64-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-sparc.c,v
retrieving revision 1.77
diff -c -3 -p -r1.77 elf64-sparc.c
*** bfd/elf64-sparc.c	11 Aug 2003 14:26:11 -0000	1.77
--- bfd/elf64-sparc.c	19 Aug 2003 16:40:38 -0000
*************** sparc64_elf_relocate_section (output_bfd
*** 2074,2115 ****
  	}
        else
  	{
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
  
! 	  relocation = 0;
! 	  if (h->root.type == bfd_link_hash_defined
! 	      || h->root.type == bfd_link_hash_defweak)
  	    {
- 	      sec = h->root.u.def.section;
- 	      if (sec->output_section == NULL)
- 		/* Set a flag that will be cleared later if we find a
- 		   relocation value for this symbol.  output_section
- 		   is typically NULL for symbols satisfied by a shared
- 		   library.  */
- 		unresolved_reloc = TRUE;
- 	      else
- 		relocation = (h->root.u.def.value
- 			      + sec->output_section->vma
- 			      + sec->output_offset);
- 	    }
- 	  else if (h->root.type == bfd_link_hash_undefweak)
- 	    ;
- 	  else if (!info->executable
- 		   && !info->no_undefined
- 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
- 	    ;
- 	  else
- 	    {
- 	      if (! ((*info->callbacks->undefined_symbol)
- 		     (info, h->root.root.string, input_bfd,
- 		      input_section, rel->r_offset,
- 		      (info->executable || info->no_undefined
- 		       || ELF_ST_VISIBILITY (h->other)))))
- 		return FALSE;
- 
  	      /* To avoid generating warning messages about truncated
  		 relocations, set the relocation's address to be the same as
  		 the start of this section.  */
--- 2074,2087 ----
  	}
        else
  	{
! 	  bfd_boolean warned;
  
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
! 				   symtab_hdr, relocation, sec,
! 				   unresolved_reloc, info,
! 				   warned);
! 	  if (warned)
  	    {
  	      /* To avoid generating warning messages about truncated
  		 relocations, set the relocation's address to be the same as
  		 the start of this section.  */
Index: bfd/elf64-x86-64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
retrieving revision 1.66
diff -c -3 -p -r1.66 elf64-x86-64.c
*** bfd/elf64-x86-64.c	11 Aug 2003 14:26:11 -0000	1.66
--- bfd/elf64-x86-64.c	19 Aug 2003 16:40:41 -0000
*************** elf64_x86_64_relocate_section (bfd *outp
*** 1827,1871 ****
  	}
        else
  	{
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
  
! 	  if (h->root.type == bfd_link_hash_defined
! 	      || h->root.type == bfd_link_hash_defweak)
! 	    {
! 	      sec = h->root.u.def.section;
! 	      if (sec->output_section == NULL)
! 		{
! 		  /* Set a flag that will be cleared later if we find a
! 		     relocation value for this symbol.  output_section
! 		     is typically NULL for symbols satisfied by a shared
! 		     library.  */
! 		  unresolved_reloc = TRUE;
! 		  relocation = 0;
! 		}
! 	      else
! 		relocation = (h->root.u.def.value
! 			      + sec->output_section->vma
! 			      + sec->output_offset);
! 	    }
! 	  else if (h->root.type == bfd_link_hash_undefweak)
! 	    relocation = 0;
! 	  else if (!info->executable
! 		   && !info->no_undefined
! 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
! 	    relocation = 0;
! 	  else
! 	    {
! 	      if (! ((*info->callbacks->undefined_symbol)
! 		     (info, h->root.root.string, input_bfd,
! 		      input_section, rel->r_offset,
! 		      (info->executable || info->no_undefined
! 		       || ELF_ST_VISIBILITY (h->other)))))
! 		return FALSE;
! 	      relocation = 0;
! 	    }
  	}
        /* When generating a shared object, the relocations handled here are
  	 copied into the output file to be resolved at run time.  */
--- 1827,1838 ----
  	}
        else
  	{
! 	  bfd_boolean warned;
  
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
! 				   symtab_hdr, relocation, sec,
! 				   unresolved_reloc, info,
! 				   warned);
  	}
        /* When generating a shared object, the relocations handled here are
  	 copied into the output file to be resolved at run time.  */
Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.238
diff -c -3 -p -r1.238 elflink.h
*** bfd/elflink.h	7 Aug 2003 08:38:10 -0000	1.238
--- bfd/elflink.h	19 Aug 2003 16:40:47 -0000
*************** elf_link_output_extsym (struct elf_link_
*** 4363,4399 ****
  	return TRUE;
      }
  
!   /* If we are not creating a shared library, and this symbol is
!      referenced by a shared library but is not defined anywhere, then
!      warn that it is undefined.  If we do not do this, the runtime
!      linker will complain that the symbol is undefined when the
!      program is run.  We don't have to worry about symbols that are
!      referenced by regular files, because we will already have issued
!      warnings for them.  */
!   if (! finfo->info->relocatable
!       && (finfo->info->executable
! 	  || ! finfo->info->allow_shlib_undefined)
!       && h->root.type == bfd_link_hash_undefined
        && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0
        && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
!       && ! elf_link_check_versioned_symbol (finfo->info, h))
      {
        if (! ((*finfo->info->callbacks->undefined_symbol)
  	     (finfo->info, h->root.root.string, h->root.u.undef.abfd,
! 	      NULL, 0, TRUE)))
  	{
  	  eoinfo->failed = TRUE;
  	  return FALSE;
  	}
      }
  
    /* We should also warn if a forced local symbol is referenced from
       shared libraries.  */
    if (! finfo->info->relocatable
!       && (! finfo->info->shared || ! finfo->info->allow_shlib_undefined)
        && (h->elf_link_hash_flags
! 	  & (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC
! 	     | ELF_LINK_DYNAMIC_DEF | ELF_LINK_DYNAMIC_WEAK))
  	 == (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC)
        && ! elf_link_check_versioned_symbol (finfo->info, h))
      {
--- 4363,4394 ----
  	return TRUE;
      }
  
!   /* If we have an undefined symbol reference here then it must have
!      come from a shared library that is being linked in.  (Undefined
!      references in regular files have already been handled).  If we
!      are reporting errors for this situation then do so now.  */
!   if (h->root.type == bfd_link_hash_undefined
        && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0
        && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
!       && ! elf_link_check_versioned_symbol (finfo->info, h)
!       && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE)
      {
        if (! ((*finfo->info->callbacks->undefined_symbol)
  	     (finfo->info, h->root.root.string, h->root.u.undef.abfd,
! 	      NULL, 0, finfo->info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)))
  	{
  	  eoinfo->failed = TRUE;
  	  return FALSE;
  	}
      }
  
    /* We should also warn if a forced local symbol is referenced from
       shared libraries.  */
    if (! finfo->info->relocatable
!       && (! finfo->info->shared)
        && (h->elf_link_hash_flags
! 	  & (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_DYNAMIC_DEF | ELF_LINK_DYNAMIC_WEAK))
  	 == (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC)
        && ! elf_link_check_versioned_symbol (finfo->info, h))
      {
Index: bfd/elfxx-ia64.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-ia64.c,v
retrieving revision 1.97
diff -c -3 -p -r1.97 elfxx-ia64.c
*** bfd/elfxx-ia64.c	11 Aug 2003 14:26:11 -0000	1.97
--- bfd/elfxx-ia64.c	19 Aug 2003 16:40:51 -0000
*************** elfNN_ia64_check_relocs (abfd, info, sec
*** 2162,2168 ****
  	 this may help reduce memory usage and processing time later.  */
        maybe_dynamic = FALSE;
        if (h && ((!info->executable
! 		      && (!info->symbolic || info->allow_shlib_undefined))
  		|| ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
  		|| h->root.type == bfd_link_hash_defweak))
  	maybe_dynamic = TRUE;
--- 2162,2168 ----
  	 this may help reduce memory usage and processing time later.  */
        maybe_dynamic = FALSE;
        if (h && ((!info->executable
! 		 && (!info->symbolic || info->unresolved_syms_in_shared_libs == RM_IGNORE))
  		|| ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
  		|| h->root.type == bfd_link_hash_defweak))
  	maybe_dynamic = TRUE;
*************** elfNN_ia64_relocate_section (output_bfd,
*** 3852,3903 ****
  	}
        else
  	{
! 	  long indx;
  
! 	  /* Reloc against global symbol.  */
! 	  indx = r_symndx - symtab_hdr->sh_info;
! 	  h = elf_sym_hashes (input_bfd)[indx];
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
! 
! 	  value = 0;
! 	  if (h->root.type == bfd_link_hash_defined
! 	      || h->root.type == bfd_link_hash_defweak)
! 	    {
! 	      sym_sec = h->root.u.def.section;
! 
! 	      /* Detect the cases that sym_sec->output_section is
! 		 expected to be NULL -- all cases in which the symbol
! 		 is defined in another shared module.  This includes
! 		 PLT relocs for which we've created a PLT entry and
! 		 other relocs for which we're prepared to create
! 		 dynamic relocations.  */
! 	      /* ??? Just accept it NULL and continue.  */
  
! 	      if (sym_sec->output_section != NULL)
! 		{
! 		  value = (h->root.u.def.value
! 			   + sym_sec->output_section->vma
! 			   + sym_sec->output_offset);
! 		}
! 	    }
! 	  else if (h->root.type == bfd_link_hash_undefweak)
  	    undef_weak_ref = TRUE;
! 	  else if (! info->executable
! 		   && !info->no_undefined
! 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
! 	    ;
! 	  else
! 	    {
! 	      if (! ((*info->callbacks->undefined_symbol)
! 		     (info, h->root.root.string, input_bfd,
! 		      input_section, rel->r_offset,
! 		      (info->executable || info->no_undefined
! 		       || ELF_ST_VISIBILITY (h->other)))))
! 		return FALSE;
! 	      continue;
! 	    }
  	}
  
        hit_addr = contents + rel->r_offset;
--- 3852,3870 ----
  	}
        else
  	{
! 	  bfd_boolean unresolved_reloc;
! 	  bfd_boolean warned;
  
! 	  RELOC_FOR_GLOBAL_SYMBOL (h, elf_sym_hashes (input_bfd),
! 				   r_symndx,
! 				   symtab_hdr, value, sym_sec,
! 				   unresolved_reloc, info,
! 				   warned);
  
! 	  if (h->root.type == bfd_link_hash_undefweak)
  	    undef_weak_ref = TRUE;
! 	  else if (warned)
! 	    continue;
  	}
  
        hit_addr = contents + rel->r_offset;
Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.73
diff -c -3 -p -r1.73 elfxx-mips.c
*** bfd/elfxx-mips.c	14 Aug 2003 09:30:34 -0000	1.73
--- bfd/elfxx-mips.c	19 Aug 2003 16:41:00 -0000
*************** mips_elf_calculate_relocation (abfd, inp
*** 3008,3013 ****
--- 3008,3015 ----
      }
    else
      {
+       /* ??? Could we use RELOC_FOR_GLOBAL_SYMBOL here ?  */
+ 
        /* For global symbols we look up the symbol in the hash-table.  */
        h = ((struct mips_elf_link_hash_entry *)
  	   elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
*************** mips_elf_calculate_relocation (abfd, inp
*** 3021,3027 ****
  
        /* See if this is the special _gp_disp symbol.  Note that such a
  	 symbol must always be a global symbol.  */
!       if (strcmp (h->root.root.root.string, "_gp_disp") == 0
  	  && ! NEWABI_P (input_bfd))
  	{
  	  /* Relocations against _gp_disp are permitted only with
--- 3023,3029 ----
  
        /* See if this is the special _gp_disp symbol.  Note that such a
  	 symbol must always be a global symbol.  */
!       if (strcmp (*namep, "_gp_disp") == 0
  	  && ! NEWABI_P (input_bfd))
  	{
  	  /* Relocations against _gp_disp are permitted only with
*************** mips_elf_calculate_relocation (abfd, inp
*** 3054,3064 ****
  	   addresses.  */
  	symbol = 0;
        else if (info->shared
! 	       && !info->no_undefined
  	       && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
  	symbol = 0;
!       else if (strcmp (h->root.root.root.string, "_DYNAMIC_LINK") == 0 ||
!               strcmp (h->root.root.root.string, "_DYNAMIC_LINKING") == 0)
  	{
  	  /* If this is a dynamic link, we should have created a
  	     _DYNAMIC_LINK symbol or _DYNAMIC_LINKING(for normal mips) symbol
--- 3056,3066 ----
  	   addresses.  */
  	symbol = 0;
        else if (info->shared
! 	       && info->unresolved_syms_in_objects == RM_IGNORE
  	       && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
  	symbol = 0;
!       else if (strcmp (*namep, "_DYNAMIC_LINK") == 0 ||
!               strcmp (*namep, "_DYNAMIC_LINKING") == 0)
  	{
  	  /* If this is a dynamic link, we should have created a
  	     _DYNAMIC_LINK symbol or _DYNAMIC_LINKING(for normal mips) symbol
*************** mips_elf_calculate_relocation (abfd, inp
*** 3075,3081 ****
  	  if (! ((*info->callbacks->undefined_symbol)
  		 (info, h->root.root.root.string, input_bfd,
  		  input_section, relocation->r_offset,
! 		  (!info->shared || info->no_undefined
  		   || ELF_ST_VISIBILITY (h->root.other)))))
  	    return bfd_reloc_undefined;
  	  symbol = 0;
--- 3077,3084 ----
  	  if (! ((*info->callbacks->undefined_symbol)
  		 (info, h->root.root.root.string, input_bfd,
  		  input_section, relocation->r_offset,
! 		  ((info->shared && info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)
! 		   || (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
  		   || ELF_ST_VISIBILITY (h->root.other)))))
  	    return bfd_reloc_undefined;
  	  symbol = 0;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]