From 8769bc4bab847cefc2bb5682a0a0dad579528ac8 Mon Sep 17 00:00:00 2001 From: Han Shen Date: Tue, 26 Jul 2016 08:49:12 -0700 Subject: [PATCH] [Gold, aarch64] Implement some AArch64 relocs. This CL implemented the following relocs for AArch64 target. - R_AARCH64_MOVW_UABS_G* - R_AARCH64_MOVW_SABS_G* relocations gold/ChangeLog 2016-07-26 Igor Kudrin * aarch64-reloc-property.cc (Rvalue_bit_select_impl): New class. (rvalue_bit_select): Use Rvalue_bit_select_impl. * aarch64-reloc.def (MOVW_UABS_G0, MOVW_UABS_G0_NC, MOVW_UABS_G1, MOVW_UABS_G1_NC, MOVW_UABS_G2, MOVW_UABS_G2_NC, MOVW_UABS_G3, MOVW_SABS_G0, MOVW_SABS_G1, MOVW_SABS_G2): New relocations. * aarch64.cc (Target_aarch64::Scan::local): Add cases for new MOVW_UABS_* and MOVW_SABS_* relocations. (Target_aarch64::Scan::global): Likewise. (Target_aarch64::Relocate::relocate): Add cases and handlings for new MOVW_UABS_* and MOVW_SABS_* relocations. * testsuite/Makefile.am (aarch64_relocs): New test. * testsuite/Makefile.in: Regenerate. * testsuite/aarch64_globals.s: New test source file. * testsuite/aarch64_relocs.s: Likewise. * testsuite/aarch64_relocs.sh: New test script. --- gold/aarch64-reloc-property.cc | 46 +++++++++++-- gold/aarch64-reloc.def | 14 ++++ gold/aarch64.cc | 51 ++++++++++++++ gold/testsuite/Makefile.am | 13 ++++ gold/testsuite/Makefile.in | 19 +++++- gold/testsuite/aarch64_globals.s | 11 ++++ gold/testsuite/aarch64_relocs.s | 45 +++++++++++++ gold/testsuite/aarch64_relocs.sh | 110 +++++++++++++++++++++++++++++++ 8 files changed, 300 insertions(+), 9 deletions(-) create mode 100644 gold/testsuite/aarch64_globals.s create mode 100644 gold/testsuite/aarch64_relocs.s create mode 100644 gold/testsuite/aarch64_relocs.sh diff --git a/gold/aarch64-reloc-property.cc b/gold/aarch64-reloc-property.cc index bf521d72df8..d0dee406d55 100644 --- a/gold/aarch64-reloc-property.cc +++ b/gold/aarch64-reloc-property.cc @@ -59,18 +59,52 @@ template<> bool rvalue_checkup<0, 0>(int64_t) { return true; } +namespace +{ + +template +class Rvalue_bit_select_impl +{ +public: + static uint64_t + calc(uint64_t x) + { + return (x & ((1ULL << (U+1)) - 1)) >> L; + } +}; + +template +class Rvalue_bit_select_impl +{ +public: + static uint64_t + calc(uint64_t x) + { + return x >> L; + } +}; + +// By our convention, L=U=0 means that the whole value should be retrieved. +template<> +class Rvalue_bit_select_impl<0, 0> +{ +public: + static uint64_t + calc(uint64_t x) + { + return x; + } +}; + +} // End anonymous namespace. + template uint64_t rvalue_bit_select(uint64_t x) { - if (U == 63) return x >> L; - return (x & (((uint64_t)1 << (U+1)) - 1)) >> L; + return Rvalue_bit_select_impl::calc(x); } -template<> -uint64_t -rvalue_bit_select<0, 0>(uint64_t x) { return x; } - AArch64_reloc_property::AArch64_reloc_property( unsigned int code, const char* name, diff --git a/gold/aarch64-reloc.def b/gold/aarch64-reloc.def index 763d372c67e..6d2981d0b81 100644 --- a/gold/aarch64-reloc.def +++ b/gold/aarch64-reloc.def @@ -43,6 +43,20 @@ ARD(PREL32 , STATIC , DATA , Y, -1, 31,32 ARD(PREL16 , STATIC , DATA , Y, -1, 15,16 , 0,0 , Symbol::RELATIVE_REF , DATA ) // Above is from Table 4-6, Data relocations, 257-262. +ARD(MOVW_UABS_G0 , STATIC , AARCH64 , Y, 0, 0,16 , 0,15 , Symbol::ABSOLUTE_REF , MOVW ) +ARD(MOVW_UABS_G0_NC , STATIC , AARCH64 , Y, 0, 0,0 , 0,15 , Symbol::ABSOLUTE_REF , MOVW ) +ARD(MOVW_UABS_G1 , STATIC , AARCH64 , Y, 0, 0,32 , 16,31 , Symbol::ABSOLUTE_REF , MOVW ) +ARD(MOVW_UABS_G1_NC , STATIC , AARCH64 , Y, 0, 0,0 , 16,31 , Symbol::ABSOLUTE_REF , MOVW ) +ARD(MOVW_UABS_G2 , STATIC , AARCH64 , Y, 0, 0,48 , 32,47 , Symbol::ABSOLUTE_REF , MOVW ) +ARD(MOVW_UABS_G2_NC , STATIC , AARCH64 , Y, 0, 0,0 , 32,47 , Symbol::ABSOLUTE_REF , MOVW ) +ARD(MOVW_UABS_G3 , STATIC , AARCH64 , Y, 0, 0,0 , 48,63 , Symbol::ABSOLUTE_REF , MOVW ) +// Above is from Table 4-7, Group relocations to create a 16-, 32-, 48-, or 64-bit unsigned data value or address inline. + +ARD(MOVW_SABS_G0 , STATIC , AARCH64 , Y, 0, 16,16 , 0,15 , Symbol::ABSOLUTE_REF , MOVW ) +ARD(MOVW_SABS_G1 , STATIC , AARCH64 , Y, 0, 32,32 , 16,31 , Symbol::ABSOLUTE_REF , MOVW ) +ARD(MOVW_SABS_G2 , STATIC , AARCH64 , Y, 0, 48,48 , 32,47 , Symbol::ABSOLUTE_REF , MOVW ) +// Above is from Table 4-8, Group relocations to create a 16, 32, 48, or 64 bit signed data or offset value inline. + ARD(LD_PREL_LO19 , STATIC , AARCH64 , Y, -1, 20,20 , 2,20 , Symbol::RELATIVE_REF , LDST ) ARD(ADR_PREL_LO21 , STATIC , AARCH64 , Y, -1, 20,20 , 0,20 , Symbol::RELATIVE_REF , ADR ) ARD(ADR_PREL_PG_HI21 , STATIC , AARCH64 , Y, -1, 32,32 , 12,32 , Symbol::RELATIVE_REF , ADRP ) diff --git a/gold/aarch64.cc b/gold/aarch64.cc index db9f06c1c67..ab7e56316f6 100644 --- a/gold/aarch64.cc +++ b/gold/aarch64.cc @@ -6026,6 +6026,23 @@ Target_aarch64::Scan::local( } break; + case elfcpp::R_AARCH64_MOVW_UABS_G0: // 263 + case elfcpp::R_AARCH64_MOVW_UABS_G0_NC: // 264 + case elfcpp::R_AARCH64_MOVW_UABS_G1: // 265 + case elfcpp::R_AARCH64_MOVW_UABS_G1_NC: // 266 + case elfcpp::R_AARCH64_MOVW_UABS_G2: // 267 + case elfcpp::R_AARCH64_MOVW_UABS_G2_NC: // 268 + case elfcpp::R_AARCH64_MOVW_UABS_G3: // 269 + case elfcpp::R_AARCH64_MOVW_SABS_G0: // 270 + case elfcpp::R_AARCH64_MOVW_SABS_G1: // 271 + case elfcpp::R_AARCH64_MOVW_SABS_G2: // 272 + if (parameters->options().output_is_position_independent()) + { + gold_error(_("%s: unsupported reloc %u in pos independent link."), + object->name().c_str(), r_type); + } + break; + case elfcpp::R_AARCH64_LD_PREL_LO19: // 273 case elfcpp::R_AARCH64_ADR_PREL_LO21: // 274 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21: // 275 @@ -6311,6 +6328,23 @@ Target_aarch64::Scan::global( } break; + case elfcpp::R_AARCH64_MOVW_UABS_G0: // 263 + case elfcpp::R_AARCH64_MOVW_UABS_G0_NC: // 264 + case elfcpp::R_AARCH64_MOVW_UABS_G1: // 265 + case elfcpp::R_AARCH64_MOVW_UABS_G1_NC: // 266 + case elfcpp::R_AARCH64_MOVW_UABS_G2: // 267 + case elfcpp::R_AARCH64_MOVW_UABS_G2_NC: // 268 + case elfcpp::R_AARCH64_MOVW_UABS_G3: // 269 + case elfcpp::R_AARCH64_MOVW_SABS_G0: // 270 + case elfcpp::R_AARCH64_MOVW_SABS_G1: // 271 + case elfcpp::R_AARCH64_MOVW_SABS_G2: // 272 + if (parameters->options().output_is_position_independent()) + { + gold_error(_("%s: unsupported reloc %u in pos independent link."), + object->name().c_str(), r_type); + } + break; + case elfcpp::R_AARCH64_LD_PREL_LO19: // 273 case elfcpp::R_AARCH64_ADR_PREL_LO21: // 274 case elfcpp::R_AARCH64_ADR_PREL_PG_HI21: // 275 @@ -6993,6 +7027,23 @@ Target_aarch64::Relocate::relocate( view, object, psymval, addend, address, reloc_property); break; + case elfcpp::R_AARCH64_MOVW_UABS_G0: + case elfcpp::R_AARCH64_MOVW_UABS_G0_NC: + case elfcpp::R_AARCH64_MOVW_UABS_G1: + case elfcpp::R_AARCH64_MOVW_UABS_G1_NC: + case elfcpp::R_AARCH64_MOVW_UABS_G2: + case elfcpp::R_AARCH64_MOVW_UABS_G2_NC: + case elfcpp::R_AARCH64_MOVW_UABS_G3: + reloc_status = Reloc::template rela_general<32>( + view, object, psymval, addend, reloc_property); + break; + case elfcpp::R_AARCH64_MOVW_SABS_G0: + case elfcpp::R_AARCH64_MOVW_SABS_G1: + case elfcpp::R_AARCH64_MOVW_SABS_G2: + reloc_status = Reloc::movnz(view, psymval->value(object, addend), + reloc_property); + break; + case elfcpp::R_AARCH64_LD_PREL_LO19: reloc_status = Reloc::template pcrela_general<32>( view, object, psymval, addend, address, reloc_property); diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index c8d30934d70..39f9e9efcdb 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -3619,6 +3619,19 @@ aarch64_reloc_none.stdout: aarch64_reloc_none MOSTLYCLEANFILES += aarch64_reloc_none +check_SCRIPTS += aarch64_relocs.sh +check_DATA += aarch64_relocs.stdout +aarch64_globals.o: aarch64_globals.s + $(TEST_AS) -o $@ $< +aarch64_relocs.o: aarch64_relocs.s + $(TEST_AS) -o $@ $< +aarch64_relocs: aarch64_relocs.o aarch64_globals.o ../ld-new + ../ld-new -o $@ aarch64_relocs.o aarch64_globals.o -e0 --emit-relocs +aarch64_relocs.stdout: aarch64_relocs + $(TEST_OBJDUMP) -dr $< > $@ + +MOSTLYCLEANFILES += aarch64_relocs + endif DEFAULT_TARGET_AARCH64 if DEFAULT_TARGET_S390 diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index 4185287d03e..bd58d134420 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -909,9 +909,12 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_thumb_6m \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_arm \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_arm_5t -@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_94 = aarch64_reloc_none.sh -@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_95 = aarch64_reloc_none.stdout -@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_96 = aarch64_reloc_none +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_94 = aarch64_reloc_none.sh \ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ aarch64_relocs.sh +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_95 = aarch64_reloc_none.stdout \ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ aarch64_relocs.stdout +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_96 = aarch64_reloc_none \ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ aarch64_relocs @DEFAULT_TARGET_S390_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_97 = split_s390.sh @DEFAULT_TARGET_S390_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_98 = split_s390_z1.stdout split_s390_z2.stdout split_s390_z3.stdout \ @DEFAULT_TARGET_S390_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ split_s390_z4.stdout split_s390_n1.stdout split_s390_n2.stdout \ @@ -5148,6 +5151,8 @@ arm_farcall_thumb_arm.sh.log: arm_farcall_thumb_arm.sh @p='arm_farcall_thumb_arm.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) aarch64_reloc_none.sh.log: aarch64_reloc_none.sh @p='aarch64_reloc_none.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) +aarch64_relocs.sh.log: aarch64_relocs.sh + @p='aarch64_relocs.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) split_s390.sh.log: split_s390.sh @p='split_s390.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) dwp_test_1.sh.log: dwp_test_1.sh @@ -7587,6 +7592,14 @@ uninstall-am: @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new -o $@ aarch64_reloc_none.o --gc-sections @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@aarch64_reloc_none.stdout: aarch64_reloc_none @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_NM) $< > $@ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@aarch64_globals.o: aarch64_globals.s +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@aarch64_relocs.o: aarch64_relocs.s +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@aarch64_relocs: aarch64_relocs.o aarch64_globals.o ../ld-new +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new -o $@ aarch64_relocs.o aarch64_globals.o -e0 --emit-relocs +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@aarch64_relocs.stdout: aarch64_relocs +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -dr $< > $@ @DEFAULT_TARGET_S390_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_s390_1_z1.o: split_s390_1_z1.s @DEFAULT_TARGET_S390_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -m31 -o $@ $< @DEFAULT_TARGET_S390_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_s390_1_z2.o: split_s390_1_z2.s diff --git a/gold/testsuite/aarch64_globals.s b/gold/testsuite/aarch64_globals.s new file mode 100644 index 00000000000..f6a18970356 --- /dev/null +++ b/gold/testsuite/aarch64_globals.s @@ -0,0 +1,11 @@ +.global abs_0x1234 +abs_0x1234=0x1234 + +.global abs_0x11000 +abs_0x11000=0x11000 + +.global abs_0x45000 +abs_0x45000=0x45000 + +.global abs_0x3600010000 +abs_0x3600010000=0x3600010000 diff --git a/gold/testsuite/aarch64_relocs.s b/gold/testsuite/aarch64_relocs.s new file mode 100644 index 00000000000..0aa3d68f1a7 --- /dev/null +++ b/gold/testsuite/aarch64_relocs.s @@ -0,0 +1,45 @@ +.text + +test_R_AARCH64_MOVW_UABS_G0: + movz x4, :abs_g0:abs_0x1234 + movz x4, :abs_g0:abs_0x1234 + 4 + +test_R_AARCH64_MOVW_UABS_G0_NC: + movz x4, :abs_g0_nc:abs_0x1234 + movz x4, :abs_g0_nc:abs_0x1234 + 0x45000 + +test_R_AARCH64_MOVW_UABS_G1: + movz x4, :abs_g1:abs_0x1234 - 4 + movz x4, :abs_g1:abs_0x11000 + movz x4, :abs_g1:abs_0x45000 + 0x20010 + +test_R_AARCH64_MOVW_UABS_G1_NC: + movz x4, :abs_g1_nc:abs_0x1234 - 4 + movz x4, :abs_g1_nc:abs_0x11000 + movz x4, :abs_g1_nc:abs_0x45000 + 0x100020010 + +test_R_AARCH64_MOVW_UABS_G2: + movz x4, :abs_g2:abs_0x45000 + 0x20010 + movz x4, :abs_g2:abs_0x3600010000 + 0x100020010 + +test_R_AARCH64_MOVW_UABS_G2_NC: + movz x4, :abs_g2_nc:abs_0x45000 + 0x20010 + movz x4, :abs_g2_nc:abs_0x3600010000 + 0x3000100020010 + +test_R_AARCH64_MOVW_UABS_G3: + movz x4, :abs_g3:abs_0x3600010000 + 0x100020010 + movz x4, :abs_g3:abs_0x3600010000 + 0x3000100020010 + +test_R_AARCH64_MOVW_SABS_G0: + movz x4, :abs_g0_s:abs_0x1234 + 4 + movz x4, :abs_g0_s:abs_0x1234 - 0x2345 + +test_R_AARCH64_MOVW_SABS_G1: + movz x4, :abs_g1_s:abs_0x1234 - 0x2345 + movz x4, :abs_g1_s:abs_0x45000 + 0x20010 + movz x4, :abs_g1_s:abs_0x45000 - 0x56000 + +test_R_AARCH64_MOVW_SABS_G2: + movz x4, :abs_g2_s:abs_0x45000 + 0x20010 + movz x4, :abs_g2_s:abs_0x3600010000 + 0x100020010 + movz x4, :abs_g2_s:abs_0x3600010000 - 0x4400010000 diff --git a/gold/testsuite/aarch64_relocs.sh b/gold/testsuite/aarch64_relocs.sh new file mode 100644 index 00000000000..f23c58f7827 --- /dev/null +++ b/gold/testsuite/aarch64_relocs.sh @@ -0,0 +1,110 @@ +#!/bin/sh + +# aarch64_relocs.sh -- test AArch64 relocations. + +# Copyright (C) 2016 Free Software Foundation, Inc. +# Written by Igor Kudrin + +# This file is part of gold. + +# 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. + +check() +{ + file=$1 + lbl=$2 + line=$3 + pattern=$4 + + found=`grep "<$lbl>:" $file` + if test -z "$found"; then + echo "Label $lbl not found." + exit 1 + fi + + match_pattern=`grep "<$lbl>:" -A$line $file | tail -n 1 | grep -e "$pattern"` + if test -z "$match_pattern"; then + echo "Expected pattern did not found in line $line after label $lbl:" + echo " $pattern" + echo "" + echo "Extract:" + grep "<$lbl>:" -A$line $file + echo "" + echo "Actual output below:" + cat "$file" + exit 1 + fi +} + +check "aarch64_relocs.stdout" "test_R_AARCH64_MOVW_UABS_G0" 1 "\