-// Modified version of symtab.h class Symbol member
-// Given a direct absolute or pc-relative static relocation against
-// the global symbol, this function returns whether a dynamic relocation
-// is needed.
-
-template<int size>
-bool
-needs_dynamic_reloc(const Symbol* gsym, int flags)
-{
- // No dynamic relocations in a static link!
- if (parameters->doing_static_link())
- return false;
-
- // A reference to an undefined symbol from an executable should be
- // statically resolved to 0, and does not need a dynamic relocation.
- // This matches gnu ld behavior.
- if (gsym->is_undefined() && !parameters->options().shared())
- return false;
-
- // A reference to an absolute symbol does not need a dynamic relocation.
- if (gsym->is_absolute())
- return false;
-
- // An absolute reference within a position-independent output file
- // will need a dynamic relocation.
- if ((flags & Symbol::ABSOLUTE_REF)
- && parameters->options().output_is_position_independent())
- return true;
-
- // A function call that can branch to a local PLT entry does not need
- // a dynamic relocation.
- if ((flags & Symbol::FUNCTION_CALL) && gsym->has_plt_offset())
- return false;
-
- // A reference to any PLT entry in a non-position-independent executable
- // does not need a dynamic relocation.
- // Except due to having function descriptors on powerpc64 we don't define
- // functions to their plt code in an executable, so this doesn't apply.
- if (size == 32
- && !parameters->options().output_is_position_independent()
- && gsym->has_plt_offset())
- return false;
-
- // A reference to a symbol defined in a dynamic object or to a
- // symbol that is preemptible will need a dynamic relocation.
- if (gsym->is_from_dynobj()
- || gsym->is_undefined()
- || gsym->is_preemptible())
- return true;
-
- // For all other cases, return FALSE.
- return false;
-}
-
-// Modified version of symtab.h class Symbol member
-// Whether we should use the PLT offset associated with a symbol for
-// a relocation. FLAGS is a set of Reference_flags.
-
-template<int size>
-bool
-use_plt_offset(const Symbol* gsym, int flags)
-{
- // If the symbol doesn't have a PLT offset, then naturally we
- // don't want to use it.
- if (!gsym->has_plt_offset())
- return false;
-
- // For a STT_GNU_IFUNC symbol we always have to use the PLT entry.
- if (gsym->type() == elfcpp::STT_GNU_IFUNC)
- return true;
-
- // If we are going to generate a dynamic relocation, then we will
- // wind up using that, so no need to use the PLT entry.
- if (needs_dynamic_reloc<size>(gsym, flags))
- return false;
-
- // If the symbol is from a dynamic object, we need to use the PLT
- // entry.
- if (gsym->is_from_dynobj())
- return true;
-
- // If we are generating a shared object, and this symbol is
- // undefined or preemptible, we need to use the PLT entry.
- if (parameters->options().shared()
- && (gsym->is_undefined() || gsym->is_preemptible()))
- return true;
-
- // If this is a call to a weak undefined symbol, we need to use
- // the PLT entry; the symbol may be defined by a library loaded
- // at runtime.
- if ((flags & Symbol::FUNCTION_CALL) && gsym->is_weak_undefined())
- return true;
-
- // Otherwise we can use the regular definition.
- return false;
-}