/* Since shared library global symbols interpose, any
PC-relative relocations against external symbols
- should not be used to build shared libraries. */
+ should not be used to build shared libraries.
+ In static PIE undefined weak symbols may be allowed
+ by rewriting pcaddi to addi.w if addend is in [-2048, 2048). */
case R_LARCH_PCREL20_S2:
if (bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0
&& (sec->flags & SEC_READONLY) != 0
- && ! LARCH_REF_LOCAL (info, h))
+ && ! LARCH_REF_LOCAL (info, h)
+ && (!info->nointerp
+ || h->root.type != bfd_link_hash_undefweak))
return bad_static_reloc (info, abfd, rel, sec, r_type, h, NULL);
break;
}
/* PC-relative relocations are allowed For first version
- medium cmodel function call. */
+ medium cmodel function call. Those against undefined
+ weak symbol are allowed for static PIE by rewritting
+ pcalau12i to lu12i.w. */
if (h != NULL && !h->needs_plt
&& bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0
&& (sec->flags & SEC_READONLY) != 0
- && ! LARCH_REF_LOCAL (info, h))
+ && ! LARCH_REF_LOCAL (info, h)
+ && (!info->nointerp
+ || h->root.type != bfd_link_hash_undefweak))
return bad_static_reloc (info, abfd, rel, sec, r_type, h, NULL);
break;
case R_LARCH_PCALA_HI20:
unresolved_reloc = false;
- /* If sym is hidden undefined weak, (sym + addend) should be
- resolved to runtime address (0 + addend). */
+ /* If sym is undef weak and it's hidden or we are doing a static
+ link, (sym + addend) should be resolved to runtime address
+ (0 + addend). */
resolve_pcrel_undef_weak =
- (is_undefweak
- && h
- && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT);
+ ((info->nointerp
+ || (h && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT))
+ && is_undefweak);
if (resolve_pcrel_undef_weak)
pc = 0;
--- /dev/null
+#ld: -static -pie --no-dynamic-linker -z text -Ttext=0x1111222233334ff0
+#objdump: -d
+
+#...
+1111222233334ff0:[ ]+159999a4[ ]+lu12i.w[ ]+\$a0,[ ]+-209715
+1111222233334ff4:[ ]+02f77405[ ]+li.d[ ]+\$a1,[ ]+-547
+1111222233334ff8:[ ]+17777765[ ]+lu32i.d[ ]+\$a1,[ ]+-279621
+1111222233334ffc:[ ]+032aa8a5[ ]+lu52i.d[ ]+\$a1,[ ]+\$a1,[ ]+-1366
+1111222233335000:[ ]+00109484[ ]+add.d[ ]+\$a0,[ ]+\$a0,[ ]+\$a1
+1111222233335004:[ ]+029ffc06[ ]+li.w[ ]+\$a2,[ ]+2047
+1111222233335008:[ ]+02a00007[ ]+li.w[ ]+\$a3,[ ]+-2048
+111122223333500c:[ ]+4c000020[ ]+ret
+#pass