[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 11:04:08 PDT 2025


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

Compression of SHT_LLVM_BB_ADDR_MAP with zstd can give 3X compression ratio, which is especially beneficial with PGO_analysis_map. To read the data back, we must decompress it. Though we can use llvm-objcopy to do this, it's much better to do this decompression internally in the library API.

>From 506d359cfbc60c0bb6676c7b0e60b11e4a22527f 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 +++++++++++++++++++
 .../tools/llvm-readobj/ELF/bb-addr-map.test   | 10 ++++++---
 2 files changed, 28 insertions(+), 3 deletions(-)

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.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
index c5d071c11d1de..7e584694e07f2 100644
--- a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
+++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
@@ -5,15 +5,19 @@
 # RUN: llvm-readobj %t1.x64.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.x64.o --check-prefix=CHECK
 # RUN: llvm-readelf %t1.x64.o --bb-addr-map | FileCheck %s --check-prefix=GNU
 
-## Check 64-bit:
-# RUN: yaml2obj --docnum=1 %s -DBITS=64 -DADDR=0x999999999 -o %t1.v1.x64.o
-# RUN: llvm-readobj %t1.v1.x64.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.v1.x64.o --check-prefix=CHECK
+## Check compressed sections:
+# 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-readobj %t1.x32.o --bb-addr-map 2>&1 | FileCheck -DADDR=0x11111 %s -DFILE=%t1.x32.o --check-prefix=CHECK
 # RUN: llvm-readelf %t1.x32.o --bb-addr-map | FileCheck %s --check-prefix=GNU
 
+## Check compressed sections:
+# 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 that a malformed section can be handled.
 # RUN: yaml2obj --docnum=1 %s -DBITS=32 -DSIZE=7 -o %t2.o
 # RUN: llvm-readobj %t2.o --bb-addr-map 2>&1 | FileCheck %s -DOFFSET=0x00000007 -DFILE=%t2.o --check-prefix=TRUNCATED



More information about the llvm-commits mailing list