Add first bits for emitting LC_FUNCTION_STARTS.
Test plan: make check-all
Differential revision: https://reviews.llvm.org/D97260
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) {}
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";
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:
WeakBindingSection *weakBinding = nullptr;
LazyBindingSection *lazyBinding = nullptr;
ExportSection *exports = nullptr;
+ FunctionStartsSection *functionStarts = nullptr;
GotSection *got = nullptr;
TlvPointerSection *tlvPointers = nullptr;
LazyPointerSection *lazyPointers = nullptr;
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,
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));
in.weakBinding->finalizeContents();
in.lazyBinding->finalizeContents();
in.exports->finalizeContents();
+ in.functionStarts->finalizeContents();
symtabSection->finalizeContents();
indirectSymtabSection->finalizeContents();
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>();
--- /dev/null
+# 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
# 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 \
## 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.
# 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