[lld] 9ab49ae - [lld/mac] Implement -sectalign
Nico Weber via llvm-commits
llvm-commits at lists.llvm.org
Tue May 11 10:31:52 PDT 2021
Author: Nico Weber
Date: 2021-05-11T13:31:32-04:00
New Revision: 9ab49ae55dd7b928c2b806adccf6d07a89e59102
URL: https://github.com/llvm/llvm-project/commit/9ab49ae55dd7b928c2b806adccf6d07a89e59102
DIFF: https://github.com/llvm/llvm-project/commit/9ab49ae55dd7b928c2b806adccf6d07a89e59102.diff
LOG: [lld/mac] Implement -sectalign
clang sometimes passes this flag along (see D68351), so we should implement it.
Differential Revision: https://reviews.llvm.org/D102247
Added:
lld/test/MachO/sectalign.s
Modified:
lld/MachO/Config.h
lld/MachO/Driver.cpp
lld/MachO/Options.td
lld/MachO/OutputSegment.cpp
Removed:
################################################################################
diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index 077762c850840..471d5dae73117 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -51,6 +51,12 @@ enum class UndefinedSymbolTreatment {
dynamic_lookup,
};
+struct SectionAlign {
+ llvm::StringRef segName;
+ llvm::StringRef sectName;
+ uint32_t align;
+};
+
struct SegmentProtection {
llvm::StringRef name;
uint32_t maxProt;
@@ -115,8 +121,9 @@ struct Configuration {
std::vector<llvm::StringRef> runtimePaths;
std::vector<std::string> astPaths;
std::vector<Symbol *> explicitUndefineds;
- // There are typically very few custom segmentProtections, so use a vector
- // instead of a map.
+ // There are typically few custom sectionAlignments or segmentProtections,
+ // so use a vector instead of a map.
+ std::vector<SectionAlign> sectionAlignments;
std::vector<SegmentProtection> segmentProtections;
llvm::DenseMap<llvm::StringRef, SymbolPriorityEntry> priorities;
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index a5d74853d3e79..58a6036da3dfa 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -751,6 +751,30 @@ static uint32_t parseProtection(StringRef protStr) {
return prot;
}
+static std::vector<SectionAlign> parseSectAlign(const opt::InputArgList &args) {
+ std::vector<SectionAlign> sectAligns;
+ for (const Arg *arg : args.filtered(OPT_sectalign)) {
+ StringRef segName = arg->getValue(0);
+ StringRef sectName = arg->getValue(1);
+ StringRef alignStr = arg->getValue(2);
+ if (alignStr.startswith("0x") || alignStr.startswith("0X"))
+ alignStr = alignStr.drop_front(2);
+ uint32_t align;
+ if (alignStr.getAsInteger(16, align)) {
+ error("-sectalign: failed to parse '" + StringRef(arg->getValue(2)) +
+ "' as number");
+ continue;
+ }
+ if (!isPowerOf2_32(align)) {
+ error("-sectalign: '" + StringRef(arg->getValue(2)) +
+ "' (in base 16) not a power of two");
+ continue;
+ }
+ sectAligns.push_back({segName, sectName, align});
+ }
+ return sectAligns;
+}
+
static bool dataConstDefault(const InputArgList &args) {
switch (config->outputType) {
case MH_EXECUTE:
@@ -1039,6 +1063,8 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
validName(arg->getValue(1));
}
+ config->sectionAlignments = parseSectAlign(args);
+
for (const Arg *arg : args.filtered(OPT_segprot)) {
StringRef segName = arg->getValue(0);
uint32_t maxProt = parseProtection(arg->getValue(1));
diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index d950559ed2b86..44fddc72a11a9 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -778,7 +778,6 @@ def segalign : Separate<["-"], "segalign">,
def sectalign : MultiArg<["-"], "sectalign", 3>,
MetaVarName<"<segment> <section> <boundary>">,
HelpText<"Align <section> within <segment> to hex power-of-2 <boundary>">,
- Flags<[HelpHidden]>,
Group<grp_rare>;
def stack_addr : Separate<["-"], "stack_addr">,
MetaVarName<"<address>">,
diff --git a/lld/MachO/OutputSegment.cpp b/lld/MachO/OutputSegment.cpp
index a561a5a6037d9..d860ac8d59818 100644
--- a/lld/MachO/OutputSegment.cpp
+++ b/lld/MachO/OutputSegment.cpp
@@ -52,6 +52,10 @@ size_t OutputSegment::numNonHiddenSections() const {
void OutputSegment::addOutputSection(OutputSection *osec) {
osec->parent = this;
sections.push_back(osec);
+
+ for (const SectionAlign §Align : config->sectionAlignments)
+ if (sectAlign.segName == name && sectAlign.sectName == osec->name)
+ osec->align = sectAlign.align;
}
static DenseMap<StringRef, OutputSegment *> nameToOutputSegment;
diff --git a/lld/test/MachO/sectalign.s b/lld/test/MachO/sectalign.s
new file mode 100644
index 0000000000000..9eb8bf328ea43
--- /dev/null
+++ b/lld/test/MachO/sectalign.s
@@ -0,0 +1,42 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
+
+# RUN: not %lld -dylib -o %t %t.o -sectalign __TEXT __text asdf 2>&1 \
+# RUN: | FileCheck --check-prefix=NONUM -DNUM=asdf %s
+# RUN: not %lld -dylib -o %t %t.o -sectalign __TEXT __text 0x0X4 2>&1 \
+# RUN: | FileCheck --check-prefix=NONUM -DNUM=0x0X4 %s
+# NONUM: error: -sectalign: failed to parse '[[NUM]]' as number
+
+# RUN: not %lld -dylib -o %t %t.o -sectalign __TEXT __text 16 2>&1 \
+# RUN: | FileCheck --check-prefix=NOPOW -DNUM=16 %s
+# RUN: not %lld -dylib -o %t %t.o -sectalign __TEXT __text 0x16 2>&1 \
+# RUN: | FileCheck --check-prefix=NOPOW -DNUM=0x16 %s
+# RUN: not %lld -dylib -o %t %t.o -sectalign __TEXT __text 0 2>&1 \
+# RUN: | FileCheck --check-prefix=NOPOW -DNUM=0 %s
+# NOPOW: error: -sectalign: '[[NUM]]' (in base 16) not a power of two
+
+## __DATA_CONST tests that the flag applies to names after section renaming.
+# RUN: %lld -dylib -o %t %t.o -sectalign __TEXT __text 20 \
+# RUN: -sectalign __DATA_CONST __const 0x40
+# RUN: llvm-readobj --section-headers %t \
+# RUN: | FileCheck -DSECT=__text -DSEG=__TEXT -DALIGN=5 %s
+# RUN: llvm-readobj --section-headers %t \
+# RUN: | FileCheck -DSECT=__const -DSEG=__DATA_CONST -DALIGN=6 %s
+
+# RUN: %lld -dylib -o %t %t.o -rename_section __TEXT __text __TxT __foo \
+# RUN: -sectalign __TxT __foo 0x40
+# RUN: llvm-readobj --section-headers %t \
+# RUN: | FileCheck -DSECT=__foo -DSEG=__TxT -DALIGN=6 %s
+
+# CHECK: Name: [[SECT]]
+# CHECK-NEXT: Segment: [[SEG]]
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Alignment: [[ALIGN]]
+
+.section __TEXT,__text
+.space 1
+
+.section __DATA,__const
+.space 1
More information about the llvm-commits
mailing list