* lexsup.c (parse_args): Handle --wrap.
authorIan Lance Taylor <ian@airs.com>
Tue, 12 Mar 1996 23:39:18 +0000 (23:39 +0000)
committerIan Lance Taylor <ian@airs.com>
Tue, 12 Mar 1996 23:39:18 +0000 (23:39 +0000)
* ldmain.c (main): Initialize link_info.wrap_hash.
* ldexp.c (fold_name): Use bfd_wrapped_link_hash_lookup in DEFINED
and NAME cases.
* ld.texinfo, ld.1: Document --wrap.

ld/ChangeLog
ld/ld.1
ld/ld.texinfo
ld/ldmain.c
ld/lexsup.c

index 89cbc473a0b9ddec462739fb170ec3b82b4533c0..96f6ed04a333ff0bf35ba3a0e3b81c0bb9988ebf 100644 (file)
@@ -8,6 +8,12 @@ Tue Mar 12 12:43:59 1996  David Mosberger-Tang  <davidm@koala.azstarnet.com>
 
 Tue Mar 12 12:02:21 1996  Ian Lance Taylor  <ian@cygnus.com>
 
+       * lexsup.c (parse_args): Handle --wrap.
+       * ldmain.c (main): Initialize link_info.wrap_hash.
+       * ldexp.c (fold_name): Use bfd_wrapped_link_hash_lookup in DEFINED
+       and NAME cases.
+       * ld.texinfo, ld.1: Document --wrap.
+
        * configure: Rebuild with autoconf 2.8.
 
        Don't do SunOS style dynamic linking for sparc-aout:
diff --git a/ld/ld.1 b/ld/ld.1
index 802926cc6e56704df3f48f1bff2df062125b8fa3..ccc47dda63f90bf09798aafdc20f15d550d604e0 100644 (file)
--- a/ld/ld.1
+++ b/ld/ld.1
@@ -123,6 +123,9 @@ ld \- the GNU linker
 .RB "[\|" \-warn\-once "\|]" 
 .RB "[\|" \-\-whole\-archive "\|]" 
 .RB "[\|" \-\-no\-whole\-archive "\|]" 
+.RB "[\|" "\-\-wrap\ "\c
+.I symbol\c
+\&\|]
 .RB "[\|" \-X "\|]" 
 .RB "[\|" \-x "\|]" 
 .ad b
@@ -933,6 +936,19 @@ Turn off the effect of the
 .B \-\-whole\-archive
 option for archives which appear later on the command line.
 
+.TP
+.BI "--wrap " "symbol"
+Use a wrapper function for 
+.I symbol.
+Any undefined reference to
+.I symbol
+will be resolved to
+.BI "__wrap_" "symbol".
+Any undefined reference to
+.BI "__real_" "symbol"
+will be resolved to
+.I symbol.
+
 .TP
 .B \-X 
 Delete all temporary local symbols.  For most targets, this is all local
index 23fc78a81f0b9e65d69b73632950b7d1df0e0af4..11d6d39bf43886061662eb5d13de971491b7af97 100644 (file)
@@ -184,12 +184,12 @@ ld [ -o @var{output} ]  @var{objfile}@dots{}
   [ -Ttext @var{org} ]  [ -Tdata @var{org} ]
   [ -Tbss @var{org} ]  [ -t ] [ -traditional-format ]
   [ -u @var{symbol}]  [-V]  [-v]  [ -verbose]  [ -version ]
-  [ -warn-common ] [ -warn-constructors] [ -warn-multiple-gp ] [ -warn-once ]
-  [ -y @var{symbol} ]  [ -X ]  [-x ]
+  [ -warn-common ] [ -warn-constructors] [ -warn-multiple-gp ]
+  [ -warn-once ] [ -y @var{symbol} ]  [ -X ]  [-x ]
   [ -( [ archives ] -) ]
   [ --start-group [ archives ] --end-group ]
   [ -split-by-reloc @var{count} ] [ -split-by-file ]
