MCSymbol *getEndSymbol(MCContext &Ctx);
bool hasEnded() const;
- unsigned getAlignment() const { return Alignment.value(); }
+ Align getAlign() const { return Alignment; }
void setAlignment(Align Value) { Alignment = Value; }
unsigned getOrdinal() const { return Ordinal; }
bool is64Bit() const;
bool usesRela(const MCSectionELF &Sec) const;
- uint64_t align(unsigned Alignment);
+ uint64_t align(Align Alignment);
bool maybeWriteCompression(uint32_t ChType, uint64_t Size,
SmallVectorImpl<uint8_t> &CompressedContents,
- unsigned Alignment);
+ Align Alignment);
public:
ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS,
void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
uint64_t Address, uint64_t Offset, uint64_t Size,
- uint32_t Link, uint32_t Info, uint64_t Alignment,
+ uint32_t Link, uint32_t Info, MaybeAlign Alignment,
uint64_t EntrySize);
void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
} // end anonymous namespace
-uint64_t ELFWriter::align(unsigned Alignment) {
- uint64_t Offset = W.OS.tell(), NewOffset = alignTo(Offset, Alignment);
+uint64_t ELFWriter::align(Align Alignment) {
+ uint64_t Offset = W.OS.tell();
+ uint64_t NewOffset = alignTo(Offset, Alignment);
W.OS.write_zeros(NewOffset - Offset);
return NewOffset;
}
SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4));
SymbolTableIndex = addToSectionTable(SymtabSection);
- uint64_t SecStart = align(SymtabSection->getAlignment());
+ uint64_t SecStart = align(SymtabSection->getAlign());
// The first entry is the undefined symbol entry.
Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
// Include the debug info compression header.
bool ELFWriter::maybeWriteCompression(
uint32_t ChType, uint64_t Size,
- SmallVectorImpl<uint8_t> &CompressedContents, unsigned Alignment) {
+ SmallVectorImpl<uint8_t> &CompressedContents, Align Alignment) {
uint64_t HdrSize =
is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr);
if (Size <= HdrSize + CompressedContents.size())
write(static_cast<ELF::Elf64_Word>(ChType));
write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
write(static_cast<ELF::Elf64_Xword>(Size));
- write(static_cast<ELF::Elf64_Xword>(Alignment));
+ write(static_cast<ELF::Elf64_Xword>(Alignment.value()));
} else {
// Write Elf32_Chdr header otherwise.
write(static_cast<ELF::Elf32_Word>(ChType));
write(static_cast<ELF::Elf32_Word>(Size));
- write(static_cast<ELF::Elf32_Word>(Alignment));
+ write(static_cast<ELF::Elf32_Word>(Alignment.value()));
}
return true;
}
compression::compress(compression::Params(CompressionType), Uncompressed,
Compressed);
if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
- Sec.getAlignment())) {
+ Sec.getAlign())) {
W.OS << UncompressedData;
return;
}
void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
uint64_t Address, uint64_t Offset,
uint64_t Size, uint32_t Link, uint32_t Info,
- uint64_t Alignment, uint64_t EntrySize) {
+ MaybeAlign Alignment, uint64_t EntrySize) {
W.write<uint32_t>(Name); // sh_name: index into string table
W.write<uint32_t>(Type); // sh_type
WriteWord(Flags); // sh_flags
WriteWord(Size); // sh_size
W.write<uint32_t>(Link); // sh_link
W.write<uint32_t>(Info); // sh_info
- WriteWord(Alignment); // sh_addralign
+ WriteWord(Alignment ? Alignment->value() : 0); // sh_addralign
WriteWord(EntrySize); // sh_entsize
}
WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()),
Section.getType(), Section.getFlags(), 0, Offset, Size,
- sh_link, sh_info, Section.getAlignment(),
+ sh_link, sh_info, Section.getAlign(),
Section.getEntrySize());
}
// Null section first.
uint64_t FirstSectionSize =
(NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
- WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, 0, 0);
+ WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, None, 0);
for (const MCSectionELF *Section : SectionTable) {
uint32_t GroupSymbolIndex;
continue;
// Remember the offset into the file for this section.
- const uint64_t SecStart = align(Section.getAlignment());
+ const uint64_t SecStart = align(Section.getAlign());
const MCSymbolELF *SignatureSymbol = Section.getGroup();
writeSectionData(Asm, Section, Layout);
for (MCSectionELF *Group : Groups) {
// Remember the offset into the file for this section.
- const uint64_t SecStart = align(Group->getAlignment());
+ const uint64_t SecStart = align(Group->getAlign());
const MCSymbol *SignatureSymbol = Group->getGroup();
assert(SignatureSymbol);
for (MCSectionELF *RelSection : Relocations) {
// Remember the offset into the file for this section.
- const uint64_t SecStart = align(RelSection->getAlignment());
+ const uint64_t SecStart = align(RelSection->getAlign());
writeRelocations(Asm,
cast<MCSectionELF>(*RelSection->getLinkedToSection()));
SectionOffsets[StrtabSection] = std::make_pair(SecStart, W.OS.tell());
}
- const uint64_t SectionHeaderOffset = align(is64Bit() ? 8 : 4);
+ const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));
// ... then the section header table ...
writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
static void setSectionAlignmentForBundling(const MCAssembler &Assembler,
MCSection *Section) {
if (Section && Assembler.isBundlingEnabled() && Section->hasInstructions() &&
- Section->getAlignment() < Assembler.getBundleAlignSize())
+ Section->getAlign() < Assembler.getBundleAlignSize())
Section->setAlignment(Align(Assembler.getBundleAlignSize()));
}
// Update the maximum alignment on the current section if necessary.
MCSection *CurSec = getCurrentSectionOnly();
- if (ByteAlignment > CurSec->getAlignment())
+ if (CurSec->getAlign() < ByteAlignment)
CurSec->setAlignment(Align(ByteAlignment));
}
MCSectionXCOFF::~MCSectionXCOFF() = default;
void MCSectionXCOFF::printCsectDirective(raw_ostream &OS) const {
- OS << "\t.csect " << QualName->getName() << "," << Log2_32(getAlignment())
- << '\n';
+ OS << "\t.csect " << QualName->getName() << "," << Log2(getAlign()) << '\n';
}
void MCSectionXCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
MCSection *SXData = getContext().getObjectFileInfo()->getSXDataSection();
getAssembler().registerSection(*SXData);
- if (SXData->getAlignment() < 4)
+ if (SXData->getAlign() < 4)
SXData->setAlignment(Align(4));
new MCSymbolIdFragment(Symbol, SXData);
void MCWinCOFFStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {
MCSection *Sec = getCurrentSectionOnly();
getAssembler().registerSection(*Sec);
- if (Sec->getAlignment() < 4)
+ if (Sec->getAlign() < 4)
Sec->setAlignment(Align(4));
new MCSymbolIdFragment(Symbol, getCurrentSectionOnly());
const MCSection &NextSec = *Layout.getSectionOrder()[Next];
if (NextSec.isVirtualSection())
return 0;
- return offsetToAlignment(EndAddr, Align(NextSec.getAlignment()));
+ return offsetToAlignment(EndAddr, NextSec.getAlign());
}
void MachObjectWriter::writeHeader(MachO::HeaderFileType Type,
}
W.write<uint32_t>(FileOffset);
- assert(isPowerOf2_32(Section.getAlignment()) && "Invalid alignment!");
- W.write<uint32_t>(Log2_32(Section.getAlignment()));
+ W.write<uint32_t>(Log2(Section.getAlign()));
W.write<uint32_t>(NumRelocations ? RelocationsStart : 0);
W.write<uint32_t>(NumRelocations);
W.write<uint32_t>(Flags);
const MCAsmLayout &Layout) {
uint64_t StartAddress = 0;
for (const MCSection *Sec : Layout.getSectionOrder()) {
- StartAddress = alignTo(StartAddress, Sec->getAlignment());
+ StartAddress = alignTo(StartAddress, Sec->getAlign());
SectionAddress[Sec] = StartAddress;
StartAddress += Layout.getSectionAddressSize(Sec);
MCSectionWasm &DataSection) {
LLVM_DEBUG(errs() << "addData: " << DataSection.getName() << "\n");
- DataBytes.resize(alignTo(DataBytes.size(), DataSection.getAlignment()));
+ DataBytes.resize(alignTo(DataBytes.size(), DataSection.getAlign()));
for (const MCFragment &Frag : DataSection) {
if (Frag.hasInstructions())
if (Section.isWasmData()) {
uint32_t SegmentIndex = DataSegments.size();
- DataSize = alignTo(DataSize, Section.getAlignment());
+ DataSize = alignTo(DataSize, Section.getAlign());
DataSegments.emplace_back();
WasmDataSegment &Segment = DataSegments.back();
Segment.Name = SectionName;
Segment.Offset = DataSize;
Segment.Section = &Section;
addData(Segment.Data, Section);
- Segment.Alignment = Log2_32(Section.getAlignment());
+ Segment.Alignment = Log2(Section.getAlign());
Segment.LinkingFlags = Section.getSegmentFlags();
DataSize += Segment.Data.size();
Section.setSegmentIndex(SegmentIndex);
}
static uint32_t getAlignment(const MCSectionCOFF &Sec) {
- switch (Sec.getAlignment()) {
+ switch (Sec.getAlign().value()) {
case 1:
return COFF::IMAGE_SCN_ALIGN_1BYTES;
case 2:
for (auto &Csect : *Group) {
const MCSectionXCOFF *MCSec = Csect.MCSec;
- Csect.Address = alignTo(Address, MCSec->getAlignment());
+ Csect.Address = alignTo(Address, MCSec->getAlign());
Csect.Size = Layout.getSectionAddressSize(MCSec);
Address = Csect.Address + Csect.Size;
Csect.SymbolTableIndex = SymbolTableIndex;
if (!DwarfSections.empty())
PaddingsBeforeDwarf =
alignTo(Address,
- (*DwarfSections.begin()).DwarfSect->MCSec->getAlignment()) -
+ (*DwarfSections.begin()).DwarfSect->MCSec->getAlign()) -
Address;
DwarfSectionEntry *LastDwarfSection = nullptr;
// This address is used to tell where is the section in the final object.
// See writeSectionForDwarfSectionEntry().
DwarfSection.Address = DwarfSect.Address =
- alignTo(Address, MCSec->getAlignment());
+ alignTo(Address, MCSec->getAlign());
// Section size.
// For DWARF section, we must use the real size which may be not aligned.
// significant bits of a byte, then or's in the csect type into the least
// significant 3 bits.
uint8_t getEncodedType(const MCSectionXCOFF *Sec) {
- unsigned Align = Sec->getAlignment();
- assert(isPowerOf2_32(Align) && "Alignment must be a power of 2.");
- unsigned Log2Align = Log2_32(Align);
+ unsigned Log2Align = Log2(Sec->getAlign());
// Result is a number in the range [0, 31] which fits in the 5 least
// significant bits. Shift this value into the 5 most significant bits, and
// bitwise-or in the csect type.
// CP microcode requires the kernel descriptor to be allocated on 64 byte
// alignment.
Streamer.emitValueToAlignment(64, 0, 1, 0);
- if (ReadOnlySection.getAlignment() < 64)
+ if (ReadOnlySection.getAlign() < 64)
ReadOnlySection.setAlignment(Align(64));
const GCNSubtarget &STM = MF->getSubtarget<GCNSubtarget>();
}
// Update the maximum alignment of the section if necessary.
- if (Align(ByteAlignment) > Section.getAlignment())
+ if (Section.getAlign() < ByteAlignment)
Section.setAlignment(Align(ByteAlignment));
switchSection(P.first, P.second);
MCSection &BSSSection = *OFI.getBSSSection();
MCA.registerSection(BSSSection);
- TextSection.setAlignment(Align(std::max(16u, TextSection.getAlignment())));
- DataSection.setAlignment(Align(std::max(16u, DataSection.getAlignment())));
- BSSSection.setAlignment(Align(std::max(16u, BSSSection.getAlignment())));
+ TextSection.setAlignment(std::max(Align(16), TextSection.getAlign()));
+ DataSection.setAlignment(std::max(Align(16), DataSection.getAlign()));
+ BSSSection.setAlignment(std::max(Align(16), BSSSection.getAlign()));
if (RoundSectionSizes) {
// Make sections sizes a multiple of the alignment. This is useful for
for (MCSection &S : MCA) {
MCSectionELF &Section = static_cast<MCSectionELF &>(S);
- unsigned Alignment = Section.getAlignment();
- if (Alignment) {
- OS.switchSection(&Section);
- if (Section.useCodeAlign())
- OS.emitCodeAlignment(Alignment, &STI, Alignment);
- else
- OS.emitValueToAlignment(Alignment, 0, 1, Alignment);
- }
+ Align Alignment = Section.getAlign();
+ OS.switchSection(&Section);
+ if (Section.useCodeAlign())
+ OS.emitCodeAlignment(Alignment.value(), &STI, Alignment.value());
+ else
+ OS.emitValueToAlignment(Alignment.value(), 0, 1, Alignment.value());
}
}
getObjFileLowering().SectionForGlobal(GO, GOKind, TM));
Align GOAlign = getGVAlignment(GO, GO->getParent()->getDataLayout());
- if (GOAlign > Csect->getAlignment())
+ if (GOAlign > Csect->getAlign())
Csect->setAlignment(GOAlign);
};
// Update the maximum alignment on the current section if necessary.
MCSection *Sec = OS.getCurrentSectionOnly();
- if (AlignBoundary.value() > Sec->getAlignment())
+ if (Sec->getAlign() < AlignBoundary)
Sec->setAlignment(AlignBoundary);
}
/// If WithFrameRecord is true, then __hwasan_tls will be used to access the
/// ring buffer for storing stack allocations on targets that support it.
struct ShadowMapping {
- int Scale;
+ uint8_t Scale;
uint64_t Offset;
bool InGlobal;
bool InTls;
bool WithFrameRecord;
void init(Triple &TargetTriple, bool InstrumentWithCalls);
- uint64_t getObjectAlignment() const { return 1ULL << Scale; }
+ Align getObjectAlignment() const { return Align(1ULL << Scale); }
};
ShadowMapping Mapping;
IRBuilder<> IRB(O.getInsn());
if (isPowerOf2_64(O.TypeSize) &&
(O.TypeSize / 8 <= (1ULL << (kNumberOfAccessSizes - 1))) &&
- (!O.Alignment || *O.Alignment >= (1ULL << Mapping.Scale) ||
+ (!O.Alignment || *O.Alignment >= Mapping.getObjectAlignment() ||
*O.Alignment >= O.TypeSize / 8)) {
size_t AccessSizeIndex = TypeSizeToSizeIndex(O.TypeSize);
if (InstrumentWithCalls) {
if (ShadowSize)
IRB.CreateMemSet(ShadowPtr, JustTag, ShadowSize, Align(1));
if (Size != AlignedSize) {
- IRB.CreateStore(
- ConstantInt::get(Int8Ty, Size % Mapping.getObjectAlignment()),
- IRB.CreateConstGEP1_32(Int8Ty, ShadowPtr, ShadowSize));
+ const uint8_t SizeRemainder = Size % Mapping.getObjectAlignment().value();
+ IRB.CreateStore(ConstantInt::get(Int8Ty, SizeRemainder),
+ IRB.CreateConstGEP1_32(Int8Ty, ShadowPtr, ShadowSize));
IRB.CreateStore(JustTag, IRB.CreateConstGEP1_32(
Int8Ty, IRB.CreateBitCast(AI, Int8PtrTy),
AlignedSize - 1));
for (auto &II : Info.LifetimeEnd)
II->eraseFromParent();
}
- memtag::alignAndPadAlloca(Info, Align(Mapping.getObjectAlignment()));
+ memtag::alignAndPadAlloca(Info, Mapping.getObjectAlignment());
}
for (auto &I : SInfo.UnrecognizedLifetimes)
I->eraseFromParent();
NewGV->setLinkage(GlobalValue::PrivateLinkage);
NewGV->copyMetadata(GV, 0);
NewGV->setAlignment(
- MaybeAlign(std::max(GV->getAlignment(), Mapping.getObjectAlignment())));
+ std::max(GV->getAlign().valueOrOne(), Mapping.getObjectAlignment()));
// It is invalid to ICF two globals that have different tags. In the case
// where the size of the global is a multiple of the tag granularity the
if (Sec->begin() == Sec->end() || !Layout.getSectionFileSize(Sec))
continue;
- unsigned Align = Sec->getAlignment();
- if (Align > 1) {
- VMAddr = alignTo(VMAddr, Align);
- FileOffset = alignTo(FileOffset, Align);
+ Align Alignment = Sec->getAlign();
+ if (Alignment > 1) {
+ VMAddr = alignTo(VMAddr, Alignment);
+ FileOffset = alignTo(FileOffset, Alignment);
if (FileOffset > UINT32_MAX)
return error("section " + Sec->getName() + "'s file offset exceeds 4GB."
" Refusing to produce an invalid Mach-O file.");
continue;
if (uint64_t Size = Layout.getSectionFileSize(Sec)) {
- DwarfSegmentSize = alignTo(DwarfSegmentSize, Sec->getAlignment());
+ DwarfSegmentSize = alignTo(DwarfSegmentSize, Sec->getAlign());
DwarfSegmentSize += Size;
++NumDwarfSections;
}
continue;
uint64_t Pos = OutFile.tell();
- OutFile.write_zeros(alignTo(Pos, Sec.getAlignment()) - Pos);
+ OutFile.write_zeros(alignTo(Pos, Sec.getAlign()) - Pos);
MCAsm.writeSectionData(OutFile, &Sec, Layout);
}