2011-07-05 Doug Kwan <dougkwan@google.com>
PR gold/12771 * arm.cc (Arm_relocate_functions::abs8): Use int32_t for addend and Arm_Address type for relocation result. (Arm_relocate_functions::abs16): Use unaligned access. Also fix overflow check. (Arm_relocate_functions::abs32): Use unaligned access. (Arm_relocate_functions::rel32): Ditto. (Arm_relocate_functions::prel31): Ditto. (Arm_exidix_cantunwind::do_fixed_endian_write): Ditto. * testsuite/Makefile.am: Add new test arm_unaligned_reloc for unaligned static data relocations. * testsuite/Makefile.in: Regnerate. * testsuite/arm_unaligned_reloc.{s,sh}: New files.
This commit is contained in:
parent
8f7ae68682
commit
f6cccc2cd8
6 changed files with 166 additions and 29 deletions
|
@ -1,3 +1,19 @@
|
|||
2011-07-05 Doug Kwan <dougkwan@google.com>
|
||||
|
||||
PR gold/12771
|
||||
* arm.cc (Arm_relocate_functions::abs8): Use int32_t for addend and
|
||||
Arm_Address type for relocation result.
|
||||
(Arm_relocate_functions::abs16): Use unaligned access. Also fix
|
||||
overflow check.
|
||||
(Arm_relocate_functions::abs32): Use unaligned access.
|
||||
(Arm_relocate_functions::rel32): Ditto.
|
||||
(Arm_relocate_functions::prel31): Ditto.
|
||||
(Arm_exidix_cantunwind::do_fixed_endian_write): Ditto.
|
||||
* testsuite/Makefile.am: Add new test arm_unaligned_reloc for unaligned
|
||||
static data relocations.
|
||||
* testsuite/Makefile.in: Regnerate.
|
||||
* testsuite/arm_unaligned_reloc.{s,sh}: New files.
|
||||
|
||||
2011-07-05 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
PR gold/12392
|
||||
|
|
51
gold/arm.cc
51
gold/arm.cc
|
@ -3215,11 +3215,10 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian>
|
|||
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);
|
||||
|
||||
|
@ -3277,15 +3276,17 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian>
|
|||
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);
|
||||
}
|
||||
|
@ -3297,11 +3298,10 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian>
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -3313,11 +3313,10 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian>
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -3435,13 +3434,12 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian>
|
|||
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);
|
||||
}
|
||||
|
@ -5221,8 +5219,7 @@ Arm_exidx_cantunwind::do_fixed_endian_write(Output_file* of)
|
|||
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);
|
||||
|
@ -5263,8 +5260,10 @@ Arm_exidx_cantunwind::do_fixed_endian_write(Output_file* of)
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -2343,6 +2343,20 @@ pr12826_1.o: pr12826_1.s
|
|||
pr12826_2.o: pr12826_2.s
|
||||
$(TEST_AS) -o $@ $<
|
||||
|
||||
check_SCRIPTS += arm_unaligned_reloc.sh
|
||||
check_DATA += arm_unaligned_reloc.stdout
|
||||
|
||||
arm_unaligned_reloc.stdout: arm_unaligned_reloc
|
||||
$(TEST_OBJDUMP) -D $< > $@
|
||||
|
||||
arm_unaligned_reloc: arm_unaligned_reloc.o ../ld-new
|
||||
../ld-new -o $@ $<
|
||||
|
||||
arm_unaligned_reloc.o: arm_unaligned_reloc.s
|
||||
$(TEST_AS) -o $@ $<
|
||||
|
||||
MOSTLYCLEANFILES += arm_unaligned_reloc
|
||||
|
||||
endif DEFAULT_TARGET_ARM
|
||||
|
||||
endif NATIVE_OR_CROSS_LINKER
|
||||
|
|
|
@ -492,7 +492,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
|||
@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 \
|
||||
|
@ -520,7 +521,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
|||
@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 \
|
||||
|
@ -546,7 +548,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
|||
@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
|
||||
|
@ -3529,6 +3532,8 @@ arm_exidx_test.sh.log: arm_exidx_test.sh
|
|||
@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)
|
||||
|
@ -5121,6 +5126,15 @@ uninstall-am:
|
|||
@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:
|
||||
|
|
44
gold/testsuite/arm_unaligned_reloc.s
Normal file
44
gold/testsuite/arm_unaligned_reloc.s
Normal file
|
@ -0,0 +1,44 @@
|
|||
.syntax unified
|
||||
|
||||
.global _start
|
||||
.type _start, %function
|
||||
.text
|
||||
_start:
|
||||
bx lr
|
||||
.size _start,.-_start
|
||||
|
||||
.section .data.0,"aw",%progbits
|
||||
.align 12
|
||||
.type x, %object
|
||||
.size x, 4
|
||||
x:
|
||||
.word 1
|
||||
|
||||
.section .data.1,"aw",%progbits
|
||||
.align 2
|
||||
|
||||
# This causes following relocations to be unaligned.
|
||||
.global padding
|
||||
.type padding, %object
|
||||
.size padding, 1
|
||||
padding:
|
||||
.byte 0
|
||||
|
||||
.global abs32
|
||||
.type abs32, %object
|
||||
.size abs32, 4
|
||||
abs32:
|
||||
.word x
|
||||
|
||||
.global rel32
|
||||
.type rel32, %object
|
||||
.size rel32, 4
|
||||
rel32:
|
||||
.word x - .
|
||||
|
||||
.global abs16
|
||||
.type abs16, %object
|
||||
.size abs16, 2
|
||||
abs16:
|
||||
.short x
|
||||
.short 0
|
50
gold/testsuite/arm_unaligned_reloc.sh
Executable file
50
gold/testsuite/arm_unaligned_reloc.sh
Executable file
|
@ -0,0 +1,50 @@
|
|||
#!/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
|
Loading…
Reference in a new issue