void partitionIntoSections();
bool addBranchIslands();
bool addPPCBranchIslands();
- uint8_t branch24Reference();
+ bool isBranch24Reference(uint8_t kind);
void adjustLoadCommandsAndPadding();
void createDynamicLinkerCommand();
void createDylibCommands();
virtual bool requiresFollowOnAtom() const { return false; }
virtual ObjectFile::Atom& getFollowOnAtom() const { return *((ObjectFile::Atom*)NULL); }
virtual std::vector<ObjectFile::LineInfo>* getLineInfo() const { return NULL; }
- virtual uint8_t getAlignment() const { return 2; }
+ virtual ObjectFile::Alignment getAlignment() const { return ObjectFile::Alignment(2); }
virtual void copyRawContent(uint8_t buffer[]) const { throw "don't use copyRawContent"; }
virtual void setScope(Scope) { }
virtual bool isZeroFill() const { return true; }
virtual uint64_t getSize() const { return fSize; }
virtual const char* getSectionName() const { return "._zeropage"; }
- virtual uint8_t getAlignment() const { return 12; }
+ virtual ObjectFile::Alignment getAlignment() const { return ObjectFile::Alignment(12); }
void setSize(uint64_t size) { fSize = size; }
private:
using WriterAtom<A>::fWriter;
virtual ObjectFile::Atom::Scope getScope() const { return ObjectFile::Atom::scopeLinkageUnit; }
virtual ObjectFile::Atom::SymbolTableInclusion getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableNotIn; }
virtual uint64_t getSize() const { return 0; }
- virtual uint8_t getAlignment() const { return 12; }
+ virtual ObjectFile::Alignment getAlignment() const { return ObjectFile::Alignment(12); }
virtual const char* getSectionName() const { return "._mach_header"; }
virtual void copyRawContent(uint8_t buffer[]) const {}
};
virtual ObjectFile::Atom::Scope getScope() const;
virtual ObjectFile::Atom::SymbolTableInclusion getSymbolTableInclusion() const;
virtual uint64_t getSize() const { return sizeof(macho_header<typename A::P>); }
- virtual uint8_t getAlignment() const { return 12; }
+ virtual ObjectFile::Alignment getAlignment() const { return ObjectFile::Alignment(12); }
virtual const char* getSectionName() const { return "._mach_header"; }
virtual void copyRawContent(uint8_t buffer[]) const;
private:
virtual bool isZeroFill() const { return true; }
virtual uint64_t getSize() const { return fWriter.fOptions.customStackSize(); }
virtual const char* getSectionName() const { return "._stack"; }
- virtual uint8_t getAlignment() const { return 12; }
+ virtual ObjectFile::Alignment getAlignment() const { return ObjectFile::Alignment(12); }
private:
using WriterAtom<A>::fWriter;
typedef typename A::P P;
{
protected:
LoadCommandAtom(Writer<A>& writer, Segment& segment) : WriterAtom<A>(writer, segment) {}
+ virtual ObjectFile::Alignment getAlignment() const { return ObjectFile::Alignment(log2(sizeof(typename A::P::uint_t))); }
+ virtual const char* getSectionName() const { return "._load_commands"; }
static uint64_t alignedSize(uint64_t size);
};
{ writer.fSegmentCommands = this; }
virtual const char* getDisplayName() const { return "segment load commands"; }
virtual uint64_t getSize() const { return fSize; }
- virtual uint8_t getAlignment() const { return 2; }
- virtual const char* getSectionName() const { return "._load_commands"; }
virtual void copyRawContent(uint8_t buffer[]) const;
void computeSize();
SymbolTableLoadCommandsAtom(Writer<A>&);
virtual const char* getDisplayName() const { return "symbol table load commands"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 2; }
- virtual const char* getSectionName() const { return "._load_commands"; }
virtual void copyRawContent(uint8_t buffer[]) const;
unsigned int commandCount();
: LoadCommandAtom<A>(writer, Segment::fgTextSegment) {}
virtual const char* getDisplayName() const { return "thread load commands"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 2; }
- virtual const char* getSectionName() const { return "._load_commands"; }
virtual void copyRawContent(uint8_t buffer[]) const;
private:
using WriterAtom<A>::fWriter;
DyldLoadCommandsAtom(Writer<A>& writer) : LoadCommandAtom<A>(writer, Segment::fgTextSegment) {}
virtual const char* getDisplayName() const { return "dyld load command"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 2; }
- virtual const char* getSectionName() const { return "._load_commands"; }
virtual void copyRawContent(uint8_t buffer[]) const;
private:
using WriterAtom<A>::fWriter;
LoadCommandAtom<A>(writer, Segment::fgTextSegment), clientString(client) {}
virtual const char* getDisplayName() const { return "allowable_client load command"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 2; }
- virtual const char* getSectionName() const { return "._load_commands"; }
virtual void copyRawContent(uint8_t buffer[]) const;
private:
using WriterAtom<A>::fWriter;
: LoadCommandAtom<A>(writer, Segment::fgTextSegment), fInfo(info) {}
virtual const char* getDisplayName() const { return "dylib load command"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 2; }
- virtual const char* getSectionName() const { return "._load_commands"; }
virtual void copyRawContent(uint8_t buffer[]) const;
private:
using WriterAtom<A>::fWriter;
DylibIDLoadCommandsAtom(Writer<A>& writer) : LoadCommandAtom<A>(writer, Segment::fgTextSegment) {}
virtual const char* getDisplayName() const { return "dylib ID load command"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 2; }
- virtual const char* getSectionName() const { return "._load_commands"; }
virtual void copyRawContent(uint8_t buffer[]) const;
private:
using WriterAtom<A>::fWriter;
RoutinesLoadCommandsAtom(Writer<A>& writer) : LoadCommandAtom<A>(writer, Segment::fgTextSegment) {}
virtual const char* getDisplayName() const { return "routines load command"; }
virtual uint64_t getSize() const { return sizeof(macho_routines_command<typename A::P>); }
- virtual uint8_t getAlignment() const { return 2; }
- virtual const char* getSectionName() const { return "._load_commands"; }
virtual void copyRawContent(uint8_t buffer[]) const;
private:
using WriterAtom<A>::fWriter;
: LoadCommandAtom<A>(writer, Segment::fgTextSegment), fName(name) {}
virtual const char* getDisplayName() const { return "sub-umbrella load command"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 2; }
- virtual const char* getSectionName() const { return "._load_commands"; }
virtual void copyRawContent(uint8_t buffer[]) const;
private:
typedef typename A::P P;
: LoadCommandAtom<A>(writer, Segment::fgTextSegment), fNameStart(nameStart), fNameLength(nameLen) {}
virtual const char* getDisplayName() const { return "sub-library load command"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 2; }
- virtual const char* getSectionName() const { return "._load_commands"; }
virtual void copyRawContent(uint8_t buffer[]) const;
private:
using WriterAtom<A>::fWriter;
: LoadCommandAtom<A>(writer, Segment::fgTextSegment), fName(name) {}
virtual const char* getDisplayName() const { return "umbrella load command"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 2; }
- virtual const char* getSectionName() const { return "._load_commands"; }
virtual void copyRawContent(uint8_t buffer[]) const;
private:
using WriterAtom<A>::fWriter;
: LoadCommandAtom<A>(writer, Segment::fgTextSegment), fEmit(false) { ::uuid_generate_random(fUUID);}
virtual const char* getDisplayName() const { return "uuid load command"; }
virtual uint64_t getSize() const { return fEmit ? sizeof(macho_uuid_command<typename A::P>) : 0; }
- virtual uint8_t getAlignment() const { return 2; }
- virtual const char* getSectionName() const { return "._load_commands"; }
virtual void copyRawContent(uint8_t buffer[]) const;
virtual void emit() { fEmit = true; }
private:
: WriterAtom<A>(writer, Segment::fgTextSegment), fSize(0) {}
virtual const char* getDisplayName() const { return "header padding"; }
virtual uint64_t getSize() const { return fSize; }
- virtual uint8_t getAlignment() const { return 2; }
virtual const char* getSectionName() const { return "._load_cmds_pad"; }
virtual void copyRawContent(uint8_t buffer[]) const;
SectionRelocationsLinkEditAtom(Writer<A>& writer) : LinkEditAtom<A>(writer) { }
virtual const char* getDisplayName() const { return "section relocations"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 3; }
+ virtual ObjectFile::Alignment getAlignment() const { return ObjectFile::Alignment(3); }
virtual const char* getSectionName() const { return "._section_relocs"; }
virtual void copyRawContent(uint8_t buffer[]) const;
private:
LocalRelocationsLinkEditAtom(Writer<A>& writer) : LinkEditAtom<A>(writer) { }
virtual const char* getDisplayName() const { return "local relocations"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 3; }
+ virtual ObjectFile::Alignment getAlignment() const { return ObjectFile::Alignment(3); }
virtual const char* getSectionName() const { return "._local_relocs"; }
virtual void copyRawContent(uint8_t buffer[]) const;
private:
SymbolTableLinkEditAtom(Writer<A>& writer) : LinkEditAtom<A>(writer) { }
virtual const char* getDisplayName() const { return "symbol table"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 2; }
virtual const char* getSectionName() const { return "._symbol_table"; }
virtual void copyRawContent(uint8_t buffer[]) const;
private:
ExternalRelocationsLinkEditAtom(Writer<A>& writer) : LinkEditAtom<A>(writer) { }
virtual const char* getDisplayName() const { return "external relocations"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 3; }
+ virtual ObjectFile::Alignment getAlignment() const { return ObjectFile::Alignment(3); }
virtual const char* getSectionName() const { return "._extern_relocs"; }
virtual void copyRawContent(uint8_t buffer[]) const;
private:
IndirectTableLinkEditAtom(Writer<A>& writer) : LinkEditAtom<A>(writer) { }
virtual const char* getDisplayName() const { return "indirect symbol table"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 2; }
virtual const char* getSectionName() const { return "._indirect_syms"; }
virtual void copyRawContent(uint8_t buffer[]) const;
StringsLinkEditAtom(Writer<A>& writer);
virtual const char* getDisplayName() const { return "string pool"; }
virtual uint64_t getSize() const;
- virtual uint8_t getAlignment() const { return 2; }
virtual const char* getSectionName() const { return "._string_pool"; }
virtual void copyRawContent(uint8_t buffer[]) const;
StubAtom(Writer<A>& writer, ObjectFile::Atom& target);
virtual const char* getName() const { return fName; }
virtual ObjectFile::Atom::Scope getScope() const { return ObjectFile::Atom::scopeLinkageUnit; }
- virtual uint8_t getAlignment() const { return 2; }
virtual uint64_t getSize() const;
+ virtual ObjectFile::Alignment getAlignment() const;
virtual const char* getSectionName() const { return "__symbol_stub1"; }
virtual std::vector<ObjectFile::Reference*>& getReferences() const { return (std::vector<ObjectFile::Reference*>&)(fReferences); }
virtual void copyRawContent(uint8_t buffer[]) const;
StubHelperAtom(Writer<A>& writer, ObjectFile::Atom& target, ObjectFile::Atom& lazyPointer);
virtual const char* getName() const { return fName; }
virtual ObjectFile::Atom::Scope getScope() const { return ObjectFile::Atom::scopeLinkageUnit; }
- virtual uint8_t getAlignment() const { return 2; }
virtual uint64_t getSize() const;
virtual const char* getSectionName() const { return "__stub_helper"; }
virtual std::vector<ObjectFile::Reference*>& getReferences() const { return (std::vector<ObjectFile::Reference*>&)(fReferences); }
template <typename A>
Writer<A>::Writer(const char* path, Options& options, std::vector<ExecutableFile::DyLibUsed>& dynamicLibraries)
: ExecutableFile::Writer(dynamicLibraries), fFilePath(strdup(path)), fOptions(options), fLoadCommandsSection(NULL),
- fLoadCommandsSegment(NULL), fPadSegmentInfo(NULL), fPageZeroAtom(NULL), fLargestAtomSize(1),
+ fLoadCommandsSegment(NULL), fPadSegmentInfo(NULL), fPageZeroAtom(NULL), fSymbolTableCount(0), fLargestAtomSize(1),
fEmitVirtualSections(false), fHasWeakExports(false), fReferencesWeakImports(false),
fSeenFollowOnReferences(false), fWritableSegmentPastFirst4GB(false), fFirstWritableSegment(NULL)
{
if ( fOptions.outputKind() == Options::kObjectFile )
permissions = 0666;
// Calling unlink first assures the file is gone so that open creates it with correct permissions
- // It also handles the case where fFilePath file is not writeable but its directory is
+ // It also handles the case where fFilePath file is not writable but its directory is
// And it means we don't have to truncate the file when done writing (in case new is smaller than old)
(void)unlink(fFilePath);
fFileDescriptor = open(fFilePath, O_CREAT | O_WRONLY | O_TRUNC, permissions);
//fprintf(stderr, "found -mdyanmic-no-pic codegen in %s in %s\n", atom->getDisplayName(), atom->getFile()->getPath());
// shrink page-zero and add pad segment to compensate
fPadSegmentInfo = new SegmentInfo();
- strcpy(fPadSegmentInfo->fName, "__4BGFILL");
+ strcpy(fPadSegmentInfo->fName, "__4GBFILL");
fPageZeroAtom->setSize(0x1000);
return;
}
currentSectionInfo = new SectionInfo();
strcpy(currentSectionInfo->fSectionName, atom->getSectionName());
strcpy(currentSectionInfo->fSegmentName, atom->getSegment().getName());
- currentSectionInfo->fAlignment = atom->getAlignment();
+ currentSectionInfo->fAlignment = atom->getAlignment().powerOf2;
currentSectionInfo->fAllZeroFill = atom->isZeroFill();
currentSectionInfo->fVirtualSection = ( (currentSectionInfo->fSectionName[0] == '.') ||
(oneSegmentCommand && (atom->getDefinitionKind()==ObjectFile::Atom::kTentativeDefinition)) && !fOptions.makeTentativeDefinitionsReal() );
currentSectionInfo->fAtoms.reserve(fAllAtoms->size()/4); // reduce reallocations by starting large
strcpy(currentSectionInfo->fSectionName, atom->getSectionName());
strcpy(currentSectionInfo->fSegmentName, atom->getSegment().getName());
- currentSectionInfo->fAlignment = atom->getAlignment();
+ currentSectionInfo->fAlignment = atom->getAlignment().powerOf2;
// check for -sectalign override
std::vector<Options::SectionAlignment>& alignmentOverrides = fOptions.sectionAlignments();
for(std::vector<Options::SectionAlignment>::iterator it=alignmentOverrides.begin(); it != alignmentOverrides.end(); ++it) {
// change section object to be Writer's SectionInfo object
atom->setSection(currentSectionInfo);
// section alignment is that of a contained atom with the greatest alignment
- uint8_t atomAlign = atom->getAlignment();
+ uint8_t atomAlign = atom->getAlignment().powerOf2;
if ( currentSectionInfo->fAlignment < atomAlign )
currentSectionInfo->fAlignment = atomAlign;
// calculate section offset for this atom
uint64_t offset = currentSectionInfo->fSize;
uint64_t alignment = 1 << atomAlign;
- offset = ( (offset+alignment-1) & (-alignment) );
+ uint64_t currentModulus = (offset % alignment);
+ uint64_t requiredModulus = atom->getAlignment().modulus;
+ if ( currentModulus != requiredModulus ) {
+ if ( requiredModulus > currentModulus )
+ offset += requiredModulus-currentModulus;
+ else
+ offset += requiredModulus+alignment-currentModulus;
+ }
atom->setSectionOffset(offset);
uint64_t curAtomSize = atom->getSize();
currentSectionInfo->fSize = offset + curAtomSize;
template <>
-inline uint8_t Writer<ppc>::branch24Reference()
+bool Writer<ppc>::isBranch24Reference(uint8_t kind)
{
- return ppc::kBranch24;
+ switch (kind) {
+ case ppc::kBranch24:
+ case ppc::kBranch24WeakImport:
+ return true;
+ }
+ return false;
}
template <>
-inline uint8_t Writer<ppc64>::branch24Reference()
+bool Writer<ppc64>::isBranch24Reference(uint8_t kind)
{
- return ppc64::kBranch24;
+ switch (kind) {
+ case ppc64::kBranch24:
+ case ppc64::kBranch24WeakImport:
+ return true;
+ }
+ return false;
}
//
template <typename A>
bool Writer<A>::addPPCBranchIslands()
{
+ bool log = false;
bool result = false;
// Can only possibly need branch islands if __TEXT segment > 16M
if ( fLoadCommandsSegment->fSize > 16000000 ) {
- //fprintf(stderr, "ld64: checking for branch islands, __TEXT segment size=%llu\n", fLoadCommandsSegment->fSize);
+ if ( log) fprintf(stderr, "ld64: checking for branch islands, __TEXT segment size=%llu\n", fLoadCommandsSegment->fSize);
const uint32_t kBetweenRegions = 15000000; // place regions of islands every 15MB in __text section
SectionInfo* textSection = NULL;
for (std::vector<SectionInfo*>::iterator it=fLoadCommandsSegment->fSections.begin(); it != fLoadCommandsSegment->fSections.end(); it++) {
if ( strcmp((*it)->fSectionName, "__text") == 0 ) {
textSection = *it;
- //fprintf(stderr, "ld64: checking for branch islands, __text section size=%llu\n", textSection->fSize);
+ if ( log) fprintf(stderr, "ld64: checking for branch islands, __text section size=%llu\n", textSection->fSize);
break;
}
}
std::vector<ObjectFile::Reference*>& references = atom->getReferences();
for (std::vector<ObjectFile::Reference*>::iterator rit=references.begin(); rit != references.end(); rit++) {
ObjectFile::Reference* ref = *rit;
- if ( ref->getKind() == this->branch24Reference() ) {
+ if ( this->isBranch24Reference(ref->getKind()) ) {
ObjectFile::Atom& target = ref->getTarget();
int64_t srcAddr = atom->getAddress() + ref->getFixUpOffset();
int64_t dstAddr = target.getAddress() + ref->getTargetOffset();
int64_t displacement = dstAddr - srcAddr;
+ TargetAndOffset finalTargetAndOffset = { &target, ref->getTargetOffset() };
const int64_t kFifteenMegLimit = kBetweenRegions;
- if ( (displacement > kFifteenMegLimit) || (displacement < (-kFifteenMegLimit)) ) {
- for (int i=0; i < kIslandRegionsCount; ++i) {
- AtomToIsland* region=®ionsMap[i];
+ if ( displacement > kFifteenMegLimit ) {
+ // create forward branch chain
+ ObjectFile::Atom* nextTarget = ⌖
+ uint64_t nextTargetOffset = ref->getTargetOffset();
+ for (int i=kIslandRegionsCount-1; i >=0 ; --i) {
+ AtomToIsland* region = ®ionsMap[i];
int64_t islandRegionAddr = kBetweenRegions * (i+1);
- if ( ((srcAddr < islandRegionAddr) && (dstAddr > islandRegionAddr))
- ||((dstAddr < islandRegionAddr) && (srcAddr > islandRegionAddr)) ) {
- TargetAndOffset islandTarget = { &target, ref->getTargetOffset() };
- AtomToIsland::iterator pos = region->find(islandTarget);
+ if ( (srcAddr < islandRegionAddr) && (islandRegionAddr <= dstAddr) ) {
+ AtomToIsland::iterator pos = region->find(finalTargetAndOffset);
if ( pos == region->end() ) {
- BranchIslandAtom<A>* island = new BranchIslandAtom<A>(*this, target.getDisplayName(), i, target, ref->getTargetOffset());
+ BranchIslandAtom<A>* island = new BranchIslandAtom<A>(*this, target.getDisplayName(), i, *nextTarget, nextTargetOffset);
island->setSection(textSection);
- (*region)[islandTarget] = island;
+ (*region)[finalTargetAndOffset] = island;
+ if (log) fprintf(stderr, "added island %s to region %d for %s\n", island->getDisplayName(), i, atom->getDisplayName());
regionsIslands[i].push_back(island);
++islandCount;
- ref->setTarget(*island, 0);
+ nextTarget = island;
+ nextTargetOffset = 0;
}
else {
- ref->setTarget(*(pos->second), 0);
+ nextTarget = pos->second;
+ nextTargetOffset = 0;
}
}
}
+ if (log) fprintf(stderr, "using island %s for %s\n", nextTarget->getDisplayName(), atom->getDisplayName());
+ ref->setTarget(*nextTarget, nextTargetOffset);
+ }
+ else if ( displacement < (-kFifteenMegLimit) ) {
+ // create back branching chain
+ ObjectFile::Atom* prevTarget = ⌖
+ uint64_t prevTargetOffset = ref->getTargetOffset();
+ for (int i=0; i < kIslandRegionsCount ; ++i) {
+ AtomToIsland* region = ®ionsMap[i];
+ int64_t islandRegionAddr = kBetweenRegions * (i+1);
+ if ( (dstAddr <= islandRegionAddr) && (islandRegionAddr < srcAddr) ) {
+ AtomToIsland::iterator pos = region->find(finalTargetAndOffset);
+ if ( pos == region->end() ) {
+ BranchIslandAtom<A>* island = new BranchIslandAtom<A>(*this, target.getDisplayName(), i, *prevTarget, prevTargetOffset);
+ island->setSection(textSection);
+ (*region)[finalTargetAndOffset] = island;
+ if (log) fprintf(stderr, "added back island %s to region %d for %s\n", island->getDisplayName(), i, atom->getDisplayName());
+ regionsIslands[i].push_back(island);
+ ++islandCount;
+ prevTarget = island;
+ prevTargetOffset = 0;
+ }
+ else {
+ prevTarget = pos->second;
+ prevTargetOffset = 0;
+ }
+ }
+ }
+ if (log) fprintf(stderr, "using back island %s for %s\n", prevTarget->getDisplayName(), atom->getDisplayName());
+ ref->setTarget(*prevTarget, prevTargetOffset);
}
}
}
// insert islands into __text section and adjust section offsets
if ( islandCount > 0 ) {
- //fprintf(stderr, "ld64: %u branch islands required\n", islandCount);
+ if ( log) fprintf(stderr, "ld64: %u branch islands required\n", islandCount);
std::vector<ObjectFile::Atom*> newAtomList;
newAtomList.reserve(textSection->fAtoms.size()+islandCount);
uint64_t islandRegionAddr = kBetweenRegions;
+ uint64_t textSectionAlignment = (1 << textSection->fAlignment);
int regionIndex = 0;
+ uint64_t atomSlide = 0;
uint64_t sectionOffset = 0;
for (std::vector<ObjectFile::Atom*>::iterator it=textSection->fAtoms.begin(); it != textSection->fAtoms.end(); it++) {
ObjectFile::Atom* atom = *it;
newAtomList.push_back(atom);
if ( atom->getAddress() > islandRegionAddr ) {
+ uint64_t islandStartOffset = atom->getSectionOffset();
+ sectionOffset = islandStartOffset + atomSlide;
std::vector<ObjectFile::Atom*>* regionIslands = ®ionsIslands[regionIndex];
for (std::vector<ObjectFile::Atom*>::iterator rit=regionIslands->begin(); rit != regionIslands->end(); rit++) {
ObjectFile::Atom* islandAtom = *rit;
newAtomList.push_back(islandAtom);
- uint64_t alignment = 1 << (islandAtom->getAlignment());
+ uint64_t alignment = 1 << (islandAtom->getAlignment().powerOf2);
sectionOffset = ( (sectionOffset+alignment-1) & (-alignment) );
islandAtom->setSectionOffset(sectionOffset);
sectionOffset += islandAtom->getSize();
}
++regionIndex;
islandRegionAddr += kBetweenRegions;
+ uint64_t islandRegionAlignmentBlocks = (sectionOffset - islandStartOffset + textSectionAlignment - 1) / textSectionAlignment;
+ atomSlide += (islandRegionAlignmentBlocks * textSectionAlignment);
}
- uint64_t alignment = 1 << (atom->getAlignment());
- sectionOffset = ( (sectionOffset+alignment-1) & (-alignment) );
- atom->setSectionOffset(sectionOffset);
- sectionOffset += atom->getSize();
+ if ( atomSlide != 0 )
+ atom->setSectionOffset(atom->getSectionOffset()+atomSlide);
}
// put any remaining islands at end of __text section
if ( regionIndex < kIslandRegionsCount ) {
for (std::vector<ObjectFile::Atom*>::iterator rit=regionIslands->begin(); rit != regionIslands->end(); rit++) {
ObjectFile::Atom* islandAtom = *rit;
newAtomList.push_back(islandAtom);
- uint64_t alignment = 1 << (islandAtom->getAlignment());
+ uint64_t alignment = 1 << (islandAtom->getAlignment().powerOf2);
sectionOffset = ( (sectionOffset+alignment-1) & (-alignment) );
islandAtom->setSectionOffset(sectionOffset);
sectionOffset += islandAtom->getSize();
const unsigned int atomCount = loadCommandAtoms.size();
for (unsigned int i=0; i < atomCount; ++i) {
ObjectFile::Atom* atom = loadCommandAtoms[i];
- uint64_t alignment = 1 << atom->getAlignment();
+ uint64_t alignment = 1 << atom->getAlignment().powerOf2;
offset = ( (offset+alignment-1) & (-alignment) );
atom->setSectionOffset(offset);
uint32_t atomSize = atom->getSize();
lastSeg->fSections[i]->setBaseAddress(address);
for (unsigned int j=0; j < atomCount; ++j) {
ObjectFile::Atom* atom = atoms[j];
- uint64_t alignment = 1 << atom->getAlignment();
+ uint64_t alignment = 1 << atom->getAlignment().powerOf2;
sectionOffset = ( (sectionOffset+alignment-1) & (-alignment) );
atom->setSectionOffset(sectionOffset);
uint64_t size = atom->getSize();
return ( fWriter.fOptions.outputKind() != Options::kDynamicExecutable );
}
+template <>
+ObjectFile::Alignment StubAtom<ppc>::getAlignment() const
+{
+ return 2;
+}
+
+template <>
+ObjectFile::Alignment StubAtom<ppc64>::getAlignment() const
+{
+ return 2;
+}
template <>
StubAtom<ppc>::StubAtom(Writer<ppc>& writer, ObjectFile::Atom& target)
}
template <>
-uint8_t StubAtom<x86>::getAlignment() const
+ObjectFile::Alignment StubAtom<x86>::getAlignment() const
{
// special case x86 fast stubs to be byte aligned
return 0;
// x86_64 stubs are 7 bytes and need no alignment
template <>
-uint8_t StubAtom<x86_64>::getAlignment() const
+ObjectFile::Alignment StubAtom<x86_64>::getAlignment() const
{
return 0;
}