[lld][MachO] Make emitEndFunStab independent from .subsections_via_symbols

This diff addresses FIXME in SyntheticSections.cpp and removes
the dependency of emitEndFunStab on .subsections_via_symbols.

Test plan: make check-lld-macho

Differential revision: https://reviews.llvm.org/D99054

GitOrigin-RevId: f6ad0453665f63cf036fcb01f26fb4f023e4cfbb
diff --git a/MachO/Driver.cpp b/MachO/Driver.cpp
index 267adbc..befaf67 100644
--- a/MachO/Driver.cpp
+++ b/MachO/Driver.cpp
@@ -531,6 +531,7 @@
     inputSections.push_back(isec);
 
     replaceSymbol<Defined>(sym, sym->getName(), isec->file, isec, /*value=*/0,
+                           /*size=*/0,
                            /*isWeakDef=*/false,
                            /*isExternal=*/true, common->privateExtern);
   }
diff --git a/MachO/InputFiles.cpp b/MachO/InputFiles.cpp
index d37db36..e31c506 100644
--- a/MachO/InputFiles.cpp
+++ b/MachO/InputFiles.cpp
@@ -332,7 +332,7 @@
 
 static macho::Symbol *createDefined(const structs::nlist_64 &sym,
                                     StringRef name, InputSection *isec,
-                                    uint64_t value) {
+                                    uint64_t value, uint64_t size) {
   // Symbol scope is determined by sym.n_type & (N_EXT | N_PEXT):
   // N_EXT: Global symbols
   // N_EXT | N_PEXT: Linkage unit (think: dylib) scoped
@@ -342,10 +342,11 @@
 
   if (sym.n_type & (N_EXT | N_PEXT)) {
     assert((sym.n_type & N_EXT) && "invalid input");
-    return symtab->addDefined(name, isec->file, isec, value,
+    return symtab->addDefined(name, isec->file, isec, value, size,
                               sym.n_desc & N_WEAK_DEF, sym.n_type & N_PEXT);
   }
-  return make<Defined>(name, isec->file, isec, value, sym.n_desc & N_WEAK_DEF,
+  return make<Defined>(name, isec->file, isec, value, size,
+                       sym.n_desc & N_WEAK_DEF,
                        /*isExternal=*/false, /*isPrivateExtern=*/false);
 }
 
@@ -381,10 +382,11 @@
                                      InputFile *file, StringRef name) {
   if (sym.n_type & (N_EXT | N_PEXT)) {
     assert((sym.n_type & N_EXT) && "invalid input");
-    return symtab->addDefined(name, file, nullptr, sym.n_value,
+    return symtab->addDefined(name, file, nullptr, sym.n_value, /*size=*/0,
                               /*isWeakDef=*/false, sym.n_type & N_PEXT);
   }
-  return make<Defined>(name, file, nullptr, sym.n_value, /*isWeakDef=*/false,
+  return make<Defined>(name, file, nullptr, sym.n_value, /*size=*/0,
+                       /*isWeakDef=*/false,
                        /*isExternal=*/false, /*isPrivateExtern=*/false);
 }
 
@@ -477,16 +479,25 @@
 
     uint64_t offset = sym.n_value - sec.addr;
 
+    auto it = llvm::upper_bound(
+        subsecMap, offset, [](int64_t value, SubsectionEntry subsectionEntry) {
+          return value < subsectionEntry.offset;
+        });
+    uint32_t size = it != subsecMap.end()
+                        ? it->offset - offset
+                        : subsecMap.front().isec->getSize() - offset;
+
     // If the input file does not use subsections-via-symbols, all symbols can
     // use the same subsection. Otherwise, we must split the sections along
     // symbol boundaries.
     if (!subsectionsViaSymbols) {
-      symbols[i] = createDefined(sym, name, subsecMap.front().isec, offset);
+      symbols[i] =
+          createDefined(sym, name, subsecMap.front().isec, offset, size);
       continue;
     }
 
-    InputSection *subsec = findContainingSubsection(subsecMap, &offset);
-    symbols[i] = createDefined(sym, name, subsec, offset);
+    InputSection *subsec = (--it)->isec;
+    symbols[i] = createDefined(sym, name, subsec, offset - it->offset, size);
   }
 
   if (!subsectionsViaSymbols)
@@ -864,7 +875,7 @@
   }
 
   return symtab->addDefined(name, &file, /*isec=*/nullptr, /*value=*/0,
-                            objSym.isWeak(), isPrivateExtern);
+                            /*size=*/0, objSym.isWeak(), isPrivateExtern);
 }
 
 BitcodeFile::BitcodeFile(MemoryBufferRef mbref)
diff --git a/MachO/SymbolTable.cpp b/MachO/SymbolTable.cpp
index 311c001..0a565b3 100644
--- a/MachO/SymbolTable.cpp
+++ b/MachO/SymbolTable.cpp
@@ -38,8 +38,9 @@
 }
 
 Defined *SymbolTable::addDefined(StringRef name, InputFile *file,
-                                 InputSection *isec, uint32_t value,
-                                 bool isWeakDef, bool isPrivateExtern) {
+                                 InputSection *isec, uint64_t value,
+                                 uint64_t size, bool isWeakDef,
+                                 bool isPrivateExtern) {
   Symbol *s;
   bool wasInserted;
   bool overridesWeakDef = false;
@@ -66,7 +67,7 @@
   }
 
   Defined *defined =