-  [ --whole-archive ] [ --no-whole-archive ]
+  [ --whole-archive ] [ --no-whole-archive ] [ --wrap @var{symbol} ]
 @end smallexample
 
 This plethora of command-line options may seem intimidating, but in
@@ -968,6 +968,40 @@ library.
 Turn off the effect of the @code{--whole-archive} option for archives
 which appear later on the command line.
 
+@kindex --wrap
+@item --wrap @var{symbol}
+Use a wrapper function for @var{symbol}.  Any undefined reference to
+@var{symbol} will be resolved to @code{__wrap_@var{symbol}}.  Any
+undefined reference to @code{__real_@var{symbol}} will be resolved to
+@var{symbol}.
+
+This can be used to provide a wrapper for a system function.  The
+wrapper function should be called @code{__wrap_@var{symbol}}.  If it
+wishes to call the system function, it should call
+@code{__real_@var{symbol}}.
+
+Here is a trivial example:
+
+@smallexample
+void *
+__wrap_malloc (int c)
+@{
+  printf ("malloc called with %ld\n", c);
+  return __real_malloc (c);
+@}
+@end smallexample
+
+If you link other code with this file using @code{--wrap malloc}, then
+all calls to @code{malloc} will call the function @code{__wrap_malloc}
+instead.  The call to @code{__real_malloc} in @code{__wrap_malloc} will
+call the real @code{malloc} function.
+
+You may wish to provide a @code{__real_malloc} function as well, so that
+links without the @code{--wrap} option will succeed.  If you do this,
+you should not put the definition of @code{__real_malloc} in the same
+file as @code{__wrap_malloc}; if you do, the assembler may resolve the
+call before the linker has a chance to wrap it to @code{malloc}.
+
 @kindex -X
 @cindex local symbols, deleting
 @cindex L, deleting symbols beginning
index 5dbfc557429f4a23354e45da74b61c10a2b3ebbf..6d78e27defa46ffe2895ceed3132985ee58ca95d 100644 (file)
@@ -189,7 +189,7 @@ main (argc, argv)
   link_info.hash = NULL;
   link_info.keep_hash = NULL;
   link_info.notice_hash = NULL;
-
+  link_info.wrap_hash = NULL;
   
   ldfile_add_arch ("");
 
index d90b8c71ae518d39457e86f128f8949cd6ed48a0..47fd2c5fb98b066d0679b42076dd5d1aeaeb3b39 100644 (file)
@@ -108,7 +108,7 @@ parse_args (argc, argv)
 #define OPTION_SPLIT_BY_RELOC          (OPTION_WARN_ONCE + 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)
 
   static struct option longopts[] = {
   /* Sorted alphabeticaly, except for the PE options grouped at the end. */
@@ -165,8 +165,8 @@ parse_args (argc, argv)
     {"split-by-reloc", required_argument, NULL, OPTION_SPLIT_BY_RELOC},
     {"split-by-file", no_argument, NULL, OPTION_SPLIT_BY_FILE},
     {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE},
+    {"wrap", required_argument, NULL, OPTION_WRAP},
 
-      
     {NULL, no_argument, NULL, 0}
   };
 
@@ -498,6 +498,20 @@ parse_args (argc, argv)
        case OPTION_WHOLE_ARCHIVE:
          whole_archive = true;
          break;
+       case OPTION_WRAP:
+         if (link_info.wrap_hash == NULL)
+           {
+             link_info.wrap_hash = ((struct bfd_hash_table *)
+                                    xmalloc (sizeof (struct bfd_hash_table)));
+             if (! bfd_hash_table_init_n (link_info.wrap_hash,
+                                          bfd_hash_newfunc,
+                                          61))
+               einfo ("%P%F: bfd_hash_table_init failed: %E\n");
+           }
+         if (bfd_hash_lookup (link_info.wrap_hash, optarg, true, true)
+             == NULL)
+           einfo ("%P%F: bfd_hash_lookup failed: %E\n");
+         break;
        case 'X':
          link_info.discard = discard_l;
          break;