// is acceptable because section merging is optional.
if (auto *ms = dyn_cast<MergeInputSection>(s)) {
s = makeThreadLocal<InputSection>(
- ms->file, ms->flags, ms->type, ms->alignment,
+ ms->file, ms->flags, ms->type, ms->addralign,
ms->contentMaybeDecompress(), ms->name);
sections[info] = s;
}
InputSectionBase::InputSectionBase(InputFile *file, uint64_t flags,
uint32_t type, uint64_t entsize,
uint32_t link, uint32_t info,
- uint32_t alignment, ArrayRef<uint8_t> data,
+ uint32_t addralign, ArrayRef<uint8_t> data,
StringRef name, Kind sectionKind)
- : SectionBase(sectionKind, name, flags, entsize, alignment, type, info,
+ : SectionBase(sectionKind, name, flags, entsize, addralign, type, info,
link),
file(file), content_(data.data()), size(data.size()) {
// In order to reduce memory allocation, we assume that mergeable
// The ELF spec states that a value of 0 means the section has
// no alignment constraints.
- uint32_t v = std::max<uint32_t>(alignment, 1);
+ uint32_t v = std::max<uint32_t>(addralign, 1);
if (!isPowerOf2_64(v))
fatal(toString(this) + ": sh_addralign is not a power of 2");
- this->alignment = v;
+ this->addralign = v;
// If SHF_COMPRESSED is set, parse the header. The legacy .zdebug format is no
// longer supported.
compressed = true;
compressedSize = size;
size = hdr->ch_size;
- alignment = std::max<uint32_t>(hdr->ch_addralign, 1);
+ addralign = std::max<uint32_t>(hdr->ch_addralign, 1);
}
InputSection *InputSectionBase::getLinkOrderDep() const {
InputSection InputSection::discarded(nullptr, 0, 0, 0, ArrayRef<uint8_t>(), "");
InputSection::InputSection(InputFile *f, uint64_t flags, uint32_t type,
- uint32_t alignment, ArrayRef<uint8_t> data,
+ uint32_t addralign, ArrayRef<uint8_t> data,
StringRef name, Kind k)
: InputSectionBase(f, flags, type,
- /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, alignment, data,
+ /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, addralign, data,
name, k) {}
template <class ELFT>
}
void InputSection::replace(InputSection *other) {
- alignment = std::max(alignment, other->alignment);
+ addralign = std::max(addralign, other->addralign);
// When a section is replaced with another section that was allocated to
// another partition, the replacement section (and its associated sections)
// These corresponds to the fields in Elf_Shdr.
uint64_t flags;
- uint32_t alignment;
+ uint32_t addralign;
uint32_t entsize;
uint32_t link;
uint32_t info;
protected:
constexpr SectionBase(Kind sectionKind, StringRef name, uint64_t flags,
- uint32_t entsize, uint32_t alignment, uint32_t type,
+ uint32_t entsize, uint32_t addralign, uint32_t type,
uint32_t info, uint32_t link)
: sectionKind(sectionKind), bss(false), keepUnique(false), type(type),
- name(name), flags(flags), alignment(alignment), entsize(entsize),
+ name(name), flags(flags), addralign(addralign), entsize(entsize),
link(link), info(info) {}
};
InputSectionBase(InputFile *file, uint64_t flags, uint32_t type,
uint64_t entsize, uint32_t link, uint32_t info,
- uint32_t alignment, ArrayRef<uint8_t> data, StringRef name,
+ uint32_t addralign, ArrayRef<uint8_t> data, StringRef name,
Kind sectionKind);
static bool classof(const SectionBase *s) { return s->kind() != Output; }
// .eh_frame. It also includes the synthetic sections themselves.
class InputSection : public InputSectionBase {
public:
- InputSection(InputFile *f, uint64_t flags, uint32_t type, uint32_t alignment,
+ InputSection(InputFile *f, uint64_t flags, uint32_t type, uint32_t addralign,
ArrayRef<uint8_t> data, StringRef name, Kind k = Regular);
template <class ELFT>
InputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
class SyntheticSection : public InputSection {
public:
- SyntheticSection(uint64_t flags, uint32_t type, uint32_t alignment,
+ SyntheticSection(uint64_t flags, uint32_t type, uint32_t addralign,
StringRef name)
- : InputSection(nullptr, flags, type, alignment, {}, name,
+ : InputSection(nullptr, flags, type, addralign, {}, name,
InputSectionBase::Synthetic) {}
virtual ~SyntheticSection() = default;
// ">" is not a mistake. Sections with larger alignments are placed
// before sections with smaller alignments in order to reduce the
// amount of padding necessary. This is compatible with GNU.
- return a->alignment > b->alignment;
+ return a->addralign > b->addralign;
};
auto nameComparator = [](InputSectionBase *a, InputSectionBase *b) {
return a->name < b->name;
if (osec->subalignExpr) {
uint32_t subalign = osec->subalignExpr().getValue();
for (InputSectionBase *s : v)
- s->alignment = subalign;
+ s->addralign = subalign;
}
// Set the partition field the same way OutputSection::recordSection()
// sec->alignment is the max of ALIGN and the maximum of input
// section alignments.
const uint64_t pos = dot;
- dot = alignToPowerOf2(dot, sec->alignment);
+ dot = alignToPowerOf2(dot, sec->addralign);
sec->addr = dot;
expandMemoryRegions(dot - pos);
}
if (sec->lmaExpr) {
state->lmaOffset = sec->lmaExpr().getValue() - dot;
} else if (MemoryRegion *mr = sec->lmaRegion) {
- uint64_t lmaStart = alignToPowerOf2(mr->curPos, sec->alignment);
+ uint64_t lmaStart = alignToPowerOf2(mr->curPos, sec->addralign);
if (mr->curPos < lmaStart)
expandMemoryRegion(mr, lmaStart - mr->curPos, sec->name);
state->lmaOffset = lmaStart - dot;
for (InputSection *isec : cast<InputSectionDescription>(cmd)->sections) {
assert(isec->getParent() == sec);
const uint64_t pos = dot;
- dot = alignToPowerOf2(dot, isec->alignment);
+ dot = alignToPowerOf2(dot, isec->addralign);
isec->outSecOff = dot - sec->addr;
dot += isec->getSize();
// Handle align (e.g. ".foo : ALIGN(16) { ... }").
if (sec->alignExpr)
- sec->alignment =
- std::max<uint32_t>(sec->alignment, sec->alignExpr().getValue());
+ sec->addralign =
+ std::max<uint32_t>(sec->addralign, sec->alignExpr().getValue());
bool isEmpty = (getFirstInputSection(sec) == nullptr);
bool discardable = isEmpty && isDiscardable(*sec);
}
osec = &cast<OutputDesc>(cmd)->osec;
- writeHeader(os, osec->addr, osec->getLMA(), osec->size, osec->alignment);
+ writeHeader(os, osec->addr, osec->getLMA(), osec->size, osec->addralign);
os << osec->name << '\n';
// Dump symbols for each input section.
}
writeHeader(os, isec->getVA(), osec->getLMA() + isec->outSecOff,
- isec->getSize(), isec->alignment);
+ isec->getSize(), isec->addralign);
os << indent8 << toString(isec) << '\n';
for (Symbol *sym : llvm::make_first_range(sectionSyms[isec]))
os << symStr[sym] << '\n';
template <class ELFT>
void OutputSection::writeHeaderTo(typename ELFT::Shdr *shdr) {
shdr->sh_entsize = entsize;
- shdr->sh_addralign = alignment;
+ shdr->sh_addralign = addralign;
shdr->sh_type = type;
shdr->sh_offset = offset;
shdr->sh_flags = flags;
if (nonAlloc)
flags &= ~(uint64_t)SHF_ALLOC;
- alignment = std::max(alignment, isec->alignment);
+ addralign = std::max(addralign, isec->addralign);
// If this section contains a table of fixed-size entries, sh_entsize
// holds the element size. If it contains elements of different size we
static MergeSyntheticSection *createMergeSynthetic(StringRef name,
uint32_t type,
uint64_t flags,
- uint32_t alignment) {
+ uint32_t addralign) {
if ((flags & SHF_STRINGS) && config->optimize >= 2)
- return make<MergeTailSection>(name, type, flags, alignment);
- return make<MergeNoTailSection>(name, type, flags, alignment);
+ return make<MergeTailSection>(name, type, flags, addralign);
+ return make<MergeNoTailSection>(name, type, flags, addralign);
}
// This function scans over the InputSectionBase list sectionBases to create
//
// SHF_STRINGS section with different alignments should not be merged.
return sec->flags == ms->flags && sec->entsize == ms->entsize &&
- (sec->alignment == ms->alignment || !(sec->flags & SHF_STRINGS));
+ (sec->addralign == ms->addralign || !(sec->flags & SHF_STRINGS));
});
if (i == mergeSections.end()) {
MergeSyntheticSection *syn =
- createMergeSynthetic(name, ms->type, ms->flags, ms->alignment);
+ createMergeSynthetic(name, ms->type, ms->flags, ms->addralign);
mergeSections.push_back(syn);
i = std::prev(mergeSections.end());
syn->entsize = ms->entsize;
if (compressed.shards) {
auto *chdr = reinterpret_cast<typename ELFT::Chdr *>(buf);
chdr->ch_size = compressed.uncompressedSize;
- chdr->ch_addralign = alignment;
+ chdr->ch_addralign = addralign;
buf += sizeof(*chdr);
if (config->compressDebugSections == DebugCompressionType::Zstd) {
chdr->ch_type = ELFCOMPRESS_ZSTD;
// relrDyn sections don't support odd offsets. Also, relrDyn sections
// don't store the addend values, so we must write it to the relocated
// address.
- if (part.relrDyn && isec.alignment >= 2 && offsetInSec % 2 == 0) {
+ if (part.relrDyn && isec.addralign >= 2 && offsetInSec % 2 == 0) {
isec.addReloc({expr, type, offsetInSec, addend, &sym});
if (shard)
part.relrDyn->relocsVec[parallel::getThreadIndex()].push_back(
OutputSection *osec = &script->getOrCreateOutputSection(name)->osec;
return [=] {
checkIfExists(*osec, location);
- return osec->alignment;
+ return osec->addralign;
};
}
if (tok == "ASSERT")
for (SectionCommand *cmd : os->commands) {
if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
for (InputSection *isec : isd->sections) {
- uint64_t off = alignToPowerOf2(secSize, isec->alignment);
+ uint64_t off = alignToPowerOf2(secSize, isec->addralign);
secSize = off + isec->getSize();
}
}
// When -r is specified, a COMMON symbol is not allocated. Its st_shndx
// holds SHN_COMMON and st_value holds the alignment.
eSym->st_shndx = SHN_COMMON;
- eSym->st_value = commonSec->alignment;
+ eSym->st_value = commonSec->addralign;
eSym->st_size = cast<Defined>(sym)->size;
} else {
const uint32_t shndx = getSymSectionIndex(sym);
// On PowerPC, this section contains lazy symbol resolvers.
if (config->emachine == EM_PPC64) {
name = ".glink";
- alignment = 4;
+ addralign = 4;
}
// On x86 when IBT is enabled, this section contains the second PLT (lazy
: SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, ".iplt") {
if (config->emachine == EM_PPC || config->emachine == EM_PPC64) {
name = ".glink";
- alignment = 4;
+ addralign = 4;
}
}
PPC32GlinkSection::PPC32GlinkSection() {
name = ".glink";
- alignment = 4;
+ addralign = 4;
}
void PPC32GlinkSection::writeTo(uint8_t *buf) {
void MergeSyntheticSection::addSection(MergeInputSection *ms) {
ms->parent = this;
sections.push_back(ms);
- assert(alignment == ms->alignment || !(ms->flags & SHF_STRINGS));
- alignment = std::max(alignment, ms->alignment);
+ assert(addralign == ms->addralign || !(ms->flags & SHF_STRINGS));
+ addralign = std::max(addralign, ms->addralign);
}
MergeTailSection::MergeTailSection(StringRef name, uint32_t type,
void MergeNoTailSection::finalizeContents() {
// Initializes string table builders.
for (size_t i = 0; i < numShards; ++i)
- shards.emplace_back(StringTableBuilder::RAW, alignment);
+ shards.emplace_back(StringTableBuilder::RAW, addralign);
// Concurrency level. Must be a power of 2 to avoid expensive modulo
// operations in the following tight loop.
for (size_t i = 0; i < numShards; ++i) {
shards[i].finalizeInOrder();
if (shards[i].getSize() > 0)
- off = alignToPowerOf2(off, alignment);
+ off = alignToPowerOf2(off, addralign);
shardOffsets[i] = off;
off += shards[i].getSize();
}
for (EhInputSection *sec : ctx.ehInputSections) {
EhFrameSection &eh = *sec->getPartition().ehFrame;
sec->parent = &eh;
- eh.alignment = std::max(eh.alignment, sec->alignment);
+ eh.addralign = std::max(eh.addralign, sec->addralign);
eh.sections.push_back(sec);
llvm::append_range(eh.dependentSections, sec->dependentSections);
}
// respectively.
class BssSection final : public SyntheticSection {
public:
- BssSection(StringRef name, uint64_t size, uint32_t alignment);
+ BssSection(StringRef name, uint64_t size, uint32_t addralign);
void writeTo(uint8_t *) override {}
bool isNeeded() const override { return size != 0; }
size_t getSize() const override { return size; }
protected:
MergeSyntheticSection(StringRef name, uint32_t type, uint64_t flags,
- uint32_t alignment)
- : SyntheticSection(flags, type, alignment, name) {}
+ uint32_t addralign)
+ : SyntheticSection(flags, type, addralign, name) {}
};
class MergeTailSection final : public MergeSyntheticSection {
public:
MergeTailSection(StringRef name, uint32_t type, uint64_t flags,
- uint32_t alignment);
+ uint32_t addralign);
size_t getSize() const override;
void writeTo(uint8_t *buf) override;
class MergeNoTailSection final : public MergeSyntheticSection {
public:
MergeNoTailSection(StringRef name, uint32_t type, uint64_t flags,
- uint32_t alignment)
- : MergeSyntheticSection(name, type, flags, alignment) {}
+ uint32_t addralign)
+ : MergeSyntheticSection(name, type, flags, addralign) {}
size_t getSize() const override { return size; }
void writeTo(uint8_t *buf) override;
in.shStrTab = std::make_unique<StringTableSection>(".shstrtab", false);
Out::programHeaders = make<OutputSection>("", 0, SHF_ALLOC);
- Out::programHeaders->alignment = config->wordsize;
+ Out::programHeaders->addralign = config->wordsize;
if (config->strip != StripPolicy::All) {
in.strTab = std::make_unique<StringTableSection>(".strtab", false);
lastSec = sec;
if (!firstSec)
firstSec = sec;
- p_align = std::max(p_align, sec->alignment);
+ p_align = std::max(p_align, sec->addralign);
if (p_type == PT_LOAD)
sec->ptLoad = this;
}
for (SectionCommand *cmd : script->sectionCommands)
if (auto *osd = dyn_cast<OutputDesc>(cmd)) {
OutputSection *osec = &osd->osec;
- if (osec->addr % osec->alignment != 0)
+ if (osec->addr % osec->addralign != 0)
warn("address (0x" + Twine::utohexstr(osec->addr) + ") of section " +
osec->name + " is not a multiple of alignment (" +
- Twine(osec->alignment) + ")");
+ Twine(osec->addralign) + ")");
}
}
if (sec->partition != partNo)
continue;
if (sec->type == SHT_NOTE && (sec->flags & SHF_ALLOC)) {
- if (!note || sec->lmaExpr || note->lastSec->alignment != sec->alignment)
+ if (!note || sec->lmaExpr || note->lastSec->addralign != sec->addralign)
note = addHdr(PT_NOTE, PF_R);
note->add(sec);
} else {
OutputSection *cmd = p->firstSec;
if (!cmd)
return;
- cmd->alignExpr = [align = cmd->alignment]() { return align; };
+ cmd->alignExpr = [align = cmd->addralign]() { return align; };
if (!cmd->addrExpr) {
// Prefer advancing to align(dot, maxPageSize) + dot%maxPageSize to avoid
// padding in the file contents.
// If the section is not in a PT_LOAD, we just have to align it.
if (!os->ptLoad)
- return alignToPowerOf2(off, os->alignment);
+ return alignToPowerOf2(off, os->addralign);
// If two sections share the same PT_LOAD the file offset is calculated
// using this formula: Off2 = Off1 + (VA2 - VA1).
}
for (OutputSection *osec : outputSections)
if (!(osec->flags & SHF_ALLOC)) {
- osec->offset = alignToPowerOf2(off, osec->alignment);
+ osec->offset = alignToPowerOf2(off, osec->addralign);
off = osec->offset + osec->size;
}