[lld] bef38e8 - [ELF] Handle SHT_RISCV_ATTRIBUTES similarly to SHT_ARM_ATTRIBUTES

Jessica Clarke via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 5 10:36:46 PDT 2020


Author: Jessica Clarke
Date: 2020-09-05T18:36:23+01:00
New Revision: bef38e86b4e702a0c42e243d323fb7c09875e649

URL: https://github.com/llvm/llvm-project/commit/bef38e86b4e702a0c42e243d323fb7c09875e649
DIFF: https://github.com/llvm/llvm-project/commit/bef38e86b4e702a0c42e243d323fb7c09875e649.diff

LOG: [ELF] Handle SHT_RISCV_ATTRIBUTES similarly to SHT_ARM_ATTRIBUTES

Currently we treat SHT_RISCV_ATTRIBUTES like a normal section and
concatenate all such input sections, yielding invalid output unless only
a single attributes section is present in the input. Instead, pick the
first as with SHT_ARM_ATTRIBUTES. We do not currently need to condition
our behaviour on the contents, unlike Arm. In future, we should both do
stricter validation of the input and merge all sections together to
ensure we have, for example, the full arch string requirement, but this
rudimentary implementation is good enough for most common cases.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D86309

Added: 
    lld/test/ELF/riscv-attributes.s

Modified: 
    lld/ELF/InputFiles.cpp
    lld/ELF/SyntheticSections.h

Removed: 
    


################################################################################
diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index bfc8e9c1e53b..acdb5c71efb9 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -27,6 +27,7 @@
 #include "llvm/Support/ARMBuildAttributes.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/RISCVAttributeParser.h"
 #include "llvm/Support/TarWriter.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -867,10 +868,7 @@ template <class ELFT>
 InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &sec) {
   StringRef name = getSectionName(sec);
 
-  switch (sec.sh_type) {
-  case SHT_ARM_ATTRIBUTES: {
-    if (config->emachine != EM_ARM)
-      break;
+  if (config->emachine == EM_ARM && sec.sh_type == SHT_ARM_ATTRIBUTES) {
     ARMAttributeParser attributes;
     ArrayRef<uint8_t> contents = check(this->getObj().getSectionContents(&sec));
     if (Error e = attributes.parse(contents, config->ekind == ELF32LEKind
@@ -878,20 +876,45 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &sec) {
                                                  : support::big)) {
       auto *isec = make<InputSection>(*this, sec, name);
       warn(toString(isec) + ": " + llvm::toString(std::move(e)));
-      break;
+    } else {
+      updateSupportedARMFeatures(attributes);
+      updateARMVFPArgs(attributes, this);
+
+      // FIXME: Retain the first attribute section we see. The eglibc ARM
+      // dynamic loaders require the presence of an attribute section for dlopen
+      // to work. In a full implementation we would merge all attribute
+      // sections.
+      if (in.attributes == nullptr) {
+        in.attributes = make<InputSection>(*this, sec, name);
+        return in.attributes;
+      }
+      return &InputSection::discarded;
     }
-    updateSupportedARMFeatures(attributes);
-    updateARMVFPArgs(attributes, this);
-
-    // FIXME: Retain the first attribute section we see. The eglibc ARM
-    // dynamic loaders require the presence of an attribute section for dlopen
-    // to work. In a full implementation we would merge all attribute sections.
-    if (in.armAttributes == nullptr) {
-      in.armAttributes = make<InputSection>(*this, sec, name);
-      return in.armAttributes;
+  }
+
+  if (config->emachine == EM_RISCV && sec.sh_type == SHT_RISCV_ATTRIBUTES) {
+    RISCVAttributeParser attributes;
+    ArrayRef<uint8_t> contents = check(this->getObj().getSectionContents(&sec));
+    if (Error e = attributes.parse(contents, support::little)) {
+      auto *isec = make<InputSection>(*this, sec, name);
+      warn(toString(isec) + ": " + llvm::toString(std::move(e)));
+    } else {
+      // FIXME: Validate arch tag contains C if and only if EF_RISCV_RVC is
+      // present.
+
+      // FIXME: Retain the first attribute section we see. Tools such as
+      // llvm-objdump make use of the attribute section to determine which
+      // standard extensions to enable. In a full implementation we would merge
+      // all attribute sections.
+      if (in.attributes == nullptr) {
+        in.attributes = make<InputSection>(*this, sec, name);
+        return in.attributes;
+      }
+      return &InputSection::discarded;
     }
-    return &InputSection::discarded;
   }
+
+  switch (sec.sh_type) {
   case SHT_LLVM_DEPENDENT_LIBRARIES: {
     if (config->relocatable)
       break;

diff  --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 7779efcd5fe5..8943596179c1 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -1200,7 +1200,7 @@ inline Partition &SectionBase::getPartition() const {
 // Linker generated sections which can be used as inputs and are not specific to
 // a partition.
 struct InStruct {
-  InputSection *armAttributes;
+  InputSection *attributes;
   BssSection *bss;
   BssSection *bssRelRo;
   GotSection *got;

diff  --git a/lld/test/ELF/riscv-attributes.s b/lld/test/ELF/riscv-attributes.s
new file mode 100644
index 000000000000..36e506a1df66
--- /dev/null
+++ b/lld/test/ELF/riscv-attributes.s
@@ -0,0 +1,33 @@
+# REQUIRES: riscv
+
+# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=-relax %s -o %t.o
+# RUN: ld.lld %t.o -o %t
+# RUN: llvm-readelf --arch-specific %t | FileCheck %s
+# RUN: ld.lld %t.o %t.o -o %t2
+# RUN: llvm-readelf --arch-specific %t2 | FileCheck %s
+
+# CHECK:      BuildAttributes {
+# CHECK-NEXT:   FormatVersion: 0x41
+# CHECK-NEXT:   Section 1 {
+# CHECK-NEXT:     SectionLength: 52
+# CHECK-NEXT:     Vendor: riscv
+# CHECK-NEXT:     Tag: Tag_File (0x1)
+# CHECK-NEXT:     Size: 42
+# CHECK-NEXT:     FileAttributes {
+# CHECK-NEXT:       Attribute {
+# CHECK-NEXT:         Tag: 4
+# CHECK-NEXT:         Value: 16
+# CHECK-NEXT:         TagName: stack_align
+# CHECK-NEXT:         Description: Stack alignment is 16-bytes
+# CHECK-NEXT:       }
+# CHECK-NEXT:       Attribute {
+# CHECK-NEXT:         Tag: 5
+# CHECK-NEXT:         TagName: arch
+# CHECK-NEXT:         Value: rv64i2p0_m2p0_a2p0_f2p0_d2p0_c2p0
+# CHECK-NEXT:       }
+# CHECK-NEXT:     }
+# CHECK-NEXT:   }
+# CHECK-NEXT: }
+
+.attribute 4, 16
+.attribute 5, "rv64i2p0_m2p0_a2p0_f2p0_d2p0_c2p0"


        


More information about the llvm-commits mailing list