/* We didn't make a PLT entry for this symbol. This
happens when statically linking PIC code, or when
using -Bsymbolic. */
+
+ /* Replace relative long addressing instructions of weak
+ symbols, which will definitely resolve to zero, with
+ either a load address of 0 or a trapping insn.
+ This prevents the PLT32DBL relocation from overflowing in
+ case the binary will be loaded at 4GB or more. */
+ if (h->root.type == bfd_link_hash_undefweak
+ && !h->root.linker_def
+ && (bfd_link_executable (info)
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ && r_type == R_390_PLT32DBL
+ && rel->r_offset >= 2)
+ {
+ void *insn_start = contents + rel->r_offset - 2;
+ uint16_t op = bfd_get_16 (input_bfd, insn_start) & 0xff0f;
+ uint8_t reg = bfd_get_8 (input_bfd, insn_start + 1) & 0xf0;
+
+ /* NOTE: The order of the if's is important! */
+ /* Replace load address relative long (larl) with load
+ address (lay) */
+ if (op == 0xc000)
+ {
+ /* larl rX,<weak sym> -> lay rX,0(0) */
+ bfd_put_16 (output_bfd, 0xe300 | reg, insn_start);
+ bfd_put_32 (output_bfd, 0x71, insn_start + 2);
+ continue;
+ }
+ /* Replace branch relative and save long (brasl) with a trap. */
+ else if (op == 0xc005)
+ {
+ /* brasl rX,<weak sym> -> jg .+2 (6-byte trap) */
+ bfd_put_16 (output_bfd, 0xc0f4, insn_start);
+ bfd_put_32 (output_bfd, 0x1, insn_start + 2);
+ continue;
+ }
+ }
+
break;
}
if (s390_is_ifunc_symbol_p (h))
"-m64" {pltoffset-1.s}
{{objdump "-dzrj.text --stop-address=16" pltoffset-1.dd}}
"pltoffset-1"}
- {"WEAKUNDEF1: overflow test"
+ {"WEAKUNDEF1: overflow test (PC32DBL)"
"-m elf64_s390 -dT 8GB.ld --no-error-rwx-segments" "" "-m64" {weakundef-1.s}
{{objdump "-dzrj.text" weakundef-1.dd}} "weakundef-1"}
+ {"WEAKUNDEF2: overflow test (PLT32DBL)"
+ "-m elf64_s390 -dT 8GB.ld --no-error-rwx-segments -no-pie" "" "-m64" {weakundef-2.s}
+ {{objdump "-dzrj.text" weakundef-2.dd}} "weakundef-2"}
}
if [istarget "s390-*-*"] {
--- /dev/null
+tmpdir/weakundef-2: file format elf64-s390
+
+Disassembly of section .text:
+
+0+200000000 <foo>:
+.*: c0 10 00 00 00 12 [ ]*larl %r1,200000024 <d>
+.*: c0 10 00 00 00 10 [ ]*larl %r1,200000026 <wd>
+.*: e3 10 00 00 00 71 [ ]*lay %r1,0
+.*: c0 e5 00 00 00 09 [ ]*brasl %r14,200000024 <d>
+.*: c0 e5 00 00 00 07 [ ]*brasl %r14,200000026 <wd>
+.*: c0 f4 00 00 00 01 [ ]*jg .*
+
+0+200000024 <d>:
+.*: 07 fe [ ]*br %r14
+
+0+200000026 <wd>:
+.*: 07 fe [ ]*br %r14