Skip to content

Commit 5cad356

Browse files
committed
[LLD] Merge .hexagon.attributes sections
1 parent 267b136 commit 5cad356

File tree

5 files changed

+277
-0
lines changed

5 files changed

+277
-0
lines changed

lld/ELF/Arch/Hexagon.cpp

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,19 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "InputFiles.h"
10+
#include "OutputSections.h"
1011
#include "Symbols.h"
1112
#include "SyntheticSections.h"
1213
#include "Target.h"
14+
#include "Thunks.h"
15+
#include "lld/Common/ErrorHandler.h"
16+
#include "llvm/ADT/SmallVector.h"
1317
#include "llvm/BinaryFormat/ELF.h"
18+
#include "llvm/Support/ELFAttributes.h"
1419
#include "llvm/Support/Endian.h"
20+
#include "llvm/Support/HexagonAttributeParser.h"
21+
#include "llvm/Support/HexagonAttributes.h"
22+
#include "llvm/Support/LEB128.h"
1523

1624
using namespace llvm;
1725
using namespace llvm::object;
@@ -415,4 +423,117 @@ int64_t Hexagon::getImplicitAddend(const uint8_t *buf, RelType type) const {
415423
}
416424
}
417425

426+
namespace {
427+
class HexagonAttributesSection final : public SyntheticSection {
428+
public:
429+
HexagonAttributesSection(Ctx &ctx)
430+
: SyntheticSection(ctx, ".hexagon.attributes", SHT_HEXAGON_ATTRIBUTES, 0,
431+
1) {}
432+
433+
size_t getSize() const override { return size; }
434+
void writeTo(uint8_t *buf) override;
435+
436+
static constexpr StringRef vendor = "hexagon";
437+
DenseMap<unsigned, unsigned> intAttr;
438+
size_t size = 0;
439+
};
440+
} // namespace
441+
442+
static HexagonAttributesSection *
443+
mergeAttributesSection(Ctx &ctx,
444+
const SmallVector<InputSectionBase *, 0> &sections) {
445+
ctx.in.hexagonAttributes = std::make_unique<HexagonAttributesSection>(ctx);
446+
auto &merged =
447+
static_cast<HexagonAttributesSection &>(*ctx.in.hexagonAttributes);
448+
449+
// Collect all tags values from attributes section.
450+
const auto &attributesTags = HexagonAttrs::getHexagonAttributeTags();
451+
for (const InputSectionBase *sec : sections) {
452+
HexagonAttributeParser parser;
453+
if (Error e = parser.parse(sec->content(), llvm::endianness::little))
454+
Warn(ctx) << sec << ": " << std::move(e);
455+
for (const auto &tag : attributesTags) {
456+
switch (HexagonAttrs::AttrType(tag.attr)) {
457+
case HexagonAttrs::ARCH:
458+
case HexagonAttrs::HVXARCH:
459+
if (auto i = parser.getAttributeValue(tag.attr)) {
460+
auto r = merged.intAttr.try_emplace(tag.attr, *i);
461+
if (!r.second && r.first->second != *i) {
462+
if (r.first->second < *i)
463+
r.first->second = *i;
464+
}
465+
}
466+
continue;
467+
468+
case HexagonAttrs::HVXIEEEFP:
469+
case HexagonAttrs::HVXQFLOAT:
470+
case HexagonAttrs::ZREG:
471+
case HexagonAttrs::AUDIO:
472+
case HexagonAttrs::CABAC:
473+
if (auto i = parser.getAttributeValue(tag.attr)) {
474+
auto r = merged.intAttr.try_emplace(tag.attr, *i);
475+
if (!r.second && r.first->second != *i) {
476+
r.first->second |= *i;
477+
}
478+
}
479+
continue;
480+
}
481+
}
482+
}
483+
484+
// The total size of headers: format-version [ <section-length> "vendor-name"
485+
// [ <file-tag> <size>.
486+
size_t size = 5 + merged.vendor.size() + 1 + 5;
487+
for (auto &attr : merged.intAttr)
488+
if (attr.second != 0)
489+
size += getULEB128Size(attr.first) + getULEB128Size(attr.second);
490+
merged.size = size;
491+
return &merged;
492+
}
493+
494+
void HexagonAttributesSection::writeTo(uint8_t *buf) {
495+
const size_t size = getSize();
496+
uint8_t *const end = buf + size;
497+
*buf = ELFAttrs::Format_Version;
498+
write32(ctx, buf + 1, size - 1);
499+
buf += 5;
500+
501+
memcpy(buf, vendor.data(), vendor.size());
502+
buf += vendor.size() + 1;
503+
504+
*buf = ELFAttrs::File;
505+
write32(ctx, buf + 1, end - buf);
506+
buf += 5;
507+
508+
for (auto &attr : intAttr) {
509+
if (attr.second == 0)
510+
continue;
511+
buf += encodeULEB128(attr.first, buf);
512+
buf += encodeULEB128(attr.second, buf);
513+
}
514+
}
515+
516+
void elf::mergeHexagonAttributesSections(Ctx &ctx) {
517+
// Find the first input SHT_HEXAGON_ATTRIBUTES; return if not found.
518+
size_t place =
519+
llvm::find_if(ctx.inputSections,
520+
[](auto *s) { return s->type == SHT_HEXAGON_ATTRIBUTES; }) -
521+
ctx.inputSections.begin();
522+
if (place == ctx.inputSections.size())
523+
return;
524+
525+
// Extract all SHT_HEXAGON_ATTRIBUTES sections into `sections`.
526+
SmallVector<InputSectionBase *, 0> sections;
527+
llvm::erase_if(ctx.inputSections, [&](InputSectionBase *s) {
528+
if (s->type != SHT_HEXAGON_ATTRIBUTES)
529+
return false;
530+
sections.push_back(s);
531+
return true;
532+
});
533+
534+
// Add the merged section.
535+
ctx.inputSections.insert(ctx.inputSections.begin() + place,
536+
mergeAttributesSection(ctx, sections));
537+
}
538+
418539
void elf::setHexagonTargetInfo(Ctx &ctx) { ctx.target.reset(new Hexagon(ctx)); }

