From 33f986232757c186c9d1bcc165fea9a4a7f224b6 Mon Sep 17 00:00:00 2001 From: Nelson Chu Date: Fri, 4 Oct 2019 09:01:53 +0800 Subject: [PATCH 1/2] RISC-V: Report unresolved relocation error via linker's callback function. It is better to use the linker's callback functions to handle the link time error when relocating. The unresolved relocation error can be regarded as an unsupported relocation. To make user easier to understand different errors, we need to extend the current error message format of the callback function since the format is fixed. bfd/ * 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. ld/ * 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. --- bfd/elfnn-riscv.c | 45 +++++++++++++++++++----------- ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 7 +++++ ld/testsuite/ld-riscv-elf/lib-nopic-01a.s | 9 ++++++ ld/testsuite/ld-riscv-elf/lib-nopic-01b.d | 5 ++++ ld/testsuite/ld-riscv-elf/lib-nopic-01b.s | 9 ++++++ 5 files changed, 58 insertions(+), 17 deletions(-) create mode 100644 ld/testsuite/ld-riscv-elf/lib-nopic-01a.s create mode 100644 ld/testsuite/ld-riscv-elf/lib-nopic-01b.d create mode 100644 ld/testsuite/ld-riscv-elf/lib-nopic-01b.s diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index db911b1..1c2c871 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -1788,6 +1788,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 @@ -2089,6 +2090,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; } @@ -2303,24 +2305,24 @@ 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); - - bfd_set_error (bfd_error_bad_value); - ret = FALSE; - goto out; + if (asprintf (&msg_buf, + _("%%X%%P: unresolvable %s relocation against " + "symbol `%s'\n"), + howto->name, + h->root.root.string) == -1) + msg_buf = NULL; + 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 deafult message + with the "internal error" string here. */ switch (r) { case bfd_reloc_ok: @@ -2339,17 +2341,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: @@ -2357,9 +2363,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/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index c994a57..0a7ac59 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 0000000..c95cda0 --- /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 0000000..08c2890 --- /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: .*unresolvable R_RISCV_CALL relocation against symbol `func1' 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 0000000..97fe137 --- /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 -- 2.7.4