pc32 -> plt32 conversion and related questions

Message ID cf20561b-27ea-5017-cf43-728239edc16d@suse.com
State New
Headers show
Series
  • pc32 -> plt32 conversion and related questions
Related show

Commit Message

Luis Machado via Binutils June 15, 2021, 1:42 p.m.
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."

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?

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.

Comments

Fangrui Song June 16, 2021, 9:02 p.m. | #1
On 2021-06-15, Jan Beulich via Binutils 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."

>

>It doesn't mention that there's a difference between different

>kinds of branches.


I think jc/jmp should produce relocations in the example.
That is also what the llvm integrated assembler does.

(Hmm, seems that gas x86 has only implemented -mshared but not
-mno-shared. -mno-shared is probably not very useful, because
the compiler can use a local alias (especially a .L one) to 
force non-preemptible)

>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?

>

>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

>
Luis Machado via Binutils June 17, 2021, 3:13 p.m. | #2
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.
Luis Machado via Binutils June 17, 2021, 3:16 p.m. | #3
On 17.06.2021 17:13, H.J. Lu wrote:
> 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.


And this means in the case above no relocation without -mshared?

>> 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.


But that is to be dealt with by the dynamic linker, isn't it? The
static linker should assume everything fits in the 2Gb window.

Jan
Luis Machado via Binutils June 17, 2021, 3:17 p.m. | #4
On 17.06.2021 17:13, H.J. Lu wrote:
> 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.


Oh, and - any word on this?

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

>>

> 

>
Luis Machado via Binutils June 17, 2021, 3:23 p.m. | #5
On Thu, Jun 17, 2021 at 8:16 AM Jan Beulich <jbeulich@suse.com> wrote:
>

> On 17.06.2021 17:13, H.J. Lu wrote:

> > 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.

>

> And this means in the case above no relocation without -mshared?


Yes.

> >> 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.

>

> But that is to be dealt with by the dynamic linker, isn't it? The

> static linker should assume everything fits in the 2Gb window.


What can the dynamic linker do? We are talking about shared
libraries here.  The distance between a shared library and
another shared library/executable can be > 2GB.

-- 
H.J.
Luis Machado via Binutils June 17, 2021, 3:23 p.m. | #6
On Thu, Jun 17, 2021 at 8:17 AM Jan Beulich <jbeulich@suse.com> wrote:
>

> On 17.06.2021 17:13, H.J. Lu wrote:

> > 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.

>

> Oh, and - any word on this?


It sounds reasonable.

> 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.
Luis Machado via Binutils June 17, 2021, 3:30 p.m. | #7
On 17.06.2021 17:23, H.J. Lu wrote:
> On Thu, Jun 17, 2021 at 8:16 AM Jan Beulich <jbeulich@suse.com> wrote:

>> On 17.06.2021 17:13, H.J. Lu wrote:

>>> On Tue, Jun 15, 2021 at 6:42 AM Jan Beulich <jbeulich@suse.com> wrote:

>>>> 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.

>>

>> But that is to be dealt with by the dynamic linker, isn't it? The

>> static linker should assume everything fits in the 2Gb window.

> 

> What can the dynamic linker do? We are talking about shared

> libraries here.  The distance between a shared library and

> another shared library/executable can be > 2GB.


In x32? That would be a bug in the dynamic loader, wouldn't it?

Jan
Luis Machado via Binutils June 17, 2021, 3:34 p.m. | #8
On Thu, Jun 17, 2021 at 8:30 AM Jan Beulich <jbeulich@suse.com> wrote:
>

> On 17.06.2021 17:23, H.J. Lu wrote:

> > On Thu, Jun 17, 2021 at 8:16 AM Jan Beulich <jbeulich@suse.com> wrote:

> >> On 17.06.2021 17:13, H.J. Lu wrote:

> >>> On Tue, Jun 15, 2021 at 6:42 AM Jan Beulich <jbeulich@suse.com> wrote:

> >>>> 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.

> >>

> >> But that is to be dealt with by the dynamic linker, isn't it? The

> >> static linker should assume everything fits in the 2Gb window.

> >

> > What can the dynamic linker do? We are talking about shared

> > libraries here.  The distance between a shared library and

> > another shared library/executable can be > 2GB.

>

> In x32? That would be a bug in the dynamic loader, wouldn't it?

>


Why?  x32 can use the full 4GB address space.

-- 
H.J.
Luis Machado via Binutils June 17, 2021, 3:45 p.m. | #9
On 17.06.2021 17:34, H.J. Lu wrote:
> On Thu, Jun 17, 2021 at 8:30 AM Jan Beulich <jbeulich@suse.com> wrote:

>>

>> On 17.06.2021 17:23, H.J. Lu wrote:

>>> On Thu, Jun 17, 2021 at 8:16 AM Jan Beulich <jbeulich@suse.com> wrote:

>>>> On 17.06.2021 17:13, H.J. Lu wrote:

>>>>> On Tue, Jun 15, 2021 at 6:42 AM Jan Beulich <jbeulich@suse.com> wrote:

>>>>>> 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.

>>>>

>>>> But that is to be dealt with by the dynamic linker, isn't it? The

>>>> static linker should assume everything fits in the 2Gb window.

>>>

>>> What can the dynamic linker do? We are talking about shared

>>> libraries here.  The distance between a shared library and

>>> another shared library/executable can be > 2GB.

>>

>> In x32? That would be a bug in the dynamic loader, wouldn't it?

> 

> Why?  x32 can use the full 4GB address space.


Hmm, okay, I must be misremembering something then that I think I read
somewhere not so long ago. Or perhaps an outdated document. I'm sorry
for the noise then.

Jan

Patch

--- 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