-      replaceSymbol<Defined>(s, name, file, isec, value, isWeakDef,
+      replaceSymbol<Defined>(s, name, file, isec, value, size, isWeakDef,
                              /*isExternal=*/true, isPrivateExtern);
   defined->overridesWeakDef = overridesWeakDef;
   return defined;
@@ -160,7 +161,7 @@
 Defined *SymbolTable::addSynthetic(StringRef name, InputSection *isec,
                                    uint32_t value, bool isPrivateExtern,
                                    bool includeInSymtab) {
-  Defined *s = addDefined(name, nullptr, isec, value,
+  Defined *s = addDefined(name, nullptr, isec, value, /*size*/ 0,
                           /*isWeakDef=*/false, isPrivateExtern);
   s->includeInSymtab = includeInSymtab;
   return s;
diff --git a/MachO/SymbolTable.h b/MachO/SymbolTable.h
index 9aed8c9..8a5c16c 100644
--- a/MachO/SymbolTable.h
+++ b/MachO/SymbolTable.h
@@ -38,7 +38,8 @@
 class SymbolTable {
 public:
   Defined *addDefined(StringRef name, InputFile *, InputSection *,
-                      uint32_t value, bool isWeakDef, bool isPrivateExtern);
+                      uint64_t value, uint64_t size, bool isWeakDef,
+                      bool isPrivateExtern);
 
   Symbol *addUndefined(StringRef name, InputFile *, bool isWeakRef);
 
diff --git a/MachO/Symbols.h b/MachO/Symbols.h
index 8a3004a..cb678ac 100644
--- a/MachO/Symbols.h
+++ b/MachO/Symbols.h
@@ -95,9 +95,9 @@
 
 class Defined : public Symbol {
 public:
-  Defined(StringRefZ name, InputFile *file, InputSection *isec, uint32_t value,
-          bool isWeakDef, bool isExternal, bool isPrivateExtern)
-      : Symbol(DefinedKind, name, file), isec(isec), value(value),
+  Defined(StringRefZ name, InputFile *file, InputSection *isec, uint64_t value,
+          uint64_t size, bool isWeakDef, bool isExternal, bool isPrivateExtern)
+      : Symbol(DefinedKind, name, file), isec(isec), value(value), size(size),
         overridesWeakDef(false), privateExtern(isPrivateExtern),
         includeInSymtab(true), weakDef(isWeakDef), external(isExternal) {}
 
@@ -119,7 +119,8 @@
 
   InputFile *file;
   InputSection *isec;
-  uint32_t value;
+  uint64_t value;
+  uint64_t size;
 
   bool overridesWeakDef : 1;
   // Whether this symbol should appear in the output binary's export trie.
diff --git a/MachO/SyntheticSections.cpp b/MachO/SyntheticSections.cpp
index 6233079..341802a 100644
--- a/MachO/SyntheticSections.cpp
+++ b/MachO/SyntheticSections.cpp
@@ -454,9 +454,10 @@
   in.got->addEntry(stubBinder);
 
   inputSections.push_back(in.imageLoaderCache);
-  dyldPrivate = make<Defined>("__dyld_private", nullptr, in.imageLoaderCache, 0,
-                              /*isWeakDef=*/false,
-                              /*isExternal=*/false, /*isPrivateExtern=*/false);
+  dyldPrivate =
+      make<Defined>("__dyld_private", nullptr, in.imageLoaderCache, 0, 0,
+                    /*isWeakDef=*/false,
+                    /*isExternal=*/false, /*isPrivateExtern=*/false);
 }
 
 ImageLoaderCacheSection::ImageLoaderCacheSection() {
@@ -663,9 +664,7 @@
 
 void SymtabSection::emitEndFunStab(Defined *defined) {
   StabsEntry stab(N_FUN);
-  // FIXME this should be the size of the symbol. Using the section size in
-  // lieu is only correct if .subsections_via_symbols is set.
-  stab.value = defined->isec->getSize();
+  stab.value = defined->size;
   stabs.emplace_back(std::move(stab));
 }
 
diff --git a/MachO/UnwindInfoSection.cpp b/MachO/UnwindInfoSection.cpp
index ed7ae57..949d16f 100644
--- a/MachO/UnwindInfoSection.cpp
+++ b/MachO/UnwindInfoSection.cpp
@@ -148,8 +148,8 @@
       // symbols for them in the GOT.
       Symbol *&s = personalityTable[{referentIsec, r.addend}];
       if (s == nullptr) {
-        s = make<Defined>("<internal>", nullptr, referentIsec, r.addend, false,
-                          false, false);
+        s = make<Defined>("<internal>", nullptr, referentIsec, r.addend, 0,
+                          false, false, false);
         in.got->addEntry(s);
       }
       r.referent = s;