- case ABS32CODE:
- calljx_callback(in_abfd, reloc, src_address + data, dst_address+data,
- input_section, seclet);
- src_address+=4;
- dst_address+=4;
- break;
- case ABS32:
- bfd_put_32(in_abfd, get_value(reloc, seclet), data+dst_address);
- src_address+=4;
- dst_address+=4;
- break;
- case CALLJ:
- callj_callback(in_abfd, reloc ,data,src_address,dst_address,
- input_section, seclet);
- src_address+=4;
- dst_address+=4;
- break;
- case ALIGNDONE:
- src_address = reloc->addend;
- dst_address = (dst_address + reloc->howto->size) & ~reloc->howto->size;
- break;
- case ABS32CODE_SHRUNK:
- /* This used to be a callx, but we've found out that a
- callj will reach, so do the right thing */
- callj_callback(in_abfd, reloc,data,src_address+4, dst_address,
- input_section, seclet);
-
- dst_address+=4;
- src_address+=8;
- break;
- case PCREL24:
- {
- long int word = bfd_get_32(in_abfd, data+src_address);
- asymbol *symbol = *(reloc->sym_ptr_ptr);
- if (symbol->section == &bfd_und_section)
- {
- bfd_error_vector.undefined_symbol(reloc, seclet);
- }
- word = (word & ~BAL_MASK) |
- (((word & BAL_MASK) +
- symbol->section->output_offset +
- symbol->section->output_section->vma+
- symbol->value + reloc->addend - dst_address -
- ( input_section->output_section->vma + input_section->output_offset))
- & BAL_MASK);
-
- bfd_put_32(in_abfd,word, data+dst_address);
- dst_address+=4;
- src_address+=4;
-
- }
- break;
-
- case PCREL13:
- {
- long int word = bfd_get_32(in_abfd, data+src_address);
- asymbol *symbol = *(reloc->sym_ptr_ptr);
- if (symbol->section == &bfd_und_section)
- {
- bfd_error_vector.undefined_symbol(reloc, seclet);
- }
- word = (word & ~PCREL13_MASK) |
- (((word & PCREL13_MASK) +
- symbol->section->output_offset +
- symbol->section->output_section->vma+
- symbol->value + reloc->addend - dst_address -
- ( input_section->output_section->vma + input_section->output_offset))
- & PCREL13_MASK);
-
- bfd_put_32(in_abfd,word, data+dst_address);
- dst_address+=4;
- src_address+=4;
-
- }
- break;
-
- default:
-
- abort();
+ reloc = *parent;
+ if (reloc)
+ {
+ /* Note that the relaxing didn't tie up the addresses in the
+ relocation, so we use the original address to work out the
+ run of non-relocated data. */
+ BFD_ASSERT (reloc->address >= src_address);
+ run = reloc->address - src_address;
+ parent++;
+ }
+ else
+ {
+ run = link_order->size - dst_address;
+ }
+
+ /* Copy the bytes. */
+ for (idx = 0; idx < run; idx++)
+ data[dst_address++] = data[src_address++];
+
+ /* Now do the relocation. */
+ if (reloc)
+ {
+ switch (reloc->howto->type)
+ {
+ case ABS32CODE:
+ calljx_callback (input_bfd, link_info, reloc,
+ src_address + data, dst_address + data,
+ input_section);
+ src_address += 4;
+ dst_address += 4;
+ break;
+ case ABS32:
+ bfd_put_32 (input_bfd,
+ (bfd_get_32 (input_bfd, data + src_address)
+ + get_value (reloc, link_info, input_section)),
+ data + dst_address);
+ src_address += 4;
+ dst_address += 4;
+ break;
+ case CALLJ:
+ callj_callback (input_bfd, link_info, reloc, data,
+ src_address, dst_address, input_section,
+ false);
+ src_address += 4;
+ dst_address += 4;
+ break;
+ case ALIGNDONE:
+ BFD_ASSERT (reloc->addend >= src_address);
+ BFD_ASSERT ((bfd_vma) reloc->addend
+ <= input_section->_raw_size);
+ src_address = reloc->addend;
+ dst_address = ((dst_address + reloc->howto->size)
+ & ~reloc->howto->size);
+ break;
+ case ABS32CODE_SHRUNK:
+ /* This used to be a callx, but we've found out that a
+ callj will reach, so do the right thing. */
+ callj_callback (input_bfd, link_info, reloc, data,
+ src_address + 4, dst_address, input_section,
+ true);
+ dst_address += 4;
+ src_address += 8;
+ break;
+ case PCREL24:
+ {
+ long int word = bfd_get_32 (input_bfd,
+ data + src_address);
+ bfd_vma value;
+
+ value = get_value (reloc, link_info, input_section);
+ word = ((word & ~BAL_MASK)
+ | (((word & BAL_MASK)
+ + value
+ - output_addr (input_section)
+ + reloc->addend)
+ & BAL_MASK));
+
+ bfd_put_32 (input_bfd, (bfd_vma) word, data + dst_address);
+ dst_address += 4;
+ src_address += 4;
+
+ }
+ break;
+ case PCREL13:
+ {
+ long int word = bfd_get_32 (input_bfd,
+ data + src_address);
+ bfd_vma value;
+
+ value = get_value (reloc, link_info, input_section);
+ word = ((word & ~PCREL13_MASK)
+ | (((word & PCREL13_MASK)
+ + value
+ + reloc->addend
+ - output_addr (input_section))
+ & PCREL13_MASK));
+
+ bfd_put_32 (input_bfd, (bfd_vma) word, data + dst_address);
+ dst_address += 4;
+ src_address += 4;
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }