diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 74cdda4ffa..b29b2ee98d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +2019-10-17 Nelson Chu + + * elfnn-riscv.c (riscv_elf_relocate_section): Report the error message + that user should recompile their code with `fPIC` when linking non-pic + code into shared library. + + * elfnn-riscv.c (riscv_elf_relocate_section): Use asprintf to extend + the error message if needed, and then store the result into the + `msg_buf`. Finally, remember to free the unused `msg_buf`. All error + message for the dangerous relocation should be set before we call the + callback function. If we miss the error message since linker runs out + of memory, we should set the default error message for the error. + 2019-10-16 Alan Modra PR 13616 diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 4ffe6a36e6..6be209e239 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -1787,6 +1787,7 @@ riscv_elf_relocate_section (bfd *output_bfd, int r_type = ELFNN_R_TYPE (rel->r_info), tls_type; reloc_howto_type *howto = riscv_elf_rtype_to_howto (input_bfd, r_type); const char *msg = NULL; + char *msg_buf = NULL; bfd_boolean resolved_to_zero; if (howto == NULL @@ -2088,6 +2089,7 @@ riscv_elf_relocate_section (bfd *output_bfd, || (h != NULL && h->type == STT_SECTION)) && rel->r_addend) { + msg = _("%pcrel_lo section symbol with an addend"); r = bfd_reloc_dangerous; break; } @@ -2302,24 +2304,42 @@ riscv_elf_relocate_section (bfd *output_bfd, && _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset) != (bfd_vma) -1) { - (*_bfd_error_handler) - (_("%pB(%pA+%#" PRIx64 "): " - "unresolvable %s relocation against symbol `%s'"), - input_bfd, - input_section, - (uint64_t) rel->r_offset, - howto->name, - h->root.root.string); + switch (r_type) + { + case R_RISCV_CALL: + case R_RISCV_JAL: + case R_RISCV_RVC_JUMP: + if (asprintf (&msg_buf, + _("%%X%%P: relocation %s against `%s' can " + "not be used when making a shared object; " + "recompile with -fPIC\n"), + howto->name, + h->root.root.string) == -1) + msg_buf = NULL; + break; - bfd_set_error (bfd_error_bad_value); - ret = FALSE; - goto out; + default: + if (asprintf (&msg_buf, + _("%%X%%P: unresolvable %s relocation against " + "symbol `%s'\n"), + howto->name, + h->root.root.string) == -1) + msg_buf = NULL; + break; + } + + msg = msg_buf; + r = bfd_reloc_notsupported; } if (r == bfd_reloc_ok) r = perform_relocation (howto, rel, relocation, input_section, input_bfd, contents); + /* We should have already detected the error and set message before. + If the error message isn't set since the linker runs out of memory + or we don't set it before, then we should set the default message + with the "internal error" string here. */ switch (r) { case bfd_reloc_ok: @@ -2338,17 +2358,21 @@ riscv_elf_relocate_section (bfd *output_bfd, break; case bfd_reloc_outofrange: - msg = _("%X%P: internal error: out of range error\n"); + if (msg == NULL) + msg = _("%X%P: internal error: out of range error\n"); break; case bfd_reloc_notsupported: - msg = _("%X%P: internal error: unsupported relocation error\n"); + if (msg == NULL) + msg = _("%X%P: internal error: unsupported relocation error\n"); break; case bfd_reloc_dangerous: + /* The error message should already be set. */ + if (msg == NULL) + msg = _("dangerous relocation error"); info->callbacks->reloc_dangerous - (info, "%pcrel_lo section symbol with an addend", input_bfd, - input_section, rel->r_offset); + (info, msg, input_bfd, input_section, rel->r_offset); break; default: @@ -2356,9 +2380,14 @@ riscv_elf_relocate_section (bfd *output_bfd, break; } - if (msg) + /* Do not report error message for the dangerous relocation again. */ + if (msg && r != bfd_reloc_dangerous) info->callbacks->einfo (msg); + /* Free the unused `msg_buf` if needed. */ + if (msg_buf) + free (msg_buf); + /* We already reported the error via a callback, so don't try to report it again by returning false. That leads to spurious errors. */ ret = TRUE; diff --git a/ld/ChangeLog b/ld/ChangeLog index f51e6466e6..8fc2ceee9d 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,16 @@ +2019-10-17 Nelson Chu + + * testsuite/ld-riscv-elf/lib-nopic-01b.d: Update the error message. + + * testsuite/ld-riscv-elf/lib-nopic-01a.s: Create the shared library + lib-nopic-01a.so, it will be linked with lib-nopic-01b.s. + * testsuite/ld-riscv-elf/lib-nopic-01b.s: Add new test for the + unresolved relocation. Link the non-pic code into a shared library + may cause the error. + * testsuite/ld-riscv-elf/lib-nopic-01b.d: Likewise. + * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Run the new test only when + the shared library is supported. + 2019-10-16 Alan Modra PR 13616 diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index c994a57c48..0a7ac5945e 100644 --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp @@ -71,4 +71,11 @@ if [istarget "riscv*-*-*"] { [list "readelf --syms gp-test.sd"] \ "gp-test-${abi}"]] } + + run_ld_link_tests { + { "Link non-pic code into a shared library (setup)" + "-shared" "" "" {lib-nopic-01a.s} + {} "lib-nopic-01a.so" } + } + run_dump_test "lib-nopic-01b" } diff --git a/ld/testsuite/ld-riscv-elf/lib-nopic-01a.s b/ld/testsuite/ld-riscv-elf/lib-nopic-01a.s new file mode 100644 index 0000000000..c95cda05d2 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/lib-nopic-01a.s @@ -0,0 +1,9 @@ + .option nopic + .text + .align 1 + .globl func1 + .type func1, @function +func1: + call func2 + jr ra + .size func1, .-func1 diff --git a/ld/testsuite/ld-riscv-elf/lib-nopic-01b.d b/ld/testsuite/ld-riscv-elf/lib-nopic-01b.d new file mode 100644 index 0000000000..0d758a40d6 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/lib-nopic-01b.d @@ -0,0 +1,5 @@ +#name: link non-pic code into a shared library +#source: lib-nopic-01b.s +#as: +#ld: -shared tmpdir/lib-nopic-01a.so +#error: .*relocation R_RISCV_CALL against `func1' can not be used when making a shared object; recompile with -fPIC diff --git a/ld/testsuite/ld-riscv-elf/lib-nopic-01b.s b/ld/testsuite/ld-riscv-elf/lib-nopic-01b.s new file mode 100644 index 0000000000..97fe1374e4 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/lib-nopic-01b.s @@ -0,0 +1,9 @@ + .option nopic + .text + .align 1 + .globl func2 + .type func2, @function +func2: + call func1 + jr ra + .size func2, .-func2