const Symbol_value<32>* psymval)
{
typedef typename elfcpp::Swap<8, big_endian>::Valtype Valtype;
- typedef typename elfcpp::Swap<32, big_endian>::Valtype Reltype;
Valtype* wv = reinterpret_cast<Valtype*>(view);
Valtype val = elfcpp::Swap<8, big_endian>::readval(wv);
- Reltype addend = utils::sign_extend<8>(val);
- Reltype x = psymval->value(object, addend);
+ int32_t addend = utils::sign_extend<8>(val);
+ Arm_address x = psymval->value(object, addend);
val = utils::bit_select(val, x, 0xffU);
elfcpp::Swap<8, big_endian>::writeval(wv, val);
const Sized_relobj_file<32, big_endian>* object,
const Symbol_value<32>* psymval)
{
- typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
+ typedef typename elfcpp::Swap_unaligned<16, big_endian>::Valtype Valtype;
typedef typename elfcpp::Swap<32, big_endian>::Valtype Reltype;
- Valtype* wv = reinterpret_cast<Valtype*>(view);
- Valtype val = elfcpp::Swap<16, big_endian>::readval(wv);
- Reltype addend = utils::sign_extend<16>(val);
- Reltype x = psymval->value(object, addend);
+ Valtype val = elfcpp::Swap_unaligned<16, big_endian>::readval(view);
+ int32_t addend = utils::sign_extend<16>(val);
+ Arm_address x = psymval->value(object, addend);
val = utils::bit_select(val, x, 0xffffU);
- elfcpp::Swap<16, big_endian>::writeval(wv, val);
- return (utils::has_signed_unsigned_overflow<16>(x)
+ elfcpp::Swap_unaligned<16, big_endian>::writeval(view, val);
+
+ // R_ARM_ABS16 permits signed or unsigned results.
+ int signed_x = static_cast<int32_t>(x);
+ return ((signed_x < -32768 || signed_x > 65536)
? This::STATUS_OVERFLOW
: This::STATUS_OKAY);
}
const Symbol_value<32>* psymval,
Arm_address thumb_bit)
{
- typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
- Valtype* wv = reinterpret_cast<Valtype*>(view);
- Valtype addend = elfcpp::Swap<32, big_endian>::readval(wv);
+ typedef typename elfcpp::Swap_unaligned<32, big_endian>::Valtype Valtype;
+ Valtype addend = elfcpp::Swap_unaligned<32, big_endian>::readval(view);
Valtype x = psymval->value(object, addend) | thumb_bit;
- elfcpp::Swap<32, big_endian>::writeval(wv, x);
+ elfcpp::Swap_unaligned<32, big_endian>::writeval(view, x);
return This::STATUS_OKAY;
}
Arm_address address,
Arm_address thumb_bit)
{
- typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
- Valtype* wv = reinterpret_cast<Valtype*>(view);
- Valtype addend = elfcpp::Swap<32, big_endian>::readval(wv);
+ typedef typename elfcpp::Swap_unaligned<32, big_endian>::Valtype Valtype;
+ Valtype addend = elfcpp::Swap_unaligned<32, big_endian>::readval(view);
Valtype x = (psymval->value(object, addend) | thumb_bit) - address;
- elfcpp::Swap<32, big_endian>::writeval(wv, x);
+ elfcpp::Swap_unaligned<32, big_endian>::writeval(view, x);
return This::STATUS_OKAY;
}
Arm_address address,
Arm_address thumb_bit)
{
- typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
- Valtype* wv = reinterpret_cast<Valtype*>(view);
- Valtype val = elfcpp::Swap<32, big_endian>::readval(wv);
+ typedef typename elfcpp::Swap_unaligned<32, big_endian>::Valtype Valtype;
+ Valtype val = elfcpp::Swap_unaligned<32, big_endian>::readval(view);
Valtype addend = utils::sign_extend<31>(val);
Valtype x = (psymval->value(object, addend) | thumb_bit) - address;
val = utils::bit_select(val, x, 0x7fffffffU);
- elfcpp::Swap<32, big_endian>::writeval(wv, val);
+ elfcpp::Swap_unaligned<32, big_endian>::writeval(view, val);
return (utils::has_overflow<31>(x) ?
This::STATUS_OVERFLOW : This::STATUS_OKAY);
}
const section_size_type oview_size = 8;
unsigned char* const oview = of->get_output_view(offset, oview_size);
- typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
- Valtype* wv = reinterpret_cast<Valtype*>(oview);
+ typedef typename elfcpp::Swap_unaligned<32, big_endian>::Valtype Valtype;
Output_section* os = this->relobj_->output_section(this->shndx_);
gold_assert(os != NULL);
uint32_t prel31_offset = output_address - this->address();
if (utils::has_overflow<31>(offset))
gold_error(_("PREL31 overflow in EXIDX_CANTUNWIND entry"));
- elfcpp::Swap<32, big_endian>::writeval(wv, prel31_offset & 0x7fffffffU);
- elfcpp::Swap<32, big_endian>::writeval(wv + 1, elfcpp::EXIDX_CANTUNWIND);
+ elfcpp::Swap_unaligned<32, big_endian>::writeval(oview,
+ prel31_offset & 0x7fffffffU);
+ elfcpp::Swap_unaligned<32, big_endian>::writeval(oview + 4,
+ elfcpp::EXIDX_CANTUNWIND);
of->write_output_view(this->offset(), oview_size, oview);
}
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_attr_merge.sh \
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_cortex_a8.sh \
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_exidx_test.sh \
-@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ pr12826.sh
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ pr12826.sh \
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_unaligned_reloc.sh
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_65 = arm_abs_global.stdout \
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_bl_in_range.stdout \
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_bl_out_of_range.stdout \
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_cortex_a8_local.stdout \
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_cortex_a8_local_reloc.stdout \
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_exidx_test.stdout \
-@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ pr12826.stdout
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ pr12826.stdout \
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_unaligned_reloc.stdout
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_66 = arm_abs_global \
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_bl_in_range \
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_bl_out_of_range \
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_cortex_a8_bl \
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_cortex_a8_blx \
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_cortex_a8_local \
-@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_cortex_a8_local_reloc
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_cortex_a8_local_reloc \
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_unaligned_reloc
subdir = testsuite
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@p='arm_exidx_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
pr12826.sh.log: pr12826.sh
@p='pr12826.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+arm_unaligned_reloc.sh.log: arm_unaligned_reloc.sh
+ @p='arm_unaligned_reloc.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
object_unittest.log: object_unittest$(EXEEXT)
@p='object_unittest$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
binary_unittest.log: binary_unittest$(EXEEXT)
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@pr12826_2.o: pr12826_2.s
@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $<
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_unaligned_reloc.stdout: arm_unaligned_reloc
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -D $< > $@
+
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_unaligned_reloc: arm_unaligned_reloc.o ../ld-new
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new -o $@ $<
+
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_unaligned_reloc.o: arm_unaligned_reloc.s
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $<
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
--- /dev/null
+#!/bin/sh
+
+# arm_unaligned_reloc.sh -- test ARM unaligned static data relocations.
+
+# Copyright 2011 Free Software Foundation, Inc.
+# Written by Doug Kwan <dougkwan@google.com>
+
+# 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.
+
+# This file goes with the assembler source file arm_unaligned_reloc.s,
+# that is assembled and linked as a dummy executable. We want to check
+# it is okay to do unaligned static data relocations.
+
+check()
+{
+ if ! grep -q -e "$2" "$1"
+ then
+ echo "Did not find pattern \"$2\" in $1:"
+ echo " $2"
+ echo ""
+ echo "Actual disassembly below:"
+ cat "$1"
+ exit 1
+ fi
+}
+
+check arm_unaligned_reloc.stdout "^00009000 <x>:$"
+check arm_unaligned_reloc.stdout "^0000a001 <abs32>:$"
+check arm_unaligned_reloc.stdout "^ a001: 00009000 .*$"
+check arm_unaligned_reloc.stdout "^0000a005 <rel32>:"
+check arm_unaligned_reloc.stdout "^ a005: ffffeffb .*$"
+check arm_unaligned_reloc.stdout "^0000a009 <abs16>:"
+check arm_unaligned_reloc.stdout "^ a009: 00009000 .*$"
+
+exit 0