/* NDS32-specific support for 32-bit ELF.
- Copyright (C) 2012-2018 Free Software Foundation, Inc.
+ Copyright (C) 2012-2020 Free Software Foundation, Inc.
Contributed by Andes Technology Corporation.
This file is part of BFD, the Binary File Descriptor library.
#include "sysdep.h"
#include "bfd.h"
-#include "bfd_stdint.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "libiberty.h"
-#include "bfd_stdint.h"
#include "elf/nds32.h"
#include "opcode/nds32.h"
#include "elf32-nds32.h"
#include "opcode/cgen.h"
#include "../opcodes/nds32-opc.h"
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
/* Relocation HOWTO functions. */
static bfd_reloc_status_type nds32_elf_ignore_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
{
char *ptr = (char *) base;
int i, j;
- char *tmp = xmalloc (size);
+ char tmp[sizeof (Elf_Internal_Rela)];
+
+ BFD_ASSERT (size <= sizeof (tmp));
/* If i is less than j, i is inserted before j.
memmove (ptr + (j + 1) * size, ptr + j * size, (i - j) * size);
memcpy (ptr + j * size, tmp, size);
}
- free (tmp);
}
/* Sort relocation by r_offset.
{
struct elf_nds32_link_hash_table *ret;
- bfd_size_type amt = sizeof (struct elf_nds32_link_hash_table);
+ size_t amt = sizeof (struct elf_nds32_link_hash_table);
ret = (struct elf_nds32_link_hash_table *) bfd_zmalloc (amt);
if (ret == NULL)
/* _bfd_elf_create_got_section will create it for us. */
ehtab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
if (ehtab->srelgot == NULL
- || !bfd_set_section_flags (dynobj, ehtab->srelgot,
+ || !bfd_set_section_flags (ehtab->srelgot,
(SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
| SEC_IN_MEMORY | SEC_LINKER_CREATED
| SEC_READONLY))
- || !bfd_set_section_alignment (dynobj, ehtab->srelgot, 2))
+ || !bfd_set_section_alignment (ehtab->srelgot, 2))
return FALSE;
return TRUE;
s = bfd_make_section (abfd, ".plt");
ehtab->splt = s;
if (s == NULL
- || !bfd_set_section_flags (abfd, s, pltflags)
- || !bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+ || !bfd_set_section_flags (s, pltflags)
+ || !bfd_set_section_alignment (s, bed->plt_alignment))
return FALSE;
if (bed->want_plt_sym)
bed->default_use_rela_p ? ".rela.plt" : ".rel.plt");
ehtab->srelplt = s;
if (s == NULL
- || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
- || !bfd_set_section_alignment (abfd, s, ptralign))
+ || !bfd_set_section_flags (s, flags | SEC_READONLY)
+ || !bfd_set_section_alignment (s, ptralign))
return FALSE;
if (ehtab->sgot == NULL && !create_got_section (abfd, info))
for (sec = abfd->sections; sec; sec = sec->next)
{
- secflags = bfd_get_section_flags (abfd, sec);
+ secflags = bfd_section_flags (sec);
if ((secflags & (SEC_DATA | SEC_LINKER_CREATED))
|| ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS))
continue;
- secname = bfd_get_section_name (abfd, sec);
+ secname = bfd_section_name (sec);
relname = (char *) bfd_malloc ((bfd_size_type) strlen (secname) + 6);
strcpy (relname, ".rela");
strcat (relname, secname);
continue;
s = bfd_make_section (abfd, relname);
if (s == NULL
- || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
- || !bfd_set_section_alignment (abfd, s, ptralign))
+ || !bfd_set_section_flags (s, flags | SEC_READONLY)
+ || !bfd_set_section_alignment (s, ptralign))
return FALSE;
}
s = bfd_make_section (abfd, ".dynbss");
htab->sdynbss = s;
if (s == NULL
- || !bfd_set_section_flags (abfd, s, SEC_ALLOC | SEC_LINKER_CREATED))
+ || !bfd_set_section_flags (s, SEC_ALLOC | SEC_LINKER_CREATED))
return FALSE;
/* The .rel[a].bss section holds copy relocs. This section is not
normally needed. We need to create it here, though, so that the
? ".rela.bss" : ".rel.bss"));
htab->srelbss = s;
if (s == NULL
- || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
- || !bfd_set_section_alignment (abfd, s, ptralign))
+ || !bfd_set_section_flags (s, flags | SEC_READONLY)
+ || !bfd_set_section_alignment (s, ptralign))
return FALSE;
}
}
/* 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;
}
eh->dyn_relocs = NULL;
-keep:;
+ keep:;
}
/* Finally, allocate space. */
{
got_size += s->size;
}
- else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
+ else if (strncmp (bfd_section_name (s), ".rela", 5) == 0)
{
if (s->size != 0 && s != elf_hash_table (info)->srelplt)
relocs = TRUE;
return FALSE;
BFD_ASSERT (strncmp (name, ".rela", 5) == 0
- && strcmp (bfd_get_section_name (input_bfd,
- input_section),
+ && strcmp (bfd_section_name (input_section),
name + 5) == 0);
sreloc = bfd_get_section_by_name (dynobj, name);
if (h->dynindx == -1)
{
_bfd_error_handler
- (_("%pB: relocation %s against `%s' can not be used when"
+ (_("%pB: relocation %s against `%s' can not be used when "
"making a shared object; recompile with -fPIC"),
input_bfd, nds32_elf_howto_table[r_type].name, h->root.root.string);
bfd_set_error (bfd_error_bad_value);
case R_NDS32_SDA15S0_RELA:
case R_NDS32_SDA15S0:
align = 0x0;
-handle_sda:
+ handle_sda:
BFD_ASSERT (sec != NULL);
/* If the symbol is in the abs section, the out_bfd will be null.
break;
}
-check_reloc:
+ check_reloc:
if (r != bfd_reloc_ok)
{
name = bfd_elf_string_from_elf_section
(input_bfd, symtab_hdr->sh_link, sym->st_name);
if (name == NULL || *name == '\0')
- name = bfd_section_name (input_bfd, sec);
+ name = bfd_section_name (sec);
}
if (errmsg != NULL)
errmsg = _("internal error: unknown error");
/* Fall through. */
-common_error:
+ common_error:
(*info->callbacks->warning) (info, errmsg, name, input_bfd,
input_section, offset);
break;
goto get_vma;
case DT_JMPREL:
s = ehtab->srelplt->output_section;
-get_vma:
+ get_vma:
BFD_ASSERT (s != NULL);
dyn.d_un.d_ptr = s->vma;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
/* Store the machine number in the flags field. */
-static void
-nds32_elf_final_write_processing (bfd *abfd,
- bfd_boolean linker ATTRIBUTE_UNUSED)
+static bfd_boolean
+nds32_elf_final_write_processing (bfd *abfd)
{
unsigned long val;
static unsigned int cur_mach = 0;
elf_elfheader (abfd)->e_flags &= ~EF_NDS_ARCH;
elf_elfheader (abfd)->e_flags |= val;
+ return _bfd_elf_final_write_processing (abfd);
}
/* Function to keep NDS32 specific file flags. */
return FALSE;
BFD_ASSERT (strncmp (name, ".rela", 5) == 0
- && strcmp (bfd_get_section_name (abfd, sec),
+ && strcmp (bfd_section_name (sec),
name + 5) == 0);
sreloc = bfd_get_section_by_name (dynobj, name);
if ((sec->flags & SEC_ALLOC) != 0)
flags |= SEC_ALLOC | SEC_LOAD;
if (sreloc == NULL
- || !bfd_set_section_flags (dynobj, sreloc, flags)
- || !bfd_set_section_alignment (dynobj, sreloc, 2))
+ || !bfd_set_section_flags (sreloc, flags)
+ || !bfd_set_section_alignment (sreloc, 2))
return FALSE;
elf_section_type (sreloc) = SHT_RELA;
p = *head;
if (p == NULL || p->sec != sec)
{
- bfd_size_type amt = sizeof (*p);
+ size_t amt = sizeof (*p);
p = (struct elf_dyn_relocs *) bfd_alloc (dynobj, amt);
if (p == NULL)
return FALSE;
goto done;
}
-done:
+ done:
/* Bit-15 of insn16 should be set for a valid instruction. */
if ((insn16 & 0x8000) == 0)
return 0;
goto done;
}
-done:
+ done:
if (insn & 0x80000000)
return 0;
if (p < endp)
*p |= 0x80;
}
-done_adjust_diff:
+ done_adjust_diff:
if (sec == sect)
{
clean_nds32_elf_blank ();
}
-finish:
+ finish:
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return result;
-error_return:
+ error_return:
result = FALSE;
goto finish;
}
{NULL, 0, 0, 0, 0}
};
+static bfd_boolean
+nds32_elf_section_flags (const Elf_Internal_Shdr *hdr)
+{
+ const char *name = hdr->bfd_section->name;
+
+ if (strncmp (name, ".sbss", 5) == 0
+ || strncmp (name, ".sdata", 6) == 0)
+ hdr->bfd_section->flags |= SEC_SMALL_DATA;
+
+ return TRUE;
+}
+
static bfd_boolean
nds32_elf_output_arch_syms (bfd *output_bfd ATTRIBUTE_UNUSED,
struct bfd_link_info *info,
goto error_return;
}
-finish:
+ finish:
if (relax_blank_list)
{
nds32_elf_relax_delete_blanks (abfd, sec, relax_blank_list);
}
return result;
-error_return:
+ error_return:
result = FALSE;
goto finish;
}
symbol = *(*parent)->sym_ptr_ptr;
if (symbol->section && discarded_section (symbol->section))
{
- bfd_byte *p;
+ bfd_vma off;
static reloc_howto_type none_howto
= HOWTO (0, 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL,
"unused", FALSE, 0, 0, FALSE);
- p = data + (*parent)->address * bfd_octets_per_byte (input_bfd);
- _bfd_clear_contents ((*parent)->howto, input_bfd, input_section,
- p);
+ off = (*parent)->address * OCTETS_PER_BYTE (input_bfd,
+ input_section);
+ _bfd_clear_contents ((*parent)->howto, input_bfd,
+ input_section, data, off);
(*parent)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
(*parent)->addend = 0;
(*parent)->howto = &none_howto;
free (reloc_vector);
return data;
-error_return:
+ error_return:
free (reloc_vector);
return NULL;
}
#endif
}
-finish:
+ finish:
if (incontents)
contents = NULL;
return result;
-error_return:
+ error_return:
result = FALSE;
goto finish;
}
#define elf_backend_object_p nds32_elf_object_p
#define elf_backend_final_write_processing nds32_elf_final_write_processing
#define elf_backend_special_sections nds32_elf_special_sections
+#define elf_backend_section_flags nds32_elf_section_flags
#define bfd_elf32_bfd_get_relocated_section_contents \
nds32_elf_get_relocated_section_contents
#define bfd_elf32_bfd_is_target_special_symbol nds32_elf_is_target_special_symbol