summaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2012-01-10 20:58:35 +0000
committerH.J. Lu <hjl.tools@gmail.com>2012-01-10 20:58:35 +0000
commita08434b1fdfd7ff705131f8ef1331cbfe86bd9fa (patch)
treee72f3c3ec7b96d69296e47a993b84e57480c1675 /gold
parentaf5b02bb3f22b6bac0a1f69cd596eac5cfccb79f (diff)
downloadbinutils-redhat-a08434b1fdfd7ff705131f8ef1331cbfe86bd9fa.tar.gz
Properly handle R_X86_64_32 for x32
2012-01-10 H.J. Lu <hongjiu.lu@intel.com> * x86_64.cc (Scan::check_non_pic): Allow R_X86_64_32 for x32. (Scan::local): Use R_X86_64_RELATIVE relocation for R_X86_64_32 under x32.
Diffstat (limited to 'gold')
-rw-r--r--gold/ChangeLog6
-rw-r--r--gold/x86_64.cc16
2 files changed, 22 insertions, 0 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index cdbdda20b2..62f79f5d87 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,9 @@
+2012-01-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * x86_64.cc (Scan::check_non_pic): Allow R_X86_64_32 for x32.
+ (Scan::local): Use R_X86_64_RELATIVE relocation for R_X86_64_32
+ under x32.
+
2012-01-09 H.J. Lu <hongjiu.lu@intel.com>
* x86_64.cc: Initial support for x32.
diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index 97a440d32c..3a2cacef48 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -1971,6 +1971,9 @@ Target_x86_64<size>::Scan::check_non_pic(Relobj* object, unsigned int r_type,
return;
/* Fall through. */
case elfcpp::R_X86_64_32:
+ // R_X86_64_32 is OK for x32.
+ if (size == 32 && r_type == elfcpp::R_X86_64_32)
+ return;
if (this->issued_non_pic_error_)
return;
gold_assert(parameters->options().output_is_position_independent());
@@ -2079,6 +2082,19 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
// because that is always a 64-bit relocation.
if (parameters->options().output_is_position_independent())
{
+ // Use R_X86_64_RELATIVE relocation for R_X86_64_32 under x32.
+ if (size == 32 && r_type == elfcpp::R_X86_64_32)
+ {
+ unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
+ Reloc_section* rela_dyn = target->rela_dyn_section(layout);
+ rela_dyn->add_local_relative(object, r_sym,
+ elfcpp::R_X86_64_RELATIVE,
+ output_section, data_shndx,
+ reloc.get_r_offset(),
+ reloc.get_r_addend(), is_ifunc);
+ break;
+ }
+
this->check_non_pic(object, r_type, NULL);
Reloc_section* rela_dyn = target->rela_dyn_section(layout);