[lld] 9becc4a - [ELF] ObjFile::parse: check EM_AARCH64 for SHT_AARCH64_MEMTAG_GLOBAL_STATIC

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 1 12:03:40 PST 2024


Author: Fangrui Song
Date: 2024-12-01T12:03:35-08:00
New Revision: 9becc4a3c966d46b95ddfcf856b3c433c030db1e

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

LOG: [ELF] ObjFile::parse: check EM_AARCH64 for SHT_AARCH64_MEMTAG_GLOBAL_STATIC

and reorder sh_type checks to make SHT_PROGBITS/SHT_GROUP fast.

Added: 
    

Modified: 
    lld/ELF/InputFiles.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 30fbb5d9fe4527..f262e537a6d038 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -556,12 +556,45 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
   sections.resize(size);
   for (size_t i = 0; i != size; ++i) {
     const Elf_Shdr &sec = objSections[i];
+    if (LLVM_LIKELY(sec.sh_type == SHT_PROGBITS))
+      continue;
+    if (LLVM_LIKELY(sec.sh_type == SHT_GROUP)) {
+      StringRef signature = getShtGroupSignature(objSections, sec);
+      ArrayRef<Elf_Word> entries =
+          CHECK2(obj.template getSectionContentsAsArray<Elf_Word>(sec), this);
+      if (entries.empty())
+        Fatal(ctx) << this << ": empty SHT_GROUP";
+
+      Elf_Word flag = entries[0];
+      if (flag && flag != GRP_COMDAT)
+        Fatal(ctx) << this << ": unsupported SHT_GROUP format";
+
+      bool keepGroup = !flag || ignoreComdats ||
+                       ctx.symtab->comdatGroups
+                           .try_emplace(CachedHashStringRef(signature), this)
+                           .second;
+      if (keepGroup) {
+        if (!ctx.arg.resolveGroups)
+          sections[i] = createInputSection(
+              i, sec, check(obj.getSectionName(sec, shstrtab)));
+      } else {
+        // Otherwise, discard group members.
+        for (uint32_t secIndex : entries.slice(1)) {
+          if (secIndex >= size)
+            Fatal(ctx) << this
+                       << ": invalid section index in group: " << secIndex;
+          sections[secIndex] = &InputSection::discarded;
+        }
+      }
+      continue;
+    }
+
     if (sec.sh_type == SHT_LLVM_DEPENDENT_LIBRARIES && !ctx.arg.relocatable) {
       StringRef name = check(obj.getSectionName(sec, shstrtab));
       ArrayRef<char> data = CHECK2(
           this->getObj().template getSectionContentsAsArray<char>(sec), this);
       if (!data.empty() && data.back() != '\0') {
-        ErrAlways(ctx)
+        Err(ctx)
             << this
             << ": corrupted dependent libraries section (unterminated string): "
             << name;
@@ -572,74 +605,48 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
           d += s.size() + 1;
         }
       }
-      this->sections[i] = &InputSection::discarded;
+      sections[i] = &InputSection::discarded;
       continue;
     }
 
-    if (sec.sh_type == SHT_ARM_ATTRIBUTES && ctx.arg.emachine == EM_ARM) {
-      ARMAttributeParser attributes;
-      ArrayRef<uint8_t> contents =
-          check(this->getObj().getSectionContents(sec));
-      StringRef name = check(obj.getSectionName(sec, shstrtab));
-      this->sections[i] = &InputSection::discarded;
-      if (Error e = attributes.parse(contents, ekind == ELF32LEKind
-                                                   ? llvm::endianness::little
-                                                   : llvm::endianness::big)) {
-        InputSection isec(*this, sec, name);
-        Warn(ctx) << &isec << ": " << std::move(e);
-      } else {
-        updateSupportedARMFeatures(ctx, attributes);
-        updateARMVFPArgs(ctx, 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 (ctx.in.attributes == nullptr) {
-          ctx.in.attributes = std::make_unique<InputSection>(*this, sec, name);
-          this->sections[i] = ctx.in.attributes.get();
+    switch (ctx.arg.emachine) {
+    case EM_ARM:
+      if (sec.sh_type == SHT_ARM_ATTRIBUTES) {
+        ARMAttributeParser attributes;
+        ArrayRef<uint8_t> contents =
+            check(this->getObj().getSectionContents(sec));
+        StringRef name = check(obj.getSectionName(sec, shstrtab));
+        sections[i] = &InputSection::discarded;
+        if (Error e = attributes.parse(contents, ekind == ELF32LEKind
+                                                     ? llvm::endianness::little
+                                                     : llvm::endianness::big)) {
+          InputSection isec(*this, sec, name);
+          Warn(ctx) << &isec << ": " << std::move(e);
+        } else {
+          updateSupportedARMFeatures(ctx, attributes);
+          updateARMVFPArgs(ctx, 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 (ctx.in.attributes == nullptr) {
+            ctx.in.attributes =
+                std::make_unique<InputSection>(*this, sec, name);
+            sections[i] = ctx.in.attributes.get();
+          }
         }
       }
-    }
-
-    // Producing a static binary with MTE globals is not currently supported,
-    // remove all SHT_AARCH64_MEMTAG_GLOBALS_STATIC sections as they're unused
-    // medatada, and we don't want them to end up in the output file for static
-    // executables.
-    if (sec.sh_type == SHT_AARCH64_MEMTAG_GLOBALS_STATIC &&
-        !canHaveMemtagGlobals(ctx)) {
-      this->sections[i] = &InputSection::discarded;
-      continue;
-    }
-
-    if (sec.sh_type != SHT_GROUP)
-      continue;
-    StringRef signature = getShtGroupSignature(objSections, sec);
-    ArrayRef<Elf_Word> entries =
-        CHECK2(obj.template getSectionContentsAsArray<Elf_Word>(sec), this);
-    if (entries.empty())
-      Fatal(ctx) << this << ": empty SHT_GROUP";
-
-    Elf_Word flag = entries[0];
-    if (flag && flag != GRP_COMDAT)
-      Fatal(ctx) << this << ": unsupported SHT_GROUP format";
-
-    bool keepGroup = (flag & GRP_COMDAT) == 0 || ignoreComdats ||
-                     ctx.symtab->comdatGroups
-                         .try_emplace(CachedHashStringRef(signature), this)
-                         .second;
-    if (keepGroup) {
-      if (!ctx.arg.resolveGroups)
-        this->sections[i] = createInputSection(
-            i, sec, check(obj.getSectionName(sec, shstrtab)));
-      continue;
-    }
-
-    // Otherwise, discard group members.
-    for (uint32_t secIndex : entries.slice(1)) {
-      if (secIndex >= size)
-        Fatal(ctx) << this << ": invalid section index in group: " << secIndex;
-      this->sections[secIndex] = &InputSection::discarded;
+      break;
+    case EM_AARCH64:
+      // Producing a static binary with MTE globals is not currently supported,
+      // remove all SHT_AARCH64_MEMTAG_GLOBALS_STATIC sections as they're unused
+      // medatada, and we don't want them to end up in the output file for
+      // static executables.
+      if (sec.sh_type == SHT_AARCH64_MEMTAG_GLOBALS_STATIC &&
+          !canHaveMemtagGlobals(ctx))
+        sections[i] = &InputSection::discarded;
+      break;
     }
   }
 


        


More information about the llvm-commits mailing list