+ if (howto->pc_relative)
+ *addendp += sec->vma;
+
+ if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
+ {
+ /* This is a common symbol. The section contents include the
+ size (sym->n_value) as an addend. The relocate_section
+ function will be adding in the final value of the symbol. We
+ need to subtract out the current size in order to get the
+ correct result. */
+
+ BFD_ASSERT (h != NULL);
+
+#ifndef COFF_WITH_PE
+ /* I think we *do* want to bypass this. If we don't, I have
+ seen some data parameters get the wrong relocation address.
+ If I link two versions with and without this section bypassed
+ and then do a binary comparison, the addresses which are
+ different can be looked up in the map. The case in which
+ this section has been bypassed has addresses which correspond
+ to values I can find in the map. */
+ *addendp -= sym->n_value;
+#endif
+ }
+
+#ifndef COFF_WITH_PE
+ /* If the output symbol is common (in which case this must be a
+ relocatable link), we need to add in the final size of the
+ common symbol. */
+ if (h != NULL && h->root.type == bfd_link_hash_common)
+ *addendp += h->root.u.c.size;
+#endif
+
+#ifdef COFF_WITH_PE
+ if (howto->pc_relative)
+ {
+ *addendp -= 4;
+
+ /* If the symbol is defined, then the generic code is going to
+ add back the symbol value in order to cancel out an
+ adjustment it made to the addend. However, we set the addend
+ to 0 at the start of this function. We need to adjust here,
+ to avoid the adjustment the generic code will make. FIXME:
+ This is getting a bit hackish. */
+ if (sym != NULL && sym->n_scnum != 0)
+ *addendp -= sym->n_value;
+ }
+
+ if (rel->r_type == R_IMAGEBASE
+ && (bfd_get_flavour(sec->output_section->owner)
+ == bfd_target_coff_flavour))
+ {
+ *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
+ }
+
+ BFD_ASSERT (sym != NULL);
+ if (rel->r_type == R_SECREL32 && sym != NULL)
+ {
+ bfd_vma osect_vma;
+
+ if (h && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ osect_vma = h->root.u.def.section->output_section->vma;
+ else
+ {
+ asection *s;
+ int i;
+
+ /* Sigh, the only way to get the section to offset against
+ is to find it the hard way. */
+
+ for (s = abfd->sections, i = 1; i < sym->n_scnum; i++)
+ s = s->next;
+
+ osect_vma = s->output_section->vma;
+ }
+
+ *addendp -= osect_vma;
+ }
+#endif
+
+ return howto;
+}
+
+#define coff_bfd_reloc_type_lookup coff_i386_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup coff_i386_reloc_name_lookup
+
+static reloc_howto_type *
+coff_i386_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)