[lld-macho][nfc] define command UNWIND_MODE_MASK for convenience and rewrite mode...
authorVy Nguyen <vyng@google.com>
Thu, 6 Oct 2022 13:08:00 +0000 (09:08 -0400)
committerVy Nguyen <vyng@google.com>
Fri, 14 Oct 2022 19:16:40 +0000 (15:16 -0400)
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
lld/MachO/Target.h
lld/MachO/UnwindInfoSection.cpp

index 9c2051e..afd0e28 100644 (file)
@@ -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<uint32_t>(UNWIND_MODE_MASK)) ==
+        target->modeDwarfEncoding)
       continue;
 
     ConcatInputSection *referentIsec;
index 42c1142..44a8552 100644 (file)
@@ -20,6 +20,8 @@
 #include <cstddef>
 #include <cstdint>
 
+#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<uint32_t>(UNWIND_X86_64_MODE_MASK) ==
+                  static_cast<uint32_t>(UNWIND_X86_MODE_MASK) &&
+              static_cast<uint32_t>(UNWIND_ARM64_MODE_MASK) ==
+                  static_cast<uint32_t>(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 <class LP> TargetInfo(LP) {
index fa6f81d..610d879 100644 (file)
@@ -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<uint32_t>(UNWIND_X86_64_MODE_MASK) ==
-                static_cast<uint32_t>(UNWIND_X86_MODE_MASK));
   static_assert(static_cast<uint32_t>(UNWIND_X86_64_MODE_STACK_IND) ==
                 static_cast<uint32_t>(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.