+ /* We have "mov foo@GOT[(%re1g)], %reg2",
+ "test %reg1, foo@GOT(%reg2)" and
+ "binop foo@GOT[(%reg1)], %reg2".
+
+ Avoid optimizing _DYNAMIC since ld.so may use its
+ link-time address. */
+ if (h == htab->elf.hdynamic)
+ continue;
+
+ /* def_regular is set by an assignment in a linker script in
+ bfd_elf_record_link_assignment. */
+ if ((h->def_regular
+ || h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && SYMBOL_REFERENCES_LOCAL (link_info, h))
+ {
+convert_load:
+ if (opcode == 0x8b)
+ {
+ /* Convert "mov foo@GOT(%reg1), %reg2" to
+ "lea foo@GOTOFF(%reg1), %reg2". */
+ if (r_type == R_386_GOT32X
+ && (baseless || !bfd_link_pic (link_info)))
+ {
+ r_type = R_386_32;
+ /* For R_386_32, convert
+ "lea foo@GOTOFF(%reg1), %reg2" to
+ "lea foo@GOT, %reg2". */
+ if (!baseless)
+ {
+ modrm = 0x5 | (modrm & 0x38);
+ bfd_put_8 (abfd, modrm, contents + roff - 1);
+ }
+ }
+ else
+ r_type = R_386_GOTOFF;
+ opcode = 0x8d;
+ }
+ else
+ {
+ if (opcode == 0x85)
+ {
+ /* Convert "test %reg1, foo@GOT(%reg2)" to
+ "test $foo, %reg1". */
+ modrm = 0xc0 | (modrm & 0x38) >> 3;
+ opcode = 0xf7;
+ }
+ else
+ {
+ /* Convert "binop foo@GOT(%reg1), %reg2" to
+ "binop $foo, %reg2". */
+ modrm = (0xc0
+ | (modrm & 0x38) >> 3
+ | (opcode & 0x3c));
+ opcode = 0x81;
+ }
+ bfd_put_8 (abfd, modrm, contents + roff - 1);
+ r_type = R_386_32;
+ }
+
+ bfd_put_8 (abfd, opcode, contents + roff - 2);
+ irel->r_info = ELF32_R_INFO (r_symndx, r_type);
+
+ if (h)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount -= 1;
+ }
+ else
+ {
+ if (local_got_refcounts != NULL
+ && local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+
+ changed_contents = TRUE;
+ changed_relocs = TRUE;
+ }