diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h
--- a/lld/MachO/SyntheticSections.h
+++ b/lld/MachO/SyntheticSections.h
@@ -62,6 +62,11 @@
     align = WordSize;
   }
 
+  // Sections in __LINKEDIT are special: their offsets are recorded in the
+  // load commands like LC_DYLD_INFO_ONLY and LC_SYMTAB, instead of in section
+  // headers.
+  bool isHidden() const override final { return true; }
+
   virtual uint64_t getRawSize() const = 0;
 
   // codesign (or more specifically libstuff) checks that each section in
@@ -166,10 +171,6 @@
   BindingSection();
   void finalizeContents();
   uint64_t getRawSize() const override { return contents.size(); }
-  // Like other sections in __LINKEDIT, the binding section is special: its
-  // offsets are recorded in the LC_DYLD_INFO_ONLY load command, instead of in
-  // section headers.
-  bool isHidden() const override { return true; }
   bool isNeeded() const override { return !bindings.empty(); }
   void writeTo(uint8_t *buf) const override;
 
@@ -205,10 +206,6 @@
   WeakBindingSection();
   void finalizeContents();
   uint64_t getRawSize() const override { return contents.size(); }
-  // Like other sections in __LINKEDIT, the binding section is special: its
-  // offsets are recorded in the LC_DYLD_INFO_ONLY load command, instead of in
-  // section headers.
-  bool isHidden() const override { return true; }
   bool isNeeded() const override {
     return !bindings.empty() || !definitions.empty();
   }
@@ -324,10 +321,6 @@
   LazyBindingSection();
   void finalizeContents();
   uint64_t getRawSize() const override { return contents.size(); }
-  // Like other sections in __LINKEDIT, the lazy binding section is special: its
-  // offsets are recorded in the LC_DYLD_INFO_ONLY load command, instead of in
-  // section headers.
-  bool isHidden() const override { return true; }
   bool isNeeded() const override { return !entries.empty(); }
   void writeTo(uint8_t *buf) const override;
   // Note that every entry here will by referenced by a corresponding entry in
@@ -349,10 +342,6 @@
   ExportSection();
   void finalizeContents();
   uint64_t getRawSize() const override { return size; }
-  // Like other sections in __LINKEDIT, the export section is special: its
-  // offsets are recorded in the LC_DYLD_INFO_ONLY load command, instead of in
-  // section headers.
-  bool isHidden() const override { return true; }
   void writeTo(uint8_t *buf) const override;
 
   bool hasWeakSymbol = false;
@@ -369,10 +358,6 @@
   // Returns the start offset of the added string.
   uint32_t addString(StringRef);
   uint64_t getRawSize() const override { return size; }
-  // Like other sections in __LINKEDIT, the string table section is special: its
-  // offsets are recorded in the LC_SYMTAB load command, instead of in section
-  // headers.
-  bool isHidden() const override { return true; }
   void writeTo(uint8_t *buf) const override;
 
 private:
@@ -388,16 +373,12 @@
   size_t strx;
 };
 
-class SymtabSection : public SyntheticSection {
+class SymtabSection : public LinkEditSection {
 public:
   SymtabSection(StringTableSection &);
   void finalizeContents();
   size_t getNumSymbols() const { return symbols.size(); }
-  uint64_t getSize() const override;
-  // Like other sections in __LINKEDIT, the symtab section is special: its
-  // offsets are recorded in the LC_SYMTAB load command, instead of in section
-  // headers.
-  bool isHidden() const override { return true; }
+  uint64_t getRawSize() const override;
   void writeTo(uint8_t *buf) const override;
 
 private:
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -454,10 +454,10 @@
 void ExportSection::writeTo(uint8_t *buf) const { trieBuilder.writeTo(buf); }
 
 SymtabSection::SymtabSection(StringTableSection &stringTableSection)
-    : SyntheticSection(segment_names::linkEdit, section_names::symbolTable),
+    : LinkEditSection(segment_names::linkEdit, section_names::symbolTable),
       stringTableSection(stringTableSection) {}
 
-uint64_t SymtabSection::getSize() const {
+uint64_t SymtabSection::getRawSize() const {
   return symbols.size() * sizeof(structs::nlist_64);
 }