// second pass, assign section address to sections in segments that are contiguous with previous segment
address = floatingAddressStart;
lastSegName = "";
+ ld::Internal::FinalSection* overlappingFixedSection = NULL;
+ ld::Internal::FinalSection* overlappingFlowSection = NULL;
if ( log ) fprintf(stderr, "Regular layout segments:\n");
for (std::vector<ld::Internal::FinalSection*>::iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
ld::Internal::FinalSection* sect = *it;
&& (_options.outputKind() != Options::kStaticExecutable) )
throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
sect->sectionName(), address, sect->size);
+
+ // sanity check it does not overlap a fixed address segment
+ for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
+ ld::Internal::FinalSection* otherSect = *sit;
+ if ( ! _options.hasCustomSegmentAddress(otherSect->segmentName()) )
+ continue;
+ if ( sect->address > otherSect->address ) {
+ if ( (otherSect->address+otherSect->size) > sect->address ) {
+ overlappingFixedSection = otherSect;
+ overlappingFlowSection = sect;
+ }
+ }
+ else {
+ if ( (sect->address+sect->size) > otherSect->address ) {
+ overlappingFixedSection = otherSect;
+ overlappingFlowSection = sect;
+ }
+ }
+ }
if ( log ) fprintf(stderr, " address=0x%08llX, hidden=%d, alignment=%02d, padBytes=%d, section=%s,%s\n",
sect->address, sect->isSectionHidden(), sect->alignment, sect->alignmentPaddingBytes,
if ( !sect->isSectionHidden() || hiddenSectionsOccupyAddressSpace )
address += sect->size;
}
+ if ( overlappingFixedSection != NULL ) {
+ fprintf(stderr, "Section layout:\n");
+ for (std::vector<ld::Internal::FinalSection*>::iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
+ ld::Internal::FinalSection* sect = *it;
+ if ( sect->isSectionHidden() )
+ continue;
+ fprintf(stderr, " address:0x%08llX, alignment:2^%d, size:0x%08llX, padBytes:%d, section:%s/%s\n",
+ sect->address, sect->alignment, sect->size, sect->alignmentPaddingBytes,
+ sect->segmentName(), sect->sectionName());
+
+ }
+ throwf("Section (%s/%s) overlaps fixed address section (%s/%s)",
+ overlappingFlowSection->segmentName(), overlappingFlowSection->sectionName(),
+ overlappingFixedSection->segmentName(), overlappingFixedSection->sectionName());
+ }
// third pass, assign section file offsets
}
}
-void OutputFile::rangeCheckPPCBranch24(int64_t displacement, ld::Internal& state, const ld::Atom* atom, const ld::Fixup* fixup)
-{
- const int64_t bl_eightMegLimit = 0x00FFFFFF;
- if ( (displacement > bl_eightMegLimit) || (displacement < (-bl_eightMegLimit)) ) {
- // show layout of final image
- printSectionLayout(state);
-
- const ld::Atom* target;
- throwf("bl PPC branch out of range (%lld max is +/-16MB): from %s (0x%08llX) to %s (0x%08llX)",
- displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup),
- addressOf(state, fixup, &target));
- }
-}
-
-void OutputFile::rangeCheckPPCBranch14(int64_t displacement, ld::Internal& state, const ld::Atom* atom, const ld::Fixup* fixup)
-{
- const int64_t b_sixtyFourKiloLimit = 0x0000FFFF;
- if ( (displacement > b_sixtyFourKiloLimit) || (displacement < (-b_sixtyFourKiloLimit)) ) {
- // show layout of final image
- printSectionLayout(state);
-
- const ld::Atom* target;
- throwf("bcc PPC branch out of range (%lld max is +/-64KB): from %s (0x%08llX) to %s (0x%08llX)",
- displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup),
- addressOf(state, fixup, &target));
- }
-}
int64_t delta;
uint32_t instruction;
uint32_t newInstruction;
- uint16_t instructionLowHalf;
bool is_bl;
bool is_blx;
bool is_b;
}
set32LE(fixUpLocation, newInstruction);
break;
- case ld::Fixup::kindStorePPCBranch14:
- delta = accumulator - (atom->finalAddress() + fit->offsetInAtom);
- rangeCheckPPCBranch14(delta, state, atom, fit);
- instruction = get32BE(fixUpLocation);
- newInstruction = (instruction & 0xFFFF0003) | ((uint32_t)delta & 0x0000FFFC);
- set32BE(fixUpLocation, newInstruction);
- break;
- case ld::Fixup::kindStorePPCPicLow14:
- case ld::Fixup::kindStorePPCAbsLow14:
- instruction = get32BE(fixUpLocation);
- if ( (accumulator & 0x3) != 0 )
- throwf("bad offset (0x%08X) for lo14 instruction pic-base fix-up", (uint32_t)accumulator);
- newInstruction = (instruction & 0xFFFF0003) | (accumulator & 0xFFFC);
- set32BE(fixUpLocation, newInstruction);
- break;
- case ld::Fixup::kindStorePPCAbsLow16:
- case ld::Fixup::kindStorePPCPicLow16:
- instruction = get32BE(fixUpLocation);
- newInstruction = (instruction & 0xFFFF0000) | (accumulator & 0xFFFF);
- set32BE(fixUpLocation, newInstruction);
- break;
- case ld::Fixup::kindStorePPCAbsHigh16AddLow:
- case ld::Fixup::kindStorePPCPicHigh16AddLow:
- instructionLowHalf = (accumulator >> 16) & 0xFFFF;
- if ( accumulator & 0x00008000 )
- ++instructionLowHalf;
- instruction = get32BE(fixUpLocation);
- newInstruction = (instruction & 0xFFFF0000) | instructionLowHalf;
- set32BE(fixUpLocation, newInstruction);
- break;
- case ld::Fixup::kindStorePPCAbsHigh16:
- instruction = get32BE(fixUpLocation);
- newInstruction = (instruction & 0xFFFF0000) | ((accumulator >> 16) & 0xFFFF);
- set32BE(fixUpLocation, newInstruction);
- break;
case ld::Fixup::kindDtraceExtra:
break;
case ld::Fixup::kindStoreX86DtraceCallSiteNop:
fixUpLocation[3] = 0x90; // 1-byte nop
}
break;
- case ld::Fixup::kindStorePPCDtraceCallSiteNop:
- if ( _options.outputKind() != Options::kObjectFile ) {
- // change call site to a NOP
- set32BE(fixUpLocation, 0x60000000);
- }
- break;
- case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear:
- if ( _options.outputKind() != Options::kObjectFile ) {
- // change call site to a li r3,0
- set32BE(fixUpLocation, 0x38600000);
- }
- break;
case ld::Fixup::kindStoreARMDtraceCallSiteNop:
if ( _options.outputKind() != Options::kObjectFile ) {
// change call site to a NOP
set32LE(fixUpLocation, newInstruction);
}
break;
- case ld::Fixup::kindStoreTargetAddressPPCBranch24:
- accumulator = addressOf(state, fit, &toTarget);
- if ( fit->contentDetlaToAddendOnly )
- accumulator = 0;
- // fall into kindStorePPCBranch24 case
- case ld::Fixup::kindStorePPCBranch24:
- delta = accumulator - (atom->finalAddress() + fit->offsetInAtom);
- rangeCheckPPCBranch24(delta, state, atom, fit);
- instruction = get32BE(fixUpLocation);
- newInstruction = (instruction & 0xFC000003) | ((uint32_t)delta & 0x03FFFFFC);
- set32BE(fixUpLocation, newInstruction);
- break;
}
}
}
void OutputFile::copyNoOps(uint8_t* from, uint8_t* to, bool thumb)
{
switch ( _options.architecture() ) {
- case CPU_TYPE_POWERPC:
- for (uint8_t* p=from; p < to; p += 4)
- OSWriteBigInt32((uint32_t*)p, 0, 0x60000000);
- break;
case CPU_TYPE_I386:
case CPU_TYPE_X86_64:
for (uint8_t* p=from; p < to; ++p)
return addPreloadLinkEdit(state);
switch ( _options.architecture() ) {
- case CPU_TYPE_POWERPC:
- if ( _hasSectionRelocations ) {
- _sectionsRelocationsAtom = new SectionRelocationsAtom<ppc>(_options, state, *this);
- sectionRelocationsSection = state.addAtom(*_sectionsRelocationsAtom);
- }
- if ( _hasDyldInfo ) {
- _rebasingInfoAtom = new RebaseInfoAtom<ppc>(_options, state, *this);
- rebaseSection = state.addAtom(*_rebasingInfoAtom);
-
- _bindingInfoAtom = new BindingInfoAtom<ppc>(_options, state, *this);
- bindingSection = state.addAtom(*_bindingInfoAtom);
-
- _weakBindingInfoAtom = new WeakBindingInfoAtom<ppc>(_options, state, *this);
- weakBindingSection = state.addAtom(*_weakBindingInfoAtom);
-
- _lazyBindingInfoAtom = new LazyBindingInfoAtom<ppc>(_options, state, *this);
- lazyBindingSection = state.addAtom(*_lazyBindingInfoAtom);
-
- _exportInfoAtom = new ExportInfoAtom<ppc>(_options, state, *this);
- exportSection = state.addAtom(*_exportInfoAtom);
- }
- if ( _hasLocalRelocations ) {
- _localRelocsAtom = new LocalRelocationsAtom<ppc>(_options, state, *this);
- localRelocationsSection = state.addAtom(*_localRelocsAtom);
- }
- if ( _hasSplitSegInfo ) {
- _splitSegInfoAtom = new SplitSegInfoAtom<ppc>(_options, state, *this);
- splitSegInfoSection = state.addAtom(*_splitSegInfoAtom);
- }
- if ( _hasFunctionStartsInfo ) {
- _functionStartsAtom = new FunctionStartsAtom<ppc>(_options, state, *this);
- functionStartsSection = state.addAtom(*_functionStartsAtom);
- }
- if ( _hasSymbolTable ) {
- _symbolTableAtom = new SymbolTableAtom<ppc>(_options, state, *this);
- symbolTableSection = state.addAtom(*_symbolTableAtom);
- }
- if ( _hasExternalRelocations ) {
- _externalRelocsAtom = new ExternalRelocationsAtom<ppc>(_options, state, *this);
- externalRelocationsSection = state.addAtom(*_externalRelocsAtom);
- }
- if ( _hasSymbolTable ) {
- _indirectSymbolTableAtom = new IndirectSymbolTableAtom<ppc>(_options, state, *this);
- indirectSymbolTableSection = state.addAtom(*_indirectSymbolTableAtom);
- _stringPoolAtom = new StringPoolAtom(_options, state, *this, 4);
- stringPoolSection = state.addAtom(*_stringPoolAtom);
- }
- break;
case CPU_TYPE_I386:
if ( _hasSectionRelocations ) {
_sectionsRelocationsAtom = new SectionRelocationsAtom<x86>(_options, state, *this);
stringPoolSection = state.addAtom(*_stringPoolAtom);
}
break;
- case CPU_TYPE_POWERPC64:
- if ( _hasSectionRelocations ) {
- _sectionsRelocationsAtom = new SectionRelocationsAtom<ppc64>(_options, state, *this);
- sectionRelocationsSection = state.addAtom(*_sectionsRelocationsAtom);
- }
- if ( _hasDyldInfo ) {
- _rebasingInfoAtom = new RebaseInfoAtom<ppc64>(_options, state, *this);
- rebaseSection = state.addAtom(*_rebasingInfoAtom);
-
- _bindingInfoAtom = new BindingInfoAtom<ppc64>(_options, state, *this);
- bindingSection = state.addAtom(*_bindingInfoAtom);
-
- _weakBindingInfoAtom = new WeakBindingInfoAtom<ppc64>(_options, state, *this);
- weakBindingSection = state.addAtom(*_weakBindingInfoAtom);
-
- _lazyBindingInfoAtom = new LazyBindingInfoAtom<ppc64>(_options, state, *this);
- lazyBindingSection = state.addAtom(*_lazyBindingInfoAtom);
-
- _exportInfoAtom = new ExportInfoAtom<ppc64>(_options, state, *this);
- exportSection = state.addAtom(*_exportInfoAtom);
- }
- if ( _hasLocalRelocations ) {
- _localRelocsAtom = new LocalRelocationsAtom<ppc64>(_options, state, *this);
- localRelocationsSection = state.addAtom(*_localRelocsAtom);
- }
- if ( _hasSplitSegInfo ) {
- _splitSegInfoAtom = new SplitSegInfoAtom<ppc64>(_options, state, *this);
- splitSegInfoSection = state.addAtom(*_splitSegInfoAtom);
- }
- if ( _hasFunctionStartsInfo ) {
- _functionStartsAtom = new FunctionStartsAtom<ppc64>(_options, state, *this);
- functionStartsSection = state.addAtom(*_functionStartsAtom);
- }
- if ( _hasSymbolTable ) {
- _symbolTableAtom = new SymbolTableAtom<ppc64>(_options, state, *this);
- symbolTableSection = state.addAtom(*_symbolTableAtom);
- }
- if ( _hasExternalRelocations ) {
- _externalRelocsAtom = new ExternalRelocationsAtom<ppc64>(_options, state, *this);
- externalRelocationsSection = state.addAtom(*_externalRelocsAtom);
- }
- if ( _hasSymbolTable ) {
- _indirectSymbolTableAtom = new IndirectSymbolTableAtom<ppc64>(_options, state, *this);
- indirectSymbolTableSection = state.addAtom(*_indirectSymbolTableAtom);
- _stringPoolAtom = new StringPoolAtom(_options, state, *this, 4);
- stringPoolSection = state.addAtom(*_stringPoolAtom);
- }
- break;
default:
throw "unknown architecture";
}
_headersAndLoadCommandAtom = new HeaderAndLoadCommandsAtom<x86>(_options, state, *this);
headerAndLoadCommandsSection = state.addAtom(*_headersAndLoadCommandAtom);
break;
- case CPU_TYPE_POWERPC:
- _headersAndLoadCommandAtom = new HeaderAndLoadCommandsAtom<ppc>(_options, state, *this);
- headerAndLoadCommandsSection = state.addAtom(*_headersAndLoadCommandAtom);
- break;
- case CPU_TYPE_POWERPC64:
- _headersAndLoadCommandAtom = new HeaderAndLoadCommandsAtom<ppc64>(_options, state, *this);
- headerAndLoadCommandsSection = state.addAtom(*_headersAndLoadCommandAtom);
- break;
default:
throw "unknown architecture";
}
case ld::Fixup::kindStoreARMBranch24:
case ld::Fixup::kindStoreThumbBranch22:
case ld::Fixup::kindStoreARMLoad12:
- case ld::Fixup::kindStorePPCBranch24:
- case ld::Fixup::kindStorePPCBranch14:
- case ld::Fixup::kindStorePPCPicLow14:
- case ld::Fixup::kindStorePPCPicLow16:
- case ld::Fixup::kindStorePPCPicHigh16AddLow:
case ld::Fixup::kindStoreTargetAddressX86PCRel32:
case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad:
case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA:
case ld::Fixup::kindStoreTargetAddressARMBranch24:
case ld::Fixup::kindStoreTargetAddressThumbBranch22:
case ld::Fixup::kindStoreTargetAddressARMLoad12:
- case ld::Fixup::kindStoreTargetAddressPPCBranch24:
return true;
case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32:
return (_options.outputKind() != Options::kKextBundle);
case ld::Fixup::kindStoreTargetAddressARMBranch24:
case ld::Fixup::kindStoreTargetAddressThumbBranch22:
case ld::Fixup::kindStoreTargetAddressARMLoad12:
- case ld::Fixup::kindStoreTargetAddressPPCBranch24:
return true;
case ld::Fixup::kindStoreX86DtraceCallSiteNop:
case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear:
case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear:
case ld::Fixup::kindStoreThumbDtraceCallSiteNop:
case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear:
- case ld::Fixup::kindStorePPCDtraceCallSiteNop:
- case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear:
return (_options.outputKind() == Options::kObjectFile);
default:
break;
sect->hasLocalRelocs = true;
}
break;
- case ld::Fixup::kindStorePPCAbsLow14:
- case ld::Fixup::kindStorePPCAbsLow16:
- case ld::Fixup::kindStorePPCAbsHigh16AddLow:
- case ld::Fixup::kindStorePPCAbsHigh16:
- {
- assert(target != NULL);
- if ( target->definition() == ld::Atom::definitionProxy )
- throwf("half word text relocs not supported in %s", atom->name());
- if ( _options.outputSlidable() ) {
- if ( inReadOnlySeg )
- noteTextReloc(atom, target);
- uint32_t machoSectionIndex = (target->definition() == ld::Atom::definitionAbsolute)
- ? R_ABS : target->machoSection();
- _localRelocsAtom->addTextReloc(relocAddress, fixupWithTarget->kind,
- target->finalAddress(), machoSectionIndex);
- sect->hasLocalRelocs = true;
- }
- }
- break;
case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32:
if ( _options.outputKind() == Options::kKextBundle ) {
assert(target != NULL);
case ld::Fixup::kindStoreX86PCRel32GOTLoad:
case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA:
case ld::Fixup::kindStoreX86PCRel32GOT:
- case ld::Fixup::kindStorePPCPicHigh16AddLow:
case ld::Fixup::kindStoreTargetAddressX86PCRel32:
case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad:
case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA: