diff options
author | Ian Lance Taylor <ian@airs.com> | 2011-06-17 11:15:34 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2011-06-17 11:15:34 +0000 |
commit | a29b0dada9e9feba57c5e6ba9af96246a933efaf (patch) | |
tree | 84215b98afde5531e8e9c87c2568610ec8db0016 /gold/x86_64.cc | |
parent | 9c92b47c98d463c063696d444a589c1d13fc7a9f (diff) | |
download | gdb-a29b0dada9e9feba57c5e6ba9af96246a933efaf.zip gdb-a29b0dada9e9feba57c5e6ba9af96246a933efaf.tar.gz gdb-a29b0dada9e9feba57c5e6ba9af96246a933efaf.tar.bz2 |
* x86_64.cc (check_non_pic): Add gsym parameter. Change all
callers. Don't issue warning about PC32 against locally defined
symbol.
Diffstat (limited to 'gold/x86_64.cc')
-rw-r--r-- | gold/x86_64.cc | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/gold/x86_64.cc b/gold/x86_64.cc index d67069e..cdfec9e 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -488,7 +488,7 @@ class Target_x86_64 : public Target_freebsd<64, false> Symbol*); void - check_non_pic(Relobj*, unsigned int r_type); + check_non_pic(Relobj*, unsigned int r_type, Symbol*); inline bool possible_function_pointer_reloc(unsigned int r_type); @@ -1610,10 +1610,13 @@ Target_x86_64::Scan::unsupported_reloc_local( // Here we know the section is allocated, but we don't know that it is // read-only. But we check for all the relocation types which the // glibc dynamic linker supports, so it seems appropriate to issue an -// error even if the section is not read-only. +// error even if the section is not read-only. If GSYM is not NULL, +// it is the symbol the relocation is against; if it is NULL, the +// relocation is against a local symbol. void -Target_x86_64::Scan::check_non_pic(Relobj* object, unsigned int r_type) +Target_x86_64::Scan::check_non_pic(Relobj* object, unsigned int r_type, + Symbol* gsym) { switch (r_type) { @@ -1631,13 +1634,29 @@ Target_x86_64::Scan::check_non_pic(Relobj* object, unsigned int r_type) return; // glibc supports these reloc types, but they can overflow. - case elfcpp::R_X86_64_32: case elfcpp::R_X86_64_PC32: + // A PC relative reference is OK against a local symbol or if + // the symbol is defined locally. + if (gsym == NULL + || (!gsym->is_from_dynobj() + && !gsym->is_undefined() + && !gsym->is_preemptible())) + return; + /* Fall through. */ + case elfcpp::R_X86_64_32: if (this->issued_non_pic_error_) return; gold_assert(parameters->options().output_is_position_independent()); - object->error(_("requires dynamic reloc which may overflow at runtime; " - "recompile with -fPIC")); + if (gsym == NULL) + object->error(_("requires dynamic R_X86_64_32 reloc which may " + "overflow at runtime; recompile with -fPIC")); + else + object->error(_("requires dynamic %s reloc against '%s' which may " + "overflow at runtime; recompile with -fPIC"), + (r_type == elfcpp::R_X86_64_32 + ? "R_X86_64_32" + : "R_X86_64_PC32"), + gsym->name()); this->issued_non_pic_error_ = true; return; @@ -1648,8 +1667,9 @@ Target_x86_64::Scan::check_non_pic(Relobj* object, unsigned int r_type) if (this->issued_non_pic_error_) return; gold_assert(parameters->options().output_is_position_independent()); - object->error(_("requires unsupported dynamic reloc; " - "recompile with -fPIC")); + object->error(_("requires unsupported dynamic reloc %u; " + "recompile with -fPIC"), + r_type); this->issued_non_pic_error_ = true; return; @@ -1730,7 +1750,7 @@ Target_x86_64::Scan::local(Symbol_table* symtab, // because that is always a 64-bit relocation. if (parameters->options().output_is_position_independent()) { - this->check_non_pic(object, r_type); + this->check_non_pic(object, r_type, NULL); Reloc_section* rela_dyn = target->rela_dyn_section(layout); unsigned int r_sym = elfcpp::elf_r_sym<64>(reloc.get_r_info()); @@ -1814,7 +1834,7 @@ Target_x86_64::Scan::local(Symbol_table* symtab, } else { - this->check_non_pic(object, r_type); + this->check_non_pic(object, r_type, NULL); gold_assert(lsym.get_st_type() != elfcpp::STT_SECTION); rela_dyn->add_local( @@ -2135,7 +2155,7 @@ Target_x86_64::Scan::global(Symbol_table* symtab, } else { - this->check_non_pic(object, r_type); + this->check_non_pic(object, r_type, gsym); Reloc_section* rela_dyn = target->rela_dyn_section(layout); rela_dyn->add_global(gsym, r_type, output_section, object, data_shndx, reloc.get_r_offset(), @@ -2163,7 +2183,7 @@ Target_x86_64::Scan::global(Symbol_table* symtab, } else { - this->check_non_pic(object, r_type); + this->check_non_pic(object, r_type, gsym); Reloc_section* rela_dyn = target->rela_dyn_section(layout); rela_dyn->add_global(gsym, r_type, output_section, object, data_shndx, reloc.get_r_offset(), |