Check R_386_GOT32/R_386_GOT32X without base register

The R_386_GOT32 and R_386_GOT32X relocations may be used without base
register:

	movl	bar@GOT, %eax

Its calculation is G + A, instead of G + A - GOT, and it can only used
to generate non-PIC executable.  Include the .got.plt section address
for R_386_GOT32 and R_386_GOT32X relocations without base register.
Don't allow R_386_GOT32 and R_386_GOT32X relocations without base
register when making a PIC output.

	PR gold/19177
	* i386.cc (Target_i386::Relocate::relocate): Check R_386_GOT32
	and R_386_GOT32X relocations without base register.
This commit is contained in:
H.J. Lu 2015-10-28 09:15:17 -07:00
parent a3718e9efd
commit 3043c1aba1
2 changed files with 32 additions and 2 deletions

View File

@ -1,3 +1,9 @@
2015-10-28 H.J. Lu <hongjiu.lu@intel.com>
PR gold/19177
* i386.cc (Target_i386::Relocate::relocate): Check R_386_GOT32
and R_386_GOT32X relocations without base register.
2015-10.27 Han Shen <shenhan@google.com>
PR gold/19042 - unsupported reloc 311/312.

View File

@ -2790,6 +2790,8 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
}
}
bool baseless;
switch (r_type)
{
case elfcpp::R_386_NONE:
@ -2839,6 +2841,22 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
case elfcpp::R_386_GOT32:
case elfcpp::R_386_GOT32X:
baseless = (view[-1] & 0xc7) == 0x5;
// R_386_GOT32 and R_386_GOT32X don't work without base register
// when generating a position-independent output file.
if (baseless
&& parameters->options().output_is_position_independent())
{
if(gsym)
gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
_("unexpected reloc %u against global symbol %s without base register in object file when generating a position-independent output file"),
r_type, gsym->demangled_name().c_str());
else
gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
_("unexpected reloc %u against local symbol without base register in object file when generating a position-independent output file"),
r_type);
}
// Convert
// mov foo@GOT(%reg), %reg
// to
@ -2852,8 +2870,11 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
{
view[-2] = 0x8d;
elfcpp::Elf_types<32>::Elf_Addr value;
value = (psymval->value(object, 0)
- target->got_plt_section()->address());
value = psymval->value(object, 0);
// Don't subtract the .got.plt section address for baseless
// addressing.
if (!baseless)
value -= target->got_plt_section()->address();
Relocate_functions<32, false>::rel32(view, value);
}
else
@ -2875,6 +2896,9 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
got_offset = (object->local_got_offset(r_sym, GOT_TYPE_STANDARD)
- target->got_size());
}
// Add the .got.plt section address for baseless addressing.
if (baseless)
got_offset += target->got_plt_section()->address();
Relocate_functions<32, false>::rel32(view, got_offset);
}
break;