[llvm] llvm-readobj: support big-endian attribute printing (PR #87806)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 8 07:04:14 PDT 2024


https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/87806

>From 6152c31a89f27c2eb3f0d7355012199be12feadc Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ram.ramachandra at arm.com>
Date: Fri, 5 Apr 2024 17:56:07 +0100
Subject: [PATCH 1/2] llvm-readobj: support big-endian attribute printing

Support attribute printing for big-endian encoding, and activate it for
ARM. The supporting code already exists, and the patch is trivial.

Fixes #62400.
---
 llvm/include/llvm/Support/DataExtractor.h        |  2 +-
 llvm/lib/Support/DataExtractor.cpp               |  6 +++---
 .../ELF/ARM/attribute-big-endian.test            | 16 +++++++++++-----
 llvm/tools/llvm-readobj/ELFDumper.cpp            | 10 +++-------
 4 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/llvm/include/llvm/Support/DataExtractor.h b/llvm/include/llvm/Support/DataExtractor.h
index f4f5905d4bccd6..c7f187cfd547fa 100644
--- a/llvm/include/llvm/Support/DataExtractor.h
+++ b/llvm/include/llvm/Support/DataExtractor.h
@@ -40,7 +40,7 @@ inline uint24_t getSwappedBytes(uint24_t C) {
 
 class DataExtractor {
   StringRef Data;
-  uint8_t IsLittleEndian;
+  bool IsLittleEndian;
   uint8_t AddressSize;
 public:
   /// A class representing a position in a DataExtractor, as well as any error
diff --git a/llvm/lib/Support/DataExtractor.cpp b/llvm/lib/Support/DataExtractor.cpp
index eac3c32cfd3b79..2bef63c44a9068 100644
--- a/llvm/lib/Support/DataExtractor.cpp
+++ b/llvm/lib/Support/DataExtractor.cpp
@@ -48,7 +48,7 @@ T DataExtractor::getU(uint64_t *offset_ptr, Error *Err) const {
   if (!prepareRead(offset, sizeof(T), Err))
     return val;
   std::memcpy(&val, &Data.data()[offset], sizeof(val));
-  if (sys::IsLittleEndianHost != IsLittleEndian)
+  if (!IsLittleEndian)
     sys::swapByteOrder(val);
 
   // Advance the offset
@@ -101,8 +101,8 @@ uint16_t *DataExtractor::getU16(uint64_t *offset_ptr, uint16_t *dst,
 
 uint32_t DataExtractor::getU24(uint64_t *OffsetPtr, Error *Err) const {
   uint24_t ExtractedVal = getU<uint24_t>(OffsetPtr, Err);
-  // The 3 bytes are in the correct byte order for the host.
-  return ExtractedVal.getAsUint32(sys::IsLittleEndianHost);
+  // The 3 bytes are in the correct byte order with the given endianness.
+  return ExtractedVal.getAsUint32(IsLittleEndian);
 }
 
 uint32_t DataExtractor::getU32(uint64_t *offset_ptr, llvm::Error *Err) const {
diff --git a/llvm/test/tools/llvm-readobj/ELF/ARM/attribute-big-endian.test b/llvm/test/tools/llvm-readobj/ELF/ARM/attribute-big-endian.test
index 7d20b310f9d906..3b94c7994cf3c0 100644
--- a/llvm/test/tools/llvm-readobj/ELF/ARM/attribute-big-endian.test
+++ b/llvm/test/tools/llvm-readobj/ELF/ARM/attribute-big-endian.test
@@ -1,17 +1,23 @@
-## We only implement attribute section printing for little-endian encoding.
-
 # RUN: yaml2obj %s -o %t.o
-# RUN: llvm-readobj -A %t.o 2>&1 | FileCheck %s -DFILE=%t.o
+# RUN: llvm-readelf -A %t.o 2>&1 | FileCheck %s
 
-# CHECK: warning: '[[FILE]]': attribute printing not implemented for big-endian ARM objects
+# CHECK:      BuildAttributes {
+# CHECK-NEXT:   FormatVersion: 0x41
+# CHECK-NEXT:   Section 1 {
+# CHECK-NEXT:     SectionLength: 22
+# CHECK-NEXT:     Vendor: armabi
+# CHECK-NEXT:   }
+# CHECK-NEXT: }
 
 --- !ELF
 FileHeader:
   Class:   ELFCLASS32
-## Test big-endian encoding.
   Data:    ELFDATA2MSB
   Type:    ET_REL
   Machine: EM_ARM
 Sections:
   - Name: .ARM.attributes
     Type: SHT_ARM_ATTRIBUTES
+    ContentArray: [ 0x41, 0x00, 0x00, 0x00, 0x16, 0x61, 0x72, 0x6D, 0x61, 0x62,
+    0x69, 0x00, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x01, 0x06, 0x01, 0x08,
+    0x01 ]
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 4b406ef12aecfe..da7837cda3c92a 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -2832,13 +2832,9 @@ template <class ELFT> void ELFDumper<ELFT>::printArchSpecificInfo() {
                     llvm::endianness::little);
     break;
   case EM_ARM:
-    if (Obj.isLE())
-      printAttributes(ELF::SHT_ARM_ATTRIBUTES,
-                      std::make_unique<ARMAttributeParser>(&W),
-                      llvm::endianness::little);
-    else
-      reportUniqueWarning("attribute printing not implemented for big-endian "
-                          "ARM objects");
+    printAttributes(
+        ELF::SHT_ARM_ATTRIBUTES, std::make_unique<ARMAttributeParser>(&W),
+        Obj.isLE() ? llvm::endianness::little : llvm::endianness::big);
     break;
   case EM_RISCV:
     if (Obj.isLE())

>From d03f037132ff4eef297f240085f237478a8f5873 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ram.ramachandra at arm.com>
Date: Sat, 6 Apr 2024 12:40:17 +0100
Subject: [PATCH 2/2] DataExtractor: revert changes

---
 llvm/lib/Support/DataExtractor.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Support/DataExtractor.cpp b/llvm/lib/Support/DataExtractor.cpp
index 2bef63c44a9068..eac3c32cfd3b79 100644
--- a/llvm/lib/Support/DataExtractor.cpp
+++ b/llvm/lib/Support/DataExtractor.cpp
@@ -48,7 +48,7 @@ T DataExtractor::getU(uint64_t *offset_ptr, Error *Err) const {
   if (!prepareRead(offset, sizeof(T), Err))
     return val;
   std::memcpy(&val, &Data.data()[offset], sizeof(val));
-  if (!IsLittleEndian)
+  if (sys::IsLittleEndianHost != IsLittleEndian)
     sys::swapByteOrder(val);
 
   // Advance the offset
@@ -101,8 +101,8 @@ uint16_t *DataExtractor::getU16(uint64_t *offset_ptr, uint16_t *dst,
 
 uint32_t DataExtractor::getU24(uint64_t *OffsetPtr, Error *Err) const {
   uint24_t ExtractedVal = getU<uint24_t>(OffsetPtr, Err);
-  // The 3 bytes are in the correct byte order with the given endianness.
-  return ExtractedVal.getAsUint32(IsLittleEndian);
+  // The 3 bytes are in the correct byte order for the host.
+  return ExtractedVal.getAsUint32(sys::IsLittleEndianHost);
 }
 
 uint32_t DataExtractor::getU32(uint64_t *offset_ptr, llvm::Error *Err) const {



More information about the llvm-commits mailing list