[llvm] Support decompressing the SHT_LLVM_BB_ADDR_MAP section. (PR #142825)

Rahman Lavaee via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 4 14:51:30 PDT 2025


https://github.com/rlavaee updated https://github.com/llvm/llvm-project/pull/142825

>From a8c2ede70978a7f0a2051504e369578fb4a9e2ac Mon Sep 17 00:00:00 2001
From: Rahman Lavaee <rahmanl at google.com>
Date: Wed, 4 Jun 2025 17:29:34 +0000
Subject: [PATCH] Support decompressing the SHT_LLVM_BB_ADDR_MAP section.

---
 llvm/lib/Object/ELF.cpp                       |  21 +++
 .../ELF/bb-addr-map-compressed-zstd.test      | 142 ++++++++++++++++++
 2 files changed, 163 insertions(+)
 create mode 100644 llvm/test/tools/llvm-readobj/ELF/bb-addr-map-compressed-zstd.test

diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp
index dfc8acb0e4542..bd9e0b6d24226 100644
--- a/llvm/lib/Object/ELF.cpp
+++ b/llvm/lib/Object/ELF.cpp
@@ -9,6 +9,7 @@
 #include "llvm/Object/ELF.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Object/Decompressor.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/DataExtractor.h"
 
@@ -782,6 +783,26 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
   if (!ContentsOrErr)
     return ContentsOrErr.takeError();
   ArrayRef<uint8_t> Content = *ContentsOrErr;
+
+  // Decompress the section if needed.
+  std::unique_ptr<uint8_t[]> DecompressedContent;
+  if (Sec.sh_flags & llvm::ELF::SHF_COMPRESSED) {
+    Expected<StringRef> SectionNameOrErr = EF.getSectionName(Sec);
+    if (!SectionNameOrErr)
+      return SectionNameOrErr.takeError();
+    auto DecompressorOrErr =
+        Decompressor::create(*SectionNameOrErr, toStringRef(*ContentsOrErr),
+                             EF.isLE(), ELFT::Is64Bits);
+    if (!DecompressorOrErr)
+      return DecompressorOrErr.takeError();
+    size_t DecompressedSize = DecompressorOrErr->getDecompressedSize();
+    DecompressedContent = std::make_unique<uint8_t[]>(DecompressedSize);
+    if (Error Err = DecompressorOrErr->decompress(
+            {DecompressedContent.get(), size_t(DecompressedSize)}))
+      return std::move(Err);
+    Content = {DecompressedContent.get(), DecompressedSize};
+  }
+
   DataExtractor Data(Content, EF.isLE(), ELFT::Is64Bits ? 8 : 4);
   std::vector<BBAddrMap> FunctionEntries;
 
diff --git a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-compressed-zstd.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-compressed-zstd.test
new file mode 100644
index 0000000000000..5a379760e4092
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map-compressed-zstd.test
@@ -0,0 +1,142 @@
+# REQUIRES: zstd
+## This test checks that we can read compressed SHT_LLVM_BB_ADDR_MAP sections.
+
+## Check 64-bit:
+# RUN: yaml2obj --docnum=1 %s -DBITS=64 -DADDR=0x999999999 -o %t1.x64.o
+# RUN: llvm-objcopy %t1.x64.o --compress-sections .llvm_bb_addr_map=zstd %t1.x64.compressed.o
+# RUN: llvm-readobj %t1.x64.compressed.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.x64.compressed.o --check-prefix=CHECK
+
+## Check 32-bit:
+# RUN: yaml2obj --docnum=1 %s -DBITS=32 -o %t1.x32.o
+# RUN: llvm-objcopy %t1.x32.o --compress-sections .llvm_bb_addr_map=zstd %t1.x32.compressed.o
+# RUN: llvm-readobj %t1.x32.compressed.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x11111 -DFILE=%t1.x32.compressed.o --check-prefix=CHECK
+
+# CHECK:      BBAddrMap [
+# CHECK-NEXT:   Function {
+# CHECK-NEXT:     At: [[ADDR]]
+# CHECK-NEXT: warning: '[[FILE]]': could not identify function symbol for address ([[ADDR]]) in SHT_LLVM_BB_ADDR_MAP section with index 3
+# CHECK-NEXT:     Name: <?>
+# CHECK-NEXT:     BB Ranges [
+# CHECK-NEXT:       {
+# CHECK-NEXT:         Base Address: [[ADDR]]
+# CHECK-NEXT:         BB Entries [
+# CHECK-NEXT:           {
+# CHECK-NEXT:             ID: 0
+# CHECK-NEXT:             Offset: 0x0
+# CHECK-NEXT:             Size: 0x1
+# CHECK-NEXT:             HasReturn: No
+# CHECK-NEXT:             HasTailCall: Yes
+# CHECK-NEXT:             IsEHPad: No
+# CHECK-NEXT:             CanFallThrough: No
+# CHECK-NEXT:             HasIndirectBranch: No
+# CHECK-NEXT:           }
+# CHECK-NEXT:         ]
+# CHECK-NEXT:       }
+# CHECK-NEXT:       {
+# CHECK-NEXT:         Base Address: 0x44444
+# CHECK-NEXT:         BB Entries [
+# CHECK-NEXT:           {
+# CHECK-NEXT:             ID: 2
+# CHECK-NEXT:             Offset: 0x3
+# CHECK-NEXT:             Size: 0x4
+# CHECK-NEXT:             HasReturn: Yes
+# CHECK-NEXT:             HasTailCall: No
+# CHECK-NEXT:             IsEHPad: Yes
+# CHECK-NEXT:             CanFallThrough: No
+# CHECK-NEXT:             HasIndirectBranch: Yes
+# CHECK-NEXT:           }
+# CHECK-NEXT:         ]
+# CHECK-NEXT:       }
+# CHECK-NEXT:     ]
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Function {
+# CHECK-NEXT:     At: 0x22222
+# CHECK-NEXT:     Name: foo
+# CHECK-NEXT:     BB Ranges [
+# CHECK-NEXT:       {
+# CHECK-NEXT:         Base Address: 0x22222
+# CHECK-NEXT:         BB Entries [
+# CHECK-NEXT:           {
+# CHECK-NEXT:             ID: 4
+# CHECK-NEXT:             Offset: 0x6
+# CHECK-NEXT:             Size: 0x7
+# CHECK-NEXT:             HasReturn: No
+# CHECK-NEXT:             HasTailCall: No
+# CHECK-NEXT:             IsEHPad: No
+# CHECK-NEXT:             CanFallThrough: Yes
+# CHECK-NEXT:            HasIndirectBranch: No
+# CHECK-NEXT:           }
+# CHECK-NEXT:         ]
+# CHECK-NEXT:       }
+# CHECK-NEXT:     ]
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+--- !ELF
+FileHeader:
+  Class: ELFCLASS[[BITS]]
+  Data:  ELFDATA2LSB
+  Type:  ET_EXEC
+Sections:
+  - Name:   .text
+    Type:   SHT_PROGBITS
+    Flags:  [SHF_ALLOC]
+  - Name:   .text.bar
+    Type:   SHT_PROGBITS
+    Flags:  [SHF_ALLOC]
+  - Name:   .llvm_bb_addr_map
+    Type:   SHT_LLVM_BB_ADDR_MAP
+    ShSize: [[SIZE=<none>]]
+    Link:   .text
+    Entries:
+      - Version: 2
+        Feature: 0x8
+        BBRanges:
+          - BaseAddress: [[ADDR=0x11111]]
+            BBEntries:
+              - ID:            0
+                AddressOffset: 0x0
+                Size:          0x1
+                Metadata:      [[METADATA=0x2]]
+          - BaseAddress: 0x44444
+            BBEntries:
+              - ID:            2
+                AddressOffset: 0x3
+                Size:          0x4
+                Metadata:      0x15
+      - Version: 2
+        BBRanges:
+          - BaseAddress: 0x22222
+            BBEntries:
+              - ID:            4
+                AddressOffset: 0x6
+                Size:          0x7
+                Metadata:      0x8
+  - Name: dummy_section
+    Type: SHT_PROGBITS
+    Size: 16
+  - Name: '.llvm_bb_addr_map (1)'
+    Type: SHT_LLVM_BB_ADDR_MAP
+    Link: .text.bar
+    Entries:
+      - Version: 2
+        BBRanges:
+          - BaseAddress: 0x33333
+            BBEntries:
+              - ID:            6
+                AddressOffset: 0x9
+                Size:          0xa
+                Metadata:      0x1b
+              - ID:            7
+                AddressOffset: 0xc
+                Size:          0xd
+                Metadata:      0xe
+Symbols:
+  - Name:    foo
+    Section: .text
+    Type:    STT_FUNC
+    Value:   0x22222
+  - Name:    bar
+    Section: .text.bar
+    Type:    STT_FUNC
+    Value:   0x33333



More information about the llvm-commits mailing list