Index: lld/MachO/UnwindInfoSection.cpp =================================================================== --- lld/MachO/UnwindInfoSection.cpp +++ lld/MachO/UnwindInfoSection.cpp @@ -256,7 +256,7 @@ // There should only be a handful of unique personality pointers, so we can // encode them as 2-bit indices into a small array. template -void encodePersonalities( +static void encodePersonalities( const std::vector *> &cuPtrVector, std::vector &personalities) { for (CompactUnwindEntry *cu : cuPtrVector) { @@ -280,6 +280,32 @@ ") for compact unwind to encode"); } +template +static void addEntriesForFunctionsWithoutUnwindInfo( + std::vector> &cuVector) { + DenseSet hasUnwindInfo; + for (CompactUnwindEntry &cuEntry : cuVector) + if (cuEntry.functionAddress != UINT64_MAX) + hasUnwindInfo.insert(cuEntry.functionAddress); + + // Add explicit "has no unwind info" entries for all global and local symbols + // without unwind info. + auto markNoUnwindInfo = [this, &hasUnwindInfo](const Defined *d) { + Ptr ptr = d->getVA(); + if (d->isLive() && isCodeSection(d->isec) && !hasUnwindInfo.count(ptr)) + cuVector.push_back({ptr, 0, 0, 0, 0}); + }; + for (Symbol *sym : symtab->getSymbols()) + if (auto *d = dyn_cast(sym)) + markNoUnwindInfo(d); + for (const InputFile *file : inputFiles) + if (auto *objFile = dyn_cast(file)) + for (Symbol *sym : objFile->symbols) + if (auto *d = dyn_cast_or_null(sym)) + if (!d->isExternal()) + markNoUnwindInfo(d); +} + // Scan the __LD,__compact_unwind entries and compute the space needs of // __TEXT,__unwind_info and __TEXT,__eh_frame template void UnwindInfoSectionImpl::finalize() { @@ -301,6 +327,8 @@ cuVector.resize(cuCount); relocateCompactUnwind(compactUnwindSection, cuVector); + addEntriesForFunctionsWithoutUnwindInfo(cuVector); + // Rather than sort & fold the 32-byte entries directly, we create a // vector of pointers to entries and sort & fold that instead. cuPtrVector.reserve(cuCount); Index: lld/test/MachO/tools/validate-unwind-info.py =================================================================== --- lld/test/MachO/tools/validate-unwind-info.py +++ lld/test/MachO/tools/validate-unwind-info.py @@ -37,9 +37,12 @@ if not object_encodings_map: sys.exit("no object encodings found in input") + # generate-cfi-funcs.py doesn't generate unwind info for _main. + object_encodings_map['_main'] = '00000000' + program_symbols_map = {address:symbol for address, symbol in - re.findall(r"^%s(%s) g\s+F __TEXT,__text (x\1)$" % (hex8, hex8), + re.findall(r"^%s(%s) g\s+F __TEXT,__text (x\1|_main)$" % (hex8, hex8), objdump_string, re.MULTILINE)} if not program_symbols_map: sys.exit("no program symbols found in input")