|| (sec->flags & SEC_CODE) == 0))
{
reloc_howto_type *howto = elf_i386_rtype_to_howto (from_type);
- _bfd_x86_elf_link_report_tls_invalid_section_error
- (abfd, sec, symtab_hdr, h, sym, howto);
+ _bfd_x86_elf_link_report_error (abfd, sec, symtab_hdr, h, sym,
+ howto, elf_x86_error_tls);
return false;
}
if (tls_type >= GOT_TLS_GD
&& tls_type <= GOT_TLS_GDESC
- && (elf_section_type (sec) != SHT_PROGBITS
+ && ((h != NULL
+ ? h->type != STT_TLS
+ : ELF_ST_TYPE (isym->st_info) != STT_TLS)
+ || elf_section_type (sec) != SHT_PROGBITS
|| (sec->flags & SEC_CODE) == 0))
{
- _bfd_x86_elf_link_report_tls_invalid_section_error
- (abfd, sec, symtab_hdr, h, isym, howto);
+ _bfd_x86_elf_link_report_error (abfd, sec, symtab_hdr,
+ h, isym, howto,
+ elf_x86_error_tls);
goto error_return;
}
{
case R_386_GOT32X:
case R_386_GOT32:
+ /* Since we don't allow non-alloced sections to create GOT/PLT
+ entries, issue an error if a non-alloced section references
+ GOT. */
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ {
+ non_alloc_error:
+ _bfd_x86_elf_link_report_error (input_bfd, input_section,
+ symtab_hdr, h, sym, howto,
+ elf_x86_error_non_alloc);
+ return false;
+ }
+
/* Relocation is to the entry for this symbol in the global
offset table. */
if (htab->elf.sgot == NULL)
break;
case R_386_GOTOFF:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
/* Relocation is relative to the start of the global offset
table. */
break;
case R_386_GOTPC:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
/* Use global offset table as symbol value. */
relocation = htab->elf.sgotplt->output_section->vma
+ htab->elf.sgotplt->output_offset;
break;
case R_386_PLT32:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
/* Relocation is to the entry for this symbol in the
procedure linkage table. */
break;
case R_386_TLS_IE:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
if (!bfd_link_executable (info))
{
Elf_Internal_Rela outrel;
case R_386_TLS_DESC_CALL:
case R_386_TLS_IE_32:
case R_386_TLS_GOTIE:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
tls_type = GOT_UNKNOWN;
if (h == NULL && local_got_offsets)
tls_type = elf_x86_local_got_tls_type (input_bfd) [r_symndx];
break;
case R_386_TLS_LDM:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
if (! elf_i386_tls_transition (info, input_bfd,
input_section, contents,
symtab_hdr, sym_hashes,
break;
case R_386_TLS_LDO_32:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
if (!bfd_link_executable (info)
|| (input_section->flags & SEC_CODE) == 0)
relocation -= _bfd_x86_elf_dtpoff_base (info);
case R_386_TLS_LE_32:
case R_386_TLS_LE:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
if (!bfd_link_executable (info))
{
Elf_Internal_Rela outrel;
{
reloc_howto_type *howto = elf_x86_64_rtype_to_howto (abfd,
from_type);
- _bfd_x86_elf_link_report_tls_invalid_section_error
- (abfd, sec, symtab_hdr, h, sym, howto);
+ _bfd_x86_elf_link_report_error (abfd, sec, symtab_hdr, h,
+ sym, howto, elf_x86_error_tls);
return false;
}
if (tls_type >= GOT_TLS_GD
&& tls_type <= GOT_TLS_GDESC
- && (elf_section_type (sec) != SHT_PROGBITS
+ && ((h != NULL
+ ? h->type != STT_TLS
+ : ELF_ST_TYPE (isym->st_info) != STT_TLS)
+ || elf_section_type (sec) != SHT_PROGBITS
|| (sec->flags & SEC_CODE) == 0))
{
- _bfd_x86_elf_link_report_tls_invalid_section_error
- (abfd, sec, symtab_hdr, h, isym, howto);
+ _bfd_x86_elf_link_report_error (abfd, sec, symtab_hdr,
+ h, isym, howto,
+ elf_x86_error_tls);
goto error_return;
}
case R_X86_64_GOTPCREL64:
/* Use global offset table entry as symbol value. */
case R_X86_64_GOTPLT64:
+ /* Since we don't allow non-alloced sections to create GOT/PLT
+ entries, issue an error if a non-alloced section references
+ GOT. */
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ {
+ non_alloc_error:
+ _bfd_x86_elf_link_report_error (input_bfd, input_section,
+ symtab_hdr, h, sym, howto,
+ elf_x86_error_non_alloc);
+ return false;
+ }
+
/* This is obsolete and treated the same as GOT64. */
base_got = htab->elf.sgot;
break;
case R_X86_64_GOTOFF64:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
/* Relocation is relative to the start of the global offset
table. */
case R_X86_64_GOTPC32:
case R_X86_64_GOTPC64:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
/* Use global offset table as symbol value. */
relocation = htab->elf.sgotplt->output_section->vma
+ htab->elf.sgotplt->output_offset;
break;
case R_X86_64_PLTOFF64:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
/* Relocation is PLT entry relative to GOT. For local
symbols it's the symbol itself relative to GOT. */
if (h != NULL
break;
case R_X86_64_PLT32:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
/* Relocation is to the entry for this symbol in the
procedure linkage table. */
case R_X86_64_CODE_4_GOTTPOFF:
case R_X86_64_CODE_5_GOTTPOFF:
case R_X86_64_CODE_6_GOTTPOFF:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
tls_type = GOT_UNKNOWN;
if (h == NULL && local_got_offsets)
tls_type = elf_x86_local_got_tls_type (input_bfd) [r_symndx];
break;
case R_X86_64_TLSLD:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
if (! elf_x86_64_tls_transition (info, input_bfd,
input_section, contents,
symtab_hdr, sym_hashes,
break;
case R_X86_64_DTPOFF32:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
if (!bfd_link_executable (info)
|| (input_section->flags & SEC_CODE) == 0)
relocation -= _bfd_x86_elf_dtpoff_base (info);
case R_X86_64_TPOFF32:
case R_X86_64_TPOFF64:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
BFD_ASSERT (bfd_link_executable (info));
relocation = elf_x86_64_tpoff (info, relocation);
break;
case R_X86_64_DTPOFF64:
+ if ((input_section->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ goto non_alloc_error;
+
BFD_ASSERT ((input_section->flags & SEC_CODE) == 0);
relocation -= _bfd_x86_elf_dtpoff_base (info);
break;
bfd_set_error (bfd_error_bad_value);
}
-/* Report TLS invalid section error. */
+/* Report link error. */
void
-_bfd_x86_elf_link_report_tls_invalid_section_error
+_bfd_x86_elf_link_report_error
(bfd *abfd, asection *sec, Elf_Internal_Shdr *symtab_hdr,
struct elf_link_hash_entry *h, Elf_Internal_Sym *sym,
- reloc_howto_type *howto)
+ reloc_howto_type *howto, enum elf_x86_error_type type)
{
const char *name;
+ bool non_thread_local;
if (h)
- name = h->root.root.string;
+ {
+ non_thread_local = h->type != STT_TLS;
+ name = h->root.root.string;
+ }
else
- name = bfd_elf_sym_name (abfd, symtab_hdr, sym, NULL);
- _bfd_error_handler
- /* xgettext:c-format */
- (_("%pB: relocation %s against thread local symbol `%s' in "
- "invalid section `%pA'"), abfd, howto->name, name, sec);
+ {
+ non_thread_local = ELF_ST_TYPE (sym->st_info) != STT_TLS;
+ name = bfd_elf_sym_name (abfd, symtab_hdr, sym, NULL);
+ if (name[0] == '\0')
+ name = "*unknown*";
+ }
+
+ switch (type)
+ {
+ case elf_x86_error_tls:
+ if (non_thread_local)
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: relocation %s against non-thread local symbol "
+ "`%s' in section `%pA'"),
+ abfd, howto->name, name, sec);
+ else
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: relocation %s against thread local symbol `%s' in "
+ "invalid section `%pA'"), abfd, howto->name, name, sec);
+ break;
+
+ case elf_x86_error_non_alloc:
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: relocation %s against symbol `%s' in non-alloc "
+ "section `%pA'"),
+ abfd, howto->name, name, sec);
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+
bfd_set_error (bfd_error_bad_value);
}
elf_x86_tls_error_yes
};
+enum elf_x86_error_type
+{
+ elf_x86_error_tls,
+ elf_x86_error_non_alloc
+};
+
/* Set if a relocation is converted from a GOTPCREL relocation. */
#define R_X86_64_converted_reloc_bit (1 << 7)
const Elf_Internal_Rela *, const char *, const char *,
enum elf_x86_tls_error_type) ATTRIBUTE_HIDDEN;
-extern void _bfd_x86_elf_link_report_tls_invalid_section_error
+extern void _bfd_x86_elf_link_report_error
(bfd *, asection *, Elf_Internal_Shdr *, struct elf_link_hash_entry *,
- Elf_Internal_Sym *, reloc_howto_type *) ATTRIBUTE_HIDDEN;
+ Elf_Internal_Sym *, reloc_howto_type *,
+ enum elf_x86_error_type) ATTRIBUTE_HIDDEN;
extern bool
_bfd_elf_x86_copy_special_section_fields