From a6d6734a41f4960bf7447db4515e2acfd187fea0 Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Thu, 6 Oct 2022 09:08:00 -0400 Subject: [PATCH] [lld-macho][nfc] define command UNWIND_MODE_MASK for convenience and rewrite mode-mask checking logic for clarity The previous form is currently "harmless" and happened to work but may not in the future: Consider the struct: (for x86-64, but same issue can be said for the ARM/64 families): ``` UNWIND_X86_64_MODE_MASK = 0x0F000000, UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000, UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000, UNWIND_X86_64_MODE_STACK_IND = 0x03000000, UNWIND_X86_64_MODE_DWARF = 0x04000000, ``` Previously, we were doing: `(encoding & MODE_DWARF) == MODE_DWARF` As soon as a new `UNWIND_X86_64_MODE_FOO = 0x05000000` is defined, then the check above would always return true for encoding=MODE_FOO (because `(0b0101 & 0b0100) == 0b0100` ) Differential Revision: https://reviews.llvm.org/D135359 --- lld/MachO/InputFiles.cpp | 3 ++- lld/MachO/Target.h | 11 +++++++++++ lld/MachO/UnwindInfoSection.cpp | 4 +--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index 9c2051e..afd0e28 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -1096,7 +1096,8 @@ void ObjFile::registerCompactUnwind(Section &compactUnwindSection) { // llvm-mc omits CU entries for functions that need DWARF encoding, but // `ld -r` doesn't. We can ignore them because we will re-synthesize these // CU entries from the DWARF info during the output phase. - if ((encoding & target->modeDwarfEncoding) == target->modeDwarfEncoding) + if ((encoding & static_cast(UNWIND_MODE_MASK)) == + target->modeDwarfEncoding) continue; ConcatInputSection *referentIsec; diff --git a/lld/MachO/Target.h b/lld/MachO/Target.h index 42c1142..44a8552 100644 --- a/lld/MachO/Target.h +++ b/lld/MachO/Target.h @@ -20,6 +20,8 @@ #include #include +#include "mach-o/compact_unwind_encoding.h" + namespace lld::macho { LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); @@ -29,6 +31,15 @@ class DylibSymbol; class InputSection; class ObjFile; +static_assert(static_cast(UNWIND_X86_64_MODE_MASK) == + static_cast(UNWIND_X86_MODE_MASK) && + static_cast(UNWIND_ARM64_MODE_MASK) == + static_cast(UNWIND_X86_64_MODE_MASK)); + +// Since the mode masks have the same value on all targets, define +// a common one for convenience. +constexpr uint32_t UNWIND_MODE_MASK = UNWIND_X86_64_MODE_MASK; + class TargetInfo { public: template TargetInfo(LP) { diff --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp index fa6f81d..610d879 100644 --- a/lld/MachO/UnwindInfoSection.cpp +++ b/lld/MachO/UnwindInfoSection.cpp @@ -418,12 +418,10 @@ static bool canFoldEncoding(compact_unwind_encoding_t encoding) { // of the unwind info's unwind address, two functions that have identical // unwind info can't be folded if it's using this encoding since both // entries need unique addresses. - static_assert(static_cast(UNWIND_X86_64_MODE_MASK) == - static_cast(UNWIND_X86_MODE_MASK)); static_assert(static_cast(UNWIND_X86_64_MODE_STACK_IND) == static_cast(UNWIND_X86_MODE_STACK_IND)); if ((target->cpuType == CPU_TYPE_X86_64 || target->cpuType == CPU_TYPE_X86) && - (encoding & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_STACK_IND) { + (encoding & UNWIND_MODE_MASK) == UNWIND_X86_64_MODE_STACK_IND) { // FIXME: Consider passing in the two function addresses and getting // their two stack sizes off the `subq` and only returning false if they're // actually different. -- 2.7.4