aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorPaul Iannetta <piannetta@kalrayinc.com>2023-08-16 14:22:28 +0100
committerNick Clifton <nickc@redhat.com>2023-08-16 14:22:54 +0100
commit6e712424f5cb1f01acf41c21f8721ee028c2a20c (patch)
treee385426177cc05115d8f5d69df67c6933ddfe6c3 /ld
parent7d6a2e34ee8eb061cf73014efefefaa074b499db (diff)
downloadgdb-6e712424f5cb1f01acf41c21f8721ee028c2a20c.zip
gdb-6e712424f5cb1f01acf41c21f8721ee028c2a20c.tar.gz
gdb-6e712424f5cb1f01acf41c21f8721ee028c2a20c.tar.bz2
kvx: New port.
Diffstat (limited to 'ld')
-rw-r--r--ld/Makefile.am6
-rw-r--r--ld/Makefile.in9
-rw-r--r--ld/NEWS2
-rw-r--r--ld/configure.tgt5
-rwxr-xr-xld/emulparams/elf32kvx.sh32
-rw-r--r--ld/emulparams/elf64kvx.sh39
-rw-r--r--ld/emulparams/elf64kvx_linux.sh41
-rw-r--r--ld/emultempl/kvxelf.em316
-rw-r--r--ld/po/BLD-POTFILES.in3
-rw-r--r--ld/testsuite/ld-ctf/nonrepresentable.d2
-rw-r--r--ld/testsuite/ld-elf/elf.exp1
-rw-r--r--ld/testsuite/ld-elf/shared.exp3
-rw-r--r--ld/testsuite/ld-ifunc/ifunc.exp1
-rw-r--r--ld/testsuite/ld-kvx/farcall-back.d79
-rw-r--r--ld/testsuite/ld-kvx/farcall-back.s54
-rw-r--r--ld/testsuite/ld-kvx/farcall-call-defsym.d14
-rw-r--r--ld/testsuite/ld-kvx/farcall-call-defsym.s12
-rw-r--r--ld/testsuite/ld-kvx/farcall-call-none-function.d24
-rw-r--r--ld/testsuite/ld-kvx/farcall-call-none-function.s19
-rw-r--r--ld/testsuite/ld-kvx/farcall-call-plt-32bits.d31
-rw-r--r--ld/testsuite/ld-kvx/farcall-call-plt.d34
-rw-r--r--ld/testsuite/ld-kvx/farcall-call-plt.s14
-rw-r--r--ld/testsuite/ld-kvx/farcall-call-section.d34
-rw-r--r--ld/testsuite/ld-kvx/farcall-call-section.s25
-rw-r--r--ld/testsuite/ld-kvx/farcall-call.d25
-rw-r--r--ld/testsuite/ld-kvx/farcall-call.s20
-rw-r--r--ld/testsuite/ld-kvx/farcall-goto-defsym.d14
-rw-r--r--ld/testsuite/ld-kvx/farcall-goto-defsym.s12
-rw-r--r--ld/testsuite/ld-kvx/farcall-goto-gsym.d5
-rw-r--r--ld/testsuite/ld-kvx/farcall-goto-gsym.s20
-rw-r--r--ld/testsuite/ld-kvx/farcall-goto-none-function.d26
-rw-r--r--ld/testsuite/ld-kvx/farcall-goto-none-function.s19
-rw-r--r--ld/testsuite/ld-kvx/farcall-goto-plt-32bits.d31
-rw-r--r--ld/testsuite/ld-kvx/farcall-goto-plt.d34
-rw-r--r--ld/testsuite/ld-kvx/farcall-goto-plt.s13
-rw-r--r--ld/testsuite/ld-kvx/farcall-goto-section.d36
-rw-r--r--ld/testsuite/ld-kvx/farcall-goto-section.s25
-rw-r--r--ld/testsuite/ld-kvx/farcall-goto.d25
-rw-r--r--ld/testsuite/ld-kvx/farcall-goto.s20
-rw-r--r--ld/testsuite/ld-kvx/kvx-elf.exp71
-rw-r--r--ld/testsuite/ld-kvx/kvx.ld18
-rw-r--r--ld/testsuite/ld-kvx/limit-call.d20
-rw-r--r--ld/testsuite/ld-kvx/limit-call.s22
-rw-r--r--ld/testsuite/ld-kvx/limit-goto.d20
-rw-r--r--ld/testsuite/ld-kvx/limit-goto.s22
-rw-r--r--ld/testsuite/ld-kvx/pcrel-reloc-32bits.d8
-rw-r--r--ld/testsuite/ld-kvx/pcrel-reloc.d14
-rw-r--r--ld/testsuite/ld-kvx/pcrel-reloc.s10
-rw-r--r--ld/testsuite/ld-scripts/fill.d2
49 files changed, 1330 insertions, 2 deletions
diff --git a/ld/Makefile.am b/ld/Makefile.am
index bce7a94..618e0bc 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -237,6 +237,7 @@ ALL_EMULATION_SOURCES = \
eelf32ip2k.c \
eelf32iq10.c \
eelf32iq2000.c \
+ eelf32kvx.c \
eelf32lm32.c \
eelf32lm32fd.c \
eelf32lppc.c \
@@ -448,6 +449,8 @@ ALL_64_EMULATION_SOURCES = \
eelf64lriscv_lp64f.c \
eelf64ltsmip.c \
eelf64ltsmip_fbsd.c \
+ eelf64kvx.c \
+ eelf64kvx_linux.c \
eelf64mmix.c \
eelf64ppc.c \
eelf64ppc_fbsd.c \
@@ -735,6 +738,7 @@ $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES): $(GEN_DEPENDS)
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ip2k.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32iq10.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32iq2000.Pc@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32kvx.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lm32.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lm32fd.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppc.Pc@am__quote@
@@ -937,6 +941,8 @@ $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES): $(GEN_DEPENDS)
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64hppa.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc_fbsd.Pc@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64kvx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64kvx_linux.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64loongarch.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv_lp64.Pc@am__quote@
diff --git a/ld/Makefile.in b/ld/Makefile.in
index cfa4772..b08de35 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -738,6 +738,7 @@ ALL_EMULATION_SOURCES = \
eelf32ip2k.c \
eelf32iq10.c \
eelf32iq2000.c \
+ eelf32kvx.c \
eelf32lm32.c \
eelf32lm32fd.c \
eelf32lppc.c \
@@ -948,6 +949,8 @@ ALL_64_EMULATION_SOURCES = \
eelf64lriscv_lp64f.c \
eelf64ltsmip.c \
eelf64ltsmip_fbsd.c \
+ eelf64kvx.c \
+ eelf64kvx_linux.c \
eelf64mmix.c \
eelf64ppc.c \
eelf64ppc_fbsd.c \
@@ -1373,6 +1376,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ip2k.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32iq10.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32iq2000.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32kvx.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32l4300.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lm32.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lm32fd.Po@am__quote@
@@ -1443,6 +1447,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip_fbsd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64hppa.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64kvx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64kvx_linux.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64loongarch.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc_fbsd.Po@am__quote@
@@ -2621,6 +2627,7 @@ $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES): $(GEN_DEPENDS)
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ebmipvxworks.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32elmip.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32elmipvxworks.Pc@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32kvx.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32l4300.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32loongarch.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lmip.Pc@am__quote@
@@ -2654,6 +2661,8 @@ $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES): $(GEN_DEPENDS)
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip_fbsd.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64hppa.Pc@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64kvx_linux.Pc@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64kvx.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc_fbsd.Pc@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64loongarch.Pc@am__quote@
diff --git a/ld/NEWS b/ld/NEWS
index e1ac20b..4b990c7 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -2,6 +2,8 @@
Changes in 2.41:
+* Add support for the KVX instruction set.
+
* The linker now accepts a command line option of --remap-inputs
<PATTERN>=<FILE> to relace any input file that matches <PATTERN> with
<FILE>. In addition the option --remap-inputs-file=<FILE> can be used to
diff --git a/ld/configure.tgt b/ld/configure.tgt
index c62b958..f78ba07 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -473,6 +473,11 @@ lm32-*-*linux*) targ_emul=elf32lm32fd
lm32-*-*) targ_emul=elf32lm32
targ_extra_emuls="elf32lm32fd"
;;
+kvx-*-linux*) targ_emul=elf64kvx_linux
+ targ_extra_emuls="elf64kvx"
+ ;;
+kvx-*-*) targ_emul=elf64kvx; targ_extra_emuls="elf64kvx_linux elf32kvx"
+ ;;
m32c-*-elf)
targ_emul=elf32m32c
;;
diff --git a/ld/emulparams/elf32kvx.sh b/ld/emulparams/elf32kvx.sh
new file mode 100755
index 0000000..eb7ffa8
--- /dev/null
+++ b/ld/emulparams/elf32kvx.sh
@@ -0,0 +1,32 @@
+# Copyright (C) 2009-2023 Free Software Foundation, Inc.
+# Contributed by Kalray SA.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3. If not,
+# see <http://www.gnu.org/licenses/>. */
+
+ARCH=kvx
+MACHINE=
+SCRIPT_NAME=elf
+
+# bundle with 1 nop insn
+NOP=0x00f0037f
+
+TEMPLATE_NAME=elf
+EXTRA_EM_FILE=kvxelf
+
+OUTPUT_FORMAT="elf32-kvx"
+TEXT_START_ADDR=0x10000
+MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
+WRITABLE_RODATA=
+GENERATE_SHLIB_SCRIPT=yes
diff --git a/ld/emulparams/elf64kvx.sh b/ld/emulparams/elf64kvx.sh
new file mode 100644
index 0000000..5a05738
--- /dev/null
+++ b/ld/emulparams/elf64kvx.sh
@@ -0,0 +1,39 @@
+# Copyright (C) 2009-2023 Free Software Foundation, Inc.
+# Contributed by Kalray SA.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3. If not,
+# see <http://www.gnu.org/licenses/>. */
+
+ARCH=kvx
+MACHINE=
+
+# bundle with 1 nop insn
+NOP=0x00f0037f
+
+SCRIPT_NAME=elf
+ELFSIZE=64
+OUTPUT_FORMAT="elf64-kvx"
+NO_REL_RELOCS=yes
+
+TEMPLATE_NAME=elf
+EXTRA_EM_FILE=kvxelf
+EMBEDDED=yes
+TEXT_START_ADDR=0x10000
+
+# No support for .s* sections.
+NO_SMALL_DATA=yes
+
+MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
+
+GENERATE_SHLIB_SCRIPT=yes
diff --git a/ld/emulparams/elf64kvx_linux.sh b/ld/emulparams/elf64kvx_linux.sh
new file mode 100644
index 0000000..0de1547
--- /dev/null
+++ b/ld/emulparams/elf64kvx_linux.sh
@@ -0,0 +1,41 @@
+# Copyright (C) 2009-2023 Free Software Foundation, Inc.
+# Contributed by Kalray SA.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3. If not,
+# see <http://www.gnu.org/licenses/>. */
+
+ARCH=kvx
+MACHINE=
+
+# bundle with 1 nop insn
+NOP=0x00f0037f
+
+SCRIPT_NAME=elf
+ELFSIZE=64
+OUTPUT_FORMAT="elf64-kvx"
+NO_REL_RELOCS=yes
+
+TEMPLATE_NAME=elf
+EXTRA_EM_FILE=kvxelf
+# first user page at 64K.
+TEXT_START_ADDR=0x10000
+
+# No support for .s* sections.
+NO_SMALL_DATA=yes
+
+MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
+
+GENERATE_SHLIB_SCRIPT=yes
+GENERATE_PIE_SCRIPT=yes
+
diff --git a/ld/emultempl/kvxelf.em b/ld/emultempl/kvxelf.em
new file mode 100644
index 0000000..16e36c5
--- /dev/null
+++ b/ld/emultempl/kvxelf.em
@@ -0,0 +1,316 @@
+# This shell script emits a C file. -*- C -*-
+# Copyright (C) 2009-2023 Free Software Foundation, Inc.
+# Contributed by Kalray Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the license, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3. If not,
+# see <http://www.gnu.org/licenses/>.
+#
+
+# This file is sourced from elf32.em, and defines extra kvx-elf
+# specific routines.
+#
+fragment <<EOF
+
+#include "ldctor.h"
+#include "elf/kvx.h"
+#include "elfxx-kvx.h"
+
+
+static void
+elf${ELFSIZE}_kvx_before_allocation (void)
+{
+EOF
+if test x"${EMULATION_NAME}" != x"elf64kvx_linux"; then
+fragment <<EOF
+ if (bfd_link_pie (&link_info)) {
+ einfo (_("%F:%P: -pie not supported\n"));
+ }
+EOF
+fi
+fragment <<EOF
+
+ /* Call the standard elf routine. */
+ gld${EMULATION_NAME}_before_allocation ();
+}
+
+
+
+/* Fake input file for stubs. */
+static lang_input_statement_type *stub_file;
+
+/* Whether we need to call gldarm_layout_sections_again. */
+static int need_laying_out = 0;
+
+/* Maximum size of a group of input sections that can be handled by
+ one stub section. A value of +/-1 indicates the bfd back-end
+ should use a suitable default size. */
+static bfd_signed_vma group_size = -1;
+
+struct hook_stub_info
+{
+ lang_statement_list_type add;
+ asection *input_section;
+};
+
+/* Traverse the linker tree to find the spot where the stub goes. */
+
+static bool
+hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
+{
+ lang_statement_union_type *l;
+ bool ret;
+
+ for (; (l = *lp) != NULL; lp = &l->header.next)
+ {
+ switch (l->header.type)
+ {
+ case lang_constructors_statement_enum:
+ ret = hook_in_stub (info, &constructor_list.head);
+ if (ret)
+ return ret;
+ break;
+
+ case lang_output_section_statement_enum:
+ ret = hook_in_stub (info,
+ &l->output_section_statement.children.head);
+
+ if (ret)
+ return ret;
+ break;
+
+ case lang_wild_statement_enum:
+ ret = hook_in_stub (info, &l->wild_statement.children.head);
+ if (ret)
+ return ret;
+ break;
+
+ case lang_group_statement_enum:
+ ret = hook_in_stub (info, &l->group_statement.children.head);
+ if (ret)
+ return ret;
+ break;
+
+ case lang_input_section_enum:
+ if (l->input_section.section == info->input_section)
+ {
+ /* We've found our section. Insert the stub immediately
+ after its associated input section. */
+ *(info->add.tail) = l->header.next;
+ l->header.next = info->add.head;
+ return true;
+ }
+
+ break;
+
+ case lang_data_statement_enum:
+ case lang_reloc_statement_enum:
+ case lang_object_symbols_statement_enum:
+ case lang_output_statement_enum:
+ case lang_target_statement_enum:
+ case lang_input_statement_enum:
+ case lang_assignment_statement_enum:
+ case lang_padding_statement_enum:
+ case lang_address_statement_enum:
+ case lang_fill_statement_enum:
+ break;
+
+ default:
+ FAIL ();
+ break;
+ }
+ }
+ return false;
+}
+
+
+/* Call-back for elf${ELFSIZE}_kvx_size_stubs. */
+
+/* Create a new stub section, and arrange for it to be linked
+ immediately after INPUT_SECTION. */
+
+static asection *
+elf${ELFSIZE}_kvx_add_stub_section (const char *stub_sec_name,
+ asection *input_section)
+{
+ asection *stub_sec;
+ flagword flags;
+ asection *output_section;
+ lang_output_section_statement_type *os;
+ struct hook_stub_info info;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
+ | SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);
+ stub_sec = bfd_make_section_anyway_with_flags (stub_file->the_bfd,
+ stub_sec_name, flags);
+ if (stub_sec == NULL)
+ goto err_ret;
+
+ bfd_set_section_alignment (stub_sec, 2);
+
+ output_section = input_section->output_section;
+ os = lang_output_section_get (output_section);
+
+ info.input_section = input_section;
+ lang_list_init (&info.add);
+ lang_add_section (&info.add, stub_sec, NULL, NULL, os);
+
+ if (info.add.head == NULL)
+ goto err_ret;
+
+ if (hook_in_stub (&info, &os->children.head))
+ return stub_sec;
+
+ err_ret:
+ einfo ("%X%P: can not make stub section: %E\n");
+ return NULL;
+}
+
+/* Another call-back for elf${ELFSIZE}_kvx_size_stubs. */
+
+static void
+gldkvx_layout_sections_again (void)
+{
+ /* If we have changed sizes of the stub sections, then we need
+ to recalculate all the section offsets. This may mean we need to
+ add even more stubs. */
+ ldelf_map_segments (true);
+ need_laying_out = -1;
+}
+
+static void
+build_section_lists (lang_statement_union_type *statement)
+{
+ if (statement->header.type == lang_input_section_enum)
+ {
+ asection *i = statement->input_section.section;
+
+ if (!((lang_input_statement_type *) i->owner->usrdata)->flags.just_syms
+ && (i->flags & SEC_EXCLUDE) == 0
+ && i->output_section != NULL
+ && i->output_section->owner == link_info.output_bfd)
+ elf${ELFSIZE}_kvx_next_input_section (& link_info, i);
+ }
+}
+
+static void
+gld${EMULATION_NAME}_after_allocation (void)
+{
+ int ret;
+
+ /* bfd_elf32_discard_info just plays with debugging sections,
+ ie. doesn't affect any code, so we can delay resizing the
+ sections. It's likely we'll resize everything in the process of
+ adding stubs. */
+ ret = bfd_elf_discard_info (link_info.output_bfd, & link_info);
+ if (ret < 0)
+ {
+ einfo ("%X%P: .eh_frame/.stab edit: %E\n");
+ return;
+ }
+ else if (ret > 0)
+ need_laying_out = 1;
+
+ /* If generating a relocatable output file, then we don't
+ have to examine the relocs. */
+ if (stub_file != NULL && !bfd_link_relocatable (&link_info))
+ {
+ ret = elf${ELFSIZE}_kvx_setup_section_lists (link_info.output_bfd,
+ &link_info);
+ if (ret != 0)
+ {
+ if (ret < 0)
+ {
+ einfo ("%X%P: could not compute sections lists for stub generation: %E\n");
+ return;
+ }
+
+ lang_for_each_statement (build_section_lists);
+
+ /* Call into the BFD backend to do the real work. */
+ if (! elf${ELFSIZE}_kvx_size_stubs (link_info.output_bfd,
+ stub_file->the_bfd,
+ & link_info,
+ group_size,
+ & elf${ELFSIZE}_kvx_add_stub_section,
+ & gldkvx_layout_sections_again))
+ {
+ einfo ("%X%P: cannot size stub section: %E\n");
+ return;
+ }
+ }
+ }
+
+ if (need_laying_out != -1)
+ ldelf_map_segments (need_laying_out);
+}
+
+static void
+gld${EMULATION_NAME}_finish (void)
+{
+ if (!bfd_link_relocatable (&link_info))
+ {
+ /* Now build the linker stubs. */
+ if (stub_file != NULL
+ && stub_file->the_bfd->sections != NULL)
+ {
+ if (! elf${ELFSIZE}_kvx_build_stubs (& link_info))
+ einfo ("%X%P: can not build stubs: %E\n");
+ }
+ }
+
+ finish_default ();
+}
+
+/* This is a convenient point to tell BFD about target specific flags.
+ After the output has been created, but before inputs are read. */
+static void
+kvx_elf_create_output_section_statements (void)
+{
+ if (!(bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
+ && elf_object_id (link_info.output_bfd) == KVX_ELF_DATA))
+ return;
+
+ stub_file = lang_add_input_file ("linker stubs",
+ lang_input_file_is_fake_enum,
+ NULL);
+ stub_file->the_bfd = bfd_create ("linker stubs", link_info.output_bfd);
+ if (stub_file->the_bfd == NULL
+ || ! bfd_set_arch_mach (stub_file->the_bfd,
+ bfd_get_arch (link_info.output_bfd),
+ bfd_get_mach (link_info.output_bfd)))
+ {
+ einfo ("%X%P: can not create BFD %E\n");
+ return;
+ }
+
+ stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
+ ldlang_add_file (stub_file);
+
+ if (!kvx_elf${ELFSIZE}_init_stub_bfd (&link_info, stub_file->the_bfd))
+ einfo ("%F%P: can not init BFD: %E\n");
+}
+
+
+#define lang_for_each_input_file kvx_lang_for_each_input_file
+
+EOF
+
+LDEMUL_BEFORE_ALLOCATION=elf${ELFSIZE}_kvx_before_allocation
+LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
+LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=kvx_elf_create_output_section_statements
+
+# Call the extra arm-elf function
+LDEMUL_FINISH=gld${EMULATION_NAME}_finish
diff --git a/ld/po/BLD-POTFILES.in b/ld/po/BLD-POTFILES.in
index 1fb352a..54de42b 100644
--- a/ld/po/BLD-POTFILES.in
+++ b/ld/po/BLD-POTFILES.in
@@ -115,6 +115,7 @@ eelf32ft32.c
eelf32ip2k.c
eelf32iq10.c
eelf32iq2000.c
+eelf32kvx.c
eelf32l4300.c
eelf32lm32.c
eelf32lm32fd.c
@@ -185,6 +186,8 @@ eelf64briscv_lp64f.c
eelf64btsmip.c
eelf64btsmip_fbsd.c
eelf64hppa.c
+eelf64kvx.c
+eelf64kvx_linux.c
eelf64loongarch.c
eelf64lppc.c
eelf64lppc_fbsd.c
diff --git a/ld/testsuite/ld-ctf/nonrepresentable.d b/ld/testsuite/ld-ctf/nonrepresentable.d
index fa3fdca..f02f52c 100644
--- a/ld/testsuite/ld-ctf/nonrepresentable.d
+++ b/ld/testsuite/ld-ctf/nonrepresentable.d
@@ -15,7 +15,7 @@ Contents of CTF section .ctf:
#...
Function objects:
#...
- foo -> 0x[0-9]*: \(kind 5\) int \(\*\) \(\(nonrepresentable type.*\)\) \(aligned at .*\)
+ foo -> 0x[0-9a-f]*: \(kind 5\) int \(\*\) \(\(nonrepresentable type.*\)\) \(aligned at .*\)
#...
Types:
#...
diff --git a/ld/testsuite/ld-elf/elf.exp b/ld/testsuite/ld-elf/elf.exp
index ca345e8..9e2c77d 100644
--- a/ld/testsuite/ld-elf/elf.exp
+++ b/ld/testsuite/ld-elf/elf.exp
@@ -199,6 +199,7 @@ proc target_defaults_to_execstack {} {
|| [istarget "arc*-*-*"]
|| [istarget "cris*-*-*"]
|| [istarget "ia64*-*-*"]
+ || [istarget "kvx*-*-*"]
|| [istarget "loongarch*-*-*"]
|| [istarget "nios2*-*-*"]
|| [istarget "powerpc64*-*-*"]
diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp
index cf010e5..1e7b7f1 100644
--- a/ld/testsuite/ld-elf/shared.exp
+++ b/ld/testsuite/ld-elf/shared.exp
@@ -468,7 +468,7 @@ run_ld_link_tests [list \
# These targets don't copy dynamic variables into .bss.
setup_xfail "alpha-*-*" "bfin-*-*" "ia64-*-*" "xtensa-*-*" *loongarch*-*-*
# or don't have .data.rel.ro
-setup_xfail "hppa*64*-*-hpux*" "tic6x-*-*"
+setup_xfail "hppa*64*-*-hpux*" "tic6x-*-*" "kvx*-*-*"
# or complain about relocs in read-only sections
setup_xfail frv-*-* lm32-*-*
run_ld_link_tests [list \
@@ -515,6 +515,7 @@ run_ld_link_tests {
}
if { [istarget *-*-linux*]
+ || [istarget kvx-*-*]
|| [istarget *-*-nacl*]
|| [istarget *-*-gnu*] } {
run_ld_link_tests {
diff --git a/ld/testsuite/ld-ifunc/ifunc.exp b/ld/testsuite/ld-ifunc/ifunc.exp
index 2bf656e..0f5222e 100644
--- a/ld/testsuite/ld-ifunc/ifunc.exp
+++ b/ld/testsuite/ld-ifunc/ifunc.exp
@@ -30,6 +30,7 @@ if { ![is_elf_format] || ![supports_gnu_osabi]
|| [istarget bfin-*-*]
|| [istarget cris*-*-*]
|| [istarget frv-*-*]
+ || [istarget kvx*-*-*]
|| [istarget lm32-*-*]
|| [istarget m32r-*-*]
|| [istarget m68k-*-*]
diff --git a/ld/testsuite/ld-kvx/farcall-back.d b/ld/testsuite/ld-kvx/farcall-back.d
new file mode 100644
index 0000000..c17dda7
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-back.d
@@ -0,0 +1,79 @@
+#name: kvx-farcall-back
+#source: farcall-back.s
+#as:
+#ld: -Ttext 0x1000 --section-start .foo=0x80001000
+#objdump: -dr
+
+#...
+
+Disassembly of section .text:
+
+.* <_start>:
+ .*: .. .. .. .. call .* <__bar1_veneer>;;
+
+ .*: .. .. .. .. goto .* <__bar1_veneer>;;
+
+ .*: .. .. .. .. call .* <__bar2_veneer>;;
+
+ .*: .. .. .. .. goto .* <__bar2_veneer>;;
+
+ .*: .. .. .. .. call .* <__bar3_veneer>;;
+
+ .*: .. .. .. .. goto .* <__bar3_veneer>;;
+
+ .*: 00 00 d0 0f ret;;
+
+ ...
+
+.* <_back>:
+ .*: 00 00 d0 0f ret;;
+
+.* <__bar3_veneer>:
+ .*: 00 .. 40 e0 0c 00 20 00 make \$r16 = .* \(0x.*\);;
+
+ .*: 10 00 d8 0f igoto \$r16;;
+
+.* <__bar2_veneer>:
+ .*: 00 .. 40 e0 08 00 20 00 make \$r16 = .* \(0x.*\);;
+
+ .*: 10 00 d8 0f igoto \$r16;;
+
+.* <__bar1_veneer>:
+ .*: 00 .. 40 e0 04 00 20 00 make \$r16 = .* \(0x.*\);;
+
+ .*: 10 00 d8 0f igoto \$r16;;
+
+
+Disassembly of section .foo:
+
+.* <bar1>:
+.*: 00 00 d0 0f ret;;
+
+.*: .. .. .. .. goto .* <___start_veneer>;;
+
+ ...
+
+.* <bar2>:
+.*: 00 00 d0 0f ret;;
+
+.*: .. .. .. .. goto .* <___start_veneer>;;
+
+ ...
+
+.* <bar3>:
+.*: 00 00 d0 0f ret;;
+
+.*: .. .. .. .. goto .* <___back_veneer>;;
+
+
+.* <___start_veneer>:
+.*: 00 .. 40 e0 04 00 00 00 make \$r16 = .* \(0x.*\);;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
+.* <___back_veneer>:
+.*: 00 .. 40 e0 08 00 00 00 make \$r16 = .* \(0x.*\);;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
+
diff --git a/ld/testsuite/ld-kvx/farcall-back.s b/ld/testsuite/ld-kvx/farcall-back.s
new file mode 100644
index 0000000..582d39d
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-back.s
@@ -0,0 +1,54 @@
+ .global _start
+ .global _back
+ .global bar1
+ .global bar2
+ .global bar3
+
+# We will place the section .text at 0x1000.
+
+ .text
+
+ .type _start, @function
+_start:
+ call bar1
+ ;;
+ goto bar1
+ ;;
+ call bar2
+ ;;
+ goto bar2
+ ;;
+ call bar3
+ ;;
+ goto bar3
+ ;;
+ ret
+ ;;
+ .space 0x1000
+ .type _back, @function
+_back: ret
+ ;;
+
+# We will place the section .foo at 0x80001000.
+
+ .section .foo, "xa"
+ .type bar1, @function
+bar1:
+ ret
+ ;;
+ goto _start
+ ;;
+ .space 0x1000
+ .type bar2, @function
+bar2:
+ ret
+ ;;
+ goto _start
+ ;;
+ .space 0x1000
+ .type bar3, @function
+bar3:
+ ret
+ ;;
+ goto _back
+ ;;
diff --git a/ld/testsuite/ld-kvx/farcall-call-defsym.d b/ld/testsuite/ld-kvx/farcall-call-defsym.d
new file mode 100644
index 0000000..71dcebc
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-call-defsym.d
@@ -0,0 +1,14 @@
+#name: kvx-farcall-call-defsym
+#source: farcall-call-defsym.s
+#as:
+#ld: -Ttext 0x1000 --defsym=bar=0x8001000
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+.* <_start>:
+ 1000: 00 00 00 1a call 8001000 <bar>;;
+
+ 1004: 00 00 d0 0f ret;;
+
diff --git a/ld/testsuite/ld-kvx/farcall-call-defsym.s b/ld/testsuite/ld-kvx/farcall-call-defsym.s
new file mode 100644
index 0000000..2072b53
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-call-defsym.s
@@ -0,0 +1,12 @@
+ .global _start
+ .global bar
+
+# We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+ call bar
+ ;;
+ ret
+ ;;
diff --git a/ld/testsuite/ld-kvx/farcall-call-none-function.d b/ld/testsuite/ld-kvx/farcall-call-none-function.d
new file mode 100644
index 0000000..3ef4131
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-call-none-function.d
@@ -0,0 +1,24 @@
+#name: kvx-farcall-call-none-function
+#source: farcall-call-none-function.s
+#as:
+#ld: -Ttext 0x1000 --section-start .foo=0x20001000
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+.* <_start>:
+.*: .. .. .. .. call .* <__bar_veneer>;;
+
+.*: 00 00 d0 0f ret;;
+
+.* <__bar_veneer>:
+.*: .. .. 40 e0 .. .. .. .. make \$r16 = .* \(0x.*\);;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
+Disassembly of section .foo:
+
+.* <bar>:
+.*: 00 00 d0 0f ret;;
+
diff --git a/ld/testsuite/ld-kvx/farcall-call-none-function.s b/ld/testsuite/ld-kvx/farcall-call-none-function.s
new file mode 100644
index 0000000..85eeca5
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-call-none-function.s
@@ -0,0 +1,19 @@
+ .global _start
+ .global bar
+
+# We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+ call bar
+ ;;
+ ret
+ ;;
+
+# We will place the section .foo at 0x10001000.
+
+ .section .foo, "xa"
+bar:
+ ret
+ ;;
diff --git a/ld/testsuite/ld-kvx/farcall-call-plt-32bits.d b/ld/testsuite/ld-kvx/farcall-call-plt-32bits.d
new file mode 100644
index 0000000..a097e28
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-call-plt-32bits.d
@@ -0,0 +1,31 @@
+
+tmpdir/dump: file format elf32-kvx
+
+
+Disassembly of section .plt:
+
+.* <foo@plt-0x20>:
+ ...
+
+.* <foo@plt>:
+ .*: 10 00 c4 0f get \$r16 = \$pc;;
+
+ .*: .. .. 40 b0 .. .. .. 18 lwz \$r16 = [0-9]* \(0x[0-9a-f]*\)\[\$r16\];;
+
+ .*: 10 00 d8 0f igoto \$r16;;
+
+
+Disassembly of section .text:
+
+.* <_start>:
+ ...
+.*: .. .. 00 18 call .* <__foo_veneer>;;
+
+.*: 00 00 d0 0f ret;;
+
+
+.* <__foo_veneer>:
+.*: .. .. 40 e0 00 00 00 00 make \$r16 = .* \(0x[0-9a-f]*\);;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
diff --git a/ld/testsuite/ld-kvx/farcall-call-plt.d b/ld/testsuite/ld-kvx/farcall-call-plt.d
new file mode 100644
index 0000000..ab431b0
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-call-plt.d
@@ -0,0 +1,34 @@
+#name: kvx-farcall-call-plt
+#source: farcall-call-plt.s
+#as:
+#ld: -shared
+#objdump: -dr
+#...
+
+Disassembly of section .plt:
+
+.* <.plt>:
+ ...
+
+.* <foo@plt>:
+.*: 10 00 c4 0f get \$r16 = \$pc;;
+
+.*: .. .. 40 .. .. .. .. 18 l[wzd]* \$r16 = [0-9]* \(0x[0-9a-f]*\)\[\$r16\];;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
+
+Disassembly of section .text:
+
+.* <_start>:
+ ...
+.*: .. .. 00 18 call .* <__foo_veneer>;;
+
+.*: 00 00 d0 0f ret;;
+
+
+.* <__foo_veneer>:
+.*: .. .. 40 e0 00 00 00 00 make \$r16 = .* \(0x[0-9a-f]*\);;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
diff --git a/ld/testsuite/ld-kvx/farcall-call-plt.s b/ld/testsuite/ld-kvx/farcall-call-plt.s
new file mode 100644
index 0000000..e1b1bbc
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-call-plt.s
@@ -0,0 +1,14 @@
+ .global _start
+ .global foo
+ .type foo, @function
+ .text
+
+_start:
+ # ((1 << 26) - 1) << 2
+ # PCREL27 relocation out of range to plt stub,
+ # we need long branch veneer.
+ .skip 268435452, 0
+ call foo
+ ;;
+ ret
+ ;;
diff --git a/ld/testsuite/ld-kvx/farcall-call-section.d b/ld/testsuite/ld-kvx/farcall-call-section.d
new file mode 100644
index 0000000..86f3f03
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-call-section.d
@@ -0,0 +1,34 @@
+#name: kvx-farcall-call-section
+#source: farcall-call-section.s
+#as:
+#ld: -Ttext 0x1000 --section-start .foo=0x20001000
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+.* <_start>:
+.*: .. .. .. .. call .* <___veneer>;;
+
+.*: .. .. .. .. call .* <___veneer>;;
+
+.*: 00 00 d0 0f ret;;
+
+.* <___veneer>:
+.*: .. 00 40 e0 .. .. .. .. make \$r16 = .* \(0x.*\);;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
+.* <___veneer>:
+.*: .. 01 40 e0 .. .. .. .. make \$r16 = .* \(0x.*\);;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
+Disassembly of section .foo:
+
+.* <bar>:
+.*: 00 00 d0 0f ret;;
+
+.* <bar2>:
+.*: 00 00 d0 0f ret;;
+
diff --git a/ld/testsuite/ld-kvx/farcall-call-section.s b/ld/testsuite/ld-kvx/farcall-call-section.s
new file mode 100644
index 0000000..3b22fc6
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-call-section.s
@@ -0,0 +1,25 @@
+ .global _start
+
+# We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+ call bar
+ ;;
+ call bar2
+ ;;
+ ret
+ ;;
+
+# We will place the section .foo at 0x20001000.
+
+ .section .foo, "xa"
+ .type bar, @function
+bar:
+ ret
+ ;;
+ .type bar2, @function
+bar2:
+ ret
+ ;;
diff --git a/ld/testsuite/ld-kvx/farcall-call.d b/ld/testsuite/ld-kvx/farcall-call.d
new file mode 100644
index 0000000..6db1f16
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-call.d
@@ -0,0 +1,25 @@
+#name: kvx-farcall-call
+#source: farcall-call.s
+#as:
+#ld: -Ttext 0x1000 --section-start .foo=0x20001000
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+
+.* <_start>:
+.*: .. .. .. 18 call .* <__bar_veneer>;;
+
+.*: 00 00 d0 0f ret;;
+
+.* <__bar_veneer>:
+.*: .. .. 40 e0 .. .. .. .. make \$r16 = .* \(0x.*\);;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
+Disassembly of section .foo:
+
+.* <bar>:
+.*: 00 00 d0 0f ret;;
+
diff --git a/ld/testsuite/ld-kvx/farcall-call.s b/ld/testsuite/ld-kvx/farcall-call.s
new file mode 100644
index 0000000..7319ae4
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-call.s
@@ -0,0 +1,20 @@
+ .global _start
+ .global bar
+
+# We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+ call bar
+ ;;
+ ret
+ ;;
+
+# We will place the section .foo at 0x20001000.
+
+ .section .foo, "xa"
+ .type bar, @function
+bar:
+ ret
+ ;;
diff --git a/ld/testsuite/ld-kvx/farcall-goto-defsym.d b/ld/testsuite/ld-kvx/farcall-goto-defsym.d
new file mode 100644
index 0000000..27ba7be
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-goto-defsym.d
@@ -0,0 +1,14 @@
+#name: kvx-farcall-goto-defsym
+#source: farcall-goto-defsym.s
+#as:
+#ld: -Ttext 0x1000 --defsym=bar=0x8001000
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+.* <_start>:
+ 1000: 00 00 00 12 goto 8001000 <bar>;;
+
+ 1004: 00 00 d0 0f ret;;
+
diff --git a/ld/testsuite/ld-kvx/farcall-goto-defsym.s b/ld/testsuite/ld-kvx/farcall-goto-defsym.s
new file mode 100644
index 0000000..f2e1da6
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-goto-defsym.s
@@ -0,0 +1,12 @@
+ .global _start
+ .global bar
+
+# We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+ goto bar
+ ;;
+ ret
+ ;;
diff --git a/ld/testsuite/ld-kvx/farcall-goto-gsym.d b/ld/testsuite/ld-kvx/farcall-goto-gsym.d
new file mode 100644
index 0000000..9874d41
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-goto-gsym.d
@@ -0,0 +1,5 @@
+#name: kvx-farcall-goto-gsym
+#source: farcall-goto-gsym.s
+#as:
+#ld: -Ttext 0x1000
+#error: .*\(.text\+0x0\): relocation truncated to fit: R_KVX_PCREL27 against symbol `bar_gsym'.*
diff --git a/ld/testsuite/ld-kvx/farcall-goto-gsym.s b/ld/testsuite/ld-kvx/farcall-goto-gsym.s
new file mode 100644
index 0000000..2cb7b19
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-goto-gsym.s
@@ -0,0 +1,20 @@
+ .global _start
+ .global bar_gsym
+
+# We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+# for long jump (goto) to global symbol, we shouldn't insert veneer
+# as the veneer will clobber r16/r17 which is caller saved, gcc only
+# reserve them for function call relocation (call).
+ goto bar_gsym
+ ;;
+ # ((1 << 26) - 1) << 2
+ .skip 268435452, 0
+bar_gsym:
+ nop
+ ;;
+ ret
+ ;;
diff --git a/ld/testsuite/ld-kvx/farcall-goto-none-function.d b/ld/testsuite/ld-kvx/farcall-goto-none-function.d
new file mode 100644
index 0000000..88b7a27
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-goto-none-function.d
@@ -0,0 +1,26 @@
+#name: kvx-farcall-goto-none-function
+#source: farcall-goto-none-function.s
+#as:
+#ld: -Ttext 0x1000 --section-start .foo=0x20001000
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+
+.* <_start>:
+.*: .. .. .. .. goto .* <__bar_veneer>;;
+
+.*: 00 00 d0 0f ret;;
+
+.* <__bar_veneer>:
+.*: .. .. 40 e0 .. .. .. .. make \$r16 = .* \(0x.*\);;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
+
+Disassembly of section .foo:
+
+.* <bar>:
+.*: 00 00 d0 0f ret;;
+
diff --git a/ld/testsuite/ld-kvx/farcall-goto-none-function.s b/ld/testsuite/ld-kvx/farcall-goto-none-function.s
new file mode 100644
index 0000000..1223bc3
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-goto-none-function.s
@@ -0,0 +1,19 @@
+ .global _start
+ .global bar
+
+# We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+ goto bar
+ ;;
+ ret
+ ;;
+
+# We will place the section .foo at 0x20001000.
+
+ .section .foo, "xa"
+bar:
+ ret
+ ;;
diff --git a/ld/testsuite/ld-kvx/farcall-goto-plt-32bits.d b/ld/testsuite/ld-kvx/farcall-goto-plt-32bits.d
new file mode 100644
index 0000000..04b4380
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-goto-plt-32bits.d
@@ -0,0 +1,31 @@
+
+tmpdir/dump: file format elf32-kvx
+
+
+Disassembly of section .plt:
+
+.* <.plt>:
+ ...
+
+.* <foo@plt>:
+.*: 10 00 c4 0f get \$r16 = \$pc;;
+
+.*: .. .. 40 .. .. .. .. .. l[wzd]* \$r16 = [0-9]* \(0x[0-9a-b]*\)\[\$r16\];;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
+
+Disassembly of section .text:
+
+.* <_start>:
+ ...
+.*: .. .. .. 10 goto .* <__foo_veneer>;;
+
+.*: 00 00 d0 0f ret;;
+
+
+.* <__foo_veneer>:
+.*: .. .. 40 e0 00 00 00 00 make \$r16 = [0-9]* \(0x[0-9a-b]*\);;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
diff --git a/ld/testsuite/ld-kvx/farcall-goto-plt.d b/ld/testsuite/ld-kvx/farcall-goto-plt.d
new file mode 100644
index 0000000..e1e20e6
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-goto-plt.d
@@ -0,0 +1,34 @@
+#name: kvx-farcall-goto-plt
+#source: farcall-goto-plt.s
+#as:
+#ld: -shared
+#objdump: -dr
+#...
+
+Disassembly of section .plt:
+
+.* <.plt>:
+ ...
+
+.* <foo@plt>:
+.*: 10 00 c4 0f get \$r16 = \$pc;;
+
+.*: .. .. 40 .. .. .. .. .. l[wzd]* \$r16 = [0-9]* \(0x[0-9a-b]*\)\[\$r16\];;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
+
+Disassembly of section .text:
+
+.* <_start>:
+ ...
+.*: .. .. .. 10 goto .* <__foo_veneer>;;
+
+.*: 00 00 d0 0f ret;;
+
+
+.* <__foo_veneer>:
+.*: .. .. 40 e0 00 00 00 00 make \$r16 = [0-9]* \(0x[0-9a-b]*\);;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
diff --git a/ld/testsuite/ld-kvx/farcall-goto-plt.s b/ld/testsuite/ld-kvx/farcall-goto-plt.s
new file mode 100644
index 0000000..f912d9f
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-goto-plt.s
@@ -0,0 +1,13 @@
+ .global _start
+ .global foo
+ .type foo, @function
+ .text
+_start:
+ # ((1 << 26) - 1) << 2
+ # PCREL27 relocation out of range to plt stub,
+ # we need long branch veneer.
+ .skip 268435452, 0
+ goto foo
+ ;;
+ ret
+ ;;
diff --git a/ld/testsuite/ld-kvx/farcall-goto-section.d b/ld/testsuite/ld-kvx/farcall-goto-section.d
new file mode 100644
index 0000000..0599795
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-goto-section.d
@@ -0,0 +1,36 @@
+#name: kvx-farcall-goto-section
+#source: farcall-goto-section.s
+#as:
+#ld: -Ttext 0x1000 --section-start .foo=0x20001000
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+.* <_start>:
+.*: .. .. .. .. goto .* <___veneer>;;
+
+.*: .. .. .. .. goto .* <___veneer>;;
+
+.*: 00 00 d0 0f ret;;
+
+.* <___veneer>:
+.*: .. .. 40 e0 .. .. .. .. make \$r16 = .* \(0x.*\);;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
+.* <___veneer>:
+.*: .. .. 40 e0 .. .. .. .. make \$r16 = .* \(0x.*\);;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
+
+Disassembly of section .foo:
+
+.* <bar>:
+.*: 00 00 d0 0f ret;;
+
+
+.* <bar2>:
+.*: 00 00 d0 0f ret;;
+
diff --git a/ld/testsuite/ld-kvx/farcall-goto-section.s b/ld/testsuite/ld-kvx/farcall-goto-section.s
new file mode 100644
index 0000000..d6287d1
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-goto-section.s
@@ -0,0 +1,25 @@
+.global _start
+
+# We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+ goto bar
+ ;;
+ goto bar2
+ ;;
+ ret
+ ;;
+
+# We will place the section .foo at 0x20001000.
+
+ .section .foo, "xa"
+ .type bar, @function
+bar:
+ ret
+ ;;
+ .type bar2, @function
+bar2:
+ ret
+ ;;
diff --git a/ld/testsuite/ld-kvx/farcall-goto.d b/ld/testsuite/ld-kvx/farcall-goto.d
new file mode 100644
index 0000000..7e34eeb
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-goto.d
@@ -0,0 +1,25 @@
+#name: kvx-farcall-goto
+#source: farcall-goto.s
+#as:
+#ld: -Ttext 0x1000 --section-start .foo=0x20001000
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+.* <_start>:
+.*: .. .. .. .. goto .* <__bar_veneer>;;
+
+.*: 00 00 d0 0f ret;;
+
+.* <__bar_veneer>:
+.*: .. .. 40 e0 .. .. .. .. make \$r16 = .* \(0x.*\);;
+
+.*: 10 00 d8 0f igoto \$r16;;
+
+
+Disassembly of section .foo:
+
+.* <bar>:
+.*: 00 00 d0 0f ret;;
+
diff --git a/ld/testsuite/ld-kvx/farcall-goto.s b/ld/testsuite/ld-kvx/farcall-goto.s
new file mode 100644
index 0000000..114bc56
--- /dev/null
+++ b/ld/testsuite/ld-kvx/farcall-goto.s
@@ -0,0 +1,20 @@
+ .global _start
+ .global bar
+
+# We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+ goto bar
+ ;;
+ ret
+ ;;
+
+# We will place the section .foo at 0x20001000.
+
+ .section .foo, "xa"
+ .type bar, @function
+bar:
+ ret
+ ;;
diff --git a/ld/testsuite/ld-kvx/kvx-elf.exp b/ld/testsuite/ld-kvx/kvx-elf.exp
new file mode 100644
index 0000000..9323a9b
--- /dev/null
+++ b/ld/testsuite/ld-kvx/kvx-elf.exp
@@ -0,0 +1,71 @@
+# Expect script for various KVX ELF tests.
+# Copyright (C) 2009-2023 Free Software Foundation, Inc.
+# Contributed by Kalray Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3. If not,
+# see <http://www.gnu.org/licenses/>.
+#
+
+# Exclude non-kvx-ELF targets.
+if { ![istarget "kvx-*-*"] } {
+ return
+}
+
+# List contains test-items with 3 items followed by 2 lists:
+# 0:name 1:ld early options 2:ld late options 3:assembler options
+# 4:filenames of assembler files 5: action and options. 6: name of output file
+
+# Actions:
+# objdump: Apply objdump options on result. Compare with regex (last arg).
+# nm: Apply nm options on result. Compare with regex (last arg).
+# readelf: Apply readelf options on result. Compare with regex (last arg).
+
+# 64bits tests
+run_dump_test "limit-call"
+run_dump_test "limit-goto"
+run_dump_test "farcall-back"
+run_dump_test "farcall-goto-defsym"
+run_dump_test "farcall-call-defsym"
+run_dump_test "farcall-goto-gsym"
+run_dump_test "farcall-goto-plt"
+run_dump_test "farcall-call-plt"
+run_dump_test "farcall-call"
+run_dump_test "farcall-goto"
+run_dump_test "farcall-goto-none-function"
+run_dump_test "farcall-call-none-function"
+run_dump_test "farcall-goto-section"
+run_dump_test "farcall-call-section"
+run_dump_test "pcrel-reloc"
+
+## 32bits tests
+if { ![istarget "kvx*-linux-*"] } {
+ set extra_32bits [list [list as -m32] [list ld -melf32kvx]]
+ run_dump_test "limit-call" $extra_32bits
+ run_dump_test "limit-goto" $extra_32bits
+ run_dump_test "farcall-back" $extra_32bits
+ run_dump_test "farcall-goto-defsym" $extra_32bits
+ run_dump_test "farcall-call-defsym" $extra_32bits
+ run_dump_test "farcall-goto-gsym" $extra_32bits
+ run_dump_test "farcall-goto-plt" $extra_32bits
+ run_dump_test "farcall-call-plt" $extra_32bits
+ run_dump_test "farcall-call" $extra_32bits
+ run_dump_test "farcall-goto" $extra_32bits
+ run_dump_test "farcall-goto-none-function" $extra_32bits
+ run_dump_test "farcall-call-none-function" $extra_32bits
+ run_dump_test "farcall-goto-section" $extra_32bits
+ run_dump_test "farcall-call-section" $extra_32bits
+ run_dump_test "pcrel-reloc" [list [list as -m32] [list ld -melf32kvx] [list dump pcrel-reloc-32bits.d]]
+}
diff --git a/ld/testsuite/ld-kvx/kvx.ld b/ld/testsuite/ld-kvx/kvx.ld
new file mode 100644
index 0000000..b1f3c05
--- /dev/null
+++ b/ld/testsuite/ld-kvx/kvx.ld
@@ -0,0 +1,18 @@
+/* Script for ld testsuite */
+OUTPUT_ARCH(kv3-1:64)
+ENTRY(_start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ PROVIDE (__executable_start = 0x8000); . = 0x8000;
+ .text :
+ {
+ *(.before)
+ *(.text)
+ *(.after)
+ } =0
+ . = 0x9000;
+ .got : { *(.got) *(.got.plt)}
+ . = 0x12340000;
+ .far : { *(.far) }
+}
diff --git a/ld/testsuite/ld-kvx/limit-call.d b/ld/testsuite/ld-kvx/limit-call.d
new file mode 100644
index 0000000..a9b6c72
--- /dev/null
+++ b/ld/testsuite/ld-kvx/limit-call.d
@@ -0,0 +1,20 @@
+#name: kvx-limit-call
+#source: limit-call.s
+#as:
+#ld: -Ttext 0x0000 --section-start .foo=0x0FFFFFFC
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+.* <_start>:
+ 0: ff ff ff 1b call ffffffc <bar>;;
+
+ 4: 00 00 d0 0f ret;;
+
+
+Disassembly of section .foo:
+
+.* <bar>:
+.*: 00 00 d0 0f ret;;
+
diff --git a/ld/testsuite/ld-kvx/limit-call.s b/ld/testsuite/ld-kvx/limit-call.s
new file mode 100644
index 0000000..e5cff12
--- /dev/null
+++ b/ld/testsuite/ld-kvx/limit-call.s
@@ -0,0 +1,22 @@
+# Test maximum encoding range of call
+
+ .global _start
+ .global bar
+
+# We will place the section .text at 0x0000.
+
+ .text
+
+_start:
+ call bar
+ ;;
+ ret
+ ;;
+
+# We will place the section .foo at 0x10000000
+
+ .section .foo, "xa"
+ .type bar, @function
+bar:
+ ret
+ ;;
diff --git a/ld/testsuite/ld-kvx/limit-goto.d b/ld/testsuite/ld-kvx/limit-goto.d
new file mode 100644
index 0000000..36c4386
--- /dev/null
+++ b/ld/testsuite/ld-kvx/limit-goto.d
@@ -0,0 +1,20 @@
+#name: kvx-limit-goto
+#source: limit-goto.s
+#as:
+#ld: -Ttext 0x0 --section-start .foo=0x0FFFFFFC
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+.* <_start>:
+ 0: ff ff ff 13 goto ffffffc <bar>;;
+
+ 4: 00 00 d0 0f ret;;
+
+
+Disassembly of section .foo:
+
+.* <bar>:
+.*: 00 00 d0 0f ret;;
+
diff --git a/ld/testsuite/ld-kvx/limit-goto.s b/ld/testsuite/ld-kvx/limit-goto.s
new file mode 100644
index 0000000..f902114
--- /dev/null
+++ b/ld/testsuite/ld-kvx/limit-goto.s
@@ -0,0 +1,22 @@
+# Test maximum encoding range of call
+
+ .global _start
+ .global bar
+
+# We will place the section .text at 0x0000.
+
+ .text
+
+_start:
+ goto bar
+ ;;
+ ret
+ ;;
+
+# We will place the section .foo at 0x10000000
+
+ .section .foo, "xa"
+ .type bar, @function
+bar:
+ ret
+ ;;
diff --git a/ld/testsuite/ld-kvx/pcrel-reloc-32bits.d b/ld/testsuite/ld-kvx/pcrel-reloc-32bits.d
new file mode 100644
index 0000000..3ca9eb9
--- /dev/null
+++ b/ld/testsuite/ld-kvx/pcrel-reloc-32bits.d
@@ -0,0 +1,8 @@
+.*: file format elf32-kvx
+
+
+Disassembly of section .text:
+
+.* <_start>:
+.*: 00 00 d0 8f ret
+.*: c0 cd 04 f0 04 00 00 00 pcrel \$r1 = 4919 \(0x1337\);;
diff --git a/ld/testsuite/ld-kvx/pcrel-reloc.d b/ld/testsuite/ld-kvx/pcrel-reloc.d
new file mode 100644
index 0000000..1931d9e
--- /dev/null
+++ b/ld/testsuite/ld-kvx/pcrel-reloc.d
@@ -0,0 +1,14 @@
+#name: pcrel-reloc
+#source: pcrel-reloc.s
+#as:
+#ld: -Ttext 0x0 --defsym foo=0x1337
+#objdump: -dr
+
+.*: file format elf64-kvx
+
+
+Disassembly of section .text:
+
+0000000000000000 <_start>:
+ 0: 00 00 d0 8f ret
+ 4: c0 cd 04 f0 04 00 00 80 00 00 00 00 pcrel \$r1 = 4919 \(0x1337\);;
diff --git a/ld/testsuite/ld-kvx/pcrel-reloc.s b/ld/testsuite/ld-kvx/pcrel-reloc.s
new file mode 100644
index 0000000..825a381
--- /dev/null
+++ b/ld/testsuite/ld-kvx/pcrel-reloc.s
@@ -0,0 +1,10 @@
+.text
+.global _start
+.weak foo
+.hidden foo
+
+.type _start, @function
+_start:
+ pcrel $r1 = @pcrel(foo)
+ ret
+ ;;
diff --git a/ld/testsuite/ld-scripts/fill.d b/ld/testsuite/ld-scripts/fill.d
index a341e78..73cc212 100644
--- a/ld/testsuite/ld-scripts/fill.d
+++ b/ld/testsuite/ld-scripts/fill.d
@@ -7,6 +7,7 @@
#skip: ia64-*-* mips*-*-freebsd* mips*-*-gnu* mips*-*-irix* mips*-*-kfreebsd*
#skip: mips*-*-linux* mips*-*-netbsd* mips*-*-openbsd* mips*-*-sysv4* sh-*-pe
#skip: tilegx*-*-* tilepro-*-* x86_64-*-cygwin x86_64-*-mingw* x86_64-*-pe*
+#skip: kvx*-*-*
#xfail: alpha*-*-*ecoff
#xfail: tic30-*-coff tic4x-*-* tic54x-*-* z8k-*-*
#
@@ -24,6 +25,7 @@
# tic54x doesn't support .p2align
# tilegx aligns code to minimum 8 bytes.
# tilepro aligns code to minimum 8 bytes.
+# kvx aligns code to minimum 8 bytes.
# x86_64-pe aligns to 16 bytes
# z8k-coff aligns to 2 bytes