X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/afe874b1634377ecb27057ee76deb04915bb34d7..b2fa67a80bc53211e4d1ea81f23e9f953ee1dd6c:/src/ld/LinkEditClassic.hpp diff --git a/src/ld/LinkEditClassic.hpp b/src/ld/LinkEditClassic.hpp index 1429d95..7fbc755 100644 --- a/src/ld/LinkEditClassic.hpp +++ b/src/ld/LinkEditClassic.hpp @@ -798,52 +798,6 @@ void LocalRelocationsAtom::addPointerReloc(uint64_t addr, uint32_t symNum) template void LocalRelocationsAtom::addTextReloc(uint64_t addr, ld::Fixup::Kind kind, uint64_t targetAddr, uint32_t symNum) { - macho_relocation_info

reloc1; - macho_relocation_info

reloc2; - switch ( kind ) { - case ld::Fixup::kindStorePPCAbsLow14: - case ld::Fixup::kindStorePPCAbsLow16: - // a reference to the absolute address of something in this same linkage unit can be - // encoded as a local text reloc in a dylib or bundle - if ( _options.outputSlidable() ) { - reloc1.set_r_address(addr); - reloc1.set_r_symbolnum(symNum); - reloc1.set_r_pcrel(false); - reloc1.set_r_length(2); - reloc1.set_r_extern(false); - reloc1.set_r_type(kind==ld::Fixup::kindStorePPCAbsLow16 ? PPC_RELOC_LO16 : PPC_RELOC_LO14); - reloc2.set_r_address(targetAddr >> 16); - reloc2.set_r_symbolnum(0); - reloc2.set_r_pcrel(false); - reloc2.set_r_length(2); - reloc2.set_r_extern(false); - reloc2.set_r_type(PPC_RELOC_PAIR); - _relocs.push_back(reloc1); - _relocs.push_back(reloc2); - } - break; - case ld::Fixup::kindStorePPCAbsHigh16AddLow: - case ld::Fixup::kindStorePPCAbsHigh16: - if ( _options.outputSlidable() ) { - reloc1.set_r_address(addr); - reloc1.set_r_symbolnum(symNum); - reloc1.set_r_pcrel(false); - reloc1.set_r_length(2); - reloc1.set_r_extern(false); - reloc1.set_r_type(kind==ld::Fixup::kindStorePPCAbsHigh16AddLow ? PPC_RELOC_HA16 : PPC_RELOC_HI16); - reloc2.set_r_address(targetAddr & 0xFFFF); - reloc2.set_r_symbolnum(0); - reloc2.set_r_pcrel(false); - reloc2.set_r_length(2); - reloc2.set_r_extern(false); - reloc2.set_r_type(PPC_RELOC_PAIR); - _relocs.push_back(reloc1); - _relocs.push_back(reloc2); - } - break; - default: - break; - } } @@ -967,9 +921,7 @@ uint64_t ExternalRelocationsAtom::size() const template <> uint32_t ExternalRelocationsAtom::pointerReloc() { return ARM_RELOC_VANILLA; } template <> uint32_t ExternalRelocationsAtom::pointerReloc() { return GENERIC_RELOC_VANILLA; } -template <> uint32_t ExternalRelocationsAtom::pointerReloc() { return PPC_RELOC_VANILLA; } template <> uint32_t ExternalRelocationsAtom::pointerReloc() { return X86_64_RELOC_UNSIGNED; } -template <> uint32_t ExternalRelocationsAtom::pointerReloc() { return PPC_RELOC_VANILLA; } template <> uint32_t ExternalRelocationsAtom::callReloc() { return X86_64_RELOC_BRANCH; } @@ -1664,582 +1616,6 @@ void SectionRelocationsAtom::encodeSectionReloc(ld::Internal::FinalSection* } -template <> -void SectionRelocationsAtom::encodeSectionReloc(ld::Internal::FinalSection* sect, - const Entry& entry, std::vector >& relocs) -{ - macho_relocation_info

reloc1; - macho_relocation_info

reloc2; - macho_scattered_relocation_info

* sreloc1 = (macho_scattered_relocation_info

*)&reloc1; - macho_scattered_relocation_info

* sreloc2 = (macho_scattered_relocation_info

*)&reloc2; - uint64_t address = entry.inAtom->finalAddress()+entry.offsetInAtom - sect->address; - bool external = entry.toTargetUsesExternalReloc; - uint32_t symbolNum = sectSymNum(external, entry.toTarget); - bool fromExternal = false; - uint32_t fromSymbolNum = 0; - if ( entry.fromTarget != NULL ) { - fromExternal = entry.fromTargetUsesExternalReloc; - fromSymbolNum= sectSymNum(fromExternal, entry.fromTarget); - } - uint32_t toAddr; - uint32_t fromAddr; - - switch ( entry.kind ) { - - case ld::Fixup::kindStorePPCBranch24: - case ld::Fixup::kindStoreTargetAddressPPCBranch24: - case ld::Fixup::kindStorePPCDtraceCallSiteNop: - case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear: - if ( !external && (entry.toAddend != 0) ) { - // use scattered reloc if target offset is non-zero - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(true); - sreloc1->set_r_length(2); - sreloc1->set_r_type(PPC_RELOC_BR24); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - } - else { - reloc1.set_r_address(address); - reloc1.set_r_symbolnum(symbolNum); - reloc1.set_r_pcrel(true); - reloc1.set_r_length(2); - reloc1.set_r_extern(external); - reloc1.set_r_type(PPC_RELOC_BR24); - } - relocs.push_back(reloc1); - break; - - case ld::Fixup::kindStorePPCBranch14: - if ( !external && (entry.toAddend != 0) ) { - // use scattered reloc if target offset is non-zero - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(true); - sreloc1->set_r_length(2); - sreloc1->set_r_type(PPC_RELOC_BR14); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - } - else { - reloc1.set_r_address(address); - reloc1.set_r_symbolnum(symbolNum); - reloc1.set_r_pcrel(true); - reloc1.set_r_length(2); - reloc1.set_r_extern(external); - reloc1.set_r_type(PPC_RELOC_BR14); - } - relocs.push_back(reloc1); - break; - - case ld::Fixup::kindStoreBigEndian32: - case ld::Fixup::kindStoreTargetAddressBigEndian32: - if ( entry.fromTarget != NULL ) { - // this is a pointer-diff - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(2); - if ( entry.toTarget->scope() == ld::Atom::scopeTranslationUnit ) - sreloc1->set_r_type(PPC_RELOC_LOCAL_SECTDIFF); - else - sreloc1->set_r_type(PPC_RELOC_SECTDIFF); - sreloc1->set_r_address(address); - if ( entry.toTarget == entry.inAtom ) - sreloc1->set_r_value(entry.toTarget->finalAddress()+entry.toAddend); - else - sreloc1->set_r_value(entry.toTarget->finalAddress()); - sreloc2->set_r_scattered(true); - sreloc2->set_r_pcrel(false); - sreloc2->set_r_length(2); - sreloc2->set_r_type(PPC_RELOC_PAIR); - sreloc2->set_r_address(0); - if ( entry.fromTarget == entry.inAtom ) { - if ( entry.fromAddend > entry.fromTarget->size() ) - sreloc2->set_r_value(entry.fromTarget->finalAddress()+entry.offsetInAtom); - else - sreloc2->set_r_value(entry.fromTarget->finalAddress()+entry.fromAddend); - } - else - sreloc2->set_r_value(entry.fromTarget->finalAddress()); - relocs.push_back(reloc1); - relocs.push_back(reloc2); - } - else { - // regular pointer - if ( !external && (entry.toAddend != 0) ) { - // use scattered reloc is target offset is non-zero - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(2); - sreloc1->set_r_type(GENERIC_RELOC_VANILLA); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - } - else { - reloc1.set_r_address(address); - reloc1.set_r_symbolnum(symbolNum); - reloc1.set_r_pcrel(false); - reloc1.set_r_length(2); - reloc1.set_r_extern(external); - reloc1.set_r_type(GENERIC_RELOC_VANILLA); - } - relocs.push_back(reloc1); - } - break; - - case ld::Fixup::kindStorePPCAbsLow14: - case ld::Fixup::kindStorePPCAbsLow16: - if ( !external && (entry.toAddend != 0) ) { - // use scattered reloc if target offset is non-zero - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(2); - sreloc1->set_r_type(entry.kind==ld::Fixup::kindStorePPCAbsLow16 ? PPC_RELOC_LO16 : PPC_RELOC_LO14); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - } - else { - reloc1.set_r_address(address); - reloc1.set_r_symbolnum(symbolNum); - reloc1.set_r_pcrel(false); - reloc1.set_r_length(2); - reloc1.set_r_extern(external); - reloc1.set_r_type(entry.kind==ld::Fixup::kindStorePPCAbsLow16 ? PPC_RELOC_LO16 : PPC_RELOC_LO14); - } - if ( external ) - reloc2.set_r_address(entry.toAddend >> 16); - else - reloc2.set_r_address((entry.toTarget->finalAddress()+entry.toAddend) >> 16); - reloc2.set_r_symbolnum(0); - reloc2.set_r_pcrel(false); - reloc2.set_r_length(2); - reloc2.set_r_extern(false); - reloc2.set_r_type(PPC_RELOC_PAIR); - relocs.push_back(reloc1); - relocs.push_back(reloc2); - break; - - case ld::Fixup::kindStorePPCAbsHigh16: - if ( !external && (entry.toAddend != 0) ) { - // use scattered reloc if target offset is non-zero - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(2); - sreloc1->set_r_type(PPC_RELOC_HI16); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - } - else { - reloc1.set_r_address(address); - reloc1.set_r_symbolnum(symbolNum); - reloc1.set_r_pcrel(false); - reloc1.set_r_length(2); - reloc1.set_r_extern(external); - reloc1.set_r_type(PPC_RELOC_HI16); - } - if ( external ) - reloc2.set_r_address(entry.toAddend & 0x0000FFFF); - else - reloc2.set_r_address((entry.toTarget->finalAddress()+entry.toAddend) & 0x0000FFFF); - reloc2.set_r_symbolnum(0); - reloc2.set_r_pcrel(false); - reloc2.set_r_length(2); - reloc2.set_r_extern(false); - reloc2.set_r_type(PPC_RELOC_PAIR); - relocs.push_back(reloc1); - relocs.push_back(reloc2); - break; - - case ld::Fixup::kindStorePPCAbsHigh16AddLow: - if ( !external && (entry.toAddend != 0) ) { - // use scattered reloc if target offset is non-zero - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(2); - sreloc1->set_r_type(PPC_RELOC_HA16); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - } - else { - reloc1.set_r_address(address); - reloc1.set_r_symbolnum(symbolNum); - reloc1.set_r_pcrel(false); - reloc1.set_r_length(2); - reloc1.set_r_extern(external); - reloc1.set_r_type(PPC_RELOC_HA16); - } - if ( external ) - reloc2.set_r_address(entry.toAddend & 0x0000FFFF); - else - reloc2.set_r_address((entry.toTarget->finalAddress()+entry.toAddend) & 0x0000FFFF); - reloc2.set_r_symbolnum(0); - reloc2.set_r_pcrel(false); - reloc2.set_r_length(2); - reloc2.set_r_extern(false); - reloc2.set_r_type(PPC_RELOC_PAIR); - relocs.push_back(reloc1); - relocs.push_back(reloc2); - break; - - case ld::Fixup::kindStorePPCPicLow14: - case ld::Fixup::kindStorePPCPicLow16: - fromAddr = entry.fromTarget->finalAddress() + entry.fromAddend; - toAddr = entry.toTarget->finalAddress() + entry.toAddend; - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(2); - sreloc1->set_r_type(entry.kind == ld::Fixup::kindStorePPCPicLow16 ? PPC_RELOC_LO16_SECTDIFF : PPC_RELOC_LO14_SECTDIFF); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - sreloc2->set_r_scattered(true); - sreloc2->set_r_pcrel(false); - sreloc2->set_r_length(2); - sreloc2->set_r_type(PPC_RELOC_PAIR); - sreloc2->set_r_address(((toAddr-fromAddr) >> 16) & 0xFFFF); - sreloc2->set_r_value(fromAddr); - relocs.push_back(reloc1); - relocs.push_back(reloc2); - break; - - case ld::Fixup::kindStorePPCPicHigh16AddLow: - fromAddr = entry.fromTarget->finalAddress() + entry.fromAddend; - toAddr = entry.toTarget->finalAddress() + entry.toAddend; - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(2); - sreloc1->set_r_type(PPC_RELOC_HA16_SECTDIFF); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - sreloc2->set_r_scattered(true); - sreloc2->set_r_pcrel(false); - sreloc2->set_r_length(2); - sreloc2->set_r_type(PPC_RELOC_PAIR); - sreloc2->set_r_address((toAddr-fromAddr) & 0xFFFF); - sreloc2->set_r_value(fromAddr); - relocs.push_back(reloc1); - relocs.push_back(reloc2); - break; - - default: - assert(0 && "need to handle -r reloc"); - - } -} - -template <> -void SectionRelocationsAtom::encodeSectionReloc(ld::Internal::FinalSection* sect, - const Entry& entry, std::vector >& relocs) -{ - macho_relocation_info

reloc1; - macho_relocation_info

reloc2; - macho_scattered_relocation_info

* sreloc1 = (macho_scattered_relocation_info

*)&reloc1; - macho_scattered_relocation_info

* sreloc2 = (macho_scattered_relocation_info

*)&reloc2; - uint64_t address = entry.inAtom->finalAddress()+entry.offsetInAtom - sect->address; - bool external = entry.toTargetUsesExternalReloc; - uint32_t symbolNum = sectSymNum(external, entry.toTarget); - bool fromExternal = false; - uint32_t fromSymbolNum = 0; - if ( entry.fromTarget != NULL ) { - fromExternal = entry.fromTargetUsesExternalReloc; - fromSymbolNum= sectSymNum(fromExternal, entry.fromTarget); - } - uint32_t toAddr; - uint32_t fromAddr; - - switch ( entry.kind ) { - - case ld::Fixup::kindStorePPCBranch24: - case ld::Fixup::kindStoreTargetAddressPPCBranch24: - case ld::Fixup::kindStorePPCDtraceCallSiteNop: - case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear: - if ( !external && (entry.toAddend != 0) ) { - // use scattered reloc if target offset is non-zero - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(true); - sreloc1->set_r_length(2); - sreloc1->set_r_type(PPC_RELOC_BR24); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - } - else { - reloc1.set_r_address(address); - reloc1.set_r_symbolnum(symbolNum); - reloc1.set_r_pcrel(true); - reloc1.set_r_length(2); - reloc1.set_r_extern(external); - reloc1.set_r_type(PPC_RELOC_BR24); - } - relocs.push_back(reloc1); - break; - - case ld::Fixup::kindStorePPCBranch14: - if ( !external && (entry.toAddend != 0) ) { - // use scattered reloc if target offset is non-zero - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(true); - sreloc1->set_r_length(2); - sreloc1->set_r_type(PPC_RELOC_BR14); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - } - else { - reloc1.set_r_address(address); - reloc1.set_r_symbolnum(symbolNum); - reloc1.set_r_pcrel(true); - reloc1.set_r_length(2); - reloc1.set_r_extern(external); - reloc1.set_r_type(PPC_RELOC_BR14); - } - relocs.push_back(reloc1); - break; - - case ld::Fixup::kindStoreBigEndian32: - case ld::Fixup::kindStoreTargetAddressBigEndian32: - if ( entry.fromTarget != NULL ) { - // this is a pointer-diff - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(2); - if ( entry.toTarget->scope() == ld::Atom::scopeTranslationUnit ) - sreloc1->set_r_type(PPC_RELOC_LOCAL_SECTDIFF); - else - sreloc1->set_r_type(PPC_RELOC_SECTDIFF); - sreloc1->set_r_address(address); - if ( entry.toTarget == entry.inAtom ) - sreloc1->set_r_value(entry.toTarget->finalAddress()+entry.toAddend); - else - sreloc1->set_r_value(entry.toTarget->finalAddress()); - sreloc2->set_r_scattered(true); - sreloc2->set_r_pcrel(false); - sreloc2->set_r_length(2); - sreloc2->set_r_type(PPC_RELOC_PAIR); - sreloc2->set_r_address(0); - if ( entry.fromTarget == entry.inAtom ) { - if ( entry.fromAddend > entry.fromTarget->size() ) - sreloc2->set_r_value(entry.fromTarget->finalAddress()+entry.offsetInAtom); - else - sreloc2->set_r_value(entry.fromTarget->finalAddress()+entry.fromAddend); - } - else - sreloc2->set_r_value(entry.fromTarget->finalAddress()); - relocs.push_back(reloc1); - relocs.push_back(reloc2); - } - else { - // regular pointer - if ( !external && (entry.toAddend != 0) ) { - // use scattered reloc is target offset is non-zero - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(2); - sreloc1->set_r_type(GENERIC_RELOC_VANILLA); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - } - else { - reloc1.set_r_address(address); - reloc1.set_r_symbolnum(symbolNum); - reloc1.set_r_pcrel(false); - reloc1.set_r_length(2); - reloc1.set_r_extern(external); - reloc1.set_r_type(GENERIC_RELOC_VANILLA); - } - relocs.push_back(reloc1); - } - break; - - case ld::Fixup::kindStoreBigEndian64: - case ld::Fixup::kindStoreTargetAddressBigEndian64: - if ( entry.fromTarget != NULL ) { - // this is a pointer-diff - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(3); - if ( entry.toTarget->scope() == ld::Atom::scopeTranslationUnit ) - sreloc1->set_r_type(PPC_RELOC_LOCAL_SECTDIFF); - else - sreloc1->set_r_type(PPC_RELOC_SECTDIFF); - sreloc1->set_r_address(address); - if ( entry.toTarget == entry.inAtom ) - sreloc1->set_r_value(entry.toTarget->finalAddress()+entry.toAddend); - else - sreloc1->set_r_value(entry.toTarget->finalAddress()); - sreloc2->set_r_scattered(true); - sreloc2->set_r_pcrel(false); - sreloc2->set_r_length(3); - sreloc2->set_r_type(PPC_RELOC_PAIR); - sreloc2->set_r_address(0); - if ( entry.fromTarget == entry.inAtom ) { - if ( entry.fromAddend > entry.fromTarget->size() ) - sreloc2->set_r_value(entry.fromTarget->finalAddress()+entry.offsetInAtom); - else - sreloc2->set_r_value(entry.fromTarget->finalAddress()+entry.fromAddend); - } - else - sreloc2->set_r_value(entry.fromTarget->finalAddress()); - relocs.push_back(reloc1); - relocs.push_back(reloc2); - } - else { - // regular pointer - if ( !external && (entry.toAddend != 0) ) { - // use scattered reloc is target offset is non-zero - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(3); - sreloc1->set_r_type(GENERIC_RELOC_VANILLA); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - } - else { - reloc1.set_r_address(address); - reloc1.set_r_symbolnum(symbolNum); - reloc1.set_r_pcrel(false); - reloc1.set_r_length(3); - reloc1.set_r_extern(external); - reloc1.set_r_type(GENERIC_RELOC_VANILLA); - } - relocs.push_back(reloc1); - } - break; - - case ld::Fixup::kindStorePPCAbsLow14: - case ld::Fixup::kindStorePPCAbsLow16: - if ( !external && (entry.toAddend != 0) ) { - // use scattered reloc if target offset is non-zero - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(2); - sreloc1->set_r_type(entry.kind==ld::Fixup::kindStorePPCAbsLow16 ? PPC_RELOC_LO16 : PPC_RELOC_LO14); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - } - else { - reloc1.set_r_address(address); - reloc1.set_r_symbolnum(symbolNum); - reloc1.set_r_pcrel(false); - reloc1.set_r_length(2); - reloc1.set_r_extern(external); - reloc1.set_r_type(entry.kind==ld::Fixup::kindStorePPCAbsLow16 ? PPC_RELOC_LO16 : PPC_RELOC_LO14); - } - if ( external ) - reloc2.set_r_address(entry.toAddend >> 16); - else - reloc2.set_r_address((entry.toTarget->finalAddress()+entry.toAddend) >> 16); - reloc2.set_r_symbolnum(0); - reloc2.set_r_pcrel(false); - reloc2.set_r_length(2); - reloc2.set_r_extern(false); - reloc2.set_r_type(PPC_RELOC_PAIR); - relocs.push_back(reloc1); - relocs.push_back(reloc2); - break; - - case ld::Fixup::kindStorePPCAbsHigh16: - if ( !external && (entry.toAddend != 0) ) { - // use scattered reloc if target offset is non-zero - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(2); - sreloc1->set_r_type(PPC_RELOC_HI16); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - } - else { - reloc1.set_r_address(address); - reloc1.set_r_symbolnum(symbolNum); - reloc1.set_r_pcrel(false); - reloc1.set_r_length(2); - reloc1.set_r_extern(external); - reloc1.set_r_type(PPC_RELOC_HI16); - } - if ( external ) - reloc2.set_r_address(entry.toAddend & 0x0000FFFF); - else - reloc2.set_r_address((entry.toTarget->finalAddress()+entry.toAddend) & 0x0000FFFF); - reloc2.set_r_symbolnum(0); - reloc2.set_r_pcrel(false); - reloc2.set_r_length(2); - reloc2.set_r_extern(false); - reloc2.set_r_type(PPC_RELOC_PAIR); - relocs.push_back(reloc1); - relocs.push_back(reloc2); - break; - - case ld::Fixup::kindStorePPCAbsHigh16AddLow: - if ( !external && (entry.toAddend != 0) ) { - // use scattered reloc if target offset is non-zero - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(2); - sreloc1->set_r_type(PPC_RELOC_HA16); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - } - else { - reloc1.set_r_address(address); - reloc1.set_r_symbolnum(symbolNum); - reloc1.set_r_pcrel(false); - reloc1.set_r_length(2); - reloc1.set_r_extern(external); - reloc1.set_r_type(PPC_RELOC_HA16); - } - if ( external ) - reloc2.set_r_address(entry.toAddend & 0x0000FFFF); - else - reloc2.set_r_address((entry.toTarget->finalAddress()+entry.toAddend) & 0x0000FFFF); - reloc2.set_r_symbolnum(0); - reloc2.set_r_pcrel(false); - reloc2.set_r_length(2); - reloc2.set_r_extern(false); - reloc2.set_r_type(PPC_RELOC_PAIR); - relocs.push_back(reloc1); - relocs.push_back(reloc2); - break; - - case ld::Fixup::kindStorePPCPicLow14: - case ld::Fixup::kindStorePPCPicLow16: - fromAddr = entry.fromTarget->finalAddress() + entry.fromAddend; - toAddr = entry.toTarget->finalAddress() + entry.toAddend; - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(2); - sreloc1->set_r_type(entry.kind == ld::Fixup::kindStorePPCPicLow16 ? PPC_RELOC_LO16_SECTDIFF : PPC_RELOC_LO14_SECTDIFF); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - sreloc2->set_r_scattered(true); - sreloc2->set_r_pcrel(false); - sreloc2->set_r_length(2); - sreloc2->set_r_type(PPC_RELOC_PAIR); - sreloc2->set_r_address(((toAddr-fromAddr) >> 16) & 0xFFFF); - sreloc2->set_r_value(fromAddr); - relocs.push_back(reloc1); - relocs.push_back(reloc2); - break; - - case ld::Fixup::kindStorePPCPicHigh16AddLow: - fromAddr = entry.fromTarget->finalAddress() + entry.fromAddend; - toAddr = entry.toTarget->finalAddress() + entry.toAddend; - sreloc1->set_r_scattered(true); - sreloc1->set_r_pcrel(false); - sreloc1->set_r_length(2); - sreloc1->set_r_type(PPC_RELOC_HA16_SECTDIFF); - sreloc1->set_r_address(address); - sreloc1->set_r_value(entry.toTarget->finalAddress()); - sreloc2->set_r_scattered(true); - sreloc2->set_r_pcrel(false); - sreloc2->set_r_length(2); - sreloc2->set_r_type(PPC_RELOC_PAIR); - sreloc2->set_r_address((toAddr-fromAddr) & 0xFFFF); - sreloc2->set_r_value(fromAddr); - relocs.push_back(reloc1); - relocs.push_back(reloc2); - break; - - default: - assert(0 && "need to handle -r reloc"); - - } -} template void SectionRelocationsAtom::addSectionReloc(ld::Internal::FinalSection* sect, ld::Fixup::Kind kind,