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