/* ADI Blackfin BFD support for 32-bit ELF.
- Copyright (C) 2005-2019 Free Software Foundation, Inc.
+ Copyright (C) 2005-2021 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
#include "elf/bfin.h"
#include "dwarf2.h"
#include "hashtab.h"
+#include "elf32-bfin.h"
/* FUNCTION : bfin_pltpc_reloc
ABSTRACT : TODO : figure out how to handle pltpc relocs. */
/* Set by ld emulation if --data-in-l1. */
bfd_boolean elf32_bfin_data_in_l1 = 0;
-static void
-elf32_bfin_final_write_processing (bfd *abfd,
- bfd_boolean linker ATTRIBUTE_UNUSED)
+static bfd_boolean
+elf32_bfin_final_write_processing (bfd *abfd)
{
if (elf32_bfin_code_in_l1)
elf_elfheader (abfd)->e_flags |= EF_BFIN_CODE_IN_L1;
if (elf32_bfin_data_in_l1)
elf_elfheader (abfd)->e_flags |= EF_BFIN_DATA_IN_L1;
+ return _bfd_elf_final_write_processing (abfd);
}
/* Return TRUE if the name is a local label.
if (name == NULL)
return FALSE;
if (*name == '\0')
- name = bfd_section_name (input_bfd, sec);
+ name = bfd_section_name (sec);
}
if (r == bfd_reloc_overflow)
/* Get the Blackfin ELF linker hash table from a link_info structure. */
-#define bfinfdpic_hash_table(info) \
- (elf_hash_table_id ((struct elf_link_hash_table *) ((info)->hash)) \
- == BFIN_ELF_DATA ? ((struct bfinfdpic_elf_link_hash_table *) ((info)->hash)) : NULL)
+#define bfinfdpic_hash_table(p) \
+ ((is_elf_hash_table ((p)->hash) \
+ && elf_hash_table_id (elf_hash_table (p)) == BFIN_ELF_DATA) \
+ ? (struct bfinfdpic_elf_link_hash_table *) (p)->hash : NULL)
#define bfinfdpic_got_section(info) \
(bfinfdpic_hash_table (info)->elf.sgot)
bfinfdpic_elf_link_hash_table_create (bfd *abfd)
{
struct bfinfdpic_elf_link_hash_table *ret;
- bfd_size_type amt = sizeof (struct bfinfdpic_elf_link_hash_table);
+ size_t amt = sizeof (struct bfinfdpic_elf_link_hash_table);
ret = bfd_zmalloc (amt);
if (ret == NULL)
h = NULL;
sym = NULL;
sec = NULL;
+ picrel = NULL;
if (r_symndx < symtab_hdr->sh_info)
{
name = bfd_elf_string_from_elf_section
(input_bfd, symtab_hdr->sh_link, sym->st_name);
- name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+ name = name == NULL ? bfd_section_name (sec) : name;
}
else
{
case R_BFIN_FUNCDESC_GOTOFFLO:
case R_BFIN_FUNCDESC:
case R_BFIN_FUNCDESC_VALUE:
+ if ((input_section->flags & SEC_ALLOC) == 0)
+ break;
+
if (h != NULL)
picrel = bfinfdpic_relocs_info_for_global (bfinfdpic_relocs_info
(info), input_bfd, h,
bfd_vma offset;
addend += bfinfdpic_got_section (info)->output_section->vma;
- if ((bfd_get_section_flags (output_bfd,
- input_section->output_section)
+ if ((bfd_section_flags (input_section->output_section)
& (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
{
if (_bfinfdpic_osec_readonly_p (output_bfd,
picrel);
}
}
- else if ((bfd_get_section_flags (output_bfd,
- input_section->output_section)
+ else if ((bfd_section_flags (input_section->output_section)
& (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
{
bfd_vma offset;
if (osec)
addend += osec->output_section->vma;
if (IS_FDPIC (input_bfd)
- && (bfd_get_section_flags (output_bfd,
- input_section->output_section)
+ && (bfd_section_flags (input_section->output_section)
& (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
{
if (_bfinfdpic_osec_readonly_p (output_bfd,
}
else
{
- if ((bfd_get_section_flags (output_bfd,
- input_section->output_section)
+ if ((bfd_section_flags (input_section->output_section)
& (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
{
if (_bfinfdpic_osec_readonly_p (output_bfd,
input file basename is crt0.o only once. */
if (silence_segment_error == 1)
silence_segment_error =
- (strlen (input_bfd->filename) == 6
- && filename_cmp (input_bfd->filename, "crt0.o") == 0)
- || (strlen (input_bfd->filename) > 6
- && filename_cmp (input_bfd->filename
- + strlen (input_bfd->filename) - 7,
+ (strlen (bfd_get_filename (input_bfd)) == 6
+ && filename_cmp (bfd_get_filename (input_bfd), "crt0.o") == 0)
+ || (strlen (bfd_get_filename (input_bfd)) > 6
+ && filename_cmp (bfd_get_filename (input_bfd)
+ + strlen (bfd_get_filename (input_bfd)) - 7,
"/crt0.o") == 0)
? -1 : 0;
#endif
s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
elf_hash_table (info)->sgot = s;
if (s == NULL
- || !bfd_set_section_alignment (abfd, s, ptralign))
+ || !bfd_set_section_alignment (s, ptralign))
return FALSE;
if (bed->want_got_sym)
s = bfd_make_section_anyway_with_flags (abfd, ".rel.got",
(flags | SEC_READONLY));
if (s == NULL
- || ! bfd_set_section_alignment (abfd, s, 2))
+ || !bfd_set_section_alignment (s, 2))
return FALSE;
bfinfdpic_gotrel_section (info) = s;
s = bfd_make_section_anyway_with_flags (abfd, ".rofixup",
(flags | SEC_READONLY));
if (s == NULL
- || ! bfd_set_section_alignment (abfd, s, 2))
+ || !bfd_set_section_alignment (s, 2))
return FALSE;
bfinfdpic_gotfixup_section (info) = s;
s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags);
if (s == NULL
- || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+ || !bfd_set_section_alignment (s, bed->plt_alignment))
return FALSE;
/* Blackfin-specific: remember it. */
bfinfdpic_plt_section (info) = s;
s = bfd_make_section_anyway_with_flags (abfd, ".rel.plt",
flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ || !bfd_set_section_alignment (s, bed->s->log_file_align))
return FALSE;
/* Blackfin-specific: remember it. */
bfinfdpic_pltrel_section (info) = s;
".rela.bss",
flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ || !bfd_set_section_alignment (s, bed->s->log_file_align))
return FALSE;
}
}
if (!_bfinfdpic_size_got_plt (output_bfd, &gpinfo))
return FALSE;
- if (elf_hash_table (info)->dynamic_sections_created)
- {
- if (bfinfdpic_got_section (info)->size)
- if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0))
- return FALSE;
-
- if (bfinfdpic_pltrel_section (info)->size)
- if (!_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
- || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_REL)
- || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
- return FALSE;
-
- if (bfinfdpic_gotrel_section (info)->size)
- if (!_bfd_elf_add_dynamic_entry (info, DT_REL, 0)
- || !_bfd_elf_add_dynamic_entry (info, DT_RELSZ, 0)
- || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
- sizeof (Elf32_External_Rel)))
- return FALSE;
- }
-
s = bfd_get_linker_section (dynobj, ".dynbss");
if (s && s->size == 0)
s->flags |= SEC_EXCLUDE;
if (s && s->size == 0)
s->flags |= SEC_EXCLUDE;
- return TRUE;
+ return _bfd_elf_add_dynamic_tags (output_bfd, info, TRUE);
}
static bfd_boolean
case R_BFIN_FUNCDESC_VALUE:
picrel->relocsfdv++;
- if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+ if (bfd_section_flags (sec) & SEC_ALLOC)
picrel->relocs32--;
/* Fall through. */
break;
picrel->sym++;
- if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+ if (bfd_section_flags (sec) & SEC_ALLOC)
picrel->relocs32++;
break;
flagword old_flags, new_flags;
bfd_boolean error = FALSE;
+ /* FIXME: What should be checked when linking shared libraries? */
+ if ((ibfd->flags & DYNAMIC) != 0)
+ return TRUE;
+
new_flags = elf_elfheader (ibfd)->e_flags;
old_flags = elf_elfheader (obfd)->e_flags;
struct bfin_pcrel_relocs_copied *pcrel_relocs_copied;
};
-/* bfin ELF linker hash table. */
-
-struct bfin_link_hash_table
-{
- struct elf_link_hash_table root;
-
- /* Small local sym cache. */
- struct sym_cache sym_cache;
-};
-
#define bfin_hash_entry(ent) ((struct bfin_link_hash_entry *) (ent))
static struct bfd_hash_entry *
static struct bfd_link_hash_table *
bfin_link_hash_table_create (bfd * abfd)
{
- struct bfin_link_hash_table *ret;
- bfd_size_type amt = sizeof (struct bfin_link_hash_table);
+ struct elf_link_hash_table *ret;
+ size_t amt = sizeof (struct elf_link_hash_table);
ret = bfd_zmalloc (amt);
if (ret == NULL)
return NULL;
- if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
- bfin_link_hash_newfunc,
+ if (!_bfd_elf_link_hash_table_init (ret, abfd, bfin_link_hash_newfunc,
sizeof (struct elf_link_hash_entry),
BFIN_ELF_DATA))
{
return NULL;
}
- ret->sym_cache.abfd = NULL;
-
- return &ret->root.root;
+ return &ret->root;
}
/* The size in bytes of an entry in the procedure linkage table. */
/* Apply the required alignment. */
s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (dynobj, s))
+ if (power_of_two > bfd_section_alignment (s))
{
- if (!bfd_set_section_alignment (dynobj, s, power_of_two))
+ if (!bfd_set_section_alignment (s, power_of_two))
return FALSE;
}
/* It's OK to base decisions on the section name, because none
of the dynobj section names depend upon the input files. */
- name = bfd_get_section_name (dynobj, s);
+ name = bfd_section_name (s);
strip = FALSE;
strncpy ((char *) p + 4, targetsec->output_section->name, 8);
}
- if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ if (symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
- if (internal_relocs != NULL
- && elf_section_data (datasec)->relocs != internal_relocs)
+ if (elf_section_data (datasec)->relocs != internal_relocs)
free (internal_relocs);
return TRUE;
-error_return:
- if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ error_return:
+ if (symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
- if (internal_relocs != NULL
- && elf_section_data (datasec)->relocs != internal_relocs)
+ if (elf_section_data (datasec)->relocs != internal_relocs)
free (internal_relocs);
return FALSE;
}
#define bfd_elf32_bfd_is_local_label_name \
bfin_is_local_label_name
-#define bfin_hash_table(p) \
- ((struct bfin_link_hash_table *) (p)->hash)
-
-
#define elf_backend_create_dynamic_sections \
_bfd_elf_create_dynamic_sections