[llvm] [readobj][AArch64] Parse AArch64 build attributes (PR #124276)
Oliver Stannard via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 27 06:24:23 PST 2025
================
@@ -0,0 +1,152 @@
+//===-AArch64AttributeParser.cpp-AArch64 Attribute Information Printer-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
+// Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===------------------------------------------------------------------===//
+
+#include "llvm/Support/AArch64AttributeParser.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/AArch64BuildAttributes.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+
+using namespace llvm;
+
+Error AArch64AttributeParser::parse(ArrayRef<uint8_t> Section,
+ llvm::endianness Endian) {
+
+ unsigned SectionNumber = 0;
+ de = DataExtractor(Section, Endian == llvm::endianness::little, 0);
+
+ // Early returns have specific errors. Consume the Error in cursor.
+ struct ClearCursorError {
+ DataExtractor::Cursor &Cursor;
+ ~ClearCursorError() { consumeError(Cursor.takeError()); }
+ } Clear{cursor};
+
+ /*
+ AArch64 build attributes layout:
+ <format-version: ‘A’> --> There is only one version, 'A' (0x41)
+ [ <uint32: subsection-length> <NTBS: vendor-name> <bytes: vendor-data> ]
+ --> subsection-length: the offset from the start of this subsection to the
+ start of the next one.
+ --> vendor-name: NUL-terminated byte string.
+ --> vendor-data expands to:
+ [ <uint8: optional> <uint8: parameter type> <attribute>*]
+ --> optional: 0- required, 1- optional
+ --> type: 0- ULEB128, 1- NTBS
+ --> attribute: <tag, value>* pair. Tag is ULEB128, value is <parameter
+ type> type.
+ */
+
+ // Get format-version
+ uint8_t FormatVersion = de.getU8(cursor);
+ if (ELFAttrs::Format_Version != FormatVersion)
+ return createStringError(errc::invalid_argument,
+ "unrecognized format-version: 0x" +
+ utohexstr(FormatVersion));
+
+ while (!de.eof(cursor)) {
+ uint32_t BASubsectionLength = de.getU32(cursor);
+ // Minimal valid BA subsection header size is at least 8: length(4) name(at
+ // least a single char + null) optionality(1) and type(1)
+ if (BASubsectionLength < 8)
+ return createStringError(
+ errc::invalid_argument,
+ "invalid AArch64 build attribute subsection size at offset: " +
+ utohexstr(cursor.tell() - 4));
+
+ StringRef VendorName = de.getCStrRef(cursor);
+ // The layout of a private subsection (--> vendor name does not starts with
+ // 'aeabi') is unknown, skip)
+ if (!VendorName.starts_with("aeabi")) {
+ sw->startLine()
+ << "** Skipping private AArch64 build attributes subsection: "
+ << VendorName << "\n";
+ // Offset in Section
+ uint64_t OffsetInSection = cursor.tell();
+ // Size: 4 bytes, Vendor Name: VendorName.size() + 1 (null termination)
+ uint32_t BytesForLengthName = 4 + (VendorName.size() + 1);
+ cursor.seek(OffsetInSection + BASubsectionLength - BytesForLengthName);
+ continue;
+ }
+ // All public subsections names must be known
+ if (VendorName.starts_with("aeabi")) {
+ if (!("aeabi_feature_and_bits" == VendorName ||
----------------
ostannard wrote:
We should be able to print any "aeabi*" subsection, because the format is known, even if the tag names aren't.
https://github.com/llvm/llvm-project/pull/124276
More information about the llvm-commits
mailing list