[6/7,LoongArch] LD support

Message ID CAKjxQHkMW5vxVHNA8PoxLBxF1kehbHOTJBofnf+BeaEYWb1FSg@mail.gmail.com
State New
Headers show
Series
  • Untitled series #41024
Related show

Commit Message

Alan Modra via Binutils Aug. 14, 2021, 8:19 a.m.

Comments

Alan Modra via Binutils Aug. 24, 2021, 11:58 a.m. | #1
Needs a testsuite to validate relocation.

-- 
Alan Modra
Australia Development Lab, IBM

Patch

From 45659e678b0958c5ce59a6ade462d09cf95c3d6c Mon Sep 17 00:00:00 2001
From: liuzhensong <liuzhensong@loongson.cn>
Date: Sat, 14 Aug 2021 11:36:39 +0800
Subject: [PATCH 6/7] ld: LoongArch LD Port.

  include/elf/loongarch.h
  ld/Makefile.am
  ld/Makefile.in
  ld/NEWS
  ld/configure.tgt
  ld/emulparams/elf64loongarch-defs.sh
  ld/emulparams/elf64loongarch.sh
  ld/emultempl/loongarchelf.em
---
 include/elf/loongarch.h              | 103 +++++++++++++++++++++++++++
 ld/Makefile.am                       |   2 +
 ld/Makefile.in                       |   3 +
 ld/NEWS                              |   4 ++
 ld/configure.tgt                     |   4 ++
 ld/emulparams/elf64loongarch-defs.sh |  38 ++++++++++
 ld/emulparams/elf64loongarch.sh      |  11 +++
 ld/emultempl/loongarchelf.em         |  87 ++++++++++++++++++++++
 8 files changed, 252 insertions(+)
 create mode 100644 include/elf/loongarch.h
 create mode 100644 ld/emulparams/elf64loongarch-defs.sh
 create mode 100644 ld/emulparams/elf64loongarch.sh
 create mode 100644 ld/emultempl/loongarchelf.em

diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h
new file mode 100644
index 00000000000..1c873fc1f34
--- /dev/null
+++ b/include/elf/loongarch.h
@@ -0,0 +1,103 @@ 
+/* Copyright (C) 2021 Free Software Foundation, Inc.
+   Contributed by Loongson Ltd.
+
+   This file is part of GNU Binutils.
+
+   Based on RISC_V target.
+
+   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/>.  */
+
+#ifndef _ELF_LOONGARCH_H
+#define _ELF_LOONGARCH_H
+
+#include "elf/reloc-macros.h"
+#include "libiberty.h"
+
+START_RELOC_NUMBERS (elf_loongarch_reloc_type)
+/* Used by the dynamic linker.  */
+RELOC_NUMBER (R_LARCH_NONE, 0)
+RELOC_NUMBER (R_LARCH_32, 1)
+RELOC_NUMBER (R_LARCH_64, 2)
+RELOC_NUMBER (R_LARCH_RELATIVE, 3)
+RELOC_NUMBER (R_LARCH_COPY, 4)
+RELOC_NUMBER (R_LARCH_JUMP_SLOT, 5)
+RELOC_NUMBER (R_LARCH_TLS_DTPMOD32, 6)
+RELOC_NUMBER (R_LARCH_TLS_DTPMOD64, 7)
+RELOC_NUMBER (R_LARCH_TLS_DTPREL32, 8)
+RELOC_NUMBER (R_LARCH_TLS_DTPREL64, 9)
+RELOC_NUMBER (R_LARCH_TLS_TPREL32, 10)
+RELOC_NUMBER (R_LARCH_TLS_TPREL64, 11)
+RELOC_NUMBER (R_LARCH_IRELATIVE, 12)
+
+/* Reserved for future relocs that the dynamic linker must understand.  */
+
+/* Used by the static linker for relocating .text.  */
+RELOC_NUMBER (R_LARCH_MARK_LA, 20)
+RELOC_NUMBER (R_LARCH_MARK_PCREL, 21)
+
+RELOC_NUMBER (R_LARCH_SOP_PUSH_PCREL, 22)
+
+RELOC_NUMBER (R_LARCH_SOP_PUSH_ABSOLUTE, 23)
+
+RELOC_NUMBER (R_LARCH_SOP_PUSH_DUP, 24)
+RELOC_NUMBER (R_LARCH_SOP_PUSH_GPREL, 25)
+RELOC_NUMBER (R_LARCH_SOP_PUSH_TLS_TPREL, 26)
+RELOC_NUMBER (R_LARCH_SOP_PUSH_TLS_GOT, 27)
+RELOC_NUMBER (R_LARCH_SOP_PUSH_TLS_GD, 28)
+RELOC_NUMBER (R_LARCH_SOP_PUSH_PLT_PCREL, 29)
+
+RELOC_NUMBER (R_LARCH_SOP_ASSERT, 30)
+RELOC_NUMBER (R_LARCH_SOP_NOT, 31)
+RELOC_NUMBER (R_LARCH_SOP_SUB, 32)
+RELOC_NUMBER (R_LARCH_SOP_SL, 33)
+RELOC_NUMBER (R_LARCH_SOP_SR, 34)
+RELOC_NUMBER (R_LARCH_SOP_ADD, 35)
+RELOC_NUMBER (R_LARCH_SOP_AND, 36)
+RELOC_NUMBER (R_LARCH_SOP_IF_ELSE, 37)
+RELOC_NUMBER (R_LARCH_SOP_POP_32_S_10_5, 38)
+RELOC_NUMBER (R_LARCH_SOP_POP_32_U_10_12, 39)
+RELOC_NUMBER (R_LARCH_SOP_POP_32_S_10_12, 40)
+RELOC_NUMBER (R_LARCH_SOP_POP_32_S_10_16, 41)
+RELOC_NUMBER (R_LARCH_SOP_POP_32_S_10_16_S2, 42)
+RELOC_NUMBER (R_LARCH_SOP_POP_32_S_5_20, 43)
+RELOC_NUMBER (R_LARCH_SOP_POP_32_S_0_5_10_16_S2, 44)
+RELOC_NUMBER (R_LARCH_SOP_POP_32_S_0_10_10_16_S2, 45)
+RELOC_NUMBER (R_LARCH_SOP_POP_32_U, 46)
+
+/* Used by the static linker for relocating non .text.  */
+RELOC_NUMBER (R_LARCH_ADD8, 47)
+RELOC_NUMBER (R_LARCH_ADD16, 48)
+RELOC_NUMBER (R_LARCH_ADD24, 49)
+RELOC_NUMBER (R_LARCH_ADD32, 50)
+RELOC_NUMBER (R_LARCH_ADD64, 51)
+RELOC_NUMBER (R_LARCH_SUB8, 52)
+RELOC_NUMBER (R_LARCH_SUB16, 53)
+RELOC_NUMBER (R_LARCH_SUB24, 54)
+RELOC_NUMBER (R_LARCH_SUB32, 55)
+RELOC_NUMBER (R_LARCH_SUB64, 56)
+
+/* I don't know what it is.  Existing in almost all other arch.  */
+RELOC_NUMBER (R_LARCH_GNU_VTINHERIT, 57)
+RELOC_NUMBER (R_LARCH_GNU_VTENTRY, 58)
+
+END_RELOC_NUMBERS (R_LARCH_count)
+
+/* Processor specific flags for the ELF header e_flags field.  */
+
+#define EF_LARCH_ABI 0x0003
+#define EF_LARCH_ABI_LP64 0x0003
+#define EF_LARCH_ABI_LP32 0x0001
+
+#endif /* _ELF_LOONGARCH_H */
diff --git a/ld/Makefile.am b/ld/Makefile.am
index f8e99325361..436b5577256 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -434,6 +434,7 @@  ALL_64_EMULATION_SOURCES = \
 	eelf64hppa.c \
 	eelf64lppc.c \
 	eelf64lppc_fbsd.c \
+	eelf64loongarch.c \
 	eelf64lriscv.c \
 	eelf64lriscv_lp64f.c \
 	eelf64lriscv_lp64.c \
@@ -920,6 +921,7 @@  $(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)/eelf64loongarch.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv_lp64f.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 ef2e99e08da..9fb716b0b5e 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -923,6 +923,7 @@  ALL_64_EMULATION_SOURCES = \
 	eelf64hppa.c \
 	eelf64lppc.c \
 	eelf64lppc_fbsd.c \
+	eelf64loongarch.c \
 	eelf64lriscv.c \
 	eelf64lriscv_lp64f.c \
 	eelf64lriscv_lp64.c \
@@ -1417,6 +1418,7 @@  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)/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@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv.Po@am__quote@
@@ -2578,6 +2580,7 @@  $(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)/eelf64loongarch.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv_lp64f.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv_lp64.Pc@am__quote@
diff --git a/ld/NEWS b/ld/NEWS
index 6e0b56658d3..df993d7bb2a 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,9 @@ 
 -*- text -*-
 
+Changes in 2.37:
+
+* Add support for the LoongArch instruction set.
+
 * Add -z indirect-extern-access/-z noindirect-extern-access to x86 ELF
   linker to control canonical function pointers and copy relocation.
 
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 075febff13e..b92f65b53b5 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -1016,6 +1016,10 @@  z8k-*-coff)		targ_emul=z8002
 			targ_extra_emuls=z8001
 			targ_extra_ofiles=
 			;;
+loongarch32-*)		targ_emul=elf32loongarch
+			;;
+loongarch64-*)		targ_emul=elf64loongarch
+			;;
 *-*-ieee*)		targ_emul=vanilla
 			targ_extra_ofiles=
 			;;
