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]

[patch] Fix handling of common symbols with plugins


Currently we don't produce the correct result if a common symbol shows
up in both ELF and IR. In a previous patch I tried to pass the size
information back to the plugin, but unfortunately there is no field in
d_plugin_symbol to pass the alignment.

What I have implemented now is:

* The plugin is expected to handle all common symbols in IR. It can do
it by merging them or by passing multiple objects to the linker with
each symbol.

* The linker will not blindly override a common symbol during the
replacement phase. Instead, the regular logic is applied so that we
don't discard information in case an ELF file had the largest size or
alignment.

In addition to "make check" I tested this with a small script and two
LLVM IR files. The script test all combinations of input order and
file type (IR or ELF) and checks that we get the same alignment and
size.

Cheers,
Rafael


gold
2014-09-09  Rafael Ãvila de EspÃndola <respindola@mozilla.com>

        * plugin.cc (Sized_pluginobj::do_add_symbols): Ignore isym->size.
        * resolve.cc (Symbol_table::resolve): Don't override common symbols
        during the replacement phase.

include
2014-09-09  Rafael Ãvila de EspÃndola <respindola@mozilla.com>

        * plugin-api.h (ld_plugin_symbol): Note that size is ignored.

ld
2014-09-09  Rafael Ãvila de EspÃndola <respindola@mozilla.com>

        * plugin.c (asymbol_from_plugin_symbol): Ignore ldsym->size.
        * testplug.c (parse_symdefstr): Ignore sym->size.
diff --git a/gold/plugin.cc b/gold/plugin.cc
index 6519732..0339d42 100644
--- a/gold/plugin.cc
+++ b/gold/plugin.cc
@@ -1053,8 +1053,6 @@ Sized_pluginobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
   elfcpp::Sym<size, big_endian> sym(symbuf);
   elfcpp::Sym_write<size, big_endian> osym(symbuf);
 
-  typedef typename elfcpp::Elf_types<size>::Elf_WXword Elf_size_type;
-
   this->symbols_.resize(this->nsyms_);
 
   for (int i = 0; i < this->nsyms_; ++i)
@@ -1125,7 +1123,7 @@ Sized_pluginobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
 
       osym.put_st_name(0);
       osym.put_st_value(0);
-      osym.put_st_size(static_cast<Elf_size_type>(isym->size));
+      osym.put_st_size(0);
       osym.put_st_info(bind, elfcpp::STT_NOTYPE);
       osym.put_st_other(vis, 0);
       osym.put_st_shndx(shndx);
diff --git a/gold/resolve.cc b/gold/resolve.cc
index 8cc637a..abb5d90 100644
--- a/gold/resolve.cc
+++ b/gold/resolve.cc
@@ -303,11 +303,14 @@ Symbol_table::resolve(Sized_symbol<size>* to,
 
   // If we're processing replacement files, allow new symbols to override
   // the placeholders from the plugin objects.
+  // Treat common symbols specially since it is possible that an ELF
+  // file increased the size of the alignment.
   if (to->source() == Symbol::FROM_OBJECT)
     {
       Pluginobj* obj = to->object()->pluginobj();
       if (obj != NULL
-          && parameters->options().plugins()->in_replacement_phase())
+          && parameters->options().plugins()->in_replacement_phase()
+          && !to->is_common())
         {
           this->override(to, sym, st_shndx, is_ordinary, object, version);
           return;
diff --git a/include/plugin-api.h b/include/plugin-api.h
index 5797d4d..dfcd1f2 100644
--- a/include/plugin-api.h
+++ b/include/plugin-api.h
@@ -89,7 +89,7 @@ struct ld_plugin_symbol
   char *version;
   int def;
   int visibility;
-  uint64_t size;
+  uint64_t size; /* ignored */
   char *comdat_key;
   int resolution;
 };
diff --git a/ld/plugin.c b/ld/plugin.c
index f02a97f..871c714 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -332,7 +332,7 @@ asymbol_from_plugin_symbol (bfd *abfd, asymbol *asym,
     case LDPK_COMMON:
       flags = BSF_GLOBAL;
       section = bfd_com_section_ptr;
-      asym->value = ldsym->size;
+      asym->value = 0;
       /* For ELF targets, set alignment of common symbol to 1.  */
       if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
 	{
diff --git a/ld/testplug.c b/ld/testplug.c
index 4dedf95..e6954c1 100644
--- a/ld/testplug.c
+++ b/ld/testplug.c
@@ -217,7 +217,6 @@ parse_symdefstr (const char *str, struct ld_plugin_symbol *sym)
     return LDPS_ERR;
 
   /* Parsed successfully, so allocate strings and fill out fields.  */
-  sym->size = size;
   sym->resolution = LDPR_UNKNOWN;
   sym->name = malloc (colon1 - str + 1);
   if (!sym->name)

Attachment: run.sh
Description: Bourne shell script

Attachment: test.ll
Description: Binary data

Attachment: test2.ll
Description: Binary data


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