+ unsigned long word = 0;
+ unsigned long* wordPtr = (unsigned long*) (image + sect->offset + scat->r_address);
+ checkProddableBlock(oc,wordPtr);
+
+ // Step 1: Figure out what the relocated value should be
+ if(scat->r_type == GENERIC_RELOC_VANILLA)
+ {
+ word = scat->r_value + sect->offset + ((long) image);
+ }
+ else if(scat->r_type == PPC_RELOC_SECTDIFF
+ || scat->r_type == PPC_RELOC_LO16_SECTDIFF
+ || scat->r_type == PPC_RELOC_HI16_SECTDIFF
+ || scat->r_type == PPC_RELOC_HA16_SECTDIFF)
+ {
+ struct scattered_relocation_info *pair =
+ (struct scattered_relocation_info*) &relocs[i+1];
+
+ if(!pair->r_scattered || pair->r_type != PPC_RELOC_PAIR)
+ barf("Invalid Mach-O file: "
+ "PPC_RELOC_*_SECTDIFF not followed by PPC_RELOC_PAIR");
+
+ word = (unsigned long)
+ (relocateAddress(oc, nSections, sections, scat->r_value)
+ - relocateAddress(oc, nSections, sections, pair->r_value));
+ i++;
+ }
+ else if(scat->r_type == PPC_RELOC_HI16
+ || scat->r_type == PPC_RELOC_LO16
+ || scat->r_type == PPC_RELOC_HA16
+ || scat->r_type == PPC_RELOC_LO14)
+ { // these are generated by label+offset things
+ struct relocation_info *pair = &relocs[i+1];
+ if((pair->r_address & R_SCATTERED) || pair->r_type != PPC_RELOC_PAIR)
+ barf("Invalid Mach-O file: "
+ "PPC_RELOC_* not followed by PPC_RELOC_PAIR");
+
+ if(scat->r_type == PPC_RELOC_LO16)
+ {
+ word = ((unsigned short*) wordPtr)[1];
+ word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16;
+ }
+ else if(scat->r_type == PPC_RELOC_LO14)
+ {
+ barf("Unsupported Relocation: PPC_RELOC_LO14");
+ word = ((unsigned short*) wordPtr)[1] & 0xFFFC;
+ word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16;
+ }
+ else if(scat->r_type == PPC_RELOC_HI16)
+ {
+ word = ((unsigned short*) wordPtr)[1] << 16;
+ word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF);
+ }
+ else if(scat->r_type == PPC_RELOC_HA16)
+ {
+ word = ((unsigned short*) wordPtr)[1] << 16;
+ word += ((short)relocs[i+1].r_address & (short)0xFFFF);
+ }
+
+
+ word += (unsigned long) relocateAddress(oc, nSections, sections, scat->r_value)
+ - scat->r_value;
+
+ i++;
+ }
+ else
+ continue; // ignore the others
+
+ if(scat->r_type == GENERIC_RELOC_VANILLA
+ || scat->r_type == PPC_RELOC_SECTDIFF)
+ {
+ *wordPtr = word;
+ }
+ else if(scat->r_type == PPC_RELOC_LO16_SECTDIFF || scat->r_type == PPC_RELOC_LO16)
+ {
+ ((unsigned short*) wordPtr)[1] = word & 0xFFFF;
+ }
+ else if(scat->r_type == PPC_RELOC_HI16_SECTDIFF || scat->r_type == PPC_RELOC_HI16)
+ {
+ ((unsigned short*) wordPtr)[1] = (word >> 16) & 0xFFFF;
+ }
+ else if(scat->r_type == PPC_RELOC_HA16_SECTDIFF || scat->r_type == PPC_RELOC_HA16)
+ {
+ ((unsigned short*) wordPtr)[1] = ((word >> 16) & 0xFFFF)
+ + ((word & (1<<15)) ? 1 : 0);
+ }