lld/ELF/Config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,7 @@ struct UndefinedDiag {
569569
struct InStruct {
570570
std::unique_ptr<InputSection> attributes;
571571
std::unique_ptr<SyntheticSection> riscvAttributes;
572+
std::unique_ptr<SyntheticSection> hexagonAttributes;
572573
std::unique_ptr<BssSection> bss;
573574
std::unique_ptr<BssSection> bssRelRo;
574575
std::unique_ptr<SyntheticSection> gnuProperty;

lld/ELF/Driver.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3450,6 +3450,10 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
34503450
if (ctx.arg.emachine == EM_RISCV)
34513451
mergeRISCVAttributesSections(ctx);
34523452

3453+
// Merge .hexagon.attributes sections.
3454+
if (ctx.arg.emachine == EM_HEXAGON)
3455+
mergeHexagonAttributesSections(ctx);
3456+
34533457
{
34543458
llvm::TimeTraceScope timeScope("Assign sections");
34553459

lld/ELF/Target.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ template <typename ELFT> void writeARMCmseImportLib(Ctx &);
245245
uint64_t getLoongArchPageDelta(uint64_t dest, uint64_t pc, RelType type);
246246
void riscvFinalizeRelax(int passes);
247247
void mergeRISCVAttributesSections(Ctx &);
248+
void mergeHexagonAttributesSections(Ctx &);
248249
void addArmInputSectionMappingSymbols(Ctx &);
249250
void addArmSyntheticSectionMappingSymbol(Defined *);
250251
void sortArmMappingSymbols(Ctx &);

lld/test/ELF/hexagon-attributes.s

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# REQUIRES: hexagon
2+
3+
# RUN: rm -rf %t && split-file %s %t && cd %t
4+
# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf a.s -o a.o
5+
# RUN: ld.lld -e 0 a.o -o out 2>&1 | count 0
6+
# RUN: llvm-readelf -S -l --arch-specific out | FileCheck %s --check-prefixes=HDR,CHECK
7+
# RUN: ld.lld -e 0 a.o a.o -o out1 2>&1 | count 0
8+
# RUN: llvm-readobj --arch-specific out1 | FileCheck %s
9+
# RUN: ld.lld -r a.o a.o -o out1 2>&1 | count 0
10+
# RUN: llvm-readobj --arch-specific out1 | FileCheck %s
11+
12+
# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf b.s -o b.o
13+
# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf c.s -o c.o
14+
# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf d.s -o d.o
15+
# RUN: ld.lld a.o b.o c.o -o out2
16+
# RUN: llvm-readobj --arch-specific out2 | FileCheck %s --check-prefix=CHECK2
17+
# RUN: ld.lld a.o b.o c.o d.o -o out3
18+
# RUN: llvm-readobj --arch-specific out3 | FileCheck %s --check-prefix=CHECK3
19+
20+
# HDR: Name Type Address Off Size ES Flg Lk Inf Al
21+
# HDR: .hexagon.attributes HEXAGON_ATTRIBUTES 00000000 {{.*}} {{.*}} 00 0 0 1{{$}}
22+
23+
# HDR: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
24+
# HDR: LOAD {{.*}}
25+
# HDR-NEXT: GNU_STACK {{.*}}
26+
27+
# CHECK: BuildAttributes {
28+
# CHECK-NEXT: FormatVersion: 0x41
29+
# CHECK-NEXT: Section 1 {
30+
# CHECK-NEXT: SectionLength: 19
31+
# CHECK-NEXT: Vendor: hexagon
32+
# CHECK-NEXT: Tag: Tag_File (0x1)
33+
# CHECK-NEXT: Size: 7
34+
# CHECK-NEXT: FileAttributes {
35+
# CHECK-NEXT: Attribute {
36+
# CHECK-NEXT: Tag: 4
37+
# CHECK-NEXT: TagName: arch
38+
# CHECK-NEXT: Value: 68{{$}}
39+
# CHECK-NEXT: }
40+
# CHECK-NEXT: }
41+
# CHECK-NEXT: }
42+
# CHECK-NEXT: }
43+
44+
# CHECK2: BuildAttributes {
45+
# CHECK2-NEXT: FormatVersion: 0x41
46+
# CHECK2-NEXT: Section 1 {
47+
# CHECK2-NEXT: SectionLength: 21
48+
# CHECK2-NEXT: Vendor: hexagon
49+
# CHECK2-NEXT: Tag: Tag_File (0x1)
50+
# CHECK2-NEXT: Size: 9
51+
# CHECK2-NEXT: FileAttributes {
52+
# CHECK2-NEXT: Attribute {
53+
# CHECK2-NEXT: Tag: 4
54+
# CHECK2-NEXT: TagName: arch
55+
# CHECK2-NEXT: Value: 68{{$}}
56+
# CHECK2-NEXT: }
57+
# CHECK2-NEXT: Attribute {
58+
# CHECK2-NEXT: Tag: 5
59+
# CHECK2-NEXT: TagName: hvx_arch
60+
# CHECK2-NEXT: Value: 68{{$}}
61+
# CHECK2-NEXT: }
62+
# CHECK2-NEXT: }
63+
# CHECK2-NEXT: }
64+
# CHECK2-NEXT: }
65+
66+
# CHECK3: BuildAttributes {
67+
# CHECK3-NEXT: FormatVersion: 0x41
68+
# CHECK3-NEXT: Section 1 {
69+
# CHECK3-NEXT: SectionLength: 25
70+
# CHECK3-NEXT: Vendor: hexagon
71+
# CHECK3-NEXT: Tag: Tag_File (0x1)
72+
# CHECK3-NEXT: Size: 13
73+
# CHECK3-NEXT: FileAttributes {
74+
# CHECK3-NEXT: Attribute {
75+
# CHECK3-NEXT: Tag: 7
76+
# CHECK3-NEXT: TagName: hvx_qfloat
77+
# CHECK3-NEXT: Value: 68{{$}}
78+
# CHECK3-NEXT: }
79+
# CHECK3-NEXT: Attribute {
80+
# CHECK3-NEXT: Tag: 9
81+
# CHECK3-NEXT: TagName: audio
82+
# CHECK3-NEXT: Value: 68{{$}}
83+
# CHECK3-NEXT: }
84+
# CHECK3-NEXT: Attribute {
85+
# CHECK3-NEXT: Tag: 4
86+
# CHECK3-NEXT: TagName: arch
87+
# CHECK3-NEXT: Value: 68{{$}}
88+
# CHECK3-NEXT: }
89+
# CHECK3-NEXT: Attribute {
90+
# CHECK3-NEXT: Tag: 5
91+
# CHECK3-NEXT: TagName: hvx_arch
92+
# CHECK3-NEXT: Value: 68{{$}}
93+
# CHECK3-NEXT: }
94+
# CHECK3-NEXT: }
95+
# CHECK3-NEXT: }
96+
# CHECK3-NEXT: }
97+
98+
#--- a.s
99+
.section .hexagon.attributes,"",@0x70000003
100+
.byte 0x41
101+
.long .Lend-.hexagon.attributes-1
102+
.asciz "hexagon"
103+
.Lbegin:
104+
.byte 1
105+
.long .Lend-.Lbegin
106+
.byte 4
107+
.byte 68
108+
.Lend:
109+
110+
#--- b.s
111+
.section .hexagon.attributes,"",@0x70000003
112+
.byte 0x41
113+
.long .Lend1-.hexagon.attributes-1
114+
.asciz "hexagon"
115+
.Lbegin1:
116+
.byte 1
117+
.long .Lend1-.Lbegin1
118+
.byte 4
119+
.byte 68
120+
.Lend1:
121+
122+
#--- c.s
123+
.section .hexagon.attributes,"",@0x70000003
124+
.byte 0x41
125+
.long .Lend2-.hexagon.attributes-1
126+
.asciz "hexagon"
127+
.Lbegin2:
128+
.byte 1
129+
.long .Lend2-.Lbegin2
130+
.byte 4
131+
.byte 68
132+
.byte 5
133+
.byte 68
134+
.Lend2:
135+
136+
#--- d.s
137+
.section .hexagon.attributes,"",@0x70000003
138+
.byte 0x41
139+
.long .Lend3-.hexagon.attributes-1
140+
.asciz "hexagon"
141+
.Lbegin3:
142+
.byte 1
143+
.long .Lend3-.Lbegin3
144+
.byte 4
145+
.byte 68
146+
.byte 7
147+
.byte 68
148+
.byte 9
149+
.byte 68
150+
.Lend3:

0 commit comments

Comments
 (0)