BinarySection(BinaryContext &BC, SectionRef Section)
: BC(BC), Name(getName(Section)), Section(Section),
Contents(getContents(Section)), Address(Section.getAddress()),
- Size(Section.getSize()), Alignment(Section.getAlignment()),
+ Size(Section.getSize()), Alignment(Section.getAlignment().value()),
OutputName(Name), SectionNumber(++Count) {
if (isELF()) {
ELFType = ELFSectionRef(Section).getType();
unsigned SectionID, StringRef SectionName,
bool IsReadOnly) override;
- void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
- uintptr_t RODataSize, uint32_t RODataAlign,
- uintptr_t RWDataSize,
- uint32_t RWDataAlign) override;
+ void reserveAllocationSpace(uintptr_t CodeSize, Align CodeAlign,
+ uintptr_t RODataSize, Align RODataAlign,
+ uintptr_t RWDataSize, Align RWDataAlign) override;
bool needsToReserveAllocationSpace() override;
///
/// Note that by default the callback is disabled. To enable it
/// redefine the method needsToReserveAllocationSpace to return true.
- virtual void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
- uintptr_t RODataSize,
- uint32_t RODataAlign,
+ virtual void reserveAllocationSpace(uintptr_t CodeSize, Align CodeAlign,
+ uintptr_t RODataSize, Align RODataAlign,
uintptr_t RWDataSize,
- uint32_t RWDataAlign) {}
+ Align RWDataAlign) {}
/// Override to return true to enable the reserveAllocationSpace callback.
virtual bool needsToReserveAllocationSpace() { return false; }
uint64_t getSize() const;
Expected<StringRef> getContents() const;
- /// Get the alignment of this section as the actual value (not log 2).
- uint64_t getAlignment() const;
+ /// Get the alignment of this section.
+ Align getAlignment() const;
bool isCompressed() const;
/// Whether this section contains instructions.
return StringRef(reinterpret_cast<const char *>(Res->data()), Res->size());
}
-inline uint64_t SectionRef::getAlignment() const {
- return OwningObject->getSectionAlignment(SectionPimpl);
+inline Align SectionRef::getAlignment() const {
+ return MaybeAlign(OwningObject->getSectionAlignment(SectionPimpl))
+ .valueOrOne();
}
inline bool SectionRef::isCompressed() const {
}
void EPCGenericRTDyldMemoryManager::reserveAllocationSpace(
- uintptr_t CodeSize, uint32_t CodeAlign, uintptr_t RODataSize,
- uint32_t RODataAlign, uintptr_t RWDataSize, uint32_t RWDataAlign) {
+ uintptr_t CodeSize, Align CodeAlign, uintptr_t RODataSize,
+ Align RODataAlign, uintptr_t RWDataSize, Align RWDataAlign) {
{
std::lock_guard<std::mutex> Lock(M);
if (!ErrMsg.empty())
return;
- if (!isPowerOf2_32(CodeAlign) || CodeAlign > EPC.getPageSize()) {
+ if (CodeAlign > EPC.getPageSize()) {
ErrMsg = "Invalid code alignment in reserveAllocationSpace";
return;
}
- if (!isPowerOf2_32(RODataAlign) || RODataAlign > EPC.getPageSize()) {
+ if (RODataAlign > EPC.getPageSize()) {
ErrMsg = "Invalid ro-data alignment in reserveAllocationSpace";
return;
}
- if (!isPowerOf2_32(RWDataAlign) || RWDataAlign > EPC.getPageSize()) {
+ if (RWDataAlign > EPC.getPageSize()) {
ErrMsg = "Invalid rw-data alignment in reserveAllocationSpace";
return;
}
// and pass this information to the memory manager
if (MemMgr.needsToReserveAllocationSpace()) {
uint64_t CodeSize = 0, RODataSize = 0, RWDataSize = 0;
- uint32_t CodeAlign = 1, RODataAlign = 1, RWDataAlign = 1;
- if (auto Err = computeTotalAllocSize(Obj,
- CodeSize, CodeAlign,
- RODataSize, RODataAlign,
- RWDataSize, RWDataAlign))
+ Align CodeAlign, RODataAlign, RWDataAlign;
+ if (auto Err = computeTotalAllocSize(Obj, CodeSize, CodeAlign, RODataSize,
+ RODataAlign, RWDataSize, RWDataAlign))
return std::move(Err);
MemMgr.reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign,
RWDataSize, RWDataAlign);
// assuming that all sections are allocated with the given alignment
static uint64_t
computeAllocationSizeForSections(std::vector<uint64_t> &SectionSizes,
- uint64_t Alignment) {
+ Align Alignment) {
uint64_t TotalSize = 0;
- for (uint64_t SectionSize : SectionSizes) {
- uint64_t AlignedSize =
- (SectionSize + Alignment - 1) / Alignment * Alignment;
- TotalSize += AlignedSize;
- }
+ for (uint64_t SectionSize : SectionSizes)
+ TotalSize += alignTo(SectionSize, Alignment);
return TotalSize;
}
// Compute an upper bound of the memory size that is required to load all
// sections
-Error RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
- uint64_t &CodeSize,
- uint32_t &CodeAlign,
- uint64_t &RODataSize,
- uint32_t &RODataAlign,
- uint64_t &RWDataSize,
- uint32_t &RWDataAlign) {
+Error RuntimeDyldImpl::computeTotalAllocSize(
+ const ObjectFile &Obj, uint64_t &CodeSize, Align &CodeAlign,
+ uint64_t &RODataSize, Align &RODataAlign, uint64_t &RWDataSize,
+ Align &RWDataAlign) {
// Compute the size of all sections required for execution
std::vector<uint64_t> CodeSectionSizes;
std::vector<uint64_t> ROSectionSizes;
// Consider only the sections that are required to be loaded for execution
if (IsRequired) {
uint64_t DataSize = Section.getSize();
- uint64_t Alignment64 = Section.getAlignment();
- unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
+ Align Alignment = Section.getAlignment();
bool IsCode = Section.isText();
bool IsReadOnly = isReadOnlyData(Section);
bool IsTLS = isTLS(Section);
if (Name == ".eh_frame")
PaddingSize += 4;
if (StubBufSize != 0)
- PaddingSize += getStubAlignment() - 1;
+ PaddingSize += getStubAlignment().value() - 1;
uint64_t SectionSize = DataSize + PaddingSize + StubBufSize;
// single GOT entry.
if (unsigned GotSize = computeGOTSize(Obj)) {
RWSectionSizes.push_back(GotSize);
- RWDataAlign = std::max<uint32_t>(RWDataAlign, getGOTEntrySize());
+ RWDataAlign = std::max(RWDataAlign, Align(getGOTEntrySize()));
}
// Compute the size of all common symbols
uint64_t CommonSize = 0;
- uint32_t CommonAlign = 1;
+ Align CommonAlign;
for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;
++I) {
Expected<uint32_t> FlagsOrErr = I->getFlags();
if (*FlagsOrErr & SymbolRef::SF_Common) {
// Add the common symbols to a list. We'll allocate them all below.
uint64_t Size = I->getCommonSize();
- uint32_t Align = I->getAlignment();
+ Align Alignment = Align(I->getAlignment());
// If this is the first common symbol, use its alignment as the alignment
// for the common symbols section.
if (CommonSize == 0)
- CommonAlign = Align;
- CommonSize = alignTo(CommonSize, Align) + Size;
+ CommonAlign = Alignment;
+ CommonSize = alignTo(CommonSize, Alignment) + Size;
}
}
if (CommonSize != 0) {
// Get section data size and alignment
uint64_t DataSize = Section.getSize();
- uint64_t Alignment64 = Section.getAlignment();
+ Align Alignment = Section.getAlignment();
// Add stubbuf size alignment
- unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
- unsigned StubAlignment = getStubAlignment();
- unsigned EndAlignment = (DataSize | Alignment) & -(DataSize | Alignment);
+ Align StubAlignment = getStubAlignment();
+ Align EndAlignment = commonAlignment(Alignment, DataSize);
if (StubAlignment > EndAlignment)
- StubBufSize += StubAlignment - EndAlignment;
+ StubBufSize += StubAlignment.value() - EndAlignment.value();
return StubBufSize;
}
const SectionRef &Section,
bool IsCode) {
StringRef data;
- uint64_t Alignment64 = Section.getAlignment();
+ Align Alignment = Section.getAlignment();
- unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
unsigned PaddingSize = 0;
unsigned StubBufSize = 0;
bool IsRequired = isRequiredForExecution(Section);
bool IsTLS = isTLS(Section);
uint64_t DataSize = Section.getSize();
- // An alignment of 0 (at least with ELF) is identical to an alignment of 1,
- // while being more "polite". Other formats do not support 0-aligned sections
- // anyway, so we should guarantee that the alignment is always at least 1.
- Alignment = std::max(1u, Alignment);
-
Expected<StringRef> NameOrErr = Section.getName();
if (!NameOrErr)
return NameOrErr.takeError();
// section is remapped.
if (StubBufSize != 0) {
Alignment = std::max(Alignment, getStubAlignment());
- PaddingSize += getStubAlignment() - 1;
+ PaddingSize += getStubAlignment().value() - 1;
}
// Some sections, such as debug info, don't need to be loaded for execution.
if (!Allocate)
Allocate = 1;
if (IsTLS) {
- auto TLSSection =
- MemMgr.allocateTLSSection(Allocate, Alignment, SectionID, Name);
+ auto TLSSection = MemMgr.allocateTLSSection(Allocate, Alignment.value(),
+ SectionID, Name);
Addr = TLSSection.InitializationImage;
LoadAddress = TLSSection.Offset;
} else if (IsCode) {
- Addr = MemMgr.allocateCodeSection(Allocate, Alignment, SectionID, Name);
+ Addr = MemMgr.allocateCodeSection(Allocate, Alignment.value(), SectionID,
+ Name);
} else {
- Addr = MemMgr.allocateDataSection(Allocate, Alignment, SectionID, Name,
- IsReadOnly);
+ Addr = MemMgr.allocateDataSection(Allocate, Alignment.value(), SectionID,
+ Name, IsReadOnly);
}
if (!Addr)
report_fatal_error("Unable to allocate section memory!");
// Align DataSize to stub alignment if we have any stubs (PaddingSize will
// have been increased above to account for this).
if (StubBufSize > 0)
- DataSize &= -(uint64_t)getStubAlignment();
+ DataSize &= -(uint64_t)getStubAlignment().value();
}
LLVM_DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: "
LLVM_DEBUG(dbgs() << " Create a new stub function\n");
uintptr_t BaseAddress = uintptr_t(Section.getAddress());
- uintptr_t StubAlignment = getStubAlignment();
StubAddress =
- (BaseAddress + Section.getStubOffset() + StubAlignment - 1) &
- -StubAlignment;
+ alignTo(BaseAddress + Section.getStubOffset(), getStubAlignment());
unsigned StubOffset = StubAddress - BaseAddress;
Stubs[Value] = StubOffset;
LLVM_DEBUG(dbgs() << " Create a new stub function\n");
uintptr_t BaseAddress = uintptr_t(Section->getAddress());
- uintptr_t StubAlignment = getStubAlignment();
- StubAddress =
- (BaseAddress + Section->getStubOffset() + StubAlignment - 1) &
- -StubAlignment;
+ StubAddress = alignTo(BaseAddress + Section->getStubOffset(),
+ getStubAlignment());
unsigned StubOffset = StubAddress - BaseAddress;
Stubs[Value] = StubOffset;
createStubFunction((uint8_t *)StubAddress);
return 0;
}
- unsigned getStubAlignment() override {
+ Align getStubAlignment() override {
if (Arch == Triple::systemz)
- return 8;
+ return Align(8);
else
- return 1;
+ return Align(1);
}
void setMipsABI(const ObjectFile &Obj) override;
NotifyStubEmittedFunction NotifyStubEmitted;
virtual unsigned getMaxStubSize() const = 0;
- virtual unsigned getStubAlignment() = 0;
+ virtual Align getStubAlignment() = 0;
bool HasError;
std::string ErrorStr;
// Compute an upper bound of the memory that is required to load all
// sections
- Error computeTotalAllocSize(const ObjectFile &Obj,
- uint64_t &CodeSize, uint32_t &CodeAlign,
- uint64_t &RODataSize, uint32_t &RODataAlign,
- uint64_t &RWDataSize, uint32_t &RWDataAlign);
+ Error computeTotalAllocSize(const ObjectFile &Obj, uint64_t &CodeSize,
+ Align &CodeAlign, uint64_t &RODataSize,
+ Align &RODataAlign, uint64_t &RWDataSize,
+ Align &RWDataAlign);
// Compute GOT size
unsigned computeGOTSize(const ObjectFile &Obj);
: RuntimeDyldCOFF(MM, Resolver, 8, COFF::IMAGE_REL_ARM64_ADDR64),
ImageBase(0) {}
- unsigned getStubAlignment() override { return 8; }
+ Align getStubAlignment() override { return Align(8); }
unsigned getMaxStubSize() const override { return 20; }
return 8; // 2-byte jmp instruction + 32-bit relative address + 2 byte pad
}
- unsigned getStubAlignment() override { return 1; }
+ Align getStubAlignment() override { return Align(1); }
Expected<object::relocation_iterator>
processRelocationRef(unsigned SectionID,
return 16; // 8-byte load instructions, 4-byte jump, 4-byte padding
}
- unsigned getStubAlignment() override { return 1; }
+ Align getStubAlignment() override { return Align(1); }
Expected<object::relocation_iterator>
processRelocationRef(unsigned SectionID,
: RuntimeDyldCOFF(MM, Resolver, 8, COFF::IMAGE_REL_AMD64_ADDR64),
ImageBase(0) {}
- unsigned getStubAlignment() override { return 1; }
+ Align getStubAlignment() override { return Align(1); }
// 2-byte jmp instruction + 32-bit relative address + 64-bit absolute jump
unsigned getMaxStubSize() const override { return 14; }
unsigned getMaxStubSize() const override { return 8; }
- unsigned getStubAlignment() override { return 8; }
+ Align getStubAlignment() override { return Align(8); }
/// Extract the addend encoded in the instruction / memory location.
Expected<int64_t> decodeAddend(const RelocationEntry &RE) const {
// FIXME: There must be a better way to do this then to check and fix the
// alignment every time!!!
uintptr_t BaseAddress = uintptr_t(Section.getAddress());
- uintptr_t StubAlignment = getStubAlignment();
+ uintptr_t StubAlignment = getStubAlignment().value();
uintptr_t StubAddress =
(BaseAddress + Section.getStubOffset() + StubAlignment - 1) &
-StubAlignment;
unsigned StubOffset = StubAddress - BaseAddress;
Stubs[Value] = StubOffset;
- assert(((StubAddress % getStubAlignment()) == 0) &&
+ assert(isAligned(getStubAlignment(), StubAddress) &&
"GOT entry not aligned");
RelocationEntry GOTRE(RE.SectionID, StubOffset,
MachO::ARM64_RELOC_UNSIGNED, Value.Offset,
unsigned getMaxStubSize() const override { return 8; }
- unsigned getStubAlignment() override { return 4; }
+ Align getStubAlignment() override { return Align(4); }
Expected<JITSymbolFlags> getJITSymbolFlags(const SymbolRef &SR) override {
auto Flags = RuntimeDyldImpl::getJITSymbolFlags(SR);
unsigned getMaxStubSize() const override { return 0; }
- unsigned getStubAlignment() override { return 1; }
+ Align getStubAlignment() override { return Align(1); }
Expected<relocation_iterator>
processRelocationRef(unsigned SectionID, relocation_iterator RelI,
unsigned getMaxStubSize() const override { return 8; }
- unsigned getStubAlignment() override { return 8; }
+ Align getStubAlignment() override { return Align(8); }
Expected<relocation_iterator>
processRelocationRef(unsigned SectionID, relocation_iterator RelI,
// place.
SectionToOffsetInDwarf[SectionKind] += Section.getSize();
Streamer->emitSwiftReflectionSection(SectionKind, *SectionContents,
- Section.getAlignment(),
+ Section.getAlignment().value(),
Section.getSize());
}
}
IsReadOnly);
}
- void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
- uintptr_t RODataSize, uint32_t RODataAlign,
+ void reserveAllocationSpace(uintptr_t CodeSize, Align CodeAlign,
+ uintptr_t RODataSize, Align RODataAlign,
uintptr_t RWDataSize,
- uint32_t RWDataAlign) override {
+ Align RWDataAlign) override {
MemMgr->reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign,
RWDataSize, RWDataAlign);
}
bool needsToReserveAllocationSpace() override { return true; }
- void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
- uintptr_t DataSizeRO, uint32_t RODataAlign,
+ void reserveAllocationSpace(uintptr_t CodeSize, Align CodeAlign,
+ uintptr_t DataSizeRO, Align RODataAlign,
uintptr_t DataSizeRW,
- uint32_t RWDataAlign) override {
+ Align RWDataAlign) override {
ReservedCodeSize = CodeSize;
ReservedDataSizeRO = DataSizeRO;
ReservedDataSizeRW = DataSizeRW;