mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-22 19:09:31 +08:00
x86: Don't change r_type when performing TLS transitions
Don't change r_type when performing TLS transitions to avoid getting the relocation type with ELF32_R_TYPE again. * elf32-i386.c (elf_i386_relocate_section): Don't change r_type when calling elf_i386_tls_transition. Don't use ELF32_R_TYPE to get the relocation type again. * elf64-x86-64.c (elf_x86_64_relocate_section): Don't change r_type when calling elf_x86_64_tls_transition. Don't use ELF32_R_TYPE to get the relocation type again.
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
2017-09-06 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
* elf32-i386.c (elf_i386_relocate_section): Don't change r_type
|
||||||
|
when calling elf_i386_tls_transition. Don't use ELF32_R_TYPE
|
||||||
|
to get the relocation type again.
|
||||||
|
* elf64-x86-64.c (elf_x86_64_relocate_section): Don't change
|
||||||
|
r_type when calling elf_x86_64_tls_transition. Don't use
|
||||||
|
ELF32_R_TYPE to get the relocation type again.
|
||||||
|
|
||||||
2017-09-05 H.J. Lu <hongjiu.lu@intel.com>
|
2017-09-05 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
* elf64-x86-64.c (elf_x86_64_convert_load_reloc): Properly set
|
* elf64-x86-64.c (elf_x86_64_convert_load_reloc): Properly set
|
||||||
|
@ -2182,7 +2182,7 @@ elf_i386_relocate_section (bfd *output_bfd,
|
|||||||
relend = relocs + input_section->reloc_count;
|
relend = relocs + input_section->reloc_count;
|
||||||
for (; rel < relend; wrel++, rel++)
|
for (; rel < relend; wrel++, rel++)
|
||||||
{
|
{
|
||||||
unsigned int r_type;
|
unsigned int r_type, r_type_tls;
|
||||||
reloc_howto_type *howto;
|
reloc_howto_type *howto;
|
||||||
unsigned long r_symndx;
|
unsigned long r_symndx;
|
||||||
struct elf_link_hash_entry *h;
|
struct elf_link_hash_entry *h;
|
||||||
@ -3029,17 +3029,18 @@ disallow_got32:
|
|||||||
if (tls_type == GOT_TLS_IE)
|
if (tls_type == GOT_TLS_IE)
|
||||||
tls_type = GOT_TLS_IE_NEG;
|
tls_type = GOT_TLS_IE_NEG;
|
||||||
|
|
||||||
|
r_type_tls = r_type;
|
||||||
if (! elf_i386_tls_transition (info, input_bfd,
|
if (! elf_i386_tls_transition (info, input_bfd,
|
||||||
input_section, contents,
|
input_section, contents,
|
||||||
symtab_hdr, sym_hashes,
|
symtab_hdr, sym_hashes,
|
||||||
&r_type, tls_type, rel,
|
&r_type_tls, tls_type, rel,
|
||||||
relend, h, r_symndx, TRUE))
|
relend, h, r_symndx, TRUE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (r_type == R_386_TLS_LE_32)
|
if (r_type_tls == R_386_TLS_LE_32)
|
||||||
{
|
{
|
||||||
BFD_ASSERT (! unresolved_reloc);
|
BFD_ASSERT (! unresolved_reloc);
|
||||||
if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GD)
|
if (r_type == R_386_TLS_GD)
|
||||||
{
|
{
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
bfd_vma roff;
|
bfd_vma roff;
|
||||||
@ -3082,7 +3083,7 @@ disallow_got32:
|
|||||||
wrel++;
|
wrel++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC)
|
else if (r_type == R_386_TLS_GOTDESC)
|
||||||
{
|
{
|
||||||
/* GDesc -> LE transition.
|
/* GDesc -> LE transition.
|
||||||
It's originally something like:
|
It's originally something like:
|
||||||
@ -3107,7 +3108,7 @@ disallow_got32:
|
|||||||
contents + roff);
|
contents + roff);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_DESC_CALL)
|
else if (r_type == R_386_TLS_DESC_CALL)
|
||||||
{
|
{
|
||||||
/* GDesc -> LE transition.
|
/* GDesc -> LE transition.
|
||||||
It's originally:
|
It's originally:
|
||||||
@ -3122,7 +3123,7 @@ disallow_got32:
|
|||||||
bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
|
bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_IE)
|
else if (r_type == R_386_TLS_IE)
|
||||||
{
|
{
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
|
|
||||||
@ -3216,7 +3217,7 @@ disallow_got32:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
BFD_FAIL ();
|
BFD_FAIL ();
|
||||||
if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTIE)
|
if (r_type == R_386_TLS_GOTIE)
|
||||||
bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
|
bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
|
||||||
contents + rel->r_offset);
|
contents + rel->r_offset);
|
||||||
else
|
else
|
||||||
@ -3359,13 +3360,13 @@ disallow_got32:
|
|||||||
if (off >= (bfd_vma) -2
|
if (off >= (bfd_vma) -2
|
||||||
&& ! GOT_TLS_GDESC_P (tls_type))
|
&& ! GOT_TLS_GDESC_P (tls_type))
|
||||||
abort ();
|
abort ();
|
||||||
if (r_type == R_386_TLS_GOTDESC
|
if (r_type_tls == R_386_TLS_GOTDESC
|
||||||
|| r_type == R_386_TLS_DESC_CALL)
|
|| r_type_tls == R_386_TLS_DESC_CALL)
|
||||||
{
|
{
|
||||||
relocation = htab->sgotplt_jump_table_size + offplt;
|
relocation = htab->sgotplt_jump_table_size + offplt;
|
||||||
unresolved_reloc = FALSE;
|
unresolved_reloc = FALSE;
|
||||||
}
|
}
|
||||||
else if (r_type == ELF32_R_TYPE (rel->r_info))
|
else if (r_type_tls == r_type)
|
||||||
{
|
{
|
||||||
bfd_vma g_o_t = htab->elf.sgotplt->output_section->vma
|
bfd_vma g_o_t = htab->elf.sgotplt->output_section->vma
|
||||||
+ htab->elf.sgotplt->output_offset;
|
+ htab->elf.sgotplt->output_offset;
|
||||||
@ -3378,7 +3379,7 @@ disallow_got32:
|
|||||||
relocation += g_o_t;
|
relocation += g_o_t;
|
||||||
unresolved_reloc = FALSE;
|
unresolved_reloc = FALSE;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GD)
|
else if (r_type == R_386_TLS_GD)
|
||||||
{
|
{
|
||||||
unsigned int val, type;
|
unsigned int val, type;
|
||||||
bfd_vma roff;
|
bfd_vma roff;
|
||||||
@ -3434,7 +3435,7 @@ disallow_got32:
|
|||||||
wrel++;
|
wrel++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC)
|
else if (r_type == R_386_TLS_GOTDESC)
|
||||||
{
|
{
|
||||||
/* GDesc -> IE transition.
|
/* GDesc -> IE transition.
|
||||||
It's originally something like:
|
It's originally something like:
|
||||||
@ -3473,7 +3474,7 @@ disallow_got32:
|
|||||||
contents + roff);
|
contents + roff);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_DESC_CALL)
|
else if (r_type == R_386_TLS_DESC_CALL)
|
||||||
{
|
{
|
||||||
/* GDesc -> IE transition.
|
/* GDesc -> IE transition.
|
||||||
It's originally:
|
It's originally:
|
||||||
|
@ -2511,7 +2511,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
|||||||
relend = relocs + input_section->reloc_count;
|
relend = relocs + input_section->reloc_count;
|
||||||
for (; rel < relend; wrel++, rel++)
|
for (; rel < relend; wrel++, rel++)
|
||||||
{
|
{
|
||||||
unsigned int r_type;
|
unsigned int r_type, r_type_tls;
|
||||||
reloc_howto_type *howto;
|
reloc_howto_type *howto;
|
||||||
unsigned long r_symndx;
|
unsigned long r_symndx;
|
||||||
struct elf_link_hash_entry *h;
|
struct elf_link_hash_entry *h;
|
||||||
@ -3413,20 +3413,21 @@ direct:
|
|||||||
else if (h != NULL)
|
else if (h != NULL)
|
||||||
tls_type = elf_x86_hash_entry (h)->tls_type;
|
tls_type = elf_x86_hash_entry (h)->tls_type;
|
||||||
|
|
||||||
|
r_type_tls = r_type;
|
||||||
if (! elf_x86_64_tls_transition (info, input_bfd,
|
if (! elf_x86_64_tls_transition (info, input_bfd,
|
||||||
input_section, contents,
|
input_section, contents,
|
||||||
symtab_hdr, sym_hashes,
|
symtab_hdr, sym_hashes,
|
||||||
&r_type, tls_type, rel,
|
&r_type_tls, tls_type, rel,
|
||||||
relend, h, r_symndx, TRUE))
|
relend, h, r_symndx, TRUE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (r_type == R_X86_64_TPOFF32)
|
if (r_type_tls == R_X86_64_TPOFF32)
|
||||||
{
|
{
|
||||||
bfd_vma roff = rel->r_offset;
|
bfd_vma roff = rel->r_offset;
|
||||||
|
|
||||||
BFD_ASSERT (! unresolved_reloc);
|
BFD_ASSERT (! unresolved_reloc);
|
||||||
|
|
||||||
if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
|
if (r_type == R_X86_64_TLSGD)
|
||||||
{
|
{
|
||||||
/* GD->LE transition. For 64bit, change
|
/* GD->LE transition. For 64bit, change
|
||||||
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
|
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
|
||||||
@ -3489,7 +3490,7 @@ direct:
|
|||||||
wrel++;
|
wrel++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
|
else if (r_type == R_X86_64_GOTPC32_TLSDESC)
|
||||||
{
|
{
|
||||||
/* GDesc -> LE transition.
|
/* GDesc -> LE transition.
|
||||||
It's originally something like:
|
It's originally something like:
|
||||||
@ -3512,7 +3513,7 @@ direct:
|
|||||||
contents + roff);
|
contents + roff);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
|
else if (r_type == R_X86_64_TLSDESC_CALL)
|
||||||
{
|
{
|
||||||
/* GDesc -> LE transition.
|
/* GDesc -> LE transition.
|
||||||
It's originally:
|
It's originally:
|
||||||
@ -3523,7 +3524,7 @@ direct:
|
|||||||
bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
|
bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTTPOFF)
|
else if (r_type == R_X86_64_GOTTPOFF)
|
||||||
{
|
{
|
||||||
/* IE->LE transition:
|
/* IE->LE transition:
|
||||||
For 64bit, originally it can be one of:
|
For 64bit, originally it can be one of:
|
||||||
@ -3701,7 +3702,7 @@ direct:
|
|||||||
if (off >= (bfd_vma) -2
|
if (off >= (bfd_vma) -2
|
||||||
&& ! GOT_TLS_GDESC_P (tls_type))
|
&& ! GOT_TLS_GDESC_P (tls_type))
|
||||||
abort ();
|
abort ();
|
||||||
if (r_type == ELF32_R_TYPE (rel->r_info))
|
if (r_type_tls == r_type)
|
||||||
{
|
{
|
||||||
if (r_type == R_X86_64_GOTPC32_TLSDESC
|
if (r_type == R_X86_64_GOTPC32_TLSDESC
|
||||||
|| r_type == R_X86_64_TLSDESC_CALL)
|
|| r_type == R_X86_64_TLSDESC_CALL)
|
||||||
@ -3717,7 +3718,7 @@ direct:
|
|||||||
{
|
{
|
||||||
bfd_vma roff = rel->r_offset;
|
bfd_vma roff = rel->r_offset;
|
||||||
|
|
||||||
if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
|
if (r_type == R_X86_64_TLSGD)
|
||||||
{
|
{
|
||||||
/* GD->IE transition. For 64bit, change
|
/* GD->IE transition. For 64bit, change
|
||||||
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
|
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
|
||||||
@ -3786,7 +3787,7 @@ direct:
|
|||||||
wrel++;
|
wrel++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
|
else if (r_type == R_X86_64_GOTPC32_TLSDESC)
|
||||||
{
|
{
|
||||||
/* GDesc -> IE transition.
|
/* GDesc -> IE transition.
|
||||||
It's originally something like:
|
It's originally something like:
|
||||||
@ -3811,7 +3812,7 @@ direct:
|
|||||||
contents + roff);
|
contents + roff);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
|
else if (r_type == R_X86_64_TLSDESC_CALL)
|
||||||
{
|
{
|
||||||
/* GDesc -> IE transition.
|
/* GDesc -> IE transition.
|
||||||
It's originally:
|
It's originally:
|
||||||
|
Reference in New Issue
Block a user