diff --git a/ld/emulparams/elf64loongarch-defs.sh b/ld/emulparams/elf64loongarch-defs.sh
new file mode 100644
index 00000000000..ed793565a06
--- /dev/null
+++ b/ld/emulparams/elf64loongarch-defs.sh
@@ -0,0 +1,38 @@ 
+# This is an ELF platform.
+SCRIPT_NAME=elf
+ARCH=loongarch
+NO_REL_RELOCS=yes
+
+#TEMPLATE_NAME=elf32
+TEMPLATE_NAME=elf
+EXTRA_EM_FILE=loongarchelf
+
+ELFSIZE=64
+
+if test `echo "$host" | sed -e s/64//` = `echo "$target" | sed -e s/64//`; then
+  case " $EMULATION_LIBPATH " in
+    *" ${EMULATION_NAME} "*)
+      NATIVE=yes
+      ;;
+  esac
+fi
+
+# Enable shared library support for everything except an embedded elf target.
+case "$target" in
+  loongarch*-elf)
+    ;;
+  *)
+    GENERATE_SHLIB_SCRIPT=yes
+    GENERATE_PIE_SCRIPT=yes
+    ;;
+esac
+
+NOP=0x03400000
+
+TEXT_START_ADDR=0x120000000
+MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
+COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)"
+
+SEPARATE_GOTPLT=0
+INITIAL_READONLY_SECTIONS=".interp         : { *(.interp) } ${CREATE_PIE-${INITIAL_READONLY_SECTIONS}}"
+INITIAL_READONLY_SECTIONS="${RELOCATING+${CREATE_SHLIB-${INITIAL_READONLY_SECTIONS}}}"
diff --git a/ld/emulparams/elf64loongarch.sh b/ld/emulparams/elf64loongarch.sh
new file mode 100644
index 00000000000..a9d800ad107
--- /dev/null
+++ b/ld/emulparams/elf64loongarch.sh
@@ -0,0 +1,11 @@ 
+. ${srcdir}/emulparams/elf64loongarch-defs.sh
+OUTPUT_FORMAT="elf64-loongarch"
+
+case "$target" in
+  loong64*-linux*)
+    case "$EMULATION_NAME" in
+      *64*)
+	LIBPATH_SUFFIX="64/lib64 64";;
+    esac
+    ;;
+esac
diff --git a/ld/emultempl/loongarchelf.em b/ld/emultempl/loongarchelf.em
new file mode 100644
index 00000000000..b688ef7bc1d
--- /dev/null
+++ b/ld/emultempl/loongarchelf.em
@@ -0,0 +1,87 @@ 
+# This shell script emits a C file. -*- C -*-
+#   Copyright (C) 2021 Free Software Foundation, Inc.
+#   Contributed by Loongson Ltd.
+#
+# 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/>.
+
+fragment <<EOF
+
+#include "ldmain.h"
+#include "ldctor.h"
+#include "elf/loongarch.h"
+
+static void
+larch_elf_before_allocation (void)
+{
+  gld${EMULATION_NAME}_before_allocation ();
+
+  if (link_info.discard == discard_sec_merge)
+    link_info.discard = discard_l;
+
+  if (!bfd_link_relocatable (&link_info))
+    {
+      /* We always need at least some relaxation to handle code alignment.  */
+      if (RELAXATION_DISABLED_BY_USER)
+	TARGET_ENABLE_RELAXATION;
+      else
+	ENABLE_RELAXATION;
+    }
+
+  link_info.relax_pass = 3;
+}
+
+static void
+gld${EMULATION_NAME}_after_allocation (void)
+{
+  int need_layout = 0;
+
+  /* Don't attempt to discard unused .eh_frame sections until the final link,
+     as we can't reliably tell if they're used until after relaxation.  */
+  if (!bfd_link_relocatable (&link_info))
+    {
+      need_layout = bfd_elf_discard_info (link_info.output_bfd, &link_info);
+      if (need_layout < 0)
+	{
+	  einfo (_("%X%P: .eh_frame/.stab edit: %E\n"));
+	  return;
+	}
+    }
+
+  /* gld${EMULATION_NAME}_map_segments (need_layout); */
+  ldelf_map_segments (need_layout);
+}
+
+/* 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
+larch_create_output_section_statements (void)
+{
+  /* See PR 22920 for an example of why this is necessary.  */
+  if (strstr (bfd_get_target (link_info.output_bfd), "loong") == NULL)
+    {
+      einfo (_("%F%P: error: cannot change output format"
+	       " whilst linking %s binaries\n"), "LoongArch");
+      return;
+    }
+}
+
+EOF
+
+LDEMUL_BEFORE_ALLOCATION=larch_elf_before_allocation
+LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
+LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=larch_create_output_section_statements
-- 
2.27.0