[llvm] [dsymutil] collect pseudoprobe sections from debug map into __LLVM segment (PR #206817)
Henry Jiang via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 7 23:48:54 PDT 2026
https://github.com/mustartt updated https://github.com/llvm/llvm-project/pull/206817
>From a88400d2f74ee75500683c7465dc3bd4ed506551 Mon Sep 17 00:00:00 2001
From: Henry Jiang <henry_jiang2 at apple.com>
Date: Tue, 7 Jul 2026 13:18:11 -0700
Subject: [PATCH 1/2] Revert "[dsymutil] Add support for pseudo probes
(#186877)"
This reverts commit bc3386c1b9a5bff82ce4baaf4254fc4268f69ff4.
The companion-copy approach (transferring the __PSEUDO_PROBE segment into
the dSYM companion binary) is superseded by gathering the pseudo-probe
sections from the debug-map objects into a sidecar, added in the following
commit.
---
.../tools/dsymutil/AArch64/pseudo-probe.test | 319 ------------------
llvm/tools/dsymutil/MachOUtils.cpp | 72 +---
2 files changed, 7 insertions(+), 384 deletions(-)
delete mode 100644 llvm/test/tools/dsymutil/AArch64/pseudo-probe.test
diff --git a/llvm/test/tools/dsymutil/AArch64/pseudo-probe.test b/llvm/test/tools/dsymutil/AArch64/pseudo-probe.test
deleted file mode 100644
index 0bc97eb574eae..0000000000000
--- a/llvm/test/tools/dsymutil/AArch64/pseudo-probe.test
+++ /dev/null
@@ -1,319 +0,0 @@
-## Test that dsymutil correctly copies pseudoprobe sections and segments
-
-# https://github.com/llvm/llvm-project/issues/190481
-# REQUIRES: host-byteorder-little-endian
-
-# RUN: rm -rf %t && mkdir -p %t
-# RUN: yaml2obj %s -o %t/main.o
-# RUN: dsymutil --linker classic %t/main.o -o %t/main.dSYM
-# RUN: obj2yaml %t/main.dSYM/Contents/Resources/DWARF/main.o -o %t/out.yaml
-# RUN: FileCheck %s < %t/out.yaml
-# RUN: dsymutil --linker parallel %t/main.o -o %t/main.dSYM
-# RUN: obj2yaml %t/main.dSYM/Contents/Resources/DWARF/main.o -o %t/out.yaml
-# RUN: FileCheck %s < %t/out.yaml
-
-# CHECK: segname: __PSEUDO_PROBE
-# CHECK: Sections:
-# CHECK-NEXT: - sectname: __probe_descs
-# CHECK-NEXT: segname: __PSEUDO_PROBE
-# CHECK: content: ACBD18DB4CC2F85CFFFFFFFF0000000003666F6F37B51D194A7513E4FFFFFFFF000000000362617273FEFFA4B7F6BB68FFFFFFFF000002000362617AFAD58DE7366495DBFFFFFFFF00000100046D61696E
-# CHECK-NEXT: - sectname: __probes
-# CHECK-NEXT: segname: __PSEUDO_PROBE
-# CHECK: content: 37B51D194A7513E402000020A9A7418A5E3E02B5018000FAD58DE7366495DB0200002001411FAE90F5722601800073FEFFA4B7F6BB6802000020DEDF76EC3AE9F50501800037B51D194A7513E402000020DEDF76EC3AE9F505018000ACBD18DB4CC2F85C020000208774C18D504B6E28018000
-
---- !mach-o
-FileHeader:
- magic: 0xFEEDFACF
- cputype: 0x100000C
- cpusubtype: 0x0
- filetype: 0x2
- ncmds: 17
- sizeofcmds: 976
- flags: 0x200085
- reserved: 0x0
-LoadCommands:
- - cmd: LC_SEGMENT_64
- cmdsize: 72
- segname: __PAGEZERO
- vmaddr: 0
- vmsize: 4294967296
- fileoff: 0
- filesize: 0
- maxprot: 0
- initprot: 0
- nsects: 0
- flags: 0
- - cmd: LC_SEGMENT_64
- cmdsize: 232
- segname: __TEXT
- vmaddr: 4294967296
- vmsize: 16384
- fileoff: 0
- filesize: 16384
- maxprot: 5
- initprot: 5
- nsects: 2
- flags: 0
- Sections:
- - sectname: __text
- segname: __TEXT
- addr: 0x100000410
- size: 20
- offset: 0x410
- align: 2
- reloff: 0x0
- nreloc: 0
- flags: 0x80000400
- reserved1: 0x0
- reserved2: 0x0
- reserved3: 0x0
- content: C0035FD6C0035FD6C0035FD600008052C0035FD6
- - sectname: __unwind_info
- segname: __TEXT
- addr: 0x100000424
- size: 88
- offset: 0x424
- align: 2
- reloff: 0x0
- nreloc: 0
- flags: 0x0
- reserved1: 0x0
- reserved2: 0x0
- reserved3: 0x0
- content: 010000001C000000000000001C000000000000001C00000002000000100400004000000040000000250400000000000040000000000000000000000000000000030000000C00010010000100000000000000000200000000
- - cmd: LC_SEGMENT_64
- cmdsize: 232
- segname: __PSEUDO_PROBE
- vmaddr: 4294983680
- vmsize: 16384
- fileoff: 16384
- filesize: 16384
- maxprot: 3
- initprot: 3
- nsects: 2
- flags: 0
- Sections:
- - sectname: __probe_descs
- segname: __PSEUDO_PROBE
- addr: 0x100004000
- size: 81
- offset: 0x4000
- align: 0
- reloff: 0x0
- nreloc: 0
- flags: 0x0
- reserved1: 0x0
- reserved2: 0x0
- reserved3: 0x0
- content: ACBD18DB4CC2F85CFFFFFFFF0000000003666F6F37B51D194A7513E4FFFFFFFF000000000362617273FEFFA4B7F6BB68FFFFFFFF000002000362617AFAD58DE7366495DBFFFFFFFF00000100046D61696E
- - sectname: __probes
- segname: __PSEUDO_PROBE
- addr: 0x100004051
- size: 115
- offset: 0x4051
- align: 0
- reloff: 0x0
- nreloc: 0
- flags: 0x0
- reserved1: 0x0
- reserved2: 0x0
- reserved3: 0x0
- content: 37B51D194A7513E402000020A9A7418A5E3E02B5018000FAD58DE7366495DB0200002001411FAE90F5722601800073FEFFA4B7F6BB6802000020DEDF76EC3AE9F50501800037B51D194A7513E402000020DEDF76EC3AE9F505018000ACBD18DB4CC2F85C020000208774C18D504B6E28018000
- - cmd: LC_SEGMENT_64
- cmdsize: 72
- segname: __LINKEDIT
- vmaddr: 4295000064
- vmsize: 16384
- fileoff: 32768
- filesize: 680
- maxprot: 1
- initprot: 1
- nsects: 0
- flags: 0
- - cmd: LC_DYLD_CHAINED_FIXUPS
- cmdsize: 16
- dataoff: 32768
- datasize: 56
- - cmd: LC_DYLD_EXPORTS_TRIE
- cmdsize: 16
- dataoff: 32824
- datasize: 80
- - cmd: LC_SYMTAB
- cmdsize: 24
- symoff: 32912
- nsyms: 5
- stroff: 32992
- strsize: 48
- - cmd: LC_DYSYMTAB
- cmdsize: 80
- ilocalsym: 0
- nlocalsym: 0
- iextdefsym: 0
- nextdefsym: 5
- iundefsym: 5
- nundefsym: 0
- tocoff: 0
- ntoc: 0
- modtaboff: 0
- nmodtab: 0
- extrefsymoff: 0
- nextrefsyms: 0
- indirectsymoff: 0
- nindirectsyms: 0
- extreloff: 0
- nextrel: 0
- locreloff: 0
- nlocrel: 0
- - cmd: LC_LOAD_DYLINKER
- cmdsize: 32
- name: 12
- Content: '/usr/lib/dyld'
- ZeroPadBytes: 7
- - cmd: LC_UUID
- cmdsize: 24
- uuid: B95C17E1-7B8C-362B-B402-C636C09BB979
- - cmd: LC_BUILD_VERSION
- cmdsize: 32
- platform: 1
- minos: 1703936
- sdk: 1704448
- ntools: 1
- Tools:
- - tool: 3
- version: 86573312
- - cmd: LC_SOURCE_VERSION
- cmdsize: 16
- version: 0
- - cmd: LC_MAIN
- cmdsize: 24
- entryoff: 1052
- stacksize: 0
- - cmd: LC_LOAD_DYLIB
- cmdsize: 56
- dylib:
- name: 24
- timestamp: 2
- current_version: 88866816
- compatibility_version: 65536
- Content: '/usr/lib/libSystem.B.dylib'
- ZeroPadBytes: 6
- - cmd: LC_FUNCTION_STARTS
- cmdsize: 16
- dataoff: 32904
- datasize: 8
- - cmd: LC_DATA_IN_CODE
- cmdsize: 16
- dataoff: 32912
- datasize: 0
- - cmd: LC_CODE_SIGNATURE
- cmdsize: 16
- dataoff: 33040
- datasize: 408
-LinkEditData:
- ExportTrie:
- TerminalSize: 0
- NodeOffset: 0
- Name: ''
- Flags: 0x0
- Address: 0x0
- Other: 0x0
- ImportName: ''
- Children:
- - TerminalSize: 0
- NodeOffset: 41
- Name: _
- Flags: 0x0
- Address: 0x0
- Other: 0x0
- ImportName: ''
- Children:
- - TerminalSize: 2
- NodeOffset: 9
- Name: _mh_execute_header
- Flags: 0x0
- Address: 0x0
- Other: 0x0
- ImportName: ''
- - TerminalSize: 0
- NodeOffset: 23
- Name: ba
- Flags: 0x0
- Address: 0x0
- Other: 0x0
- ImportName: ''
- Children:
- - TerminalSize: 3
- NodeOffset: 13
- Name: r
- Flags: 0x0
- Address: 0x414
- Other: 0x0
- ImportName: ''
- - TerminalSize: 3
- NodeOffset: 18
- Name: z
- Flags: 0x0
- Address: 0x418
- Other: 0x0
- ImportName: ''
- - TerminalSize: 3
- NodeOffset: 31
- Name: foo
- Flags: 0x0
- Address: 0x410
- Other: 0x0
- ImportName: ''
- - TerminalSize: 3
- NodeOffset: 36
- Name: main
- Flags: 0x0
- Address: 0x41C
- Other: 0x0
- ImportName: ''
- NameList:
- - n_strx: 2
- n_type: 0xF
- n_sect: 1
- n_desc: 16
- n_value: 4294967296
- - n_strx: 22
- n_type: 0xF
- n_sect: 1
- n_desc: 0
- n_value: 4294968340
- - n_strx: 27
- n_type: 0xF
- n_sect: 1
- n_desc: 0
- n_value: 4294968344
- - n_strx: 32
- n_type: 0xF
- n_sect: 1
- n_desc: 0
- n_value: 4294968336
- - n_strx: 37
- n_type: 0xF
- n_sect: 1
- n_desc: 0
- n_value: 4294968348
- StringTable:
- - ' '
- - __mh_execute_header
- - _bar
- - _baz
- - _foo
- - _main
- - ''
- - ''
- - ''
- - ''
- - ''
- FunctionStarts: [ 0x410, 0x414, 0x418, 0x41C ]
- ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x34, 0x0,
- 0x0, 0x0, 0x34, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
-...
-
diff --git a/llvm/tools/dsymutil/MachOUtils.cpp b/llvm/tools/dsymutil/MachOUtils.cpp
index a6dd3afa223e7..9b143157ac773 100644
--- a/llvm/tools/dsymutil/MachOUtils.cpp
+++ b/llvm/tools/dsymutil/MachOUtils.cpp
@@ -269,19 +269,13 @@ getSection(const object::MachOObjectFile &Obj,
//
// When the eh_frame section is transferred, its offset and size are set resp.
// to \a EHFrameOffset and \a EHFrameSize.
-//
-// When the __PSEUDO_PROBE segment is transferred, its offset and size are set
-// resp. to \a PseudoProbeOffset and \a PseudoProbeSize, and its sections'
-// offsets are updated using \a PseudoProbeProbesOffset for __probes and
-// \a PseudoProbeDescsOffset for __probe_descs.
template <typename SegmentTy>
static void transferSegmentAndSections(
const object::MachOObjectFile::LoadCommandInfo &LCI, SegmentTy Segment,
const object::MachOObjectFile &Obj, MachObjectWriter &Writer,
uint64_t LinkeditOffset, uint64_t LinkeditSize, uint64_t EHFrameOffset,
- uint64_t EHFrameSize, uint64_t PseudoProbeOffset, uint64_t PseudoProbeSize,
- uint64_t PseudoProbeProbesOffset, uint64_t PseudoProbeDescsOffset,
- uint64_t DwarfSegmentSize, uint64_t &GapForDwarf, uint64_t &EndAddress) {
+ uint64_t EHFrameSize, uint64_t DwarfSegmentSize, uint64_t &GapForDwarf,
+ uint64_t &EndAddress) {
if (StringRef("__DWARF") == Segment.segname)
return;
@@ -293,10 +287,6 @@ static void transferSegmentAndSections(
Segment.filesize = LinkeditSize;
// Resize vmsize by rounding to the page size.
Segment.vmsize = alignTo(LinkeditSize, 0x1000);
- } else if (StringRef("__PSEUDO_PROBE") == Segment.segname &&
- PseudoProbeSize > 0) {
- Segment.fileoff = PseudoProbeOffset;
- Segment.filesize = PseudoProbeSize;
} else {
Segment.fileoff = Segment.filesize = 0;
}
@@ -322,14 +312,6 @@ static void transferSegmentAndSections(
if (StringRef("__eh_frame") == Sect.sectname) {
Sect.offset = EHFrameOffset;
Sect.reloff = Sect.nreloc = 0;
- } else if (StringRef("__probes") == Sect.sectname &&
- PseudoProbeProbesOffset > 0) {
- Sect.offset = PseudoProbeProbesOffset;
- Sect.reloff = Sect.nreloc = 0;
- } else if (StringRef("__probe_descs") == Sect.sectname &&
- PseudoProbeDescsOffset > 0) {
- Sect.offset = PseudoProbeDescsOffset;
- Sect.reloff = Sect.nreloc = 0;
} else {
Sect.offset = Sect.reloff = Sect.nreloc = 0;
}
@@ -481,10 +463,6 @@ bool generateDsymCompanion(
// If we have a valid eh_frame to copy, do it.
uint64_t EHFrameSize = 0;
StringRef EHFrameData;
- StringRef PseudoProbeProbesData;
- uint64_t PseudoProbeProbesSize = 0;
- StringRef PseudoProbeDescsData;
- uint64_t PseudoProbeDescsSize = 0;
for (const object::SectionRef &Section : InputBinary.sections()) {
Expected<StringRef> NameOrErr = Section.getName();
if (!NameOrErr) {
@@ -500,23 +478,8 @@ bool generateDsymCompanion(
} else {
consumeError(ContentsOrErr.takeError());
}
- } else if (SectionName == "probes") {
- if (Expected<StringRef> ContentsOrErr = Section.getContents()) {
- PseudoProbeProbesData = *ContentsOrErr;
- PseudoProbeProbesSize = Section.getSize();
- } else {
- consumeError(ContentsOrErr.takeError());
- }
- } else if (SectionName == "probe_descs") {
- if (Expected<StringRef> ContentsOrErr = Section.getContents()) {
- PseudoProbeDescsData = *ContentsOrErr;
- PseudoProbeDescsSize = Section.getSize();
- } else {
- consumeError(ContentsOrErr.takeError());
- }
}
}
- uint64_t PseudoProbeSize = PseudoProbeProbesSize + PseudoProbeDescsSize;
unsigned HeaderSize =
Is64Bit ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header);
@@ -598,16 +561,8 @@ bool generateDsymCompanion(
uint64_t EHFrameStart = StringStart + NewStringsSize;
EHFrameStart = alignTo(EHFrameStart, 0x1000);
- // Place pseudo probe data after the EH frame.
- uint64_t PseudoProbeStart = PseudoProbeSize > 0
- ? alignTo(EHFrameStart + EHFrameSize, 0x1000)
- : EHFrameStart + EHFrameSize;
-
- uint64_t PseudoProbeProbesStart = PseudoProbeStart;
- uint64_t PseudoProbeDescsStart = PseudoProbeStart + PseudoProbeProbesSize;
-
- uint64_t DwarfSegmentStart =
- alignTo(PseudoProbeStart + PseudoProbeSize, 0x1000);
+ uint64_t DwarfSegmentStart = EHFrameStart + EHFrameSize;
+ DwarfSegmentStart = alignTo(DwarfSegmentStart, 0x1000);
// Write the load commands for the segments and sections we 'import' from
// the original binary.
@@ -618,16 +573,12 @@ bool generateDsymCompanion(
transferSegmentAndSections(
LCI, InputBinary.getSegmentLoadCommand(LCI), InputBinary, Writer,
SymtabStart, StringStart + NewStringsSize - SymtabStart, EHFrameStart,
- EHFrameSize, PseudoProbeStart, PseudoProbeSize,
- PseudoProbeProbesStart, PseudoProbeDescsStart, DwarfSegmentSize,
- GapForDwarf, EndAddress);
+ EHFrameSize, DwarfSegmentSize, GapForDwarf, EndAddress);
else if (LCI.C.cmd == MachO::LC_SEGMENT_64)
transferSegmentAndSections(
LCI, InputBinary.getSegment64LoadCommand(LCI), InputBinary, Writer,
SymtabStart, StringStart + NewStringsSize - SymtabStart, EHFrameStart,
- EHFrameSize, PseudoProbeStart, PseudoProbeSize,
- PseudoProbeProbesStart, PseudoProbeDescsStart, DwarfSegmentSize,
- GapForDwarf, EndAddress);
+ EHFrameSize, DwarfSegmentSize, GapForDwarf, EndAddress);
}
uint64_t DwarfVMAddr = alignTo(EndAddress, 0x1000);
@@ -681,17 +632,8 @@ bool generateDsymCompanion(
OutFile << EHFrameData;
assert(OutFile.tell() == EHFrameStart + EHFrameSize);
- // Transfer pseudo probe.
- if (PseudoProbeSize > 0) {
- OutFile.write_zeros(PseudoProbeStart - (EHFrameStart + EHFrameSize));
- assert(OutFile.tell() == PseudoProbeStart);
- OutFile << PseudoProbeProbesData;
- OutFile << PseudoProbeDescsData;
- assert(OutFile.tell() == PseudoProbeStart + PseudoProbeSize);
- }
-
// Pad till the Dwarf segment start.
- OutFile.write_zeros(DwarfSegmentStart - OutFile.tell());
+ OutFile.write_zeros(DwarfSegmentStart - (EHFrameStart + EHFrameSize));
assert(OutFile.tell() == DwarfSegmentStart);
// Emit the Dwarf sections contents.
>From 23983c5c8c8713f94e56f2683eadb182776019ae Mon Sep 17 00:00:00 2001
From: Henry Jiang <henry_jiang2 at apple.com>
Date: Tue, 7 Jul 2026 13:41:14 -0700
Subject: [PATCH 2/2] [dsymutil] Collect MachO pseudo-probe sections into dSYM
companion file
---
.../AArch64/pseudo-probe-universal.test | 439 ++++++++++++++++++
.../tools/dsymutil/AArch64/pseudo-probe.test | 366 +++++++++++++++
llvm/tools/dsymutil/CMakeLists.txt | 1 +
llvm/tools/dsymutil/PseudoProbeLinker.cpp | 184 ++++++++
llvm/tools/dsymutil/PseudoProbeLinker.h | 55 +++
llvm/tools/dsymutil/dsymutil.cpp | 5 +
6 files changed, 1050 insertions(+)
create mode 100644 llvm/test/tools/dsymutil/AArch64/pseudo-probe-universal.test
create mode 100644 llvm/test/tools/dsymutil/AArch64/pseudo-probe.test
create mode 100644 llvm/tools/dsymutil/PseudoProbeLinker.cpp
create mode 100644 llvm/tools/dsymutil/PseudoProbeLinker.h
diff --git a/llvm/test/tools/dsymutil/AArch64/pseudo-probe-universal.test b/llvm/test/tools/dsymutil/AArch64/pseudo-probe-universal.test
new file mode 100644
index 0000000000000..6ff9caadf3449
--- /dev/null
+++ b/llvm/test/tools/dsymutil/AArch64/pseudo-probe-universal.test
@@ -0,0 +1,439 @@
+# REQUIRES: aarch64-registered-target
+# REQUIRES: host-byteorder-little-endian
+
+# RUN: rm -rf %t && split-file %s %t
+# RUN: yaml2obj %t/fat.dylib.yaml -o %t/fat.dylib
+# RUN: yaml2obj %t/a.o.yaml -o %t/a.o
+# RUN: yaml2obj %t/e.o.yaml -o %t/e.o
+
+# RUN: dsymutil --linker classic --no-object-timestamp %t/fat.dylib -oso-prepend-path=%t -o %t/classic.dSYM
+# RUN: llvm-readobj --file-headers --sections %t/classic.dSYM/Contents/Resources/Profiling/pseudo_probes-arm64 \
+# RUN: | FileCheck %s --check-prefix=ARM64
+# RUN: llvm-readobj --file-headers --sections %t/classic.dSYM/Contents/Resources/Profiling/pseudo_probes-arm64e \
+# RUN: | FileCheck %s --check-prefix=ARM64E
+# RUN: llvm-objdump -s --section=__probes --section=__probe_descs %t/classic.dSYM/Contents/Resources/Profiling/pseudo_probes-arm64 \
+# RUN: | FileCheck %s --check-prefix=DATA
+
+# RUN: dsymutil --linker parallel --no-object-timestamp %t/fat.dylib -oso-prepend-path=%t -o %t/parallel.dSYM
+# RUN: llvm-readobj --file-headers --sections %t/parallel.dSYM/Contents/Resources/Profiling/pseudo_probes-arm64 \
+# RUN: | FileCheck %s --check-prefix=ARM64
+# RUN: llvm-readobj --file-headers --sections %t/parallel.dSYM/Contents/Resources/Profiling/pseudo_probes-arm64e \
+# RUN: | FileCheck %s --check-prefix=ARM64E
+# RUN: llvm-objdump -s --section=__probes --section=__probe_descs %t/parallel.dSYM/Contents/Resources/Profiling/pseudo_probes-arm64 \
+# RUN: | FileCheck %s --check-prefix=DATA
+
+# ARM64: CpuType: Arm64
+# ARM64: CpuSubType: CPU_SUBTYPE_ARM64_ALL
+# ARM64: Name: __probes
+# ARM64-NEXT: Segment: __LLVM
+# ARM64-NEXT: Address: 0x0
+# ARM64-NEXT: Size: 0x3C
+# ARM64-NEXT: Offset: 368
+# ARM64: Name: __probe_descs
+# ARM64-NEXT: Segment: __LLVM
+# ARM64-NEXT: Address: 0x3C
+# ARM64-NEXT: Size: 0x27
+# ARM64-NEXT: Offset: 428
+
+# ARM64E: CpuType: Arm64
+# ARM64E: CpuSubType: CPU_SUBTYPE_ARM64E
+# ARM64E: Name: __probes
+# ARM64E-NEXT: Segment: __LLVM
+# ARM64E-NEXT: Address: 0x0
+# ARM64E-NEXT: Size: 0x3C
+# ARM64E-NEXT: Offset: 368
+# ARM64E: Name: __probe_descs
+# ARM64E-NEXT: Segment: __LLVM
+# ARM64E-NEXT: Address: 0x3C
+# ARM64E-NEXT: Size: 0x27
+# ARM64E-NEXT: Offset: 428
+
+# DATA: Contents of section __LLVM,__probes:
+# DATA-NEXT: 0000 fad58de7 366495db
+# DATA: Contents of section __LLVM,__probe_descs:
+# DATA-NEXT: 003c 8fa14cdd 754f91cc
+# DATA: 046d 61696e
+
+
+#--- fat.dylib.yaml
+--- !fat-mach-o
+FatHeader:
+ magic: 0xCAFEBABE
+ nfat_arch: 2
+FatArchs:
+ - cputype: 0x100000C
+ cpusubtype: 0x0
+ offset: 0x4000
+ size: 181
+ align: 14
+ - cputype: 0x100000C
+ cpusubtype: 0x2
+ offset: 0x8000
+ size: 181
+ align: 14
+Slices:
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x0
+ filetype: 0x6
+ ncmds: 3
+ sizeofcmds: 128
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 16384
+ vmsize: 4096
+ fileoff: 160
+ filesize: 21
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 32
+ dylib:
+ name: 24
+ timestamp: 0
+ current_version: 0
+ compatibility_version: 0
+ Content: probe
+ ZeroPadBytes: 3
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 160
+ nsyms: 1
+ stroff: 176
+ strsize: 5
+ LinkEditData:
+ NameList:
+ - n_strx: 1
+ n_type: 0x66
+ n_sect: 0
+ n_desc: 1
+ n_value: 0
+ StringTable:
+ - ''
+ - a.o
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x2
+ filetype: 0x6
+ ncmds: 3
+ sizeofcmds: 128
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 16384
+ vmsize: 4096
+ fileoff: 160
+ filesize: 21
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 32
+ dylib:
+ name: 24
+ timestamp: 0
+ current_version: 0
+ compatibility_version: 0
+ Content: probe
+ ZeroPadBytes: 3
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 160
+ nsyms: 1
+ stroff: 176
+ strsize: 5
+ LinkEditData:
+ NameList:
+ - n_strx: 1
+ n_type: 0x66
+ n_sect: 0
+ n_desc: 1
+ n_value: 0
+ StringTable:
+ - ''
+ - e.o
+...
+
+#--- a.o.yaml
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x0
+ filetype: 0x1
+ ncmds: 4
+ sizeofcmds: 440
+ flags: 0x2000
+ reserved: 0x0
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 312
+ segname: ''
+ vmaddr: 0
+ vmsize: 813
+ fileoff: 472
+ filesize: 115
+ maxprot: 7
+ initprot: 7
+ nsects: 3
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x0
+ size: 16
+ offset: 0x1D8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 00040011C0035FD640008052C0035FD6
+ - sectname: __probe_descs
+ segname: __PSEUDO_PROBE
+ addr: 0x10
+ size: 39
+ offset: 0x1E8
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x12000000
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 8FA14CDD754F91CCFFFFFFFF000000000166FAD58DE7366495DBFFFFFFFF00000100046D61696E
+ - sectname: __probes
+ segname: __PSEUDO_PROBE
+ addr: 0x2F1
+ size: 60
+ offset: 0x20F
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x12000000
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: FAD58DE7366495DB0201002001411FAE90F57226018000028FA14CDD754F91CC01000180008FA14CDD754F91CC02000020E99036E91302D08B018000
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 24
+ platform: 1
+ minos: 1703936
+ sdk: 1704960
+ ntools: 0
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 587
+ nsyms: 5
+ stroff: 667
+ strsize: 32
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 3
+ iextdefsym: 3
+ nextdefsym: 2
+ iundefsym: 5
+ nundefsym: 0
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 0
+ nindirectsyms: 0
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+LinkEditData:
+ NameList:
+ - n_strx: 22
+ n_type: 0xE
+ n_sect: 1
+ n_desc: 0
+ n_value: 0
+ - n_strx: 16
+ n_type: 0xE
+ n_sect: 2
+ n_desc: 0
+ n_value: 16
+ - n_strx: 10
+ n_type: 0xE
+ n_sect: 3
+ n_desc: 0
+ n_value: 753
+ - n_strx: 7
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 0
+ - n_strx: 1
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 8
+ StringTable:
+ - ''
+ - _main
+ - _f
+ - ltmp2
+ - ltmp1
+ - ltmp0
+ - ''
+ - ''
+ - ''
+ - ''
+...
+
+#--- e.o.yaml
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x80000002
+ filetype: 0x1
+ ncmds: 4
+ sizeofcmds: 440
+ flags: 0x2000
+ reserved: 0x0
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 312
+ segname: ''
+ vmaddr: 0
+ vmsize: 813
+ fileoff: 472
+ filesize: 115
+ maxprot: 7
+ initprot: 7
+ nsects: 3
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x0
+ size: 16
+ offset: 0x1D8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 00040011C0035FD640008052C0035FD6
+ - sectname: __probe_descs
+ segname: __PSEUDO_PROBE
+ addr: 0x10
+ size: 39
+ offset: 0x1E8
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x12000000
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 8FA14CDD754F91CCFFFFFFFF000000000166FAD58DE7366495DBFFFFFFFF00000100046D61696E
+ - sectname: __probes
+ segname: __PSEUDO_PROBE
+ addr: 0x2F1
+ size: 60
+ offset: 0x20F
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x12000000
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: FAD58DE7366495DB0201002001411FAE90F57226018000028FA14CDD754F91CC01000180008FA14CDD754F91CC02000020E99036E91302D08B018000
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 24
+ platform: 1
+ minos: 1703936
+ sdk: 1704960
+ ntools: 0
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 587
+ nsyms: 5
+ stroff: 667
+ strsize: 32
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 3
+ iextdefsym: 3
+ nextdefsym: 2
+ iundefsym: 5
+ nundefsym: 0
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 0
+ nindirectsyms: 0
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+LinkEditData:
+ NameList:
+ - n_strx: 22
+ n_type: 0xE
+ n_sect: 1
+ n_desc: 0
+ n_value: 0
+ - n_strx: 16
+ n_type: 0xE
+ n_sect: 2
+ n_desc: 0
+ n_value: 16
+ - n_strx: 10
+ n_type: 0xE
+ n_sect: 3
+ n_desc: 0
+ n_value: 753
+ - n_strx: 7
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 0
+ - n_strx: 1
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 8
+ StringTable:
+ - ''
+ - _main
+ - _f
+ - ltmp2
+ - ltmp1
+ - ltmp0
+ - ''
+ - ''
+ - ''
+ - ''
+...
diff --git a/llvm/test/tools/dsymutil/AArch64/pseudo-probe.test b/llvm/test/tools/dsymutil/AArch64/pseudo-probe.test
new file mode 100644
index 0000000000000..bf676af963c81
--- /dev/null
+++ b/llvm/test/tools/dsymutil/AArch64/pseudo-probe.test
@@ -0,0 +1,366 @@
+# REQUIRES: aarch64-registered-target
+# REQUIRES: host-byteorder-little-endian
+
+# RUN: rm -rf %t
+# RUN: split-file %s %t
+# RUN: mkdir -p %t
+# RUN: yaml2obj %t/a.yaml -o %t/a.o
+# RUN: yaml2obj %t/b.yaml -o %t/b.o
+
+# RUN: dsymutil --linker classic -y %t/debug.map -oso-prepend-path=%t -o %t/classic.dSYM
+# RUN: llvm-objdump --section-headers %t/classic.dSYM/Contents/Resources/Profiling/pseudo_probes \
+# RUN: | FileCheck %s --check-prefix=SIZE
+# RUN: llvm-readobj --sections %t/classic.dSYM/Contents/Resources/Profiling/pseudo_probes \
+# RUN: | FileCheck %s --check-prefix=SEG
+# RUN: llvm-objdump -s --section=__probes --section=__probe_descs \
+# RUN: %t/classic.dSYM/Contents/Resources/Profiling/pseudo_probes | FileCheck %s --check-prefix=DATA
+
+# RUN: dsymutil --linker parallel -y %t/debug.map -oso-prepend-path=%t -o %t/parallel.dSYM
+# RUN: llvm-objdump --section-headers %t/parallel.dSYM/Contents/Resources/Profiling/pseudo_probes \
+# RUN: | FileCheck %s --check-prefix=SIZE
+# RUN: llvm-readobj --sections %t/parallel.dSYM/Contents/Resources/Profiling/pseudo_probes \
+# RUN: | FileCheck %s --check-prefix=SEG
+# RUN: llvm-objdump -s --section=__probes --section=__probe_descs \
+# RUN: %t/parallel.dSYM/Contents/Resources/Profiling/pseudo_probes | FileCheck %s --check-prefix=DATA
+
+# SEG: Name: __probes
+# SEG-NEXT: Segment: __LLVM
+# SEG: Name: __probe_descs
+# SEG-NEXT: Segment: __LLVM
+
+# SIZE: __probes 00000040
+# SIZE: __probe_descs 00000024
+
+# DATA: Contents of section __LLVM,__probes:
+# DATA-NEXT: {{[0-9a-f]+}} 0cc175b9 c0f1b6a8 05000020 5c855e09
+# DATA-NEXT: {{[0-9a-f]+}} 4bdf284e 01800c02 80140380 0c048008
+# DATA-NEXT: {{[0-9a-f]+}} 92eb5ffe e6ae2fec 05000020 c716fb29
+# DATA-NEXT: {{[0-9a-f]+}} 298ad96a 01800c02 80140380 0c048008
+# DATA: Contents of section __LLVM,__probe_descs:
+# DATA-NEXT: {{[0-9a-f]+}} 0cc175b9 c0f1b6a8 94da52e8 10000000
+# DATA-NEXT: {{[0-9a-f]+}} 016192eb 5ffee6ae 2fec94da 52e81000
+# DATA-NEXT: {{[0-9a-f]+}} 00000162
+
+#--- debug.map
+---
+triple: 'arm64-apple-darwin'
+objects:
+ - filename: a.o
+ symbols: []
+ - filename: b.o
+ symbols: []
+...
+
+#--- a.yaml
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x0
+ filetype: 0x1
+ ncmds: 4
+ sizeofcmds: 520
+ flags: 0x2000
+ reserved: 0x0
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 392
+ segname: ''
+ vmaddr: 0
+ vmsize: 144
+ fileoff: 552
+ filesize: 144
+ maxprot: 7
+ initprot: 7
+ nsects: 4
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x0
+ size: 60
+ offset: 0x228
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: FF4300D1E00B00B9E80B40B9C800003401000014E80B40B908050011E80F00B90400001408008052E80F00B901000014E00F40B9FF430091C0035FD6
+ - sectname: __probe_descs
+ segname: __LLVM
+ addr: 0x3C
+ size: 18
+ offset: 0x264
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x12000000
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 0CC175B9C0F1B6A894DA52E8100000000161
+ - sectname: __compact_unwind
+ segname: __LD
+ addr: 0x50
+ size: 32
+ offset: 0x278
+ align: 3
+ reloff: 0x2B8
+ nreloc: 1
+ flags: 0x2000000
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 00000000000000003C0000000010000200000000000000000000000000000000
+ relocations:
+ - address: 0x0
+ symbolnum: 1
+ pcrel: false
+ length: 3
+ extern: false
+ type: 0
+ scattered: false
+ value: 0
+ - sectname: __probes
+ segname: __LLVM
+ addr: 0x70
+ size: 32
+ offset: 0x298
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x12000000
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 0CC175B9C0F1B6A8050000205C855E094BDF284E01800C02801403800C048008
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 24
+ platform: 1
+ minos: 1703936
+ sdk: 1704960
+ ntools: 0
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 704
+ nsyms: 5
+ stroff: 784
+ strsize: 32
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 4
+ iextdefsym: 4
+ nextdefsym: 1
+ iundefsym: 5
+ nundefsym: 0
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 0
+ nindirectsyms: 0
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+LinkEditData:
+ NameList:
+ - n_strx: 22
+ n_type: 0xE
+ n_sect: 1
+ n_desc: 0
+ n_value: 0
+ - n_strx: 16
+ n_type: 0xE
+ n_sect: 2
+ n_desc: 0
+ n_value: 60
+ - n_strx: 10
+ n_type: 0xE
+ n_sect: 3
+ n_desc: 0
+ n_value: 80
+ - n_strx: 4
+ n_type: 0xE
+ n_sect: 4
+ n_desc: 0
+ n_value: 112
+ - n_strx: 1
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 0
+ StringTable:
+ - ''
+ - _a
+ - ltmp3
+ - ltmp2
+ - ltmp1
+ - ltmp0
+ - ''
+ - ''
+ - ''
+ - ''
+...
+
+#--- b.yaml
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x0
+ filetype: 0x1
+ ncmds: 4
+ sizeofcmds: 520
+ flags: 0x2000
+ reserved: 0x0
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 392
+ segname: ''
+ vmaddr: 0
+ vmsize: 144
+ fileoff: 552
+ filesize: 144
+ maxprot: 7
+ initprot: 7
+ nsects: 4
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x0
+ size: 60
+ offset: 0x228
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: FF4300D1E00B00B9E80B40B9C800003401000014E80B40B908791F53E80F00B90400001428008052E80F00B901000014E00F40B9FF430091C0035FD6
+ - sectname: __probe_descs
+ segname: __LLVM
+ addr: 0x3C
+ size: 18
+ offset: 0x264
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x12000000
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 92EB5FFEE6AE2FEC94DA52E8100000000162
+ - sectname: __compact_unwind
+ segname: __LD
+ addr: 0x50
+ size: 32
+ offset: 0x278
+ align: 3
+ reloff: 0x2B8
+ nreloc: 1
+ flags: 0x2000000
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 00000000000000003C0000000010000200000000000000000000000000000000
+ relocations:
+ - address: 0x0
+ symbolnum: 1
+ pcrel: false
+ length: 3
+ extern: false
+ type: 0
+ scattered: false
+ value: 0
+ - sectname: __probes
+ segname: __LLVM
+ addr: 0x70
+ size: 32
+ offset: 0x298
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x12000000
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 92EB5FFEE6AE2FEC05000020C716FB29298AD96A01800C02801403800C048008
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 24
+ platform: 1
+ minos: 1703936
+ sdk: 1704960
+ ntools: 0
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 704
+ nsyms: 5
+ stroff: 784
+ strsize: 32
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 4
+ iextdefsym: 4
+ nextdefsym: 1
+ iundefsym: 5
+ nundefsym: 0
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 0
+ nindirectsyms: 0
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+LinkEditData:
+ NameList:
+ - n_strx: 22
+ n_type: 0xE
+ n_sect: 1
+ n_desc: 0
+ n_value: 0
+ - n_strx: 16
+ n_type: 0xE
+ n_sect: 2
+ n_desc: 0
+ n_value: 60
+ - n_strx: 10
+ n_type: 0xE
+ n_sect: 3
+ n_desc: 0
+ n_value: 80
+ - n_strx: 4
+ n_type: 0xE
+ n_sect: 4
+ n_desc: 0
+ n_value: 112
+ - n_strx: 1
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 0
+ StringTable:
+ - ''
+ - _b
+ - ltmp3
+ - ltmp2
+ - ltmp1
+ - ltmp0
+ - ''
+ - ''
+ - ''
+ - ''
+...
diff --git a/llvm/tools/dsymutil/CMakeLists.txt b/llvm/tools/dsymutil/CMakeLists.txt
index d3cdbe466de08..eeff3986fef88 100644
--- a/llvm/tools/dsymutil/CMakeLists.txt
+++ b/llvm/tools/dsymutil/CMakeLists.txt
@@ -33,6 +33,7 @@ add_llvm_tool(dsymutil
DwarfLinkerForBinary.cpp
MachODebugMapParser.cpp
MachOUtils.cpp
+ PseudoProbeLinker.cpp
Reproducer.cpp
RelocationMap.cpp
SwiftModule.cpp
diff --git a/llvm/tools/dsymutil/PseudoProbeLinker.cpp b/llvm/tools/dsymutil/PseudoProbeLinker.cpp
new file mode 100644
index 0000000000000..9848dc65e6bd4
--- /dev/null
+++ b/llvm/tools/dsymutil/PseudoProbeLinker.cpp
@@ -0,0 +1,184 @@
+//===- tools/dsymutil/PseudoProbeLinker.cpp -------------------------------===//
+//
+// 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 "PseudoProbeLinker.h"
+#include "BinaryHolder.h"
+#include "DebugMap.h"
+#include "LinkUtils.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/TargetParser/Triple.h"
+
+namespace llvm {
+namespace dsymutil {
+
+Error PseudoProbeLinker::emit(const Triple &TheTriple) const {
+ // Don't create the directory and the file if there is nothing to write.
+ if (empty())
+ return Error::success();
+
+ // Without a resource directory (e.g. --flat) there is no dSYM bundle to place
+ // the content. Nothing to do in this case.
+ if (!Options.ResourceDir)
+ return Error::success();
+
+ SmallString<128> Path;
+ sys::path::append(Path, *Options.ResourceDir, "Profiling");
+ if (std::error_code EC = sys::fs::create_directories(Path.str(), true,
+ sys::fs::perms::all_all))
+ return errorCodeToError(EC);
+
+ // For fat binaries, also append a dash and the architecture name.
+ sys::path::append(Path, "pseudo_probes");
+ if (Options.NumDebugMaps > 1) {
+ Path += '-';
+ Path += TheTriple.getArchName();
+ }
+
+ // Build the minimal MC machinery needed to write a MachO object holding the
+ // probe sections. All targets and their MC layers are registered by
+ // dsymutil_main.
+ std::string TripleName = TheTriple.getTriple();
+ std::string ErrorStr;
+ const Target *TheTarget = TargetRegistry::lookupTarget(TheTriple, ErrorStr);
+ if (!TheTarget)
+ return createStringError(inconvertibleErrorCode(), ErrorStr);
+
+ std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TheTriple));
+ if (!MRI)
+ return createStringError(inconvertibleErrorCode(),
+ "no register info for target " + TripleName);
+
+ MCTargetOptions MCOptions;
+ std::unique_ptr<MCAsmInfo> MAI(
+ TheTarget->createMCAsmInfo(*MRI, TheTriple, MCOptions));
+ if (!MAI)
+ return createStringError(inconvertibleErrorCode(),
+ "no asm info for target " + TripleName);
+
+ std::unique_ptr<MCSubtargetInfo> MSTI(
+ TheTarget->createMCSubtargetInfo(TheTriple, "", ""));
+ if (!MSTI)
+ return createStringError(inconvertibleErrorCode(),
+ "no subtarget info for target " + TripleName);
+
+ MCContext Ctx(TheTriple, *MAI, *MRI, *MSTI);
+ std::unique_ptr<MCObjectFileInfo> MOFI(
+ TheTarget->createMCObjectFileInfo(Ctx, /*PIC=*/false));
+ Ctx.setObjectFileInfo(MOFI.get());
+
+ std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
+ std::unique_ptr<MCCodeEmitter> MCE(TheTarget->createMCCodeEmitter(*MII, Ctx));
+ std::unique_ptr<MCAsmBackend> MAB(
+ TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions));
+ if (!MCE || !MAB)
+ return createStringError(inconvertibleErrorCode(),
+ "no code emitter/asm backend for target " +
+ TripleName);
+
+ std::error_code EC;
+ raw_fd_ostream OS(Options.NoOutput ? "-" : Path.str(), EC, sys::fs::OF_None);
+ if (EC)
+ return errorCodeToError(EC);
+
+ std::unique_ptr<MCObjectWriter> OW = MAB->createObjectWriter(OS);
+ std::unique_ptr<MCStreamer> MS(TheTarget->createMCObjectStreamer(
+ TheTriple, Ctx, std::move(MAB), std::move(OW), std::move(MCE), *MSTI));
+ if (!MS)
+ return createStringError(inconvertibleErrorCode(),
+ "no object streamer for target " + TripleName);
+
+ auto emitSection = [&](StringRef Name, StringRef Data) {
+ if (Data.empty())
+ return;
+ MCSectionMachO *Sec = Ctx.getMachOSection(
+ "__LLVM", Name, /*TypeAndAttributes=*/0, SectionKind::getMetadata());
+ MS->switchSection(Sec);
+ MS->emitBytes(Data);
+ };
+ emitSection("__probes", getProbes());
+ emitSection("__probe_descs", getProbeDescs());
+ MS->finish();
+
+ return Error::success();
+}
+
+bool PseudoProbeLinker::link(const DebugMap &Map) {
+ for (const auto &Obj : Map.objects()) {
+ // Load the object. Any load error is reported by the DWARF link; skip
+ // silently here to avoid duplicate diagnostics.
+ auto ObjectEntry =
+ BinHolder.getObjectEntry(Obj->getObjectFilename(), Obj->getTimestamp());
+ if (!ObjectEntry) {
+ consumeError(ObjectEntry.takeError());
+ continue;
+ }
+ auto Object = ObjectEntry->getObject(Map.getTriple());
+ if (!Object) {
+ consumeError(Object.takeError());
+ continue;
+ }
+
+ collect(*Object);
+ }
+
+ if (Error E = emit(Map.getTriple())) {
+ handleAllErrors(std::move(E), [](const ErrorInfoBase &EI) {
+ WithColor::error() << EI.message() << '\n';
+ });
+ return false;
+ }
+ return true;
+}
+
+void PseudoProbeLinker::collect(const object::ObjectFile &Obj) {
+ const auto *MO = dyn_cast<object::MachOObjectFile>(&Obj);
+ if (!MO)
+ return;
+
+ for (const object::SectionRef &Section : MO->sections()) {
+ Expected<StringRef> NameOrErr = Section.getName();
+ if (!NameOrErr) {
+ consumeError(NameOrErr.takeError());
+ continue;
+ }
+ std::string *Dest = nullptr;
+ if (*NameOrErr == "__probes")
+ Dest = &Probes;
+ else if (*NameOrErr == "__probe_descs")
+ Dest = &ProbeDescs;
+ else
+ continue;
+
+ Expected<StringRef> ContentsOrErr = Section.getContents();
+ if (!ContentsOrErr) {
+ consumeError(ContentsOrErr.takeError());
+ continue;
+ }
+ *Dest += *ContentsOrErr;
+ }
+}
+} // end namespace dsymutil
+} // end namespace llvm
diff --git a/llvm/tools/dsymutil/PseudoProbeLinker.h b/llvm/tools/dsymutil/PseudoProbeLinker.h
new file mode 100644
index 0000000000000..dbe2dab6ac765
--- /dev/null
+++ b/llvm/tools/dsymutil/PseudoProbeLinker.h
@@ -0,0 +1,55 @@
+//===- tools/dsymutil/PseudoProbeLinker.h ---------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_DSYMUTIL_PSEUDOPROBELINKER_H
+#define LLVM_TOOLS_DSYMUTIL_PSEUDOPROBELINKER_H
+
+#include "LinkUtils.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Error.h"
+#include <string>
+
+namespace llvm {
+class Triple;
+namespace dsymutil {
+
+class BinaryHolder;
+class DebugMap;
+
+/// Collect and merge the __probes and __probe_descs sections from the debug map
+/// object into the companion Contents/Resources/Profiling/pseudo_probes-<arch>.
+/// Note: the probe sections contain no relocations.
+class PseudoProbeLinker {
+ BinaryHolder &BinHolder;
+ const LinkOptions &Options;
+ std::string Probes;
+ std::string ProbeDescs;
+
+ Error emit(const Triple &TheTriple) const;
+
+public:
+ PseudoProbeLinker(BinaryHolder &BinHolder, const LinkOptions &Options)
+ : BinHolder(BinHolder), Options(Options) {}
+
+ /// Emit the collected probe sections as a single MachO object sidecar for the
+ /// \p TheTriple architecture. No-op if nothing was collected.
+ bool link(const DebugMap &Map);
+
+ /// Append the pseudo-probe sections found in \p Obj, if any.
+ void collect(const object::ObjectFile &Obj);
+
+ bool empty() const { return Probes.empty() && ProbeDescs.empty(); }
+ StringRef getProbes() const { return Probes; }
+ StringRef getProbeDescs() const { return ProbeDescs; }
+};
+
+} // end namespace dsymutil
+} // end namespace llvm
+
+#endif // LLVM_TOOLS_DSYMUTIL_PSEUDOPROBELINKER_H
diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp
index 45b9d68a03f16..78ce54ac95b7c 100644
--- a/llvm/tools/dsymutil/dsymutil.cpp
+++ b/llvm/tools/dsymutil/dsymutil.cpp
@@ -17,6 +17,7 @@
#include "DwarfLinkerForBinary.h"
#include "LinkUtils.h"
#include "MachOUtils.h"
+#include "PseudoProbeLinker.h"
#include "Reproducer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
@@ -953,6 +954,10 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) {
DwarfLinkerForBinary Linker(*Stream, BinHolder, Options.LinkOpts,
ErrorHandlerMutex);
AllOK.fetch_and(Linker.link(*Map));
+
+ PseudoProbeLinker ProbeLinker(BinHolder, Options.LinkOpts);
+ AllOK.fetch_and(ProbeLinker.link(*Map));
+
Stream->flush();
if (flagIsSet(Options.Verify, DWARFVerify::Output) ||
(flagIsSet(Options.Verify, DWARFVerify::OutputOnValidInput) &&
More information about the llvm-commits
mailing list