[lld] f344dfe - [lld][MachO] Add support for LC_FUNCTION_STARTS

Alexander Shaposhnikov via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 8 20:42:38 PST 2021


Author: Alexander Shaposhnikov
Date: 2021-03-08T20:42:24-08:00
New Revision: f344dfebdb127f66f591749b1f12e9ddfa10a05c

URL: https://github.com/llvm/llvm-project/commit/f344dfebdb127f66f591749b1f12e9ddfa10a05c
DIFF: https://github.com/llvm/llvm-project/commit/f344dfebdb127f66f591749b1f12e9ddfa10a05c.diff

LOG: [lld][MachO] Add support for LC_FUNCTION_STARTS

Add first bits for emitting LC_FUNCTION_STARTS.

Test plan: make check-all

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

Added: 
    lld/test/MachO/function-starts.s

Modified: 
    lld/MachO/SyntheticSections.cpp
    lld/MachO/SyntheticSections.h
    lld/MachO/Writer.cpp
    lld/test/MachO/headerpad.s
    lld/test/MachO/local-got.s
    lld/test/MachO/x86-64-relocs.s

Removed: 
    


################################################################################
diff  --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index b38ffeacf27c..dcfdac643370 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -612,6 +612,34 @@ void ExportSection::finalizeContents() {
 
 void ExportSection::writeTo(uint8_t *buf) const { trieBuilder.writeTo(buf); }
 
+FunctionStartsSection::FunctionStartsSection()
+    : LinkEditSection(segment_names::linkEdit, section_names::functionStarts_) {
+}
+
+void FunctionStartsSection::finalizeContents() {
+  raw_svector_ostream os{contents};
+  uint64_t addr = in.header->addr;
+  for (const Symbol *sym : symtab->getSymbols()) {
+    if (const auto *defined = dyn_cast<Defined>(sym)) {
+      if (!defined->isec || !isCodeSection(defined->isec))
+        continue;
+      // TODO: Add support for thumbs, in that case
+      // the lowest bit of nextAddr needs to be set to 1.
+      uint64_t nextAddr = defined->getVA();
+      uint64_t delta = nextAddr - addr;
+      if (delta == 0)
+        continue;
+      encodeULEB128(delta, os);
+      addr = nextAddr;
+    }
+  }
+  os << '\0';
+}
+
+void FunctionStartsSection::writeTo(uint8_t *buf) const {
+  memcpy(buf, contents.data(), contents.size());
+}
+
 SymtabSection::SymtabSection(StringTableSection &stringTableSection)
     : LinkEditSection(segment_names::linkEdit, section_names::symbolTable),
       stringTableSection(stringTableSection) {}

diff  --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h
index aff5a08cab93..232035f8f5f3 100644
--- a/lld/MachO/SyntheticSections.h
+++ b/lld/MachO/SyntheticSections.h
@@ -38,6 +38,7 @@ constexpr const char binding[] = "__binding";
 constexpr const char weakBinding[] = "__weak_binding";
 constexpr const char lazyBinding[] = "__lazy_binding";
 constexpr const char export_[] = "__export";
+constexpr const char functionStarts_[] = "__functionStarts";
 constexpr const char symbolTable[] = "__symbol_table";
 constexpr const char indirectSymbolTable[] = "__ind_sym_tab";
 constexpr const char stringTable[] = "__string_table";
@@ -397,6 +398,17 @@ class ExportSection : public LinkEditSection {
   size_t size = 0;
 };
 
+class FunctionStartsSection : public LinkEditSection {
+public:
+  FunctionStartsSection();
+  void finalizeContents();
+  uint64_t getRawSize() const override { return contents.size(); }
+  void writeTo(uint8_t *buf) const override;
+
+private:
+  SmallVector<char, 128> contents;
+};
+
 // Stores the strings referenced by the symbol table.
 class StringTableSection : public LinkEditSection {
 public:
@@ -517,6 +529,7 @@ struct InStruct {
   WeakBindingSection *weakBinding = nullptr;
   LazyBindingSection *lazyBinding = nullptr;
   ExportSection *exports = nullptr;
+  FunctionStartsSection *functionStarts = nullptr;
   GotSection *got = nullptr;
   TlvPointerSection *tlvPointers = nullptr;
   LazyPointerSection *lazyPointers = nullptr;

diff  --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 2d6a41bc5d55..110c296a3677 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -114,6 +114,25 @@ class LCDyldInfo : public LoadCommand {
   ExportSection *exportSection;
 };
 
+class LCFunctionStarts : public LoadCommand {
+public:
+  explicit LCFunctionStarts(FunctionStartsSection *functionStarts)
+      : functionStarts(functionStarts) {}
+
+  uint32_t getSize() const override { return sizeof(linkedit_data_command); }
+
+  void writeTo(uint8_t *buf) const override {
+    auto *c = reinterpret_cast<linkedit_data_command *>(buf);
+    c->cmd = LC_FUNCTION_STARTS;
+    c->cmdsize = getSize();
+    c->dataoff = functionStarts->fileOff;
+    c->datasize = functionStarts->getFileSize();
+  }
+
+private:
+  FunctionStartsSection *functionStarts;
+};
+
 class LCDysymtab : public LoadCommand {
 public:
   LCDysymtab(SymtabSection *symtabSection,
@@ -503,6 +522,7 @@ void Writer::createLoadCommands() {
   in.header->addLoadCommand(make<LCSymtab>(symtabSection, stringTableSection));
   in.header->addLoadCommand(
       make<LCDysymtab>(symtabSection, indirectSymtabSection));
+  in.header->addLoadCommand(make<LCFunctionStarts>(in.functionStarts));
   for (StringRef path : config->runtimePaths)
     in.header->addLoadCommand(make<LCRPath>(path));
 
@@ -858,6 +878,7 @@ void Writer::run() {
   in.weakBinding->finalizeContents();
   in.lazyBinding->finalizeContents();
   in.exports->finalizeContents();
+  in.functionStarts->finalizeContents();
   symtabSection->finalizeContents();
   indirectSymtabSection->finalizeContents();
 
@@ -886,6 +907,7 @@ void macho::createSyntheticSections() {
   in.weakBinding = make<WeakBindingSection>();
   in.lazyBinding = make<LazyBindingSection>();
   in.exports = make<ExportSection>();
+  in.functionStarts = make<FunctionStartsSection>();
   in.got = make<GotSection>();
   in.tlvPointers = make<TlvPointerSection>();
   in.lazyPointers = make<LazyPointerSection>();

diff  --git a/lld/test/MachO/function-starts.s b/lld/test/MachO/function-starts.s
new file mode 100644
index 000000000000..5bfbaf34de62
--- /dev/null
+++ b/lld/test/MachO/function-starts.s
@@ -0,0 +1,47 @@
+# REQUIRES: x86
+
+# RUN: split-file %s %t
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/basic.s -o %t.basic.o
+# RUN: %lld %t.basic.o -o %t.basic
+# RUN: llvm-objdump --syms --macho --function-starts %t.basic | FileCheck %s --check-prefix=BASIC
+
+# BASIC:      [[#%,MAIN:]]
+# BASIC: [[#%,F1:]]
+# BASIC: [[#%,F2:]]
+# BASIC: SYMBOL TABLE:
+# BASIC: [[#MAIN]] {{.*}} _main
+# BASIC: [[#F1]] {{.*}} _f1
+# BASIC: [[#F2]] {{.*}} _f2
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/alias.s -o %t.alias.o
+# RUN: %lld %t.alias.o -o %t.alias
+# RUN: llvm-objdump --syms --macho --function-starts %t.alias | FileCheck %s --check-prefix=ALIAS
+
+# ALIAS:      [[#%,MAIN:]]
+# ALIAS: [[#%,F1:]]
+# ALIAS: SYMBOL TABLE:
+# ALIAS: [[#MAIN]] {{.*}} _main
+# ALIAS: [[#F1]] {{.*}} _f1
+
+#--- basic.s
+.section  __TEXT,__text,regular,pure_instructions
+.globl  _f1
+.globl  _f2
+.globl  _main
+_f1:
+  retq
+_f2:
+  retq
+_main:
+  retq
+
+#--- alias.s
+.section  __TEXT,__text,regular,pure_instructions
+.globl  _f1
+.equiv  _f2, _f1
+.globl  _main
+_f1:
+  retq
+_main:
+  retq

diff  --git a/lld/test/MachO/headerpad.s b/lld/test/MachO/headerpad.s
index 750919438cb0..3f7f201ba7d8 100644
--- a/lld/test/MachO/headerpad.s
+++ b/lld/test/MachO/headerpad.s
@@ -72,7 +72,7 @@
 # PADMAX-NEXT: segname __TEXT
 # PADMAX-NEXT: addr
 # PADMAX-NEXT: size
-# PADMAX-NEXT: offset [[#%u, CMDSIZE + 0x20 + mul(0x400, N - 7)]]
+# PADMAX-NEXT: offset [[#%u, CMDSIZE + 0x20 + mul(0x400, N - 8)]]
 
 ################ All 3 kinds of LCDylib swamped by a larger override
 # RUN: %lld -o %t/libnull.dylib %t/null.o -dylib \

diff  --git a/lld/test/MachO/local-got.s b/lld/test/MachO/local-got.s
index e4a1c5e9b979..9e48c7ec600b 100644
--- a/lld/test/MachO/local-got.s
+++ b/lld/test/MachO/local-got.s
@@ -12,12 +12,12 @@
 ## address offset and the contents at that address very similarly, so am using
 ## --match-full-lines to make sure we match on the right thing.
 # CHECK:      Contents of section __TEXT,__cstring:
-# CHECK-NEXT: 100000424 {{.*}}
+# CHECK-NEXT: 100000434 {{.*}}
 
 ## 1st 8 bytes refer to the start of __cstring + 0xe, 2nd 8 bytes refer to the
 ## start of __cstring
 # CHECK:      Contents of section __DATA_CONST,__got:
-# CHECK-NEXT: [[#%X,ADDR:]]  32040000 01000000 24040000 01000000 {{.*}}
+# CHECK-NEXT: [[#%X,ADDR:]]  42040000 01000000 34040000 01000000 {{.*}}
 # CHECK-NEXT: [[#ADDR + 16]] 00000000 00000000 {{.*}}
 
 ## Check that the rebase table is empty.

diff  --git a/lld/test/MachO/x86-64-relocs.s b/lld/test/MachO/x86-64-relocs.s
index c5627c49583f..8e9474454001 100644
--- a/lld/test/MachO/x86-64-relocs.s
+++ b/lld/test/MachO/x86-64-relocs.s
@@ -21,7 +21,7 @@
 
 # RUN: llvm-objdump --section=__const --full-contents %t | FileCheck %s --check-prefix=NONPCREL
 # NONPCREL:      Contents of section __DATA,__const:
-# NONPCREL-NEXT: 100001000 08040000 01000000 08040000 01000000
+# NONPCREL-NEXT: 100001000 18040000 01000000 18040000 01000000
 
 .section __TEXT,__text
 .globl _main, _f


        


More information about the llvm-commits mailing list