[lld] [llvm] [lld][AArch64][Build Attributes] Add support for converting AArch64 Build Attributes to GNU Properties (PR #131990)

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 9 09:41:56 PDT 2025


================
@@ -638,25 +808,144 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
         }
       }
       break;
-    case EM_AARCH64:
-      // FIXME: BuildAttributes have been implemented in llvm, but not yet in
-      // lld. Remove the section so that it does not accumulate in the output
-      // file. When support is implemented we expect not to output a build
-      // attributes section in files of type ET_EXEC or ET_SHARED, but ld -r
-      // ouptut will need a single merged attributes section.
-      if (sec.sh_type == SHT_AARCH64_ATTRIBUTES)
+    case EM_AARCH64: {
+      // The specification states that if a file contains both GNU properties
+      // and AArch64 build attributes, they can be assumed to be identical.
+      // Therefore, if a file contains GNU properties, the AArch64 build
+      // attributes are ignored. If a file does not contain GNU properties, we
+      // leverage the existing GNU properties mechanism by populating the
+      // corresponding data structures, which will later be handled by
+      // Driver.cpp::readSecurityNotes. This ensures that AArch64 build
+      // attributes are represented in the linked object file as GNU properties,
+      // which are already supported by the Linux kernel and the dynamic
+      // loader.
+      if (sec.sh_type == SHT_AARCH64_ATTRIBUTES) {
+        StringRef name = check(obj.getSectionName(sec, shstrtab));
+        ArrayRef<uint8_t> contents = check(obj.getSectionContents(sec));
+        AArch64AttributeParser attributes;
+        // For functions that has to warn/err/report.
+        InputSection isec(*this, sec, name);
+        if (Error e = attributes.parse(contents, ELFT::Endianness)) {
+          Warn(ctx) << &isec << ": " << std::move(e);
+          // uint32_t andFeatures = 0;
+          // std::array<uint8_t, 16> aarch64PauthAbiCoreInfoStorage;
+        } else {
+          bool writePauth = false;
+          bool wrtieFeatures = false;
+          KnownAArch64BuildAttrSubsections subSections =
+              extractBuildAttributesSubsections(attributes);
+          if (hasGnuProperties) {
+            if (!gnuPropertiesInformation.aarch64PauthAbiCoreInfo.empty()) {
+              // check for mismatch error
----------------
smithp35 wrote:

Rather than deserialize an array. I'd be tempted to make an array out of the Build Attribute values and then use an ArrayRef<uint8_t>. You can then use a similar mismatch message as in Driver.cpp.

I'd err on the terse side of error reporting here to keep it simple. If we can point the user at the file then they can use llvm-readelf to decode the contents and find the mismatch.

As the vast majority of build attributes and GNU properties are written by the compiler we do not expect discrepancies. Assembler written discrepancies 

If we must have all the individual fields then we need to move these out into separate functions far away from the main body of code.

https://github.com/llvm/llvm-project/pull/131990


More information about the llvm-commits mailing list