{
symvalue diff;
if (output_bfd == (bfd *) NULL)
returnbfd_reloc_continue;
if (bfd_is_com_section (symbol->section))
{
/* We are relocating a common symbol. The current value in the object file is ORIG + OFFSET, where ORIG is the value of the common symbol as seen by the object file when it was compiled (this may be zero if the symbol was undefined) and OFFSET is the offset into the common symbol (normally zero, but may be non-zero when referring to a field in a common structure). ORIG is the negative of reloc_entry->addend, which is set by the CALC_ADDEND macro below. We want to replace the value in the object file with NEW + OFFSET, where NEW is the value of the common symbol which we are going to put in the final object file. NEW is symbol->value. */
diff = symbol->value + reloc_entry->addend;
}
else
{
/* For some reason bfd_perform_relocation always effectively ignores the addend for a COFF target when producing relocatable output. This seems to be always wrong for 860 COFF, so we handle the addend here instead. */
diff = reloc_entry->addend;
}
#define DOIT(x) \ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))if (diff != 0)
{
reloc_howto_type *howto = reloc_entry->howto;
unsignedchar *addr = (unsignedchar *) data + reloc_entry->address;
switch (howto->size)
{
case 0:
{
charx = bfd_get_8 (abfd, addr);
DOIT (x);
bfd_put_8 (abfd, x, addr);
}
break;
case 1:
{
shortx = bfd_get_16 (abfd, addr);
DOIT (x);
bfd_put_16 (abfd, (bfd_vma) x, addr);
}
break;
case 2:
{
long x = bfd_get_32 (abfd, addr);
DOIT (x);
bfd_put_32 (abfd, (bfd_vma) x, addr);
}
break;
default:
abort ();
}
}
/* Now let bfd_perform_relocation finish everything up. */returnbfd_reloc_continue;
}

{
reloc_howto_type *howto;
if (rel->r_type > sizeof (howto_table) / sizeof (howto_table[0]))
{
bfd_set_error (bfd_error_bad_value);
returnNULL;
}
howto = howto_table + rel->r_type;
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);
/* 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;
}
/* 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;
return howto;
}