-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Open
Labels
backend:Hexagonclang:driver'clang' and 'clang++' user-facing binaries. Not 'clang-cl''clang' and 'clang++' user-facing binaries. Not 'clang-cl'
Description
lld exhibits different behavior regarding the virtual address selection and one of the loaders appears to have an expectation/requirement that the virtual addresses be 4kb-aligned (min page size). This represents different behavior from eld.
echo 'int main(){}' > test.c
clang --target=hexagon-unknown-linux-musl -c test.c -o test.o
ld.lld test.o -o test_lld
readelf -l test_lld | grep -A1 "LOAD.*R E"
LLD Output:
LOAD 0x000000 0x00010210 0x00010210 0x000123 0x000123 R E 0x10000
↑ NOT 4KB aligned
ld.eld test.o -o test_eld
readelf -l test_eld | grep -A1 "LOAD.*R E"
ELD Output:
LOAD 0x000000 0x00010000 0x00010000 0x000123 0x000123 R E 0x10000
↑ 4KB aligned
@MaskRay I can fix this with a patch like the one below. Do you think that'd be an acceptable approach?
diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index e121fa1183e9..72e4e6815c05 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -122,6 +122,8 @@ public:
unsigned defaultCommonPageSize = 4096;
unsigned defaultMaxPageSize = 4096;
+ std::optional<unsigned> minLoadSegmentAlignment;
+
uint64_t getImageBase() const;
// True if _GLOBAL_OFFSET_TABLE_ is relative to .got.plt, false if .got.
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 4fa80397cbfa..ee8d4314d82a 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -2592,6 +2592,19 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
};
else
cmd->addrExpr = [&ctx] {
+ // If the target specifies a minimum LOAD segment alignment, enforce
+ // true page alignment to ensure LOAD segments are aligned to the
+ // required boundaries in virtual memory, not just in the p_align
+ // field. Other architectures preserve sub-page offsets to avoid file
+ // padding.
+ if (ctx.target->minLoadSegmentAlignment.has_value()) {
+ // Enforce minimum alignment, even if user specifies smaller page
+ // size
+ uint64_t minAlign = std::max(
+ ctx.arg.maxPageSize,
+ static_cast<uint64_t>(*ctx.target->minLoadSegmentAlignment));
+ return alignToPowerOf2(ctx.script->getDot(), minAlign);
+ }
return alignToPowerOf2(ctx.script->getDot(), ctx.arg.maxPageSize) +
ctx.script->getDot() % ctx.arg.maxPageSize;
};
Metadata
Metadata
Assignees
Labels
backend:Hexagonclang:driver'clang' and 'clang++' user-facing binaries. Not 'clang-cl''clang' and 'clang++' user-facing binaries. Not 'clang-cl'