diff options
-rw-r--r-- | bfd/elfnn-riscv.c | 41 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 7 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-nopie.d | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-pie.d | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/pcrel-reloc-abs.s | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-nopie.d | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-pie.d | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/pcrel-reloc-rel.s | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/pcrel-reloc.s | 5 |
9 files changed, 111 insertions, 0 deletions
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 00f034a..0dd9b27 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -862,6 +862,47 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, ifunc symbol. */ h->plt.refcount += 1; } + + /* The non-preemptible absolute symbol shouldn't be referneced with + pc-relative relocation when generating shared object. However, + PCREL_HI20/LO12 relocs are always bind locally when generating + shared object, so all absolute symbol referenced need to be + disallowed, except they are defined in linker script. + + Maybe we should add this check for all pc-relative relocations, + please see pr28789 and pr25749 for details. */ + if (bfd_link_pic (info) + /* (h == NULL || SYMBOL_REFERENCES_LOCAL (info, h)) */ + && is_abs_symbol) + { + if (h != NULL && (h)->root.ldscript_def) + /* Disallow the absolute symbol defined in linker script here + will cause the glibc-linux toolchain build failed, so regard + them as pc-relative symbols, just like what x86 did. */ + ; + else + { + const char *name; + if (h->root.root.string) + name = h->root.root.string; + else + { + Elf_Internal_Sym *sym; + sym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, + r_symndx); + name = bfd_elf_sym_name (abfd, symtab_hdr, sym, NULL); + } + + reloc_howto_type *r_t = + riscv_elf_rtype_to_howto (abfd, r_type); + _bfd_error_handler + (_("%pB: relocation %s against absolute symbol `%s' can " + "not be used when making a shared object"), + abfd, r_t ? r_t->name : _("<unknown>"), name); + bfd_set_error (bfd_error_bad_value); + return false; + } + } /* Fall through. */ case R_RISCV_JAL: diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index 1b2a5ce..43572c5 100644 --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp @@ -308,4 +308,11 @@ if [istarget "riscv*-*-*"] { run_dump_test "ifunc-seperate-plt-pic" run_dump_test "ifunc-seperate-pcrel-pie" run_dump_test "ifunc-seperate-pcrel-pic" + + # Tests related to mixing medany code into position-independent targets, + # where it's not always possible to generate correct addressing sequences. + run_dump_test "pcrel-reloc-rel-nopie" + run_dump_test "pcrel-reloc-rel-pie" + run_dump_test "pcrel-reloc-abs-nopie" + run_dump_test "pcrel-reloc-abs-pie" } diff --git a/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-nopie.d b/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-nopie.d new file mode 100644 index 0000000..5402638 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-nopie.d @@ -0,0 +1,14 @@ +#source: pcrel-reloc.s +#source: pcrel-reloc-abs.s +#as: -march=rv64i -mabi=lp64 +#ld: -melf64lriscv --no-pie --no-relax +#objdump: -d + +.*:[ ]+file format .* + +Disassembly of section \.text: + +[0-9a-f]+ <_start>: +.*auipc.* +.*lw.*# [0-9a-f]* <sym> +#pass diff --git a/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-pie.d b/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-pie.d new file mode 100644 index 0000000..7f5eaa3 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-pie.d @@ -0,0 +1,5 @@ +#source: pcrel-reloc.s +#source: pcrel-reloc-abs.s +#as: -march=rv64i -mabi=lp64 +#ld: -melf64lriscv --pie --no-relax +#error: .*relocation R_RISCV_PCREL_HI20 against absolute symbol `sym' can not be used when making a shared objec.*t diff --git a/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs.s b/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs.s new file mode 100644 index 0000000..1df32a1 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs.s @@ -0,0 +1,2 @@ +.global sym +.set sym,0x8000 diff --git a/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-nopie.d b/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-nopie.d new file mode 100644 index 0000000..ab2a377 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-nopie.d @@ -0,0 +1,14 @@ +#source: pcrel-reloc.s +#source: pcrel-reloc-rel.s +#as: -march=rv64i -mabi=lp64 +#ld: -melf64lriscv --no-pie --no-relax +#objdump: -d + +.*:[ ]+file format .* + +Disassembly of section \.text: + +[0-9a-f]+ <_start>: +.*auipc.* +.*lw.*# [0-9a-f]* <sym> +#pass diff --git a/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-pie.d b/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-pie.d new file mode 100644 index 0000000..aec612d --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-pie.d @@ -0,0 +1,14 @@ +#source: pcrel-reloc.s +#source: pcrel-reloc-rel.s +#as: -march=rv64i -mabi=lp64 +#ld: -melf64lriscv --pie --no-relax +#objdump: -d + +.*:[ ]+file format .* + +Disassembly of section \.text: + +[0-9a-f]+ <_start>: +.*auipc.* +.*lw.*# [0-9a-f]* <sym> +#pass diff --git a/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel.s b/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel.s new file mode 100644 index 0000000..fb0e6c0 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel.s @@ -0,0 +1,9 @@ +.data +# Makes sure "sym" doesn't end up at the beginning of ".data", as that makes it +# tough to then later detect it from scripts. +.global buf +buf: + .fill 8192, 4, 1 +.global sym +sym: + .fill 8192, 4, 2 diff --git a/ld/testsuite/ld-riscv-elf/pcrel-reloc.s b/ld/testsuite/ld-riscv-elf/pcrel-reloc.s new file mode 100644 index 0000000..db2103b --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/pcrel-reloc.s @@ -0,0 +1,5 @@ +.text +.global _start +_start: + auipc t0, %pcrel_hi(sym) + lw t0, %pcrel_lo(_start)(t0) |