[PATCH] VAX: PIC: Use GOT for pointer for global function

Maciej W. Rozycki macro@orcam.me.uk
Mon May 5 21:31:23 GMT 2025


On Mon, 5 May 2025, Rin Okuyama wrote:

> in same file, instead of PLT
> 
> This fixes the problem reported as Bug 32941:
> https://sourceware.org/bugzilla/show_bug.cgi?id=32941
> 
> Consider the following C source, main.c:
> 
> ```
> 
> void func(void) {
> }
> 
> int main(void) {
>         printf("%s: %p\n", func);
>         return 0;
> }
> ```
> 
> Before this patch applied, `func` argument for printf(3) points PLT:
> 
> ```
> % /somewhere/vax--netbsdelf-gcc -S -fPIC -O2 main.c
> % /usr/local/vax--netbsdelf/bin/as -pic main.s -o main.o
> % readelf -r main.o
> 
> Relocation section '.rela.text.startup' at offset 0x14c contains 3 entries:
>  Offset     Info    Type            Sym.Value  Sym. Name + Addend
> 0000000d  00000504 R_VAX_PC32        00000000   .rodata.str1.1 + 0
> 00000007  0000080d R_VAX_PLT32       00000000   func + 0
> 00000014  00000a0d R_VAX_PLT32       00000000   printf + 0
> ```
> 
> After this patch applied, it points GOT as done for other platforms:
> 
> ```
> % /usr/local/vax--netbsdelf/bin/as -pic main.s -o main.o
> % readelf -r main.o
> 
> Relocation section '.rela.text.startup' at offset 0x14c contains 3 entries:
>  Offset     Info    Type            Sym.Value  Sym. Name + Addend
> 0000000d  00000504 R_VAX_PC32        00000000   .rodata.str1.1 + 0
> 00000007  00000807 R_VAX_GOT32       00000000   func + 0
> 00000014  00000a0d R_VAX_PLT32       00000000   printf + 0
> ```

 Thank you for your submission and the bug report.

 I've glanced over and while technically GAS might be doing an odd thing 
here, the bug is clearly in the linker, which doesn't handle pointer 
equality correctly.

 Taking lazy binding and pointer equality into account here there are two
approaches at the high level either of which the linker can take:

1. In the presence of any PLT relocations create a lazy binding stub
   (incorrectly called a PLT entry for the VAX target[*]) in the module
   containing the ultimate symbol definition and refer all GOT symbol
   references to it, ensuring pointer equality in the presence of lazy 
   binding.

2. In the presence of any GOT relocations refrain from creating a lazy
   binding stub and refer all symbol references to the GOT entry in the
   module containing the reference, ensuring pointer equality via 
   immediate binding.

 Most platforms choose #1, in turn causing issues with protected symbols 
(I'd have to dig out the details either from my memory or the Internet; 
it's been discussed before), while traditional SVR4 MIPS targets choose 
#2 at the price of using longer PIC code sequences even in absolute 
executables (#1 has been an option for MIPS/Linux targets for a while 
now).

 The reason most targets choose #1 is they require a longer instruction
encoding for indirect memory references than they do for direct ones.  For
example an indirect x86 CALL instruction requires an extra byte comparing
to a direct one.  This isn't a problem for VAX code as long as PC-relative
addressing is used for direct memory references.

 So I think we ought to choose #2, though of course at the expense of 
losing lazy binding for such a symbol.  More investigation might be 
required though, and we'll need to make a bunch of testsuite cases (which 
the VAX port regrettably has a poor choice of at the moment) to make sure 
we don't break one case with a fix for another.

 NB it would be good to have support for explicit relocations in assembly
too, but I guess it's unlikely to happen.  It would avoid issues with GAS
such as one discussed.

  Maciej

[*] A PLT entry is a piece of code that is always executed via a direct
    call in the course of invoking a lazily bound function, whether the
    binding has yet to be done or have been completed already.  Conversely
    a lazy binding stub is called indirectly and can at most executed
    once, in the course of resolving the binding, and any later calls pass
    control to the function called right away, which is exactly what
    happens on VAX.


More information about the Binutils mailing list