[lld] [LLD] Merge .hexagon.attributes sections (PR #148098)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 10 18:51:35 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld-elf
@llvm/pr-subscribers-lld
Author: Brian Cain (androm3da)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/148098.diff
5 Files Affected:
- (modified) lld/ELF/Arch/Hexagon.cpp (+121)
- (modified) lld/ELF/Config.h (+1)
- (modified) lld/ELF/Driver.cpp (+4)
- (modified) lld/ELF/Target.h (+1)
- (added) lld/test/ELF/hexagon-attributes.s (+150)
``````````diff
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,"", at 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,"", at 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,"", at 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,"", at 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:
``````````
</details>
https://github.com/llvm/llvm-project/pull/148098
More information about the llvm-commits
mailing list