[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