This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[4/4] C-SKY port V2: Linker
Last part of the C-SKY patch set, containing the support for LD.
-Sandra
commit 3df2a9129b92a7ea395058fed5eae291d62fe0d3
Author: Sandra Loosemore <sandra@codesourcery.com>
Date: Fri May 25 14:58:31 2018 -0700
C-SKY port: linker
2018-05-25 Lifang Xia <lifang_xia@c-sky.com>
Yunhai Shang <yunhai_shang@c-sky.com>
Wenmeng Zhang <wenmeng_zhang@c-sky.com>
Wei Cheng <wei_cheng@c-sky.com>
Linjie Yu <linjie_yu@c-sky.com>
Sandra Loosemore <sandra@codesourcery.com>
Chung-Lin Tang <cltang@codesourcery.com>
ld/
* Makefile.am (ALL_EMULATION_SOURCES): Add C-SKY emulations.
(ecskyelf.c, ecskyelf_linux.c): New rules.
* Makefile.in: Regenerated.
* configure.tgt: Add C-SKY.
* emulparams/cskyelf.sh: New file.
* emulparams/cskyelf_linux.sh: New file.
* emultempl/cskyelf.em: New file.
* gen-doc.texi: Add C-SKY.
* ld.texinfo: Likewise.
(Options specific to C-SKY targets): New section.
* testsuite/ld-csky/*: New tests.
diff --git a/ld/Makefile.am b/ld/Makefile.am
index 151e1e2..0e4ef17 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -209,6 +209,8 @@ ALL_EMULATION_SOURCES = \
ecrisaout.c \
ecriself.c \
ecrislinux.c \
+ ecskyelf.c \
+ ecskyelf_linux.c \
ed10velf.c \
ed30v_e.c \
ed30v_o.c \
@@ -874,6 +876,12 @@ ecriself.c: $(srcdir)/emulparams/criself.sh \
ecrislinux.c: $(srcdir)/emulparams/crislinux.sh \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ecskyelf.c: $(srcdir)/emulparams/cskyelf.sh \
+ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
+ecskyelf_linux.c: $(srcdir)/emulparams/cskyelf_linux.sh \
+ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
ed10velf.c: $(srcdir)/emulparams/d10velf.sh \
$(ELF_DEPS) $(srcdir)/scripttempl/elfd10v.sc ${GEN_DEPENDS}
diff --git a/ld/Makefile.in b/ld/Makefile.in
index 5cfd4ab..f933b73 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -578,6 +578,8 @@ ALL_EMULATION_SOURCES = \
ecrisaout.c \
ecriself.c \
ecrislinux.c \
+ ecskyelf.c \
+ ecskyelf_linux.c \
ed10velf.c \
ed30v_e.c \
ed30v_o.c \
@@ -1130,6 +1132,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecrisaout.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecriself.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecrislinux.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecskyelf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecskyelf_linux.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed10velf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed30v_e.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed30v_o.Po@am__quote@
@@ -2380,6 +2384,12 @@ ecriself.c: $(srcdir)/emulparams/criself.sh \
ecrislinux.c: $(srcdir)/emulparams/crislinux.sh \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ecskyelf.c: $(srcdir)/emulparams/cskyelf.sh \
+ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
+ecskyelf_linux.c: $(srcdir)/emulparams/cskyelf_linux.sh \
+ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
ed10velf.c: $(srcdir)/emulparams/d10velf.sh \
$(ELF_DEPS) $(srcdir)/scripttempl/elfd10v.sc ${GEN_DEPENDS}
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 3386c3d..542870d 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -196,6 +196,10 @@ cris-*-* | crisv32-*-*) targ_emul=criself
;;
crx-*-elf*) targ_emul=elf32crx
;;
+
+csky-*-elf*) targ_emul=cskyelf ;;
+csky-*-linux*) targ_emul=cskyelf_linux ;;
+
d10v-*-*) targ_emul=d10velf ;;
d30v-*-*ext*) targ_emul=d30v_e; targ_extra_emuls="d30velf d30v_o" ;;
d30v-*-*onchip*) targ_emul=d30v_o; targ_extra_emuls="d30velf d30v_e" ;;
diff --git a/ld/emulparams/cskyelf.sh b/ld/emulparams/cskyelf.sh
new file mode 100644
index 0000000..ad6394f
--- /dev/null
+++ b/ld/emulparams/cskyelf.sh
@@ -0,0 +1,35 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-csky-little"
+BIG_OUTPUT_FORMAT="elf32-csky-big"
+LITTLE_OUTPUT_FORMAT="elf32-csky-little"
+NO_REL_RELOCS=yes
+PAGE_SIZE=0x1000
+TARGET_PAGE_SIZE=0x400
+MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
+TEXT_START_ADDR=0x8000
+CHECK_RELOCS_AFTER_OPEN_INPUT=yes
+NONPAGED_TEXT_START_ADDR=0
+ARCH=csky
+EMBEDDED=yes
+EXTRA_EM_FILE=cskyelf
+
+# There is a problem with the NOP value - it must work for both
+# big endian and little endian systems. Unfortunately there is
+# no symmetrical mcore opcode that functions as a noop. The
+# chosen solution is to use "tst r0, r14". This is a symmetrical
+# value, and apart from the corruption of the C bit, it has no other
+# side effects. Since the carry bit is never tested without being
+# explicitly set first, and since the NOP code is only used as a
+# fill value between independently viable pieces of code, it should
+# not matter.
+NOP=0
+
+ENTRY=__start
+OTHER_BSS_SYMBOLS="__bss_start__ = . ;"
+OTHER_BSS_END_SYMBOLS="__bss_end__ = . ;"
+
+# This sets the stack to the top of the simulator memory (2^19 bytes).
+# STACK_ADDR=0x80000
+
+TEMPLATE_NAME=elf32
+
diff --git a/ld/emulparams/cskyelf_linux.sh b/ld/emulparams/cskyelf_linux.sh
new file mode 100644
index 0000000..118be1a
--- /dev/null
+++ b/ld/emulparams/cskyelf_linux.sh
@@ -0,0 +1,36 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-csky-little"
+BIG_OUTPUT_FORMAT="elf32-csky-big"
+LITTLE_OUTPUT_FORMAT="elf32-csky-little"
+NO_REL_RELOCS=yes
+TARGET_PAGE_SIZE=0x400
+MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
+COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)"
+CHECK_RELOCS_AFTER_OPEN_INPUT=yes
+TEXT_START_ADDR=0x8000
+NONPAGED_TEXT_START_ADDR=0
+ARCH=csky
+GENERATE_SHLIB_SCRIPT=yes
+GENERATE_PIE_SCRIPT=yes
+
+# There is a problem with the NOP value - it must work for both
+# big endian and little endian systems. Unfortunately there is
+# no symmetrical mcore opcode that functions as a noop. The
+# chosen solution is to use "tst r0, r14". This is a symmetrical
+# value, and apart from the corruption of the C bit, it has no other
+# side effects. Since the carry bit is never tested without being
+# explicitly set first, and since the NOP code is only used as a
+# fill value between independently viable pieces of code, it should
+# not matter.
+NOP=0
+
+OTHER_BSS_SYMBOLS="__bss_start__ = . ;"
+OTHER_BSS_END_SYMBOLS="__bss_end__ = . ;"
+
+# This sets the stack to the top of the simulator memory (2^19 bytes).
+# STACK_ADDR=0x80000
+
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
+GENERATE_COMBRELOC_SCRIPT=yes
+EXTRA_EM_FILE=cskyelf
diff --git a/ld/emultempl/cskyelf.em b/ld/emultempl/cskyelf.em
new file mode 100644
index 0000000..6e33d70
--- /dev/null
+++ b/ld/emultempl/cskyelf.em
@@ -0,0 +1,364 @@
+# This shell script emits a C file. -*- C -*-
+# Copyright (C) 2013-2018 Free Software Foundation, Inc.
+#
+# This file is part of 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; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# This file is sourced from elf32.em, and defines extra C-SKY ELF
+# specific routines.
+#
+fragment <<EOF
+
+#include "ldctor.h"
+#include "elf/csky.h"
+
+/* To use branch stub or not. */
+extern bfd_boolean use_branch_stub;
+
+/* Fake input file for stubs. */
+static lang_input_statement_type *stub_file;
+
+/* Whether we need to call gldcsky_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 bfd_boolean
+hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
+{
+ lang_statement_union_type *l;
+ bfd_boolean ret;
+
+ for (l = *lp; l != NULL; lp = &l->header.next, l = *lp)
+ 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;
+}
+EOF
+
+case ${target} in
+ csky-*-linux-*)
+fragment <<EOF
+/* 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
+csky_elf_create_output_section_statements (void)
+{
+ use_branch_stub = FALSE;
+}
+EOF
+ break
+ ;;
+ *)
+fragment <<EOF
+/* 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
+csky_elf_create_output_section_statements (void)
+{
+ /* If don't use branch stub, just do not emit stub_file. */
+ if (use_branch_stub == FALSE)
+ 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);
+}
+EOF
+ ;;
+esac
+
+fragment <<EOF
+/* Call-back for elf32_csky_size_stubs. */
+
+/* Create a new stub section, and arrange for it to be linked
+ immediately after INPUT_SECTION. */
+static asection *
+elf32_csky_add_stub_section (const char *stub_sec_name,
+ asection *input_section)
+{
+ asection *stub_sec;
+ flagword flags;
+ asection *output_section;
+ const char *secname;
+ 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_file->the_bfd, stub_sec, 3);
+
+ output_section = input_section->output_section;
+ secname = bfd_get_section_name (output_section->owner, output_section);
+ os = lang_output_section_find (secname);
+
+ info.input_section = input_section;
+ lang_list_init (&info.add);
+ lang_add_section (&info.add, stub_sec, 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_csky_size_stubs. */
+static void
+gldcsky_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. */
+ gld${EMULATION_NAME}_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 (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
+ && (i->flags & SEC_EXCLUDE) == 0
+ && i->output_section != NULL
+ && i->output_section->owner == link_info.output_bfd)
+ elf32_csky_next_input_section (&link_info, i);
+ }
+}
+
+static void
+gld${EMULATION_NAME}_after_allocation (void)
+{
+ /* 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. */
+ if (bfd_elf_discard_info (link_info.output_bfd, &link_info))
+ 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))
+ {
+ int ret = elf32_csky_setup_section_lists (link_info.output_bfd,
+ &link_info);
+
+ if (ret < 0)
+ {
+ einfo (_("%X%P: could not compute sections lists for stub generation: %E\n"));
+ return;
+ }
+ else if (ret != 0)
+ {
+ lang_for_each_statement (build_section_lists);
+
+ /* Call into the BFD backend to do the real work. */
+ if (! elf32_csky_size_stubs (link_info.output_bfd,
+ stub_file->the_bfd,
+ &link_info,
+ group_size,
+ &elf32_csky_add_stub_section,
+ &gldcsky_layout_sections_again))
+ {
+ einfo (_("%X%P: cannot size stub section: %E\n"));
+ return;
+ }
+ }
+ }
+
+ if (need_laying_out != -1)
+ gld${EMULATION_NAME}_map_segments (need_laying_out);
+}
+
+static void
+gld${EMULATION_NAME}_finish (void)
+{
+ if (stub_file != NULL
+ && !bfd_link_relocatable (&link_info)
+ && stub_file->the_bfd->sections != NULL
+ && !elf32_csky_build_stubs (&link_info))
+ einfo (_("%X%P: cannot build stubs: %E\n"));
+ finish_default ();
+}
+
+/* Avoid processing the fake stub_file in vercheck, stat_needed and
+ check_needed routines. */
+
+static void (*real_func) (lang_input_statement_type *);
+
+static void csky_for_each_input_file_wrapper (lang_input_statement_type *l)
+{
+ if (l != stub_file)
+ (*real_func) (l);
+}
+
+static void
+csky_lang_for_each_input_file (void (*func) (lang_input_statement_type *))
+{
+ real_func = func;
+ lang_for_each_input_file (&csky_for_each_input_file_wrapper);
+}
+
+#define lang_for_each_input_file csky_lang_for_each_input_file
+
+EOF
+
+# This code gets inserted into the generic elf32.sc linker script
+# and allows us to define our own command line switches.
+case ${target} in
+ csky-*-linux-*)
+ break
+ ;;
+
+ *)
+PARSE_AND_LIST_PROLOGUE='
+#define OPTION_BRANCH_STUB 301
+#define OPTION_NO_BRANCH_STUB 302
+#define OPTION_STUBGROUP_SIZE 303
+'
+
+PARSE_AND_LIST_LONGOPTS='
+ {"branch-stub", no_argument, NULL, OPTION_BRANCH_STUB},
+ {"no-branch-stub", no_argument, NULL, OPTION_NO_BRANCH_STUB},
+ {"stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE},
+'
+PARSE_AND_LIST_OPTIONS='
+ fprintf (file, _(" --[no-]branch-stub\n"));
+ fprintf (file, _("\t\t\tDisable/enable use of stubs to expand branch\n\
+\t\t\tinstructions which cannot reach the target. \n"));
+ fprintf (file, _(" --stub-group-size=N\n"));
+ fprintf (file, _("\t\t\tMaximum size of a group of input sections that can be\n\
+\t\t\thandled by one stub section. A negative value\n\
+\t\t\tlocates all stubs after their branches (with a\n\
+\t\t\tgroup size of -N), while a positive value allows\n\
+\t\t\ttwo groups of input sections, one before, and one\n\
+\t\t\tafter each stub section. Values of +/-1 indicate\n\
+\t\t\tthe linker should choose suitable defaults.\n"));
+'
+
+PARSE_AND_LIST_ARGS_CASES='
+ case OPTION_BRANCH_STUB:
+ use_branch_stub = TRUE;
+ break;
+ case OPTION_NO_BRANCH_STUB:
+ use_branch_stub = FALSE;
+ break;
+
+ case OPTION_STUBGROUP_SIZE:
+ {
+ const char *end;
+
+ group_size = bfd_scan_vma (optarg, &end, 0);
+ if (*end)
+ einfo (_("%P%F: invalid number `%s'\''\n"), optarg);
+ }
+ break;
+'
+
+ break;
+ ;;
+esac
+
+LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
+LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=csky_elf_create_output_section_statements
+LDEMUL_FINISH=gld${EMULATION_NAME}_finish
diff --git a/ld/gen-doc.texi b/ld/gen-doc.texi
index 28acc93..b60a295 100644
--- a/ld/gen-doc.texi
+++ b/ld/gen-doc.texi
@@ -8,6 +8,7 @@
@c 2. Specific target machines
@set ARM
@set C6X
+@set CSKY
@set H8300
@set HPPA
@set I960
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 40d79dd..b700b61 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -21,6 +21,7 @@
@set GENERIC
@set ARM
@set C6X
+@set CSKY
@set H8300
@set HPPA
@set M68HC11
@@ -3008,6 +3009,36 @@ exidx entries in frame unwind info.
@c man end
@end ifset
+@ifset CSKY
+@subsection Options specific to C-SKY targets
+
+@c man begin OPTIONS
+
+@table @gcctabopt
+
+@kindex --branch-stub on C-SKY
+@item --branch-stub
+This option enables linker branch relaxation by inserting branch stub
+sections when needed to extend the range of branches. This option is
+usually not required since C-SKY supports branch and call instructions that
+can access the full memory range and branch relaxation is normally handled by
+the compiler or assembler.
+
+@kindex --stub-group-size on C-SKY
+@item --stub-group-size=@var{N}
+This option allows finer control of linker branch stub creation.
+It sets the maximum size of a group of input sections that can
+be handled by one stub section. A negative value of @var{N} locates
+stub sections after their branches, while a positive value allows stub
+sections to appear either before or after the branches. Values of
+@samp{1} or @samp{-1} indicate that the
+linker should choose suitable defaults.
+
+@end table
+
+@c man end
+@end ifset
+
@ifset M68HC11
@subsection Options specific to Motorola 68HC11 and 68HC12 targets
diff --git a/ld/testsuite/ld-csky/csky.exp b/ld/testsuite/ld-csky/csky.exp
new file mode 100644
index 0000000..94a769f
--- /dev/null
+++ b/ld/testsuite/ld-csky/csky.exp
@@ -0,0 +1,15 @@
+if { ! [istarget csky-*-*] } {
+ return
+}
+
+set linux_gnu [expr [istarget csky*-*-linux*]]
+
+foreach test [lsort [glob -nocomplain $srcdir/$subdir/*.d]] {
+
+ if { ! $linux_gnu && ([string match "$srcdir/$subdir/tls-*.d" $test]
+ || [string match "$srcdir/$subdir/got*.d" $test]) } {
+ continue
+ }
+
+ run_dump_test [file rootname $test]
+}
diff --git a/ld/testsuite/ld-csky/data.d b/ld/testsuite/ld-csky/data.d
new file mode 100644
index 0000000..21b2f27
--- /dev/null
+++ b/ld/testsuite/ld-csky/data.d
@@ -0,0 +1,18 @@
+#name: GB(r28) relative .data section references
+#source: data.s
+#source: data_section.s
+#ld: -e __start
+#objdump: -dr
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <__start>:
+ [0-9a-f]+: cd400004 lrs.b r10, \[0x4\] // the offset is based on .data
+ [0-9a-f]+: cd440002 lrs.h r10, \[0x2\] // the offset is based on .data
+ [0-9a-f]+: cd480001 lrs.w r10, \[0x1\] // the offset is based on .data
+ [0-9a-f]+: cd700004 srs.b r11, \[0x4\] // the offset is based on .data
+ [0-9a-f]+: cd740002 srs.h r11, \[0x2\] // the offset is based on .data
+ [0-9a-f]+: cd780001 srs.w r11, \[0x1\] // the offset is based on .data
diff --git a/ld/testsuite/ld-csky/data.s b/ld/testsuite/ld-csky/data.s
new file mode 100644
index 0000000..b5af989
--- /dev/null
+++ b/ld/testsuite/ld-csky/data.s
@@ -0,0 +1,10 @@
+ .text
+ .global __start
+__start:
+ lrs.b r10, [word1]
+ lrs.h r10, [word1]
+ lrs.w r10, [word1]
+
+ srs.b r11, [word1]
+ srs.h r11, [word1]
+ srs.w r11, [word1]
diff --git a/ld/testsuite/ld-csky/data_section.s b/ld/testsuite/ld-csky/data_section.s
new file mode 100644
index 0000000..886561c
--- /dev/null
+++ b/ld/testsuite/ld-csky/data_section.s
@@ -0,0 +1,7 @@
+ .global word0, word1
+ .data
+ .align 4
+word0:
+ .word 0xabcd1234
+word1:
+ .word 0xdeadbeef
diff --git a/ld/testsuite/ld-csky/emit-relocs-1.d b/ld/testsuite/ld-csky/emit-relocs-1.d
new file mode 100644
index 0000000..3cc05ac
--- /dev/null
+++ b/ld/testsuite/ld-csky/emit-relocs-1.d
@@ -0,0 +1,37 @@
+#name: Emit relocs 1
+#source: emit-relocs-1a.s
+#source: emit-relocs-1b.s
+#ld: -q -T emit-relocs-1.ld
+#objdump: -sr
+
+.*: file format .*
+
+RELOCATION RECORDS FOR \[\.data\]:
+OFFSET TYPE VALUE *
+00000000 R_CKCORE_ADDR32 \.data
+00000004 R_CKCORE_ADDR32 \.data\+0x00001000
+00000008 R_CKCORE_ADDR32 \.merge1\+0x00000002
+0000000c R_CKCORE_ADDR32 \.merge2
+00000010 R_CKCORE_ADDR32 \.merge3
+00000014 R_CKCORE_ADDR32 \.merge3\+0x00000004
+00000020 R_CKCORE_ADDR32 \.data\+0x00000020
+00000024 R_CKCORE_ADDR32 \.data\+0x00001020
+00000028 R_CKCORE_ADDR32 \.merge1
+0000002c R_CKCORE_ADDR32 \.merge2\+0x00000002
+00000030 R_CKCORE_ADDR32 \.merge3\+0x00000008
+00000034 R_CKCORE_ADDR32 \.merge3\+0x00000004
+
+
+Contents of section \.text:
+ 80000 036c .*
+Contents of section \.merge1:
+ 80400 666c7574 74657200 flutter.*
+Contents of section \.merge2:
+ 80800 74617374 696e6700 tasting.*
+Contents of section \.merge3:
+ 80c00 00010000 00020000 00030000 .*
+Contents of section \.data:
+ 81000 00100800 00200800 02040800 00080800 .*
+ 81010 000c0800 040c0800 00000000 00000000 .*
+ 81020 20100800 20200800 00040800 02080800 .*
+ 81030 080c0800 040c0800 .*
diff --git a/ld/testsuite/ld-csky/emit-relocs-1.ld b/ld/testsuite/ld-csky/emit-relocs-1.ld
new file mode 100644
index 0000000..574030b
--- /dev/null
+++ b/ld/testsuite/ld-csky/emit-relocs-1.ld
@@ -0,0 +1,20 @@
+ENTRY(__start)
+SECTIONS
+{
+ . = 0x80000;
+ .text : { *(.text) }
+
+ . = ALIGN (0x400);
+ .merge1 : { *(.merge1) }
+
+ . = ALIGN (0x400);
+ .merge2 : { *(.merge2) }
+
+ . = ALIGN (0x400);
+ .merge3 : { *(.merge3) }
+
+ . = ALIGN (0x400);
+ .data : { *(.data) }
+
+ /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-csky/emit-relocs-1a.s b/ld/testsuite/ld-csky/emit-relocs-1a.s
new file mode 100644
index 0000000..89bbf99
--- /dev/null
+++ b/ld/testsuite/ld-csky/emit-relocs-1a.s
@@ -0,0 +1,24 @@
+ .text
+ .align 4
+ .globl __start
+__start:
+ nop
+
+ .section .merge1,"aMS",@progbits,1
+A: .string "utter"
+
+ .section .merge2,"aMS",@progbits,1
+B: .string "tasting"
+
+ .section .merge3,"aM",@progbits,4
+C: .4byte 0x100
+D: .4byte 0x200
+
+ .data
+ .align 4
+E: .4byte E
+ .4byte E + 0x1000
+ .4byte A
+ .4byte B
+ .4byte C
+ .4byte D
diff --git a/ld/testsuite/ld-csky/emit-relocs-1b.s b/ld/testsuite/ld-csky/emit-relocs-1b.s
new file mode 100644
index 0000000..82229c1
--- /dev/null
+++ b/ld/testsuite/ld-csky/emit-relocs-1b.s
@@ -0,0 +1,18 @@
+ .section .merge1,"aMS",@progbits,1
+A: .string "flutter"
+
+ .section .merge2,"aMS",@progbits,1
+B: .string "sting"
+
+ .section .merge3,"aM",@progbits,4
+C: .4byte 0x300
+D: .4byte 0x200
+
+ .data
+ .align 4
+E: .4byte E
+ .4byte E + 0x1000
+ .4byte A
+ .4byte B
+ .4byte C
+ .4byte D
diff --git a/ld/testsuite/ld-csky/got.d b/ld/testsuite/ld-csky/got.d
new file mode 100644
index 0000000..cc923f7
--- /dev/null
+++ b/ld/testsuite/ld-csky/got.d
@@ -0,0 +1,29 @@
+#name: GOT/PLT Link test
+#source: got.s
+#ld: -shared --hash-style=sysv
+#readelf: -d -r
+
+Dynamic section at offset 0x[0-9a-f]+ contains 13 entries:
+ Tag Type Name/Value
+ 0x00000004 \(HASH\) .*
+ 0x00000005 \(STRTAB\) .*
+ 0x00000006 \(SYMTAB\) .*
+ 0x0000000a \(STRSZ\) .* \(bytes\)
+ 0x0000000b \(SYMENT\) .* \(bytes\)
+ 0x00000003 \(PLTGOT\) 0x[0-9a-f]+
+ 0x00000002 \(PLTRELSZ\) 12 \(bytes\)
+ 0x00000014 \(PLTREL\) RELA
+ 0x00000017 \(JMPREL\) 0x[0-9a-f]+
+ 0x00000007 \(RELA\) 0x[0-9a-f]+
+ 0x00000008 \(RELASZ\) 24 \(bytes\)
+ 0x00000009 \(RELAENT\) 12 \(bytes\)
+ 0x00000000 \(NULL\) 0x0
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ Offset Info Type Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 0000040b R_CKCORE_GLOB_DAT 00000000 var1 \+ 0
+[0-9a-f]+ 0000070b R_CKCORE_GLOB_DAT 00000000 var2 \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ Offset Info Type Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 00000b0c R_CKCORE_JUMP_SLO 00000000 bar \+ .*
diff --git a/ld/testsuite/ld-csky/got.s b/ld/testsuite/ld-csky/got.s
new file mode 100644
index 0000000..d5f3b72
--- /dev/null
+++ b/ld/testsuite/ld-csky/got.s
@@ -0,0 +1,19 @@
+ .text
+ .align 2
+ .global foo
+ .type foo, @function
+foo:
+ push l0, lr, gb
+ lrw t1, .L2@GOTPC
+ grs gb, .L2
+.L2:
+ addu gb, gb, t1
+ lrs.w a3, [var1@GOT]
+ ld.w l0, (a3, 0)
+ lrs.w a3, [var2@GOT]
+ ld.w a3, (a3, 0)
+ lrs.w a0, [bar@PLT]
+ addu l0, l0, a3
+ jsr a0
+ addu a0, l0, a0
+ pop l0, lr, gb
diff --git a/ld/testsuite/ld-csky/hilo16.d b/ld/testsuite/ld-csky/hilo16.d
new file mode 100644
index 0000000..f2435c0
--- /dev/null
+++ b/ld/testsuite/ld-csky/hilo16.d
@@ -0,0 +1,14 @@
+#name: address hi16/lo16 relocations
+#source: hilo16.s
+#source: hilo16_symbol.s
+#ld: -e __start
+#objdump: -dr
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <__start>:
+ [0-9a-f]+: ea21dead movih r1, 57005
+ [0-9a-f]+: ec21beef ori r1, r1, 48879
diff --git a/ld/testsuite/ld-csky/hilo16.s b/ld/testsuite/ld-csky/hilo16.s
new file mode 100644
index 0000000..601fbc6
--- /dev/null
+++ b/ld/testsuite/ld-csky/hilo16.s
@@ -0,0 +1,7 @@
+# Test the hi16/lo16 relocations
+
+.text
+.global __start
+__start:
+ movih r1, (long_symbol) >> 16
+ ori r1, r1, (long_symbol) & 0xffff
diff --git a/ld/testsuite/ld-csky/hilo16_symbol.s b/ld/testsuite/ld-csky/hilo16_symbol.s
new file mode 100644
index 0000000..e8fad0f
--- /dev/null
+++ b/ld/testsuite/ld-csky/hilo16_symbol.s
@@ -0,0 +1,2 @@
+.global long_symbol
+.set long_symbol, 0xDEADBEEF
diff --git a/ld/testsuite/ld-csky/tls-gd-v1.d b/ld/testsuite/ld-csky/tls-gd-v1.d
new file mode 100644
index 0000000..f651c5f
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-gd-v1.d
@@ -0,0 +1,30 @@
+#name: TLS Global Dynamic link test (C-SKY V1)
+#source: tls-gd-v1.s
+#as: -mcpu=ck610
+#ld: -shared --hash-style=sysv
+#readelf: -d -r
+
+Dynamic section at offset 0x[0-9a-f]+ contains 13 entries:
+ Tag Type Name/Value
+ 0x00000004 \(HASH\) .*
+ 0x00000005 \(STRTAB\) .*
+ 0x00000006 \(SYMTAB\) .*
+ 0x0000000a \(STRSZ\) .* \(bytes\)
+ 0x0000000b \(SYMENT\) .* \(bytes\)
+ 0x00000003 \(PLTGOT\) 0x[0-9a-f]+
+ 0x00000002 \(PLTRELSZ\) 12 \(bytes\)
+ 0x00000014 \(PLTREL\) RELA
+ 0x00000017 \(JMPREL\) 0x[0-9a-f]+
+ 0x00000007 \(RELA\) 0x[0-9a-f]+
+ 0x00000008 \(RELASZ\) 24 \(bytes\)
+ 0x00000009 \(RELAENT\) 12 \(bytes\)
+ 0x00000000 \(NULL\) 0x0
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ Offset Info Type Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 00000738 R_CKCORE_TLS_DTPM 00000000 var \+ 0
+[0-9a-f]+ 00000739 R_CKCORE_TLS_DTPO 00000000 var \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ Offset Info Type Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 0000040c R_CKCORE_JUMP_SLO 00000000 __tls_get_addr \+ .*
diff --git a/ld/testsuite/ld-csky/tls-gd-v1.s b/ld/testsuite/ld-csky/tls-gd-v1.s
new file mode 100644
index 0000000..617aac0
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-gd-v1.s
@@ -0,0 +1,26 @@
+ .global __tls_get_addr
+ .text
+ .align 2
+ .global foo
+ .type foo, @function
+foo:
+ subi sp, sp, 8
+ st.w gb, (sp)
+ st.w r15, (sp, 4)
+ bsr .L2
+.L2:
+ lrw gb, .L2@GOTPC
+ addu gb, gb, r15
+ lrw r7, __tls_get_addr@PLT
+ addu r7, r7, gb
+ ld.w r7, (r7)
+ bsr .LTLS0
+.LTLS0:
+ lrw r2, var@TLSGD32
+ addu r2, r15
+ jsr r7
+ ld.w r2, (r2)
+ ld.w r15, (sp, 4)
+ ld.w gb, (sp)
+ addi sp, sp, 8
+ jmp r15
diff --git a/ld/testsuite/ld-csky/tls-gd.d b/ld/testsuite/ld-csky/tls-gd.d
new file mode 100644
index 0000000..b3cef18
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-gd.d
@@ -0,0 +1,29 @@
+#name: TLS Global Dynamic link test
+#source: tls-gd.s
+#ld: -shared --hash-style=sysv
+#readelf: -d -r
+
+Dynamic section at offset 0x[0-9a-f]+ contains 13 entries:
+ Tag Type Name/Value
+ 0x00000004 \(HASH\) .*
+ 0x00000005 \(STRTAB\) .*
+ 0x00000006 \(SYMTAB\) .*
+ 0x0000000a \(STRSZ\) .* \(bytes\)
+ 0x0000000b \(SYMENT\) .* \(bytes\)
+ 0x00000003 \(PLTGOT\) 0x[0-9a-f]+
+ 0x00000002 \(PLTRELSZ\) 12 \(bytes\)
+ 0x00000014 \(PLTREL\) RELA
+ 0x00000017 \(JMPREL\) 0x[0-9a-f]+
+ 0x00000007 \(RELA\) 0x[0-9a-f]+
+ 0x00000008 \(RELASZ\) 24 \(bytes\)
+ 0x00000009 \(RELAENT\) 12 \(bytes\)
+ 0x00000000 \(NULL\) 0x0
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ Offset Info Type Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 00000738 R_CKCORE_TLS_DTPM 00000000 var \+ 0
+[0-9a-f]+ 00000739 R_CKCORE_TLS_DTPO 00000000 var \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ Offset Info Type Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 0000040c R_CKCORE_JUMP_SLO 00000000 __tls_get_addr \+ .*
diff --git a/ld/testsuite/ld-csky/tls-gd.s b/ld/testsuite/ld-csky/tls-gd.s
new file mode 100644
index 0000000..8fe0e37
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-gd.s
@@ -0,0 +1,20 @@
+ .text
+ .global __tls_get_addr
+ .align 2
+ .global foo
+ .type foo, @function
+foo:
+ push lr, gb
+ lrw t1, .L2@GOTPC
+ grs gb, .L2
+.L2:
+ addu gb, gb, t1
+ grs a2, .LTLS0
+ lrw a3, __tls_get_addr@PLT
+.LTLS0:
+ lrw a0, var@TLSGD32
+ ldr.w a3, (gb, a3 << 0)
+ addu a0, a0, a2
+ jsr a3
+ ld.w a0, (a0, 0)
+ pop lr, gb
diff --git a/ld/testsuite/ld-csky/tls-ie-v1.d b/ld/testsuite/ld-csky/tls-ie-v1.d
new file mode 100644
index 0000000..1f5f446
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-ie-v1.d
@@ -0,0 +1,25 @@
+#name: TLS Initial Exec link test (C-SKY v1)
+#source: tls-ie-v1.s
+#as: -mcpu=ck610
+#ld: -shared --hash-style=sysv
+#readelf: -d -r
+
+Dynamic section at offset 0x[0-9a-f]+ contains 13 entries:
+ Tag Type Name/Value
+ 0x00000004 \(HASH\) .*
+ 0x00000005 \(STRTAB\) .*
+ 0x00000006 \(SYMTAB\) .*
+ 0x0000000a \(STRSZ\) .* \(bytes\)
+ 0x0000000b \(SYMENT\) .* \(bytes\)
+ 0x00000003 \(PLTGOT\) 0x[0-9a-f]+
+ 0x00000002 \(PLTRELSZ\) 0 \(bytes\)
+ 0x00000014 \(PLTREL\) RELA
+ 0x00000017 \(JMPREL\) 0x[0-9a-f]+
+ 0x00000007 \(RELA\) 0x[0-9a-f]+
+ 0x00000008 \(RELASZ\) 12 \(bytes\)
+ 0x00000009 \(RELAENT\) 12 \(bytes\)
+ 0x00000000 \(NULL\) 0x0
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entry:
+ Offset Info Type Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 0000003a R_CKCORE_TLS_TPOF 0
diff --git a/ld/testsuite/ld-csky/tls-ie-v1.s b/ld/testsuite/ld-csky/tls-ie-v1.s
new file mode 100644
index 0000000..1841da8
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-ie-v1.s
@@ -0,0 +1,30 @@
+ .text
+ .section .tbss,"awT",@nobits
+ .align 2
+ .type var, @object
+ .size var, 4
+var:
+ .word 0
+
+ .text
+ .align 2
+ .global _start
+ .type _start, @function
+_start:
+ subi sp, sp, 8
+ st.w r15, (sp)
+ bsr .LTLS0
+.LTLS0:
+ lrw r7, var@GOTTPOFF
+ addu r7, r15
+ ld.w r7, (r7)
+ bsr __read_tp
+ addu r7, r7, r2
+ ld.w r2, (r7)
+ ld.w r15, (sp)
+ addi sp, sp, 8
+ jmp r15
+__read_tp:
+ movi r2, 0
+ jmp r15
+
diff --git a/ld/testsuite/ld-csky/tls-ie.d b/ld/testsuite/ld-csky/tls-ie.d
new file mode 100644
index 0000000..45a8a11
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-ie.d
@@ -0,0 +1,24 @@
+#name: TLS Initial Exec link test
+#source: tls-ie.s
+#ld: -shared --hash-style=sysv
+#readelf: -d -r
+
+Dynamic section at offset 0x[0-9a-f]+ contains 13 entries:
+ Tag Type Name/Value
+ 0x00000004 \(HASH\) .*
+ 0x00000005 \(STRTAB\) .*
+ 0x00000006 \(SYMTAB\) .*
+ 0x0000000a \(STRSZ\) .* \(bytes\)
+ 0x0000000b \(SYMENT\) .* \(bytes\)
+ 0x00000003 \(PLTGOT\) 0x[0-9a-f]+
+ 0x00000002 \(PLTRELSZ\) 0 \(bytes\)
+ 0x00000014 \(PLTREL\) RELA
+ 0x00000017 \(JMPREL\) 0x[0-9a-f]+
+ 0x00000007 \(RELA\) 0x[0-9a-f]+
+ 0x00000008 \(RELASZ\) 12 \(bytes\)
+ 0x00000009 \(RELAENT\) 12 \(bytes\)
+ 0x00000000 \(NULL\) 0x0
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entry:
+ Offset Info Type Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 0000003a R_CKCORE_TLS_TPOF 0
diff --git a/ld/testsuite/ld-csky/tls-ie.s b/ld/testsuite/ld-csky/tls-ie.s
new file mode 100644
index 0000000..36def90
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-ie.s
@@ -0,0 +1,27 @@
+ .text
+ .section .tbss,"awT",@nobits
+ .align 2
+ .type var, @object
+ .size var, 4
+var:
+ .word 0
+
+ .text
+ .align 2
+ .global _start
+ .type _start, @function
+_start:
+ subi sp, sp, 4
+ st.w l4, (sp, 0)
+ mov l4, sp
+.LTLS0:
+ lrw a3, var@GOTTPOFF
+ grs a2, .LTLS0
+ addu a3, a3, a2
+ ld.w a3, (a3, 0)
+ ldr.w a3, (r31, a3 << 0)
+ mov a0, a3
+ mov sp, l4
+ ld.w l4, (sp, 0)
+ addi sp, sp, 4
+ rts
diff --git a/ld/testsuite/ld-csky/tls-ld-v1.d b/ld/testsuite/ld-csky/tls-ld-v1.d
new file mode 100644
index 0000000..3aaa351
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-ld-v1.d
@@ -0,0 +1,29 @@
+#name: TLS Local Dynamic link test (C-SKY v1)
+#source: tls-ld-v1.s
+#as: -mcpu=ck610
+#ld: -shared --hash-style=sysv
+#readelf: -d -r
+
+Dynamic section at offset 0x[0-9a-f]+ contains 13 entries:
+ Tag Type Name/Value
+ 0x00000004 \(HASH\) .*
+ 0x00000005 \(STRTAB\) .*
+ 0x00000006 \(SYMTAB\) .*
+ 0x0000000a \(STRSZ\) .* \(bytes\)
+ 0x0000000b \(SYMENT\) .* \(bytes\)
+ 0x00000003 \(PLTGOT\) 0x[0-9a-f]+
+ 0x00000002 \(PLTRELSZ\) 12 \(bytes\)
+ 0x00000014 \(PLTREL\) RELA
+ 0x00000017 \(JMPREL\) 0x[0-9a-f]+
+ 0x00000007 \(RELA\) 0x[0-9a-f]+
+ 0x00000008 \(RELASZ\) 12 \(bytes\)
+ 0x00000009 \(RELAENT\) 12 \(bytes\)
+ 0x00000000 \(NULL\) 0x0
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entry:
+ Offset Info Type Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 00000038 R_CKCORE_TLS_DTPM 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ Offset Info Type Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 0000050c R_CKCORE_JUMP_SLO 00000000 __tls_get_addr \+ .*
diff --git a/ld/testsuite/ld-csky/tls-ld-v1.s b/ld/testsuite/ld-csky/tls-ld-v1.s
new file mode 100644
index 0000000..e0a8e76
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-ld-v1.s
@@ -0,0 +1,34 @@
+ .global __tls_get_addr
+ .text
+ .align 2
+ .global foo
+ .type foo, @function
+foo:
+ subi sp, sp, 8
+ st.w gb, (sp)
+ st.w r15, (sp, 4)
+ bsr .L2
+.L2:
+ lrw gb, .L2@GOTPC
+ addu gb, gb, r15
+ lrw r7, __tls_get_addr@PLT
+ addu r7, r7, gb
+ ld.w r7, (r7)
+ bsr .LTLS0
+.LTLS0:
+ lrw r2, var@TLSLDM32
+ addu r2, r15
+ jsr r7
+ lrw r7, var@TLSLDO32
+ addu r2, r2, r7
+ ld.w r15, (sp, 4)
+ ld.w gb, (sp)
+ addi sp, sp, 8
+ jmp r15
+ .size foo, .-foo
+ .section .tbss,"awT",@nobits
+ .align 2
+ .type var, @object
+ .size var, 4
+var:
+ .fill 4, 1
diff --git a/ld/testsuite/ld-csky/tls-ld.d b/ld/testsuite/ld-csky/tls-ld.d
new file mode 100644
index 0000000..3922152
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-ld.d
@@ -0,0 +1,28 @@
+#name: TLS Local Dynamic link test
+#source: tls-ld.s
+#ld: -shared --hash-style=sysv
+#readelf: -d -r
+
+Dynamic section at offset 0x[0-9a-f]+ contains 13 entries:
+ Tag Type Name/Value
+ 0x00000004 \(HASH\) .*
+ 0x00000005 \(STRTAB\) .*
+ 0x00000006 \(SYMTAB\) .*
+ 0x0000000a \(STRSZ\) .* \(bytes\)
+ 0x0000000b \(SYMENT\) .* \(bytes\)
+ 0x00000003 \(PLTGOT\) 0x[0-9a-f]+
+ 0x00000002 \(PLTRELSZ\) 12 \(bytes\)
+ 0x00000014 \(PLTREL\) RELA
+ 0x00000017 \(JMPREL\) 0x[0-9a-f]+
+ 0x00000007 \(RELA\) 0x[0-9a-f]+
+ 0x00000008 \(RELASZ\) 12 \(bytes\)
+ 0x00000009 \(RELAENT\) 12 \(bytes\)
+ 0x00000000 \(NULL\) 0x0
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entry:
+ Offset Info Type Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 00000038 R_CKCORE_TLS_DTPM 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ Offset Info Type Sym.Value Sym. Name \+ Addend
+[0-9a-f]+ 0000050c R_CKCORE_JUMP_SLO 00000000 __tls_get_addr \+ .*
diff --git a/ld/testsuite/ld-csky/tls-ld.s b/ld/testsuite/ld-csky/tls-ld.s
new file mode 100644
index 0000000..b9b76e2
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-ld.s
@@ -0,0 +1,29 @@
+ .text
+ .global __tls_get_addr
+ .align 2
+ .global foo
+ .type foo, @function
+foo:
+ push lr, gb
+ lrw t1, .L2@GOTPC
+ grs gb, .L2
+.L2:
+ addu gb, gb, t1
+ grs a3, .LTLS0
+.LTLS0:
+ lrw a0, .LANCHOR0@TLSLDM32
+ addu a0, a0, a3
+ lrs.w a3, [__tls_get_addr@PLT]
+ jsr a3
+ lrw a3, .LANCHOR0@TLSLDO32
+ addu a0, a0, a3
+ pop lr, gb
+ .size foo, .-foo
+ .section .tbss,"awT",@nobits
+ .align 2
+ .set .LANCHOR0,. + 0
+ .type var, @object
+ .size var, 4
+var:
+ .fill 4, 1
+
diff --git a/ld/testsuite/ld-csky/tls-le-v1.d b/ld/testsuite/ld-csky/tls-le-v1.d
new file mode 100644
index 0000000..034d5d9
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-le-v1.d
@@ -0,0 +1,14 @@
+#name: TLS Local Exec link test (C-SKY v1)
+#source: tls-le-v1.s
+#as: -mcpu=ck610
+#ld:
+#objdump: -h
+
+.*: file format .*
+
+Sections:
+Idx Name Size VMA LMA File off Algn
+ 0 .text .*
+ .*
+ 1 .tbss .*
+ .*
diff --git a/ld/testsuite/ld-csky/tls-le-v1.s b/ld/testsuite/ld-csky/tls-le-v1.s
new file mode 100644
index 0000000..b93521e
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-le-v1.s
@@ -0,0 +1,29 @@
+ .section .tbss,"awT",@nobits
+ .align 2
+ .type var, @object
+ .size var, 4
+var:
+ .fill 4, 1
+ .text
+ .align 2
+ .global _start
+ .type _start, @function
+_start:
+ subi sp, sp, 8
+ st.w r15, (sp)
+ st.w r8, (sp, 4)
+ mov r8, sp
+ bsr __read_tp
+ mov r6, r2
+ lrw r7, var@TPOFF
+ addu r7, r7, r6
+ ld.w r7, (r7)
+ mov r2, r7
+ mov sp, r8
+ ld.w r15, (sp)
+ ld.w r8, (sp, 4)
+ addi sp, sp, 8
+ jmp r15
+__read_tp:
+ movi r2, 0
+ jmp r15
diff --git a/ld/testsuite/ld-csky/tls-le.d b/ld/testsuite/ld-csky/tls-le.d
new file mode 100644
index 0000000..8a0d90f
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-le.d
@@ -0,0 +1,13 @@
+#name: TLS Local Exec link test
+#source: tls-le.s
+#ld:
+#objdump: -h
+
+.*: file format .*
+
+Sections:
+Idx Name Size VMA LMA File off Algn
+ 0 .text .*
+ .*
+ 1 .tbss .*
+ .*
diff --git a/ld/testsuite/ld-csky/tls-le.s b/ld/testsuite/ld-csky/tls-le.s
new file mode 100644
index 0000000..240a59d
--- /dev/null
+++ b/ld/testsuite/ld-csky/tls-le.s
@@ -0,0 +1,23 @@
+ .text
+ .section .tbss,"awT",@nobits
+ .align 2
+ .type var, @object
+ .size var, 4
+var:
+ .word 0
+
+ .text
+ .align 2
+ .global _start
+ .type _start, @function
+_start:
+ subi sp, sp, 4
+ st.w l4, (sp, 0)
+ mov l4, sp
+ lrw a3, var@TPOFF
+ ldr.w a3, (r31, a3 << 0)
+ mov a0, a3
+ mov sp, l4
+ ld.w l4, (sp, 0)
+ addi sp, sp, 4
+ rts
diff --git a/ld/testsuite/ld-elf/merge.d b/ld/testsuite/ld-elf/merge.d
index ebabae8..4ae1d7d 100644
--- a/ld/testsuite/ld-elf/merge.d
+++ b/ld/testsuite/ld-elf/merge.d
@@ -6,7 +6,7 @@
#xfail: "ip2k-*-*" "iq2000-*-*" "lm32-*-*"
#xfail: "mcore-*-*" "mn102*-*-*" "ms1-*-*" "mep-*-*" "m68hc11-*-*" "nios2-*-*" s12z-*-*
#xfail: "or32-*-*" "pj-*-*" "tic6x-*-*" "vax-*-*" "xstormy16-*-*"
-#xfail: "xtensa*-*-*" "metag-*-*" "ft32-*-*" "pru-*-*"
+#xfail: "xtensa*-*-*" "metag-*-*" "ft32-*-*" "pru-*-* csky-*-*"
.*: file format .*elf.*