This is the mail archive of the binutils@sourceware.org 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]

[gold][patch] Add a add_input_library callback


GCC can introduce calls to libc functions when for example converting
printf calls into puts calls. This is a problem when using the plugin
and linking libc statically: When the plugin first scans the inputs,
there is no references to puts. When the final objects are generated
there is and gold reports an undefined reference.

The problem with libc is similar to the problem with libgcc. The
difference is that gcc doesn't know exactly which libc is used. It
just passes -lc to the linker. What this patch does is add a new
callback called add_input_library. It is similar to add_input_file,
but causes gold to search for the library.

I tested this with a modified gcc plugin that uses this feature and
was able to correctly statically like a program that fails with the
current plugin.

I also added some documentation to the plugin-api.h file that was
already in the gcc copy.

gold/
2009-10-01  Rafael Avila de Espindola  <espindola@google.com>

	* plugin.cc (add_input_library): New.
	(Plugin::load): Add add_input_library to tv.
	(Plugin_manager::add_input_file): Add the search argument.
	(add_input_file): Update call to Plugin_manager::add_input_file.
	(add_input_library): New.
	* plugin.h (Plugin_manager::add_input_file): Add the search argument.

include/
2009-10-01  Rafael Avila de Espindola  <espindola@google.com>

	* plugin-api.h (ld_plugin_symbol_resolution): Document.
	(ld_plugin_add_input_library): New.
	(ld_plugin_tag): Add LDPT_ADD_INPUT_LIBRARY.
	(ld_plugin_tv): Add tv_add_input_library.

Cheers,
-- 
Rafael Ãvila de EspÃndola
diff --git a/gold/plugin.cc b/gold/plugin.cc
index 7aee46f..de23f9c 100644
--- a/gold/plugin.cc
+++ b/gold/plugin.cc
@@ -74,6 +74,9 @@ static enum ld_plugin_status
 add_input_file(char *pathname);
 
 static enum ld_plugin_status
+add_input_library(char *pathname);
+
+static enum ld_plugin_status
 message(int level, const char *format, ...);
 
 };
@@ -118,7 +121,7 @@ Plugin::load()
   sscanf(ver, "%d.%d", &major, &minor);
 
   // Allocate and populate a transfer vector.
-  const int tv_fixed_size = 13;
+  const int tv_fixed_size = 14;
   int tv_size = this->args_.size() + tv_fixed_size;
   ld_plugin_tv *tv = new ld_plugin_tv[tv_size];
 
@@ -185,6 +188,10 @@ Plugin::load()
   tv[i].tv_u.tv_add_input_file = add_input_file;
 
   ++i;
+  tv[i].tv_tag = LDPT_ADD_INPUT_LIBRARY;
+  tv[i].tv_u.tv_add_input_library = add_input_library;
+
+  ++i;
   tv[i].tv_tag = LDPT_NULL;
   tv[i].tv_u.tv_val = 0;
 
@@ -401,9 +408,9 @@ Plugin_manager::release_input_file(unsigned int handle)
 // Add a new input file.
 
 ld_plugin_status
-Plugin_manager::add_input_file(char *pathname)
+Plugin_manager::add_input_file(char *pathname, bool search)
 {
-  Input_file_argument file(pathname, false, "", false, this->options_);
+  Input_file_argument file(pathname, search, "", false, this->options_);
   Input_argument* input_argument = new Input_argument(file);
   Task_token* next_blocker = new Task_token(true);
   next_blocker->add_blocker();
@@ -941,7 +948,16 @@ static enum ld_plugin_status
 add_input_file(char *pathname)
 {
   gold_assert(parameters->options().has_plugins());
-  return parameters->options().plugins()->add_input_file(pathname);
+  return parameters->options().plugins()->add_input_file(pathname, false);
+}
+
+// Add a new (real) library required by a plugin.
+
+static enum ld_plugin_status
+add_input_library(char *pathname)
+{
+  gold_assert(parameters->options().has_plugins());
+  return parameters->options().plugins()->add_input_file(pathname, true);
 }
 
 // Issue a diagnostic message from a plugin.
diff --git a/gold/plugin.h b/gold/plugin.h
index 6a98ac8..44b0a6b 100644
--- a/gold/plugin.h
+++ b/gold/plugin.h
@@ -227,7 +227,7 @@ class Plugin_manager
 
   // Add a new input file.
   ld_plugin_status
-  add_input_file(char *pathname);
+  add_input_file(char *pathname, bool search);
 
   // Return TRUE if we are in the replacement phase.
   bool
diff --git a/include/plugin-api.h b/include/plugin-api.h
index f536d57..106a79a 100644
--- a/include/plugin-api.h
+++ b/include/plugin-api.h
@@ -111,13 +111,34 @@ enum ld_plugin_symbol_visibility
 enum ld_plugin_symbol_resolution
 {
   LDPR_UNKNOWN = 0,
+
+  /* Symbol is still undefined at this point.  */
   LDPR_UNDEF,
+
+  /* This is the prevailing definition of the symbol, with references from
+     regular object code.  */
   LDPR_PREVAILING_DEF,
+
+  /* This is the prevailing definition of the symbol, with no
+     references from regular objects.  It is only referenced from IR
+     code.  */
   LDPR_PREVAILING_DEF_IRONLY,
+
+  /* This definition was pre-empted by a definition in a regular
+     object file.  */
   LDPR_PREEMPTED_REG,
+
+  /* This definition was pre-empted by a definition in another IR file.  */
   LDPR_PREEMPTED_IR,
+
+  /* This symbol was resolved by a definition in another IR file.  */
   LDPR_RESOLVED_IR,
+
+  /* This symbol was resolved by a definition in a regular object
+     linked into the main executable.  */
   LDPR_RESOLVED_EXEC,
+
+  /* This symbol was resolved by a definition in a shared object.  */
   LDPR_RESOLVED_DYN
 };
 
@@ -193,6 +214,12 @@ typedef
 enum ld_plugin_status
 (*ld_plugin_add_input_file) (char *pathname);
 
+/* The linker's interface for adding a library that should be searched.  */
+
+typedef
+enum ld_plugin_status
+(*ld_plugin_add_input_library) (char *pathname);
+
 /* The linker's interface for issuing a warning or error message.  */
 
 typedef
@@ -224,7 +251,8 @@ enum ld_plugin_tag
   LDPT_ADD_INPUT_FILE,
   LDPT_MESSAGE,
   LDPT_GET_INPUT_FILE,
-  LDPT_RELEASE_INPUT_FILE
+  LDPT_RELEASE_INPUT_FILE,
+  LDPT_ADD_INPUT_LIBRARY
 };
 
 /* The plugin transfer vector.  */
@@ -245,6 +273,7 @@ struct ld_plugin_tv
     ld_plugin_message tv_message;
     ld_plugin_get_input_file tv_get_input_file;
     ld_plugin_release_input_file tv_release_input_file;
+    ld_plugin_add_input_library tv_add_input_library;
   } tv_u;
 };
 

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