mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[JITLink] Don't under-align zero-fill sections.
If content sections have lower alignment than zero-fill sections then bump the overall segment alignment to avoid under-aligning the zero-fill sections. llvm-svn: 370072
This commit is contained in:
parent
7bb0bc7bff
commit
20a640eda8
@ -238,60 +238,47 @@ Error JITLinkerBase::allocateSegments(const SegmentLayoutMap &Layout) {
|
|||||||
|
|
||||||
// Calculate segment content size.
|
// Calculate segment content size.
|
||||||
size_t SegContentSize = 0;
|
size_t SegContentSize = 0;
|
||||||
|
uint32_t SegContentAlign = 1;
|
||||||
for (auto &SI : SegLayout.ContentSections) {
|
for (auto &SI : SegLayout.ContentSections) {
|
||||||
assert(!SI.S->atoms_empty() && "Sections in layout must not be empty");
|
assert(!SI.S->atoms_empty() && "Sections in layout must not be empty");
|
||||||
assert(!SI.Atoms.empty() && "Section layouts must not be empty");
|
assert(!SI.Atoms.empty() && "Section layouts must not be empty");
|
||||||
|
|
||||||
// Bump to section alignment before processing atoms.
|
// Bump to section alignment before processing atoms.
|
||||||
SegContentSize = alignTo(SegContentSize, SI.S->getAlignment());
|
SegContentSize = alignTo(SegContentSize, SI.S->getAlignment());
|
||||||
|
SegContentAlign = std::max(SegContentAlign, SI.S->getAlignment());
|
||||||
|
|
||||||
for (auto *DA : SI.Atoms) {
|
for (auto *DA : SI.Atoms) {
|
||||||
SegContentSize = alignTo(SegContentSize, DA->getAlignment());
|
SegContentSize = alignTo(SegContentSize, DA->getAlignment());
|
||||||
SegContentSize += DA->getSize();
|
SegContentSize += DA->getSize();
|
||||||
|
SegContentAlign = std::max(SegContentAlign, DA->getAlignment());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get segment content alignment.
|
|
||||||
unsigned SegContentAlign = 1;
|
|
||||||
if (!SegLayout.ContentSections.empty()) {
|
|
||||||
auto &FirstContentSection = SegLayout.ContentSections.front();
|
|
||||||
SegContentAlign =
|
|
||||||
std::max(FirstContentSection.S->getAlignment(),
|
|
||||||
FirstContentSection.Atoms.front()->getAlignment());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate segment zero-fill size.
|
// Calculate segment zero-fill size.
|
||||||
uint64_t SegZeroFillSize = 0;
|
uint64_t SegZeroFillSize = 0;
|
||||||
|
uint32_t SegZeroFillAlign = 1;
|
||||||
|
|
||||||
for (auto &SI : SegLayout.ZeroFillSections) {
|
for (auto &SI : SegLayout.ZeroFillSections) {
|
||||||
assert(!SI.S->atoms_empty() && "Sections in layout must not be empty");
|
assert(!SI.S->atoms_empty() && "Sections in layout must not be empty");
|
||||||
assert(!SI.Atoms.empty() && "Section layouts must not be empty");
|
assert(!SI.Atoms.empty() && "Section layouts must not be empty");
|
||||||
|
|
||||||
// Bump to section alignment before processing atoms.
|
// Bump to section alignment before processing atoms.
|
||||||
SegZeroFillSize = alignTo(SegZeroFillSize, SI.S->getAlignment());
|
SegZeroFillSize = alignTo(SegZeroFillSize, SI.S->getAlignment());
|
||||||
|
SegZeroFillAlign = std::max(SegZeroFillAlign, SI.S->getAlignment());
|
||||||
|
|
||||||
for (auto *DA : SI.Atoms) {
|
for (auto *DA : SI.Atoms) {
|
||||||
SegZeroFillSize = alignTo(SegZeroFillSize, DA->getAlignment());
|
SegZeroFillSize = alignTo(SegZeroFillSize, DA->getAlignment());
|
||||||
SegZeroFillSize += DA->getSize();
|
SegZeroFillSize += DA->getSize();
|
||||||
|
SegZeroFillAlign = std::max(SegZeroFillAlign, SI.S->getAlignment());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate segment zero-fill alignment.
|
assert(isPowerOf2_32(SegContentAlign) &&
|
||||||
uint32_t SegZeroFillAlign = 1;
|
"Expected content alignment to be power of 2");
|
||||||
|
assert(isPowerOf2_32(SegZeroFillAlign) &&
|
||||||
if (!SegLayout.ZeroFillSections.empty()) {
|
"Expected zero-fill alignment to be power of 2");
|
||||||
auto &FirstZeroFillSection = SegLayout.ZeroFillSections.front();
|
// Round content alignment up to segment alignment.
|
||||||
SegZeroFillAlign =
|
SegContentAlign = std::max(SegContentAlign, SegZeroFillAlign);
|
||||||
std::max(FirstZeroFillSection.S->getAlignment(),
|
|
||||||
FirstZeroFillSection.Atoms.front()->getAlignment());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SegContentSize == 0)
|
|
||||||
SegContentAlign = SegZeroFillAlign;
|
|
||||||
|
|
||||||
if (SegContentAlign % SegZeroFillAlign != 0)
|
|
||||||
return make_error<JITLinkError>("First content atom alignment does not "
|
|
||||||
"accommodate first zero-fill atom "
|
|
||||||
"alignment");
|
|
||||||
|
|
||||||
Segments[Prot] = {SegContentSize, SegContentAlign, SegZeroFillSize,
|
Segments[Prot] = {SegContentSize, SegContentAlign, SegZeroFillSize,
|
||||||
SegZeroFillAlign};
|
SegZeroFillAlign};
|
||||||
|
14
test/ExecutionEngine/JITLink/X86/MachO_zero_fill_alignment.s
Normal file
14
test/ExecutionEngine/JITLink/X86/MachO_zero_fill_alignment.s
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# RUN: rm -rf %t && mkdir -p %t
|
||||||
|
# RUN: llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o %t/macho_zero_fill_align.o %s
|
||||||
|
# RUN: llvm-jitlink -noexec %t/macho_zero_fill_align.o -entry higher_zero_fill_align
|
||||||
|
|
||||||
|
.section __DATA,__data
|
||||||
|
.globl low_aligned_data
|
||||||
|
.p2align 0
|
||||||
|
low_aligned_data:
|
||||||
|
.byte 42
|
||||||
|
|
||||||
|
.globl higher_zero_fill_align
|
||||||
|
.zerofill __DATA,__zero_fill,higher_zero_fill_align,8,3
|
||||||
|
|
||||||
|
.subsections_via_symbols
|
Loading…
Reference in New Issue
Block a user