https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118497

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The reason this has been reported is that golang cgo has some weird code to
rewrite @GOT references which can deal with R_386_GOT32{,X} relocations only in
very limited subset of instructions, just movl symbol@GOT(%reg1), %reg2 and
pushl symbol@GOT(%ebx).
And with this change it got turned into pushl symbol@GOT(%eax) instead.
GCC regularly emits also e.g. addl symbol@GOT(%reg1), %reg2 which the
https://github.com/golang/go/blob/master/src/cmd/link/internal/x86/asm.go#L177

                        if r.Off() >= 2 && sData[r.Off()-2] == 0x8b {
                                su.MakeWritable()

                                // turn MOVL of GOT entry into LEAL of symbol
address, relative to GOT.
                                writeableData := su.Data()
                                writeableData[r.Off()-2] = 0x8d
                                su.SetRelocType(rIdx, objabi.R_GOTOFF)
                                return true
                        }

                        if r.Off() >= 2 && sData[r.Off()-2] == 0xff &&
sData[r.Off()-1] == 0xb3 {
                                su.MakeWritable()
                                // turn PUSHL of GOT entry into PUSHL of symbol
itself.
                                // use unnecessary SS prefix to keep
instruction same length.
                                writeableData := su.Data()
                                writeableData[r.Off()-2] = 0x36
                                writeableData[r.Off()-1] = 0x68
                                su.SetRelocType(rIdx, objabi.R_ADDR)
                                return true
                        }

                        ldr.Errorf(s, "unexpected GOT reloc for non-dynamic
symbol %s", ldr.SymName(targ))
                        return false
code doesn't handle.  Anyway, guess that is golang bug, but the regression is
in emitting larger code unnecessarily.

Reply via email to