pc32 -> plt32 conversion and related questions

H.J. Lu hjl.tools@gmail.com
Thu Jun 17 15:13:10 GMT 2021


On Tue, Jun 15, 2021 at 6:42 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> H.J.,
>
> alongside the question of what non-zero addends mean for certain
> relocation types, I came to notice that this conversion may be
> done in cases where it would better be avoided. I have the draft
> patch below (still lacking a test case and ChangeLog entry), and
> I particularly wonder whether the information propagation
> approach to md_estimate_size_before_relax() is acceptable, or
> whether you have other (better) suggestions.
>
> While playing with this (and in particular the code that I mean
> to convert into a testcase) I came to further notice that there
> is an inconsistency in whether relocations for branches get
> emitted for locally defined symbols:
>
>         .text
>         .global _start, func
> _start:
>         call    func    # gets converted to PLT32 reloc (and would be subject to preemption even when left as PC32), ...
>         jc      func    # ... while this and ...
>         jmp     func    # ... this get resolved locally, unless ...
>
>         # ... this directive is enabled (or -mshared gets passed)
>         #.section .text.lib, "ax", @progbits
> func:
>         ret
>         .type func, @function
>         .size func, .-func
>
> In 2.30 (i.e. before the pc32 -> plt32 conversion) the CALL
> yields a PC32 reloc, so the issue isn't directly related to that
> change. But given the effect -mshared has on JMP and Jcc, do you
> agree that CALL should be handled consistently with JMP/Jcc here?
> Not the least to match the documentation of -mshared:
>
> "On ELF target, the assembler normally optimizes out non-PLT
>  relocations against defined non-weak global branch targets with
>  default visibility."

Yes, CALL should be handled like JMP/Jcc.

> It doesn't mention that there's a difference between different
> kinds of branches.
>
> And then, still in this same context, I did also notice that the
> linker complains about e.g. PC32 relocs when building a shared
> library even when that's a x32 one (suggesting to rebuild with
> -fPIC). 32-bit relocations can't overflow in that ABI, so wouldn't
> such errors better be suppressed there?

It can overflow in x32 since x32 is totally implemented on software
and there is no address wraparound.

> Thanks, Jan
>
> x86-64: restrict PC32 -> PLT32 conversion
>
> Neither non-64-bit code nor uses with a non-zero offset from a symbol
> should be converted to PLT32, as an eventual PLT entry would not express
> what was requested.
>
> --- a/gas/config/tc-i386.c
> +++ b/gas/config/tc-i386.c
> @@ -8765,6 +8765,8 @@ output_branch (void)
>        off = 0;
>      }
>
> +  frag_now->tc_frag_data.code64 = flag_code == CODE_64BIT;
> +
>    /* 1 possible extra opcode + 4 byte displacement go in var part.
>       Pass reloc in fr_var.  */
>    frag_var (rs_machine_dependent, 5, i.reloc[0], subtype, sym, off, p);
> @@ -8893,8 +8895,8 @@ output_jump (void)
>      }
>
>  #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
> -  if (size == 4
> -      && jump_reloc == NO_RELOC
> +  if (flag_code == CODE_64BIT && size == 4
> +      && jump_reloc == NO_RELOC && i.op[0].disps->X_add_number == 0
>        && need_plt32_p (i.op[0].disps->X_add_symbol))
>      jump_reloc = BFD_RELOC_X86_64_PLT32;
>  #endif
> @@ -12191,7 +12193,8 @@ md_estimate_size_before_relax (fragS *fr
>        else if (size == 2)
>         reloc_type = BFD_RELOC_16_PCREL;
>  #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
> -      else if (need_plt32_p (fragP->fr_symbol))
> +      else if (fragP->tc_frag_data.code64 && fragP->fr_offset == 0
> +              && need_plt32_p (fragP->fr_symbol))
>         reloc_type = BFD_RELOC_X86_64_PLT32;
>  #endif
>        else
> --- a/gas/config/tc-i386.h
> +++ b/gas/config/tc-i386.h
> @@ -280,6 +280,7 @@ struct i386_tc_frag_data
>    unsigned int mf_type : 3;
>    unsigned int classified : 1;
>    unsigned int branch_type : 3;
> +  unsigned int code64 : 1; /* Only set by output_branch for now.  */
>  };
>
>  /* We need to emit the right NOP pattern in .align frags.  This is
>


-- 
H.J.


More information about the Binutils mailing list