[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
This commit is contained in:
Vy Nguyen 2022-10-06 09:08:00 -04:00
parent 1fab0ac559
commit a6d6734a41
3 changed files with 14 additions and 4 deletions

View 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;

View 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) {

View 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.