Skip to content

Commit a747179

Browse files
committed
Take name, type and flags in consideration when concatenating sections.
This is mandated by the ELF spec. llvm-svn: 244911
1 parent e4fabc9 commit a747179

File tree

2 files changed

+65
-14
lines changed

2 files changed

+65
-14
lines changed

lld/ELF/Writer.cpp

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ template <class ELFT> class OutputSection {
6363
template <class ELFT> class Writer {
6464
public:
6565
typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
66+
typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
6667
Writer(SymbolTable *T) : Symtab(T) {}
6768
void run();
6869

@@ -140,13 +141,44 @@ template <class ELFT> void OutputSection<ELFT>::writeHeaderTo(Elf_Shdr *SHdr) {
140141
*SHdr = Header;
141142
}
142143

144+
namespace {
145+
template <bool Is64Bits> struct SectionKey {
146+
typedef typename std::conditional<Is64Bits, uint64_t, uint32_t>::type uintX_t;
147+
StringRef Name;
148+
uint32_t sh_type;
149+
uintX_t sh_flags;
150+
};
151+
}
152+
namespace llvm {
153+
template <bool Is64Bits> struct DenseMapInfo<SectionKey<Is64Bits>> {
154+
static SectionKey<Is64Bits> getEmptyKey() {
155+
return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getEmptyKey(), 0, 0};
156+
}
157+
static SectionKey<Is64Bits> getTombstoneKey() {
158+
return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getTombstoneKey(), 0,
159+
0};
160+
}
161+
static unsigned getHashValue(const SectionKey<Is64Bits> &Val) {
162+
return hash_combine(Val.Name, Val.sh_type, Val.sh_flags);
163+
}
164+
static bool isEqual(const SectionKey<Is64Bits> &LHS,
165+
const SectionKey<Is64Bits> &RHS) {
166+
return DenseMapInfo<StringRef>::isEqual(LHS.Name, RHS.Name) &&
167+
LHS.sh_type == RHS.sh_type && LHS.sh_flags == RHS.sh_flags;
168+
}
169+
};
170+
}
171+
143172
// Create output section objects and add them to OutputSections.
144173
template <class ELFT> void Writer<ELFT>::createSections() {
145-
SmallDenseMap<StringRef, OutputSection<ELFT> *> Map;
174+
SmallDenseMap<SectionKey<ELFT::Is64Bits>, OutputSection<ELFT> *> Map;
146175
for (std::unique_ptr<ObjectFileBase> &FileB : Symtab->ObjectFiles) {
147176
auto &File = cast<ObjectFile<ELFT>>(*FileB);
148177
for (SectionChunk<ELFT> *C : File.getChunks()) {
149-
OutputSection<ELFT> *&Sec = Map[C->getSectionName()];
178+
const Elf_Shdr *H = C->getSectionHdr();
179+
SectionKey<ELFT::Is64Bits> Key{C->getSectionName(), H->sh_type,
180+
H->sh_flags};
181+
OutputSection<ELFT> *&Sec = Map[Key];
150182
if (!Sec) {
151183
Sec = new (CAlloc.Allocate()) OutputSection<ELFT>(C->getSectionName());
152184
OutputSections.push_back(Sec);

lld/test/elf2/string-table.s

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,47 @@
66
.global _start
77
_start:
88

9-
.section foobar
9+
.section foobar,"",@progbits,unique,1
10+
.section foobar,"T",@progbits,unique,2
11+
.section foobar,"",@nobits,unique,3
12+
.section foobar,"",@nobits,unique,4
13+
1014
.section bar, "a"
1115

1216
// Both sections are in the output and that the alloc section is first:
1317
// CHECK: Name: bar
14-
// CHECK-NEXT: Type: SHT_PROGBITS
15-
// CHECK-NEXT: Flags [
16-
// CHECK-NEXT: SHF_ALLOC
17-
// CHECK-NEXT: ]
18-
// CHECK-NEXT: Address: 0x1000
18+
// CHECK-NEXT: Type: SHT_PROGBITS
19+
// CHECK-NEXT: Flags [
20+
// CHECK-NEXT: SHF_ALLOC
21+
// CHECK-NEXT: ]
22+
// CHECK-NEXT: Address: 0x1000
1923

2024
// CHECK: Name: foobar
21-
// CHECK-NEXT: Type: SHT_PROGBITS
22-
// CHECK-NEXT: Flags [
23-
// CHECK-NEXT: ]
24-
// CHECK-NEXT: Address: 0x0
25+
// CHECK-NEXT: Type: SHT_PROGBITS
26+
// CHECK-NEXT: Flags [
27+
// CHECK-NEXT: ]
28+
// CHECK-NEXT: Address: 0x0
29+
30+
// CHECK: Name: foobar
31+
// CHECK-NEXT: Type: SHT_PROGBITS
32+
// CHECK-NEXT: Flags [
33+
// CHECK-NEXT: SHF_TLS
34+
// CHECK-NEXT: ]
35+
// CHECK-NEXT: Address: 0x0
36+
37+
// CHECK: Name: foobar
38+
// CHECK-NEXT: Type: SHT_NOBITS
39+
// CHECK-NEXT: Flags [
40+
// CHECK-NEXT: ]
41+
// CHECK-NEXT: Address: 0x0
42+
43+
// CHECK-NOT: Name: foobar
2544

2645
// Test that the sting "bar" is merged into "foobar"
2746

2847
// CHECK: Section {
29-
// CHECK: Index: 6
30-
// CHECK-NEXT: Name: .strtab
48+
// CHECK: Index:
49+
// CHECK: Name: .strtab
3150
// CHECK-NEXT: Type: SHT_STRTAB (0x3)
3251
// CHECK-NEXT: Flags [ (0x0)
3352
// CHECK-NEXT: ]

0 commit comments

Comments
 (0)