diff -rup binutils-2.25.1.orig/ld/testsuite/ld-aarch64/aarch64-elf.exp binutils-2.25.1/ld/testsuite/ld-aarch64/aarch64-elf.exp --- binutils-2.25.1.orig/ld/testsuite/ld-aarch64/aarch64-elf.exp 2016-02-09 10:10:22.885172174 +0000 +++ binutils-2.25.1/ld/testsuite/ld-aarch64/aarch64-elf.exp 2016-02-09 10:10:31.657218088 +0000 @@ -99,6 +99,8 @@ run_dump_test "emit-relocs-309-low-bad" run_dump_test "emit-relocs-311" run_dump_test "emit-relocs-312" +run_dump_test "reloc-overflow-bad" + # test addend correctness when --emit-relocs specified for non-relocatable obj. run_dump_test "emit-relocs-local-addend" # test addend correctness when -r specified. @@ -185,9 +187,9 @@ run_dump_test "dt_textrel" set aarch64elflinktests { {"ld-aarch64/so with global symbol" "-shared" "" "" {copy-reloc-so.s} - {} "copy-reloc-so.so"} + {} "copy-reloc-so.so"} {"ld-aarch64/exe with copy relocation" "-e0 tmpdir/copy-reloc-so.so" "" "" - {copy-reloc-exe.s} {{objdump -R copy-reloc.d}} "copy-reloc"} + {copy-reloc-exe.s} {{objdump -R copy-reloc.d}} "copy-reloc"} } run_ld_link_tests $aarch64elflinktests --- /dev/null 2016-02-09 07:51:32.551961845 +0000 +++ binutils-2.25.1/ld/testsuite/ld-aarch64/reloc-overflow-bad.d 2016-02-09 10:10:31.658218093 +0000 @@ -0,0 +1,4 @@ +#source: reloc-overflow-1.s +#source: reloc-overflow-2.s +#ld: -e0 +#error: .*One possible cause.* --- /dev/null 2016-02-09 07:51:32.551961845 +0000 +++ binutils-2.25.1/ld/testsuite/ld-aarch64/reloc-overflow-1.s 2016-02-09 10:10:31.658218093 +0000 @@ -0,0 +1,14 @@ + .file "1.c" + .text + .align 2 + .p2align 3,,7 + .global dec + .arch armv8-a+fp+simd + //.tune generic + .type dec, %function +dec: + adrp x0, var_2 + ldr w0, [x0, #:lo12:var_2] + ret + .size dec, .-dec + .ident "GCC: (GNU) 6.0.0 20160208 (experimental) [trunk revision 233206]" --- /dev/null 2016-02-09 07:51:32.551961845 +0000 +++ binutils-2.25.1/ld/testsuite/ld-aarch64/reloc-overflow-2.s 2016-02-09 10:10:31.658218093 +0000 @@ -0,0 +1,5 @@ + .file "2.c" + .comm var_3,1,1 + .comm var_2,1,1 + .comm var_1,1,1 + .ident "GCC: (GNU) 6.0.0 20160208 (experimental) [trunk revision 233206]" --- binutils-2.25.1.orig/bfd/elfnn-aarch64.c 2016-02-09 10:10:22.528170305 +0000 +++ binutils-2.25.1/bfd/elfnn-aarch64.c 2016-02-09 10:21:25.663638222 +0000 @@ -5134,10 +5134,6 @@ elfNN_aarch64_relocate_section (bfd *out break; } - if (!save_addend) - addend = 0; - - /* Dynamic relocs are not propagated for SEC_DEBUGGING sections because such sections are not SEC_ALLOC and thus ld.so will not process them. */ @@ -5157,6 +5153,9 @@ elfNN_aarch64_relocate_section (bfd *out if (r != bfd_reloc_ok && r != bfd_reloc_continue) { + bfd_reloc_code_real_type real_r_type + = elfNN_aarch64_bfd_reloc_from_type (r_type); + switch (r) { case bfd_reloc_overflow: @@ -5170,6 +5169,35 @@ elfNN_aarch64_relocate_section (bfd *out (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))) return FALSE; + + /* Overflow can occur when a variable is referenced with a type + that has a larger alignment than the type with which it was + declared. eg: + file1.c: extern int foo; int a (void) { return foo; } + file2.c: char bar, foo, baz; + If the variable is placed into a data section at an offset + that is incompatible with the larger alignment requirement + overflow will occur. (Strictly speaking this is not overflow + but rather an alignment problem, but the bfd_reloc_ error + enum does not have a value to cover that situation). + + Try to catch this situation here and provide a more helpful + error message to the user. */ + if (addend & ((1 << howto->rightshift) - 1) + /* FIXME: Are we testing all of the appropriate reloc + types here ? */ + && (real_r_type == BFD_RELOC_AARCH64_LD_LO19_PCREL + || real_r_type == BFD_RELOC_AARCH64_LDST16_LO12 + || real_r_type == BFD_RELOC_AARCH64_LDST32_LO12 + || real_r_type == BFD_RELOC_AARCH64_LDST64_LO12 + || real_r_type == BFD_RELOC_AARCH64_LDST128_LO12)) + { + info->callbacks->warning + (info, _("One possible cause of this error is that the \ +symbol is being referenced in the indicated code as if it had a larger \ +alignment than was declared where it was defined."), + name, input_bfd, input_section, rel->r_offset); + } break; case bfd_reloc_undefined: @@ -5204,6 +5232,9 @@ elfNN_aarch64_relocate_section (bfd *out break; } } + + if (!save_addend) + addend = 0; } return TRUE; @@ -7777,7 +7808,6 @@ elfNN_aarch64_finish_dynamic_sections (b bfd_elfNN_swap_dyn_out (output_bfd, &dyn, dyncon); } - } /* Fill in the special first entry in the procedure linkage table. */