Patch to not create GOT and dynamic relocation entries for unresolved symbols with --warn-unresolved-symbols.

Sriraman Tallam tmsriram@google.com
Sat Apr 11 00:16:00 GMT 2015


Hi,

    We have a problem where we use --warn-unresolved-symbols to tide
over an issue where we know the symbol is undefined but we also know
that the it is never accessed.

Example:

extern int foo();

int (*p)() = NULL;
int main() {
  if (p == &foo)
    foo();
  return 0;
}

Now,

$ g++ -O2 foo.cc
foo.cc:function main: warning: undefined reference to 'foo()'

gives the right warning but builds a.out just fine and runs fine as
long as p is not equal to foo which is our case.

However, with -fPIE

$ g++ -O2 -fPIE foo.cc -pie
foo.cc:function main: warning: undefined reference to 'foo()'

but
$./a.out
./a.out: symbol lookup error: ./a.out: undefined symbol: _Z3foov

because with fPIE, a function pointer access is using a GOTPCREL
relocation which creates a GOT entry and a dynamic relocation for it.
The dynamic linker does not like the unresolved symbol any more.

I have attached a patch to prevent creation of GOT and dynamic
relocation entries with --warn-unresolved-symbols in general.  Is this
reasonable?


Thanks
Sri
-------------- next part --------------
	* x86_64.cc (Scan::global): Do not create GOT entry for 
	unresolved symbol with --warn-unresolved-symbols.
	(Relocate::relocate): Check for GOT entry only when the
	above condition is not true.

diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index 007af1d..bccb0ab 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -2931,6 +2931,11 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
 	  }
 	else
 	  {
+	    // If the symbol is unresolved and we use --warn-unresolved-symbols
+	    // do not create GOT entry and dynamic relocation for it.
+	    if (parameters->options().warn_unresolved_symbols()
+		&& issue_undefined_symbol_error(gsym))
+	      break;
 	    // If this symbol is not fully resolved, we need to add a
 	    // dynamic relocation for it.
 	    Reloc_section* rela_dyn = target->rela_dyn_section(layout);
@@ -3557,8 +3562,14 @@ Target_x86_64<size>::Relocate::relocate(
 	{
 	  if (gsym != NULL)
 	    {
-	      gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD));
-	      got_offset = gsym->got_offset(GOT_TYPE_STANDARD) - target->got_size();
+	      // We dont create GOT entries for unresolved symbols
+	      // with --warn-unresolved-symbols.
+	      if (!parameters->options().warn_unresolved_symbols()
+		  || !issue_undefined_symbol_error(gsym))
+		{
+		  gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD));
+		  got_offset = gsym->got_offset(GOT_TYPE_STANDARD) - target->got_size();
+		}
 	    }
 	  else
 	    {


More information about the Binutils mailing list