Skip to content

Commit

Permalink
RISC-V: Report unresolved relocation error via linker's callback func…
Browse files Browse the repository at this point in the history
…tion.

Two patches from Nelson Chu.

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.

R_RISCV_CALL, R_RISCV_JAL and R_RISCV_RVC_JUMP are pc-relative relocation.
For now, we do not allow the object with these relocation links into a shared
library since the referenced symbols may be loaded to the places that too far
from the pc.  We can improve the error message for these unsupported relocation
to notice user that they should recompile their code with `fPIC`.

	bfd/
	* 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.

	ld/
	* testsuite/ld-riscv-elf/lib-nopic-01b.d: Update the error message.

Change-Id: Ib3347a0a6fa1c2b20a9647c314d5bec2c322ff04
  • Loading branch information
Jim Wilson committed Oct 17, 2019
1 parent c5adaa1 commit 330a663
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 17 deletions.
13 changes: 13 additions & 0 deletions bfd/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
2019-10-17 Nelson Chu <nelson.chu@sifive.com>

* 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 <amodra@gmail.com>

PR 13616
Expand Down
63 changes: 46 additions & 17 deletions bfd/elfnn-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);

bfd_set_error (bfd_error_bad_value);
ret = FALSE;
goto out;
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;

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:
Expand All @@ -2338,27 +2358,36 @@ 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:
msg = _("%X%P: internal error: unknown error\n");
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;
Expand Down
13 changes: 13 additions & 0 deletions ld/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
2019-10-17 Nelson Chu <nelson.chu@sifive.com>

* 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 <amodra@gmail.com>

PR 13616
Expand Down
7 changes: 7 additions & 0 deletions ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
9 changes: 9 additions & 0 deletions ld/testsuite/ld-riscv-elf/lib-nopic-01a.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.option nopic
.text
.align 1
.globl func1
.type func1, @function
func1:
call func2
jr ra
.size func1, .-func1
5 changes: 5 additions & 0 deletions ld/testsuite/ld-riscv-elf/lib-nopic-01b.d
Original file line number Diff line number Diff line change
@@ -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
9 changes: 9 additions & 0 deletions ld/testsuite/ld-riscv-elf/lib-nopic-01b.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.option nopic
.text
.align 1
.globl func2
.type func2, @function
func2:
call func1
jr ra
.size func2, .-func2

0 comments on commit 330a663

Please sign in to comment.