-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[LLD] Merge .hexagon.attributes sections #148098
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-backend-hexagon @llvm/pr-subscribers-lld Author: Brian Cain (androm3da) ChangesFull diff: https://github.com/llvm/llvm-project/pull/148098.diff 5 Files Affected:
diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp
index 726e425b36dc6..c449efa51c715 100644
--- a/lld/ELF/Arch/Hexagon.cpp
+++ b/lld/ELF/Arch/Hexagon.cpp
@@ -7,11 +7,19 @@
//===----------------------------------------------------------------------===//
#include "InputFiles.h"
+#include "OutputSections.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
+#include "Thunks.h"
+#include "lld/Common/ErrorHandler.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Support/ELFAttributes.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/HexagonAttributeParser.h"
+#include "llvm/Support/HexagonAttributes.h"
+#include "llvm/Support/LEB128.h"
using namespace llvm;
using namespace llvm::object;
@@ -415,4 +423,117 @@ int64_t Hexagon::getImplicitAddend(const uint8_t *buf, RelType type) const {
}
}
+namespace {
+class HexagonAttributesSection final : public SyntheticSection {
+public:
+ HexagonAttributesSection(Ctx &ctx)
+ : SyntheticSection(ctx, ".hexagon.attributes", SHT_HEXAGON_ATTRIBUTES, 0,
+ 1) {}
+
+ size_t getSize() const override { return size; }
+ void writeTo(uint8_t *buf) override;
+
+ static constexpr StringRef vendor = "hexagon";
+ DenseMap<unsigned, unsigned> intAttr;
+ size_t size = 0;
+};
+} // namespace
+
+static HexagonAttributesSection *
+mergeAttributesSection(Ctx &ctx,
+ const SmallVector<InputSectionBase *, 0> §ions) {
+ ctx.in.hexagonAttributes = std::make_unique<HexagonAttributesSection>(ctx);
+ auto &merged =
+ static_cast<HexagonAttributesSection &>(*ctx.in.hexagonAttributes);
+
+ // Collect all tags values from attributes section.
+ const auto &attributesTags = HexagonAttrs::getHexagonAttributeTags();
+ for (const InputSectionBase *sec : sections) {
+ HexagonAttributeParser parser;
+ if (Error e = parser.parse(sec->content(), llvm::endianness::little))
+ Warn(ctx) << sec << ": " << std::move(e);
+ for (const auto &tag : attributesTags) {
+ switch (HexagonAttrs::AttrType(tag.attr)) {
+ case HexagonAttrs::ARCH:
+ case HexagonAttrs::HVXARCH:
+ if (auto i = parser.getAttributeValue(tag.attr)) {
+ auto r = merged.intAttr.try_emplace(tag.attr, *i);
+ if (!r.second && r.first->second != *i) {
+ if (r.first->second < *i)
+ r.first->second = *i;
+ }
+ }
+ continue;
+
+ case HexagonAttrs::HVXIEEEFP:
+ case HexagonAttrs::HVXQFLOAT:
+ case HexagonAttrs::ZREG:
+ case HexagonAttrs::AUDIO:
+ case HexagonAttrs::CABAC:
+ if (auto i = parser.getAttributeValue(tag.attr)) {
+ auto r = merged.intAttr.try_emplace(tag.attr, *i);
+ if (!r.second && r.first->second != *i) {
+ r.first->second |= *i;
+ }
+ }
+ continue;
+ }
+ }
+ }
+
+ // The total size of headers: format-version [ <section-length> "vendor-name"
+ // [ <file-tag> <size>.
+ size_t size = 5 + merged.vendor.size() + 1 + 5;
+ for (auto &attr : merged.intAttr)
+ if (attr.second != 0)
+ size += getULEB128Size(attr.first) + getULEB128Size(attr.second);
+ merged.size = size;
+ return &merged;
+}
+
+void HexagonAttributesSection::writeTo(uint8_t *buf) {
+ const size_t size = getSize();
+ uint8_t *const end = buf + size;
+ *buf = ELFAttrs::Format_Version;
+ write32(ctx, buf + 1, size - 1);
+ buf += 5;
+
+ memcpy(buf, vendor.data(), vendor.size());
+ buf += vendor.size() + 1;
+
+ *buf = ELFAttrs::File;
+ write32(ctx, buf + 1, end - buf);
+ buf += 5;
+
+ for (auto &attr : intAttr) {
+ if (attr.second == 0)
+ continue;
+ buf += encodeULEB128(attr.first, buf);
+ buf += encodeULEB128(attr.second, buf);
+ }
+}
+
+void elf::mergeHexagonAttributesSections(Ctx &ctx) {
+ // Find the first input SHT_HEXAGON_ATTRIBUTES; return if not found.
+ size_t place =
+ llvm::find_if(ctx.inputSections,
+ [](auto *s) { return s->type == SHT_HEXAGON_ATTRIBUTES; }) -
+ ctx.inputSections.begin();
+ if (place == ctx.inputSections.size())
+ return;
+
+ // Extract all SHT_HEXAGON_ATTRIBUTES sections into `sections`.
+ SmallVector<InputSectionBase *, 0> sections;
+ llvm::erase_if(ctx.inputSections, [&](InputSectionBase *s) {
+ if (s->type != SHT_HEXAGON_ATTRIBUTES)
+ return false;
+ sections.push_back(s);
+ return true;
+ });
+
+ // Add the merged section.
+ ctx.inputSections.insert(ctx.inputSections.begin() + place,
+ mergeAttributesSection(ctx, sections));
+}
+
void elf::setHexagonTargetInfo(Ctx &ctx) { ctx.target.reset(new Hexagon(ctx)); }
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 4c771e47a0e72..8961c5141200e 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -569,6 +569,7 @@ struct UndefinedDiag {
struct InStruct {
std::unique_ptr<InputSection> attributes;
std::unique_ptr<SyntheticSection> riscvAttributes;
+ std::unique_ptr<SyntheticSection> hexagonAttributes;
std::unique_ptr<BssSection> bss;
std::unique_ptr<BssSection> bssRelRo;
std::unique_ptr<SyntheticSection> gnuProperty;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index a194ae71d559a..a18cc4d4e4dd0 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -3450,6 +3450,10 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
if (ctx.arg.emachine == EM_RISCV)
mergeRISCVAttributesSections(ctx);
+ // Merge .hexagon.attributes sections.
+ if (ctx.arg.emachine == EM_HEXAGON)
+ mergeHexagonAttributesSections(ctx);
+
{
llvm::TimeTraceScope timeScope("Assign sections");
diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index 6dd20b2f0cbaa..93f15920bfedb 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -245,6 +245,7 @@ template <typename ELFT> void writeARMCmseImportLib(Ctx &);
uint64_t getLoongArchPageDelta(uint64_t dest, uint64_t pc, RelType type);
void riscvFinalizeRelax(int passes);
void mergeRISCVAttributesSections(Ctx &);
+void mergeHexagonAttributesSections(Ctx &);
void addArmInputSectionMappingSymbols(Ctx &);
void addArmSyntheticSectionMappingSymbol(Defined *);
void sortArmMappingSymbols(Ctx &);
diff --git a/lld/test/ELF/hexagon-attributes.s b/lld/test/ELF/hexagon-attributes.s
new file mode 100644
index 0000000000000..ff22e3a750e0d
--- /dev/null
+++ b/lld/test/ELF/hexagon-attributes.s
@@ -0,0 +1,150 @@
+# REQUIRES: hexagon
+
+# RUN: rm -rf %t && split-file %s %t && cd %t
+# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf a.s -o a.o
+# RUN: ld.lld -e 0 a.o -o out 2>&1 | count 0
+# RUN: llvm-readelf -S -l --arch-specific out | FileCheck %s --check-prefixes=HDR,CHECK
+# RUN: ld.lld -e 0 a.o a.o -o out1 2>&1 | count 0
+# RUN: llvm-readobj --arch-specific out1 | FileCheck %s
+# RUN: ld.lld -r a.o a.o -o out1 2>&1 | count 0
+# RUN: llvm-readobj --arch-specific out1 | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf b.s -o b.o
+# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf c.s -o c.o
+# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf d.s -o d.o
+# RUN: ld.lld a.o b.o c.o -o out2
+# RUN: llvm-readobj --arch-specific out2 | FileCheck %s --check-prefix=CHECK2
+# RUN: ld.lld a.o b.o c.o d.o -o out3
+# RUN: llvm-readobj --arch-specific out3 | FileCheck %s --check-prefix=CHECK3
+
+# HDR: Name Type Address Off Size ES Flg Lk Inf Al
+# HDR: .hexagon.attributes HEXAGON_ATTRIBUTES 00000000 {{.*}} {{.*}} 00 0 0 1{{$}}
+
+# HDR: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
+# HDR: LOAD {{.*}}
+# HDR-NEXT: GNU_STACK {{.*}}
+
+# CHECK: BuildAttributes {
+# CHECK-NEXT: FormatVersion: 0x41
+# CHECK-NEXT: Section 1 {
+# CHECK-NEXT: SectionLength: 19
+# CHECK-NEXT: Vendor: hexagon
+# CHECK-NEXT: Tag: Tag_File (0x1)
+# CHECK-NEXT: Size: 7
+# CHECK-NEXT: FileAttributes {
+# CHECK-NEXT: Attribute {
+# CHECK-NEXT: Tag: 4
+# CHECK-NEXT: TagName: arch
+# CHECK-NEXT: Value: 68{{$}}
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+
+# CHECK2: BuildAttributes {
+# CHECK2-NEXT: FormatVersion: 0x41
+# CHECK2-NEXT: Section 1 {
+# CHECK2-NEXT: SectionLength: 21
+# CHECK2-NEXT: Vendor: hexagon
+# CHECK2-NEXT: Tag: Tag_File (0x1)
+# CHECK2-NEXT: Size: 9
+# CHECK2-NEXT: FileAttributes {
+# CHECK2-NEXT: Attribute {
+# CHECK2-NEXT: Tag: 4
+# CHECK2-NEXT: TagName: arch
+# CHECK2-NEXT: Value: 68{{$}}
+# CHECK2-NEXT: }
+# CHECK2-NEXT: Attribute {
+# CHECK2-NEXT: Tag: 5
+# CHECK2-NEXT: TagName: hvx_arch
+# CHECK2-NEXT: Value: 68{{$}}
+# CHECK2-NEXT: }
+# CHECK2-NEXT: }
+# CHECK2-NEXT: }
+# CHECK2-NEXT: }
+
+# CHECK3: BuildAttributes {
+# CHECK3-NEXT: FormatVersion: 0x41
+# CHECK3-NEXT: Section 1 {
+# CHECK3-NEXT: SectionLength: 25
+# CHECK3-NEXT: Vendor: hexagon
+# CHECK3-NEXT: Tag: Tag_File (0x1)
+# CHECK3-NEXT: Size: 13
+# CHECK3-NEXT: FileAttributes {
+# CHECK3-NEXT: Attribute {
+# CHECK3-NEXT: Tag: 7
+# CHECK3-NEXT: TagName: hvx_qfloat
+# CHECK3-NEXT: Value: 68{{$}}
+# CHECK3-NEXT: }
+# CHECK3-NEXT: Attribute {
+# CHECK3-NEXT: Tag: 9
+# CHECK3-NEXT: TagName: audio
+# CHECK3-NEXT: Value: 68{{$}}
+# CHECK3-NEXT: }
+# CHECK3-NEXT: Attribute {
+# CHECK3-NEXT: Tag: 4
+# CHECK3-NEXT: TagName: arch
+# CHECK3-NEXT: Value: 68{{$}}
+# CHECK3-NEXT: }
+# CHECK3-NEXT: Attribute {
+# CHECK3-NEXT: Tag: 5
+# CHECK3-NEXT: TagName: hvx_arch
+# CHECK3-NEXT: Value: 68{{$}}
+# CHECK3-NEXT: }
+# CHECK3-NEXT: }
+# CHECK3-NEXT: }
+# CHECK3-NEXT: }
+
+#--- a.s
+.section .hexagon.attributes,"",@0x70000003
+.byte 0x41
+.long .Lend-.hexagon.attributes-1
+.asciz "hexagon"
+.Lbegin:
+.byte 1
+.long .Lend-.Lbegin
+.byte 4
+.byte 68
+.Lend:
+
+#--- b.s
+.section .hexagon.attributes,"",@0x70000003
+.byte 0x41
+.long .Lend1-.hexagon.attributes-1
+.asciz "hexagon"
+.Lbegin1:
+.byte 1
+.long .Lend1-.Lbegin1
+.byte 4
+.byte 68
+.Lend1:
+
+#--- c.s
+.section .hexagon.attributes,"",@0x70000003
+.byte 0x41
+.long .Lend2-.hexagon.attributes-1
+.asciz "hexagon"
+.Lbegin2:
+.byte 1
+.long .Lend2-.Lbegin2
+.byte 4
+.byte 68
+.byte 5
+.byte 68
+.Lend2:
+
+#--- d.s
+.section .hexagon.attributes,"",@0x70000003
+.byte 0x41
+.long .Lend3-.hexagon.attributes-1
+.asciz "hexagon"
+.Lbegin3:
+.byte 1
+.long .Lend3-.Lbegin3
+.byte 4
+.byte 68
+.byte 7
+.byte 68
+.byte 9
+.byte 68
+.Lend3:
|
lld/test/ELF/hexagon-attributes.s
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This header is now misaligned
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still misaligned
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I've addressed it now. Thanks.
MaskRay
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you update the description with the purpose and mention that this is similar to .riscv.attributes (primary patch: https://reviews.llvm.org/D138550)?
Does Hexagon have a processor supplementary ABI document? Ideally this should be mentioned.
lld/ELF/Driver.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move before RISCV
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
lld/ELF/Config.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move before riscvAttributes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
lld/ELF/Arch/Hexagon.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC this change doesn't use Thunks.h, therefore should not add this include in this patch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I must've crossed the wires with the other in-progress PR, sorry. Removed.
471b480 to
1f09d05
Compare
Done
Unfortunately, it's not mentioned in this document. We should revise this to add the |
| case HexagonAttrs::CABAC: | ||
| if (auto i = parser.getAttributeValue(tag.attr)) { | ||
| auto r = merged.intAttr.try_emplace(tag.attr, *i); | ||
| if (!r.second && r.first->second != *i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drop braces for this single-line single-statement body. We can remove && r.first->second != *i.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
Merge the attributes of object files being linked together. The
.hexagon.attributessection can be used by loaders and analysis tools. This is similar to the .riscv.attributes, introduced in 8a900f2 / https://reviews.llvm.org/D138550.