Skip to content

Commit 86b7728

Browse files
committed
Address review comments
- Remove trailing hashes from test - Joined test class references together to demonstrate spaces not required - Migrate to llvm-objdump -s for content tests; add end of line checks - Add test for missing open paren not being interpreted as a filename - Add test for undefined section class - Use abbreviation "osd" for OutputDesc variables - Add comment for section class command enum - Move classRef member variable earlier in InputSectionDescription - Use DenseMap from CachedHashStringRef over StringMap - Clarify undefined.lds test comment. - Clarify comment for section class members with different parent - Replace comment on SectionClass struct - Use unquote for section names; add test
1 parent 379d957 commit 86b7728

File tree

5 files changed

+54
-36
lines changed

5 files changed

+54
-36
lines changed

lld/ELF/LinkerScript.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,8 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
590590
// input order).
591591
sortByPositionThenCommandLine(sizeAfterPrevSort, ret.size());
592592
} else {
593-
SectionClassDesc *scd = script->sectionClasses.lookup(cmd->classRef);
593+
SectionClassDesc *scd =
594+
script->sectionClasses.lookup(CachedHashStringRef(cmd->classRef));
594595
if (!scd) {
595596
errorOrWarn("undefined section class '" + cmd->classRef + "'");
596597
return ret;
@@ -756,8 +757,9 @@ void LinkerScript::processSectionCommands() {
756757
isd->sectionBases =
757758
computeInputSections(isd, ctx.inputSections, sc->sc);
758759
for (InputSectionBase *s : isd->sectionBases) {
759-
// Section classes with --enable-non-contiguous-regions may contain
760-
// parented classes; spills for these are generated on reference.
760+
// A section class containing a section with different parent isn't
761+
// necessarily an error due to --enable-non-contiguous-regions. Such
762+
// sections all become potential spills when the class is referenced.
761763
if (!s->parent)
762764
s->parent = &sc->sc;
763765
}
@@ -831,8 +833,8 @@ void LinkerScript::processSymbolAssignments() {
831833
for (SectionCommand *cmd : sectionCommands) {
832834
if (auto *assign = dyn_cast<SymbolAssignment>(cmd))
833835
addSymbol(assign);
834-
else if (auto *od = dyn_cast<OutputDesc>(cmd))
835-
for (SectionCommand *subCmd : od->osec.commands)
836+
else if (auto *osd = dyn_cast<OutputDesc>(cmd))
837+
for (SectionCommand *subCmd : osd->osec.commands)
836838
if (auto *assign = dyn_cast<SymbolAssignment>(subCmd))
837839
addSymbol(assign);
838840
}
@@ -1529,10 +1531,10 @@ bool LinkerScript::spillSections() {
15291531

15301532
bool spilled = false;
15311533
for (SectionCommand *cmd : reverse(sectionCommands)) {
1532-
auto *od = dyn_cast<OutputDesc>(cmd);
1533-
if (!od)
1534+
auto *osd = dyn_cast<OutputDesc>(cmd);
1535+
if (!osd)
15341536
continue;
1535-
OutputSection *osec = &od->osec;
1537+
OutputSection *osec = &osd->osec;
15361538
if (!osec->memRegion)
15371539
continue;
15381540

lld/ELF/LinkerScript.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ enum SectionsCommandKind {
8181
OutputSectionKind,
8282
InputSectionKind,
8383
ByteKind, // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr)
84-
ClassKind,
84+
ClassKind, // CLASS(class_name)
8585
};
8686

8787
struct SectionCommand {
@@ -203,7 +203,7 @@ class InputSectionDescription : public SectionCommand {
203203
InputSectionDescription(StringRef filePattern, uint64_t withFlags = 0,
204204
uint64_t withoutFlags = 0, StringRef classRef = {})
205205
: SectionCommand(InputSectionKind), filePat(filePattern),
206-
withFlags(withFlags), withoutFlags(withoutFlags), classRef(classRef) {
206+
classRef(classRef), withFlags(withFlags), withoutFlags(withoutFlags) {
207207
assert((filePattern.empty() || classRef.empty()) &&
208208
"file pattern and class reference are mutually exclusive");
209209
}
@@ -218,6 +218,10 @@ class InputSectionDescription : public SectionCommand {
218218
// will be associated with this InputSectionDescription.
219219
SmallVector<SectionPattern, 0> sectionPatterns;
220220

221+
// If present, input section matching uses class membership instead of file
222+
// and section patterns (mutually exclusive).
223+
StringRef classRef;
224+
221225
// Includes InputSections and MergeInputSections. Used temporarily during
222226
// assignment of input sections to output sections.
223227
SmallVector<InputSectionBase *, 0> sectionBases;
@@ -234,10 +238,6 @@ class InputSectionDescription : public SectionCommand {
234238
// SectionPatterns can be filtered with the INPUT_SECTION_FLAGS command.
235239
uint64_t withFlags;
236240
uint64_t withoutFlags;
237-
238-
// If present, input section matching uses class membership instead of file
239-
// and section patterns (mutually exclusive).
240-
StringRef classRef;
241241
};
242242

243243
// Represents BYTE(), SHORT(), LONG(), or QUAD().
@@ -442,7 +442,7 @@ class LinkerScript final {
442442
// Named lists of input sections that can be collectively referenced in output
443443
// section descriptions. Multiple references allow for sections to spill from
444444
// one output section to another.
445-
llvm::StringMap<SectionClassDesc *> sectionClasses;
445+
llvm::DenseMap<llvm::CachedHashStringRef, SectionClassDesc *> sectionClasses;
446446
};
447447

448448
struct ScriptWrapper {

lld/ELF/OutputSections.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,9 @@ struct OutputDesc final : SectionCommand {
137137
}
138138
};
139139

140-
// A list of input sections that can be referenced in output descriptions.
141-
// Multiple references allow sections to spill from one output section to the
142-
// next.
140+
// This represents a CLASS(class_name) { ... } that can be referenced by output
141+
// section descriptions. If referenced more than once, the sections can be
142+
// spilled to the next reference like --enable-non-contiguous-regions.
143143
struct SectionClass final : public SectionBase {
144144
SmallVector<InputSectionDescription *, 0> commands;
145145
bool assigned = false;

lld/ELF/ScriptParser.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ SmallVector<SectionCommand *, 0> ScriptParser::readOverlay() {
610610
SectionClassDesc *ScriptParser::readSectionClassDescription() {
611611
StringRef name = readSectionClassName();
612612
SectionClassDesc *desc = make<SectionClassDesc>(name);
613-
if (!script->sectionClasses.insert({name, desc}).second)
613+
if (!script->sectionClasses.insert({CachedHashStringRef(name), desc}).second)
614614
setError("section class '" + name + "' already defined");
615615
expect("{");
616616
while (!errorCount() && !consume("}")) {
@@ -630,7 +630,7 @@ SectionClassDesc *ScriptParser::readSectionClassDescription() {
630630

631631
StringRef ScriptParser::readSectionClassName() {
632632
expect("(");
633-
StringRef name = next();
633+
StringRef name = unquote(next());
634634
expect(")");
635635
return name;
636636
}

lld/test/ELF/linkerscript/section-class.test

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,38 +32,37 @@
3232

3333
#--- matching.lds
3434
## CLASS definitions match sections in linker script order. The sections may be
35-
## placed in a different order. Classes may derive from one another. Class # #
35+
## placed in a different order. Classes may derive from one another. Class
3636
## references can be restricted by INPUT_SECTION_FLAGS. Classes can be referenced
3737
## in /DISCARD/ and INSERT.
3838
SECTIONS {
3939
CLASS(a) { *(.rodata.a) }
4040
CLASS(cd) { *(.rodata.c) *(.rodata.d) }
4141
CLASS(ef) { *(SORT_BY_ALIGNMENT(.rodata.e .rodata.f)) }
4242
CLASS(g) { *(.rodata.g) }
43-
CLASS(h) { *(.rodata.h) }
43+
CLASS("h)") { *(.rodata.h) }
4444
.rodata : {
4545
*(.rodata.*)
4646
INPUT_SECTION_FLAGS(SHF_EXECINSTR) CLASS( cd)
47-
CLASS(a)
48-
CLASS(ef )
47+
CLASS(a)CLASS(ef )
4948
}
5049
OVERLAY : { .rodata.d { INPUT_SECTION_FLAGS(!SHF_EXECINSTR) CLASS(cd) } }
5150
/DISCARD/ : { CLASS(g) }
5251
}
5352

5453
SECTIONS {
55-
.rodata.h : { CLASS(h) }
54+
.rodata.h : { CLASS("h)") }
5655
} INSERT AFTER .rodata;
5756

5857
# RUN: ld.lld -T matching.lds matching.o -o matching
59-
# RUN: llvm-readobj -x .rodata -x .rodata.d -x .rodata.h matching |\
58+
# RUN: llvm-objdump -s matching |\
6059
# RUN: FileCheck %s --check-prefix=MATCHING
6160
# MATCHING: .rodata
62-
# MATCHING-NEXT: 020301cc 0605
61+
# MATCHING-NEXT: 020301cc 0605 ......{{$}}
6362
# MATCHING: .rodata.h
64-
# MATCHING-NEXT: 08
63+
# MATCHING-NEXT: 08 .{{$}}
6564
# MATCHING: .rodata.d
66-
# MATCHING-NEXT: 04
65+
# MATCHING-NEXT: 04 .{{$}}
6766

6867
#--- already-defined.lds
6968
## A section class has more than one description.
@@ -79,16 +78,23 @@ SECTIONS {
7978

8079
# ALREADY-DEFINED: error: already-defined.lds:4: section class 'a' already defined
8180

82-
#--- missing-filename-pattern.lds
81+
#--- missing-filename-pattern-1.lds
8382
## A filename pattern is missing in a section class description.
8483
SECTIONS {
8584
CLASS(a) { (.rodata.a) }
8685
}
86+
#--- missing-filename-pattern-2.lds
87+
## A filename pattern is missing in a section class description.
88+
SECTIONS {
89+
CLASS(a) { .rodata.a) }
90+
}
8791

88-
# RUN: not ld.lld -T missing-filename-pattern.lds matching.o 2>&1 | \
92+
# RUN: not ld.lld -T missing-filename-pattern-1.lds matching.o 2>&1 | \
93+
# RUN: FileCheck %s --check-prefix=MISSING-FILENAME-PATTERN --implicit-check-not=error:
94+
# RUN: not ld.lld -T missing-filename-pattern-2.lds matching.o 2>&1 | \
8995
# RUN: FileCheck %s --check-prefix=MISSING-FILENAME-PATTERN --implicit-check-not=error:
9096

91-
# MISSING-FILENAME-PATTERN: error: missing-filename-pattern.lds:3: expected filename pattern
97+
# MISSING-FILENAME-PATTERN: error: missing-filename-pattern-{{[1-2]}}.lds:3: expected filename pattern
9298

9399
#--- multiple-class-names.lds
94100
## More than one class is mentioned in a reference.
@@ -103,6 +109,17 @@ SECTIONS {
103109

104110
# MULTIPLE-CLASS-NAMES: error: multiple-class-names.lds:5: ) expected, but got b
105111

112+
#--- undefined.lds
113+
## A section class is referenced but never defined
114+
SECTIONS {
115+
.rodata : { CLASS(a) }
116+
}
117+
118+
# RUN: not ld.lld -T undefined.lds matching.o 2>&1 | \
119+
# RUN: FileCheck %s --check-prefix=UNDEFINED --implicit-check-not=error:
120+
121+
# UNDEFINED: error: undefined section class 'a'
122+
106123
#--- referenced-before-defined.lds
107124
## The content of section classes is demanded before its definition is processed.
108125
SECTIONS {
@@ -119,8 +136,7 @@ SECTIONS {
119136
# REFERENCED-BEFORE-DEFINED-WARN: warning: section class 'a' referenced by '.rodata' before class definition
120137

121138
#--- unreferenced.lds
122-
## An input section is bound to a section class but is not referenced by at
123-
## least one output section.
139+
## An input section is bound to a section class but is not referenced.
124140
SECTIONS {
125141
CLASS(a) { *(.rodata.*) }
126142
}
@@ -362,9 +378,9 @@ SECTIONS {
362378
}
363379

364380
# RUN: ld.lld -T link-order.lds link-order.o -o link-order
365-
# RUN: llvm-readobj -x .order link-order | FileCheck %s --check-prefix=LINK-ORDER
381+
# RUN: llvm-objdump -s link-order | FileCheck %s --check-prefix=LINK-ORDER
366382

367-
# LINK-ORDER: 020301
383+
# LINK-ORDER: 020301 ...{{$}}
368384

369385
#--- from-insert.lds
370386
## A section might spill from INSERT.

0 commit comments

Comments
 (0)