[lld] [lld-macho] Fix compatibility between --icf=safe_thunks and --keep-icf-stabs (PR #116687)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 19 15:42:47 PST 2024
https://github.com/alx32 updated https://github.com/llvm/llvm-project/pull/116687
>From 474d9a2696d2c296e98869fa3cd7bff3e96e5a32 Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Sat, 16 Nov 2024 06:28:17 -0800
Subject: [PATCH 1/5] [lld-macho] Fix safe_thunks / --keep-icf-stabs
compatibility
---
lld/MachO/Arch/ARM64.cpp | 11 +++++
lld/MachO/ICF.cpp | 28 +++++++++++
lld/MachO/ICF.h | 6 +++
lld/MachO/SyntheticSections.cpp | 62 +++++++++++++------------
lld/MachO/SyntheticSections.h | 1 +
lld/MachO/Target.h | 6 +++
lld/test/MachO/icf-safe-thunks-dwarf.ll | 53 +++++++++++++++++++++
7 files changed, 138 insertions(+), 29 deletions(-)
diff --git a/lld/MachO/Arch/ARM64.cpp b/lld/MachO/Arch/ARM64.cpp
index 195a8f09f47c1a..882873ae5de0c1 100644
--- a/lld/MachO/Arch/ARM64.cpp
+++ b/lld/MachO/Arch/ARM64.cpp
@@ -44,6 +44,7 @@ struct ARM64 : ARM64Common {
void initICFSafeThunkBody(InputSection *thunk,
InputSection *branchTarget) const override;
+ InputSection *getThunkBranchTarget(InputSection *thunk) const override;
uint32_t getICFSafeThunkSize() const override;
};
@@ -197,6 +198,16 @@ void ARM64::initICFSafeThunkBody(InputSection *thunk,
/*referent=*/branchTarget);
}
+InputSection *ARM64::getThunkBranchTarget(InputSection *thunk) const {
+ assert(thunk->relocs.size() == 1 &&
+ "expected a single reloc on ARM64 ICF thunk");
+ auto &reloc = thunk->relocs[0];
+ assert(reloc.referent.is<InputSection *>() &&
+ "ARM64 thunk reloc is expected to point to an InputSection");
+
+ return reloc.referent.dyn_cast<InputSection *>();
+}
+
uint32_t ARM64::getICFSafeThunkSize() const { return sizeof(icfSafeThunkCode); }
ARM64::ARM64() : ARM64Common(LP64()) {
diff --git a/lld/MachO/ICF.cpp b/lld/MachO/ICF.cpp
index aedaecfdeb2c01..451aaa7caaf0c1 100644
--- a/lld/MachO/ICF.cpp
+++ b/lld/MachO/ICF.cpp
@@ -481,6 +481,34 @@ void macho::markAddrSigSymbols() {
}
}
+// Given a symbol that was folded into a thunk, return the symbol pointing to
+// the actual body of the function. We use this approach rather than storing the
+// needed info in the Defined itself in order to minimize memory usage.
+Defined *macho::getBodyForThunkFoldedSym(Defined *foldedSym) {
+ assert(isa<ConcatInputSection>(foldedSym->originalIsec) &&
+ "thunk-folded ICF symbol expected to be on a ConcatInputSection");
+ // foldedSec is the InputSection that was marked as deleted upon fold
+ ConcatInputSection *foldedSec =
+ cast<ConcatInputSection>(foldedSym->originalIsec);
+
+ // thunkBody is the actual live thunk, containing the code that branches to
+ // the actual body of the function.
+ InputSection *thunkBody = foldedSec->replacement;
+
+ // the actual (merged) body of the function that the thunk jumps to. This will
+ // end up in the final binary.
+ InputSection *functionBody = target->getThunkBranchTarget(thunkBody);
+
+ for (Symbol *sym : functionBody->symbols) {
+ Defined *d = dyn_cast<Defined>(sym);
+ // The symbol needs to be at the start of the InputSection
+ if (d && d->value == 0)
+ return d;
+ }
+
+ llvm_unreachable("could not find body symbol for ICF-generated thunk");
+ return nullptr;
+}
void macho::foldIdenticalSections(bool onlyCfStrings) {
TimeTraceScope timeScope("Fold Identical Code Sections");
// The ICF equivalence-class segregation algorithm relies on pre-computed
diff --git a/lld/MachO/ICF.h b/lld/MachO/ICF.h
index 34ceb1cf284bf3..e382fd6c60956c 100644
--- a/lld/MachO/ICF.h
+++ b/lld/MachO/ICF.h
@@ -15,11 +15,17 @@
namespace lld::macho {
class Symbol;
+class Defined;
void markAddrSigSymbols();
void markSymAsAddrSig(Symbol *s);
void foldIdenticalSections(bool onlyCfStrings);
+// Given a symbol that was folded into a thunk, return the symbol pointing to
+// the actual body of the function. We expose this function to allow getting the
+// main function body for a symbol that was folded via a thunk.
+Defined *getBodyForThunkFoldedSym(Defined *foldedSym);
+
} // namespace lld::macho
#endif
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index eee87b3a6cb4de..7e0ba8d501c994 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -10,6 +10,7 @@
#include "ConcatOutputSection.h"
#include "Config.h"
#include "ExportTrie.h"
+#include "ICF.h"
#include "InputFiles.h"
#include "MachOStructs.h"
#include "ObjC.h"
@@ -1204,6 +1205,14 @@ void SymtabSection::emitEndFunStab(Defined *defined) {
stabs.emplace_back(std::move(stab));
}
+Defined *SymtabSection::getFuncBodySym(Defined *originalSym) {
+ // If the Defined is not a thunk, we can use it directly
+ if (originalSym->identicalCodeFoldingKind != Symbol::ICFFoldKind::Thunk)
+ return originalSym;
+
+ return macho::getBodyForThunkFoldedSym(originalSym);
+}
+
void SymtabSection::emitStabs() {
if (config->omitDebugInfo)
return;
@@ -1214,9 +1223,14 @@ void SymtabSection::emitStabs() {
stabs.emplace_back(std::move(astStab));
}
- // Cache the file ID for each symbol in an std::pair for faster sorting.
- using SortingPair = std::pair<Defined *, int>;
- std::vector<SortingPair> symbolsNeedingStabs;
+ struct SymbolStabInfo {
+ Defined *originalSym; // Original Defined symbol - this may be an ICF thunk
+ int fileId; // File ID associated with the STABS symbol
+ Defined *mainBodySym; // Symbol that consists of the full function body -
+ // use this for the STABS entry
+ };
+
+ std::vector<SymbolStabInfo> symbolsNeedingStabs;
for (const SymtabEntry &entry :
concat<SymtabEntry>(localSymbols, externalSymbols)) {
Symbol *sym = entry.sym;
@@ -1229,20 +1243,10 @@ void SymtabSection::emitStabs() {
if (defined->isAbsolute())
continue;
- // Never generate a STABS entry for a symbol that has been ICF'ed using a
- // thunk, just as we do for fully ICF'ed functions. Otherwise, we end up
- // generating invalid DWARF as dsymutil will assume the entire function
- // body is at that location, when, in reality, only the thunk is
- // present. This will end up causing overlapping DWARF entries.
- // TODO: Find an implementation that works in combination with
- // `--keep-icf-stabs`.
- if (defined->identicalCodeFoldingKind == Symbol::ICFFoldKind::Thunk)
- continue;
-
// Constant-folded symbols go in the executable's symbol table, but don't
- // get a stabs entry unless --keep-icf-stabs flag is specified
+ // get a stabs entry unless --keep-icf-stabs flag is specified.
if (!config->keepICFStabs &&
- defined->identicalCodeFoldingKind == Symbol::ICFFoldKind::Body)
+ defined->identicalCodeFoldingKind != Symbol::ICFFoldKind::None)
continue;
ObjFile *file = defined->getObjectFile();
@@ -1251,26 +1255,26 @@ void SymtabSection::emitStabs() {
// We use 'originalIsec' to get the file id of the symbol since 'isec()'
// might point to the merged ICF symbol's file
- symbolsNeedingStabs.emplace_back(defined,
- defined->originalIsec->getFile()->id);
+ Defined *funcBodySym = getFuncBodySym(defined);
+ symbolsNeedingStabs.emplace_back(SymbolStabInfo{
+ defined, funcBodySym->originalIsec->getFile()->id, funcBodySym});
}
}
llvm::stable_sort(symbolsNeedingStabs,
- [&](const SortingPair &a, const SortingPair &b) {
- return a.second < b.second;
+ [&](const SymbolStabInfo &a, const SymbolStabInfo &b) {
+ return a.fileId < b.fileId;
});
// Emit STABS symbols so that dsymutil and/or the debugger can map address
// regions in the final binary to the source and object files from which they
// originated.
InputFile *lastFile = nullptr;
- for (SortingPair &pair : symbolsNeedingStabs) {
- Defined *defined = pair.first;
+ for (const SymbolStabInfo &info : symbolsNeedingStabs) {
// We use 'originalIsec' of the symbol since we care about the actual origin
// of the symbol, not the canonical location returned by `isec()`.
- InputSection *isec = defined->originalIsec;
- ObjFile *file = cast<ObjFile>(isec->getFile());
+ InputSection *bodyIsec = info.mainBodySym->originalIsec;
+ ObjFile *file = cast<ObjFile>(bodyIsec->getFile());
if (lastFile == nullptr || lastFile != file) {
if (lastFile != nullptr)
@@ -1282,16 +1286,16 @@ void SymtabSection::emitStabs() {
}
StabsEntry symStab;
- symStab.sect = isec->parent->index;
- symStab.strx = stringTableSection.addString(defined->getName());
- symStab.value = defined->getVA();
+ symStab.sect = bodyIsec->parent->index;
+ symStab.strx = stringTableSection.addString(info.originalSym->getName());
+ symStab.value = info.mainBodySym->getVA();
- if (isCodeSection(isec)) {
+ if (isCodeSection(bodyIsec)) {
symStab.type = N_FUN;
stabs.emplace_back(std::move(symStab));
- emitEndFunStab(defined);
+ emitEndFunStab(info.mainBodySym);
} else {
- symStab.type = defined->isExternal() ? N_GSYM : N_STSYM;
+ symStab.type = info.originalSym->isExternal() ? N_GSYM : N_STSYM;
stabs.emplace_back(std::move(symStab));
}
}
diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h
index a4c7f58481aa14..af99f22788d6e9 100644
--- a/lld/MachO/SyntheticSections.h
+++ b/lld/MachO/SyntheticSections.h
@@ -485,6 +485,7 @@ class SymtabSection : public LinkEditSection {
void emitEndSourceStab();
void emitObjectFileStab(ObjFile *);
void emitEndFunStab(Defined *);
+ Defined *getFuncBodySym(Defined *);
void emitStabs();
protected:
diff --git a/lld/MachO/Target.h b/lld/MachO/Target.h
index eaa0336e70cb6b..b5b80e083a6c34 100644
--- a/lld/MachO/Target.h
+++ b/lld/MachO/Target.h
@@ -80,6 +80,12 @@ class TargetInfo {
llvm_unreachable("target does not support ICF safe thunks");
}
+ // Given a thunk for which `initICFSafeThunkBody` was called, return the
+ // branchTarget it was initialized with.
+ virtual InputSection *getThunkBranchTarget(InputSection *thunk) const {
+ llvm_unreachable("target does not support ICF safe thunks");
+ }
+
virtual uint32_t getICFSafeThunkSize() const {
llvm_unreachable("target does not support ICF safe thunks");
}
diff --git a/lld/test/MachO/icf-safe-thunks-dwarf.ll b/lld/test/MachO/icf-safe-thunks-dwarf.ll
index 1e4422a3313239..9edad60946837e 100644
--- a/lld/test/MachO/icf-safe-thunks-dwarf.ll
+++ b/lld/test/MachO/icf-safe-thunks-dwarf.ll
@@ -20,6 +20,59 @@
; VERIFY-STABS: N_FUN{{.*}}_func_A
; VERIFY-STABS: N_FUN{{.*}}_take_func_addr
+;;;;;;;;;;;;;;;;;;;;;;;;;;;; Check safe_thunks ICF + keeping STABS entries ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Check scenario with where we do safe_thunks ICF and also generate STABS entries
+; RUN: %lld -arch arm64 -lSystem --icf=safe_thunks --keep-icf-stabs -dylib -o %t/a_thunks.dylib %t/a.o
+; RUN: dsymutil -s %t/a_thunks.dylib > %t/a_thunks.txt
+
+
+; RUN: dsymutil --flat --verify-dwarf=none %t/a_thunks.dylib -o %t/a_thunks.dSYM
+; RUN: dsymutil -s %t/a_thunks.dSYM >> %t/a_thunks.txt
+; RUN: llvm-dwarfdump -a %t/a_thunks.dSYM >> %t/a_thunks.txt
+
+; RUN: cat %t/a_thunks.txt | FileCheck %s --check-prefix=VERIFY-THUNK
+
+# VERIFY-THUNK-LABEL: Symbol table for: '{{.*}}/a_thunks.dylib'
+# Capture the 'n_value's for N_FUN entries of _func_A, _func_B, and _func_C
+# VERIFY-THUNK: [[MERGED_FUN_ADDR:[0-9a-f]+]] '_func_A'
+# VERIFY-THUNK: [[MERGED_FUN_ADDR]] '_func_B'
+# VERIFY-THUNK: [[MERGED_FUN_ADDR]] '_func_C'
+
+# Capture the 'n_value's for SECT EXT entries in the first part
+# VERIFY-THUNK: SECT EXT{{.*}} [[SECT_EXT_A_NVALUE:[0-9a-f]+]] '_func_A'
+# VERIFY-THUNK: SECT EXT{{.*}} [[SECT_EXT_B_NVALUE:[0-9a-f]+]] '_func_B'
+# VERIFY-THUNK: SECT EXT{{.*}} [[SECT_EXT_C_NVALUE:[0-9a-f]+]] '_func_C'
+
+# VERIFY-THUNK: ----------------------------------------------------------------------
+# VERIFY-THUNK-LABEL: Symbol table for: '{{.*}}/a_thunks.dSYM'
+
+# Verify that the SECT EXT 'n_value's in the second part match the first part
+# VERIFY-THUNK: SECT EXT{{.*}} [[SECT_EXT_A_NVALUE]] '_func_A'
+# VERIFY-THUNK: SECT EXT{{.*}} [[SECT_EXT_B_NVALUE]] '_func_B'
+# VERIFY-THUNK: SECT EXT{{.*}} [[SECT_EXT_C_NVALUE]] '_func_C'
+
+# Ensure that N_FUN 'n_value's match the DW_TAG_subprogram's DW_AT_low_pc
+# and that the DW_AT_name is at a specific relative position
+
+# VERIFY-THUNK-LABEL: .debug_info contents:
+# VERIFY-THUNK: Compile Unit: length = {{.*}}
+
+# Match the subprogram for func_A
+# VERIFY-THUNK: : DW_TAG_subprogram
+# VERIFY-THUNK-NEXT: {{ +}}DW_AT_low_pc (0x[[MERGED_FUN_ADDR]])
+# VERIFY-THUNK-NEXT-NEXT-NEXT-NEXT-NEXT: {{ +}}DW_AT_name ("func_A")
+
+# Match the subprogram for func_B
+# VERIFY-THUNK: : DW_TAG_subprogram
+# VERIFY-THUNK-NEXT: {{ +}}DW_AT_low_pc (0x[[MERGED_FUN_ADDR]])
+# VERIFY-THUNK-NEXT-NEXT-NEXT-NEXT-NEXT: {{ +}}DW_AT_name ("func_B")
+
+# Match the subprogram for func_C
+# VERIFY-THUNK: : DW_TAG_subprogram
+# VERIFY-THUNK-NEXT: {{ +}}DW_AT_low_pc (0x[[MERGED_FUN_ADDR]])
+# VERIFY-THUNK-NEXT-NEXT-NEXT-NEXT-NEXT: {{ +}}DW_AT_name ("func_C")
+
;--- a.cpp
#define ATTR __attribute__((noinline)) extern "C"
typedef unsigned long long ULL;
>From 5ab60755500acf8542af4eeac74d3ba2bee57fa2 Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Mon, 18 Nov 2024 17:08:23 -0800
Subject: [PATCH 2/5] Address feedback nr.1
---
lld/MachO/ICF.cpp | 1 -
lld/MachO/SyntheticSections.cpp | 18 ++++++++++--------
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/lld/MachO/ICF.cpp b/lld/MachO/ICF.cpp
index 451aaa7caaf0c1..a20da12b097f2d 100644
--- a/lld/MachO/ICF.cpp
+++ b/lld/MachO/ICF.cpp
@@ -507,7 +507,6 @@ Defined *macho::getBodyForThunkFoldedSym(Defined *foldedSym) {
}
llvm_unreachable("could not find body symbol for ICF-generated thunk");
- return nullptr;
}
void macho::foldIdenticalSections(bool onlyCfStrings) {
TimeTraceScope timeScope("Fold Identical Code Sections");
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index 7e0ba8d501c994..7c76de1cca00f6 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -1205,8 +1205,11 @@ void SymtabSection::emitEndFunStab(Defined *defined) {
stabs.emplace_back(std::move(stab));
}
+// Given a pointer to a function symbol, return the symbol that points to the
+// actual function body that will go in the final binary. Generally this is the
+// symbol itself, but if the symbol was folded using a thunk, we retrieve the
+// target function body from the thunk.
Defined *SymtabSection::getFuncBodySym(Defined *originalSym) {
- // If the Defined is not a thunk, we can use it directly
if (originalSym->identicalCodeFoldingKind != Symbol::ICFFoldKind::Thunk)
return originalSym;
@@ -1226,8 +1229,6 @@ void SymtabSection::emitStabs() {
struct SymbolStabInfo {
Defined *originalSym; // Original Defined symbol - this may be an ICF thunk
int fileId; // File ID associated with the STABS symbol
- Defined *mainBodySym; // Symbol that consists of the full function body -
- // use this for the STABS entry
};
std::vector<SymbolStabInfo> symbolsNeedingStabs;
@@ -1256,8 +1257,8 @@ void SymtabSection::emitStabs() {
// We use 'originalIsec' to get the file id of the symbol since 'isec()'
// might point to the merged ICF symbol's file
Defined *funcBodySym = getFuncBodySym(defined);
- symbolsNeedingStabs.emplace_back(SymbolStabInfo{
- defined, funcBodySym->originalIsec->getFile()->id, funcBodySym});
+ symbolsNeedingStabs.emplace_back(
+ SymbolStabInfo{defined, funcBodySym->originalIsec->getFile()->id});
}
}
@@ -1273,7 +1274,8 @@ void SymtabSection::emitStabs() {
for (const SymbolStabInfo &info : symbolsNeedingStabs) {
// We use 'originalIsec' of the symbol since we care about the actual origin
// of the symbol, not the canonical location returned by `isec()`.
- InputSection *bodyIsec = info.mainBodySym->originalIsec;
+ Defined *funcBodySym = getFuncBodySym(info.originalSym);
+ InputSection *bodyIsec = funcBodySym->originalIsec;
ObjFile *file = cast<ObjFile>(bodyIsec->getFile());
if (lastFile == nullptr || lastFile != file) {
@@ -1288,12 +1290,12 @@ void SymtabSection::emitStabs() {
StabsEntry symStab;
symStab.sect = bodyIsec->parent->index;
symStab.strx = stringTableSection.addString(info.originalSym->getName());
- symStab.value = info.mainBodySym->getVA();
+ symStab.value = funcBodySym->getVA();
if (isCodeSection(bodyIsec)) {
symStab.type = N_FUN;
stabs.emplace_back(std::move(symStab));
- emitEndFunStab(info.mainBodySym);
+ emitEndFunStab(funcBodySym);
} else {
symStab.type = info.originalSym->isExternal() ? N_GSYM : N_STSYM;
stabs.emplace_back(std::move(symStab));
>From 56d75f47f4ad59597b452c192c275692e7fbee9b Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Mon, 18 Nov 2024 23:09:34 -0800
Subject: [PATCH 3/5] Address Feedbak Nr.2
---
lld/MachO/SyntheticSections.cpp | 33 +++++++++++++++------------------
1 file changed, 15 insertions(+), 18 deletions(-)
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index 7c76de1cca00f6..a897a8889bd1f6 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -1226,12 +1226,9 @@ void SymtabSection::emitStabs() {
stabs.emplace_back(std::move(astStab));
}
- struct SymbolStabInfo {
- Defined *originalSym; // Original Defined symbol - this may be an ICF thunk
- int fileId; // File ID associated with the STABS symbol
- };
-
- std::vector<SymbolStabInfo> symbolsNeedingStabs;
+ // Cache the file ID for each symbol in an std::pair for faster sorting.
+ using SortingPair = std::pair<Defined *, int>;
+ std::vector<SortingPair> symbolsNeedingStabs;
for (const SymtabEntry &entry :
concat<SymtabEntry>(localSymbols, externalSymbols)) {
Symbol *sym = entry.sym;
@@ -1256,27 +1253,27 @@ void SymtabSection::emitStabs() {
// We use 'originalIsec' to get the file id of the symbol since 'isec()'
// might point to the merged ICF symbol's file
- Defined *funcBodySym = getFuncBodySym(defined);
symbolsNeedingStabs.emplace_back(
- SymbolStabInfo{defined, funcBodySym->originalIsec->getFile()->id});
+ defined, getFuncBodySym(defined)->originalIsec->getFile()->id);
}
}
llvm::stable_sort(symbolsNeedingStabs,
- [&](const SymbolStabInfo &a, const SymbolStabInfo &b) {
- return a.fileId < b.fileId;
+ [&](const SortingPair &a, const SortingPair &b) {
+ return a.second < b.second;
});
// Emit STABS symbols so that dsymutil and/or the debugger can map address
// regions in the final binary to the source and object files from which they
// originated.
InputFile *lastFile = nullptr;
- for (const SymbolStabInfo &info : symbolsNeedingStabs) {
+ for (SortingPair &pair : symbolsNeedingStabs) {
+ Defined *defined = pair.first;
// We use 'originalIsec' of the symbol since we care about the actual origin
// of the symbol, not the canonical location returned by `isec()`.
- Defined *funcBodySym = getFuncBodySym(info.originalSym);
- InputSection *bodyIsec = funcBodySym->originalIsec;
- ObjFile *file = cast<ObjFile>(bodyIsec->getFile());
+ Defined *funcBodySym = getFuncBodySym(defined);
+ InputSection *isec = funcBodySym->originalIsec;
+ ObjFile *file = cast<ObjFile>(isec->getFile());
if (lastFile == nullptr || lastFile != file) {
if (lastFile != nullptr)
@@ -1288,16 +1285,16 @@ void SymtabSection::emitStabs() {
}
StabsEntry symStab;
- symStab.sect = bodyIsec->parent->index;
- symStab.strx = stringTableSection.addString(info.originalSym->getName());
+ symStab.sect = isec->parent->index;
+ symStab.strx = stringTableSection.addString(defined->getName());
symStab.value = funcBodySym->getVA();
- if (isCodeSection(bodyIsec)) {
+ if (isCodeSection(isec)) {
symStab.type = N_FUN;
stabs.emplace_back(std::move(symStab));
emitEndFunStab(funcBodySym);
} else {
- symStab.type = info.originalSym->isExternal() ? N_GSYM : N_STSYM;
+ symStab.type = defined->isExternal() ? N_GSYM : N_STSYM;
stabs.emplace_back(std::move(symStab));
}
}
>From ee3c683da86d7c0ebace50bd02971c404587137d Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Tue, 19 Nov 2024 14:37:29 -0800
Subject: [PATCH 4/5] Address Feedbak Nr.3
---
lld/MachO/SyntheticSections.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index a897a8889bd1f6..24844c2f3a1eb2 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -1210,7 +1210,8 @@ void SymtabSection::emitEndFunStab(Defined *defined) {
// symbol itself, but if the symbol was folded using a thunk, we retrieve the
// target function body from the thunk.
Defined *SymtabSection::getFuncBodySym(Defined *originalSym) {
- if (originalSym->identicalCodeFoldingKind != Symbol::ICFFoldKind::Thunk)
+ if (originalSym->identicalCodeFoldingKind == Symbol::ICFFoldKind::None ||
+ originalSym->identicalCodeFoldingKind == Symbol::ICFFoldKind::Body)
return originalSym;
return macho::getBodyForThunkFoldedSym(originalSym);
>From 4d38f9677eb1df567f791ac475aac99f5995c996 Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Tue, 19 Nov 2024 15:42:35 -0800
Subject: [PATCH 5/5] Address Feedback Nr.4
---
lld/MachO/ICF.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lld/MachO/ICF.cpp b/lld/MachO/ICF.cpp
index a20da12b097f2d..32dd44ab729e61 100644
--- a/lld/MachO/ICF.cpp
+++ b/lld/MachO/ICF.cpp
@@ -495,7 +495,7 @@ Defined *macho::getBodyForThunkFoldedSym(Defined *foldedSym) {
// the actual body of the function.
InputSection *thunkBody = foldedSec->replacement;
- // the actual (merged) body of the function that the thunk jumps to. This will
+ // The actual (merged) body of the function that the thunk jumps to. This will
// end up in the final binary.
InputSection *functionBody = target->getThunkBranchTarget(thunkBody);
More information about the llvm-commits
mailing list