[llvm] a6e1b3c - [ObjectYAML][MachO] Add LC_FUNCTION_STARTS support
Keith Smiley via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 13 09:27:55 PST 2022
Author: Keith Smiley
Date: 2022-02-13T09:24:47-08:00
New Revision: a6e1b3c5c223e4868ab77d6d66b62f136b12febc
URL: https://github.com/llvm/llvm-project/commit/a6e1b3c5c223e4868ab77d6d66b62f136b12febc
DIFF: https://github.com/llvm/llvm-project/commit/a6e1b3c5c223e4868ab77d6d66b62f136b12febc.diff
LOG: [ObjectYAML][MachO] Add LC_FUNCTION_STARTS support
This adds support for encoding and decoding the LC_FUNCTION_STARTS load
command payload.
Differential Revision: https://reviews.llvm.org/D119205
Added:
llvm/test/ObjectYAML/MachO/function_starts.yaml
Modified:
llvm/include/llvm/Object/MachO.h
llvm/include/llvm/ObjectYAML/MachOYAML.h
llvm/lib/Object/MachOObjectFile.cpp
llvm/lib/ObjectYAML/MachOEmitter.cpp
llvm/lib/ObjectYAML/MachOYAML.cpp
llvm/tools/obj2yaml/macho2yaml.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Object/MachO.h b/llvm/include/llvm/Object/MachO.h
index 49a0706b84be..840faa700428 100644
--- a/llvm/include/llvm/Object/MachO.h
+++ b/llvm/include/llvm/Object/MachO.h
@@ -563,6 +563,7 @@ class MachOObjectFile : public ObjectFile {
ArrayRef<uint8_t> getDyldInfoWeakBindOpcodes() const;
ArrayRef<uint8_t> getDyldInfoLazyBindOpcodes() const;
ArrayRef<uint8_t> getDyldInfoExportsTrie() const;
+ SmallVector<uint64_t> getFunctionStarts() const;
ArrayRef<uint8_t> getUuid() const;
StringRef getStringTableData() const;
@@ -689,6 +690,7 @@ class MachOObjectFile : public ObjectFile {
const char *DataInCodeLoadCmd = nullptr;
const char *LinkOptHintsLoadCmd = nullptr;
const char *DyldInfoLoadCmd = nullptr;
+ const char *FuncStartsLoadCmd = nullptr;
const char *UuidLoadCmd = nullptr;
bool HasPageZeroSegment = false;
};
diff --git a/llvm/include/llvm/ObjectYAML/MachOYAML.h b/llvm/include/llvm/ObjectYAML/MachOYAML.h
index 38a7de3d6131..095377c1b824 100644
--- a/llvm/include/llvm/ObjectYAML/MachOYAML.h
+++ b/llvm/include/llvm/ObjectYAML/MachOYAML.h
@@ -122,6 +122,7 @@ struct LinkEditData {
std::vector<NListEntry> NameList;
std::vector<StringRef> StringTable;
std::vector<yaml::Hex32> IndirectSymbols;
+ std::vector<yaml::Hex64> FunctionStarts;
bool isEmpty() const;
};
diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp
index 909a4cf4848c..85f3824aedd8 100644
--- a/llvm/lib/Object/MachOObjectFile.cpp
+++ b/llvm/lib/Object/MachOObjectFile.cpp
@@ -1303,7 +1303,6 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
}
const char *DyldIdLoadCmd = nullptr;
- const char *FuncStartsLoadCmd = nullptr;
const char *SplitInfoLoadCmd = nullptr;
const char *CodeSignDrsLoadCmd = nullptr;
const char *CodeSignLoadCmd = nullptr;
@@ -4663,6 +4662,21 @@ ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
return makeArrayRef(Ptr, DyldInfo.export_size);
}
+SmallVector<uint64_t> MachOObjectFile::getFunctionStarts() const {
+ if (!FuncStartsLoadCmd)
+ return {};
+
+ auto InfoOrErr =
+ getStructOrErr<MachO::linkedit_data_command>(*this, FuncStartsLoadCmd);
+ if (!InfoOrErr)
+ return {};
+
+ MachO::linkedit_data_command Info = InfoOrErr.get();
+ SmallVector<uint64_t, 8> FunctionStarts;
+ this->ReadULEB128s(Info.dataoff, FunctionStarts);
+ return std::move(FunctionStarts);
+}
+
ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
if (!UuidLoadCmd)
return None;
diff --git a/llvm/lib/ObjectYAML/MachOEmitter.cpp b/llvm/lib/ObjectYAML/MachOEmitter.cpp
index b9fad2982828..c7811520c76e 100644
--- a/llvm/lib/ObjectYAML/MachOEmitter.cpp
+++ b/llvm/lib/ObjectYAML/MachOEmitter.cpp
@@ -55,6 +55,7 @@ class MachOWriter {
void writeStringTable(raw_ostream &OS);
void writeExportTrie(raw_ostream &OS);
void writeDynamicSymbolTable(raw_ostream &OS);
+ void writeFunctionStarts(raw_ostream &OS);
void dumpExportEntry(raw_ostream &OS, MachOYAML::ExportEntry &Entry);
void ZeroToOffset(raw_ostream &OS, size_t offset);
@@ -484,6 +485,7 @@ void MachOWriter::writeLinkEditData(raw_ostream &OS) {
MachO::dyld_info_command *DyldInfoOnlyCmd = nullptr;
MachO::symtab_command *SymtabCmd = nullptr;
MachO::dysymtab_command *DSymtabCmd = nullptr;
+ MachO::linkedit_data_command *FunctionStartsCmd = nullptr;
for (auto &LC : Obj.LoadCommands) {
switch (LC.Data.load_command_data.cmd) {
case MachO::LC_SYMTAB:
@@ -511,6 +513,11 @@ void MachOWriter::writeLinkEditData(raw_ostream &OS) {
WriteQueue.push_back(std::make_pair(
DSymtabCmd->indirectsymoff, &MachOWriter::writeDynamicSymbolTable));
break;
+ case MachO::LC_FUNCTION_STARTS:
+ FunctionStartsCmd = &LC.Data.linkedit_data_command_data;
+ WriteQueue.push_back(std::make_pair(FunctionStartsCmd->dataoff,
+ &MachOWriter::writeFunctionStarts));
+ break;
}
}
@@ -569,6 +576,17 @@ void MachOWriter::writeDynamicSymbolTable(raw_ostream &OS) {
sizeof(yaml::Hex32::BaseType));
}
+void MachOWriter::writeFunctionStarts(raw_ostream &OS) {
+ uint64_t Addr = 0;
+ for (uint64_t NextAddr : Obj.LinkEdit.FunctionStarts) {
+ uint64_t Delta = NextAddr - Addr;
+ encodeULEB128(Delta, OS);
+ Addr = NextAddr;
+ }
+
+ OS.write('\0');
+}
+
class UniversalWriter {
public:
UniversalWriter(yaml::YamlObjectFile &ObjectFile)
diff --git a/llvm/lib/ObjectYAML/MachOYAML.cpp b/llvm/lib/ObjectYAML/MachOYAML.cpp
index f32009458110..b6f3b53a42b3 100644
--- a/llvm/lib/ObjectYAML/MachOYAML.cpp
+++ b/llvm/lib/ObjectYAML/MachOYAML.cpp
@@ -26,10 +26,10 @@ namespace llvm {
MachOYAML::LoadCommand::~LoadCommand() = default;
bool MachOYAML::LinkEditData::isEmpty() const {
- return 0 ==
- RebaseOpcodes.size() + BindOpcodes.size() + WeakBindOpcodes.size() +
- LazyBindOpcodes.size() + ExportTrie.Children.size() +
- NameList.size() + StringTable.size();
+ return 0 == RebaseOpcodes.size() + BindOpcodes.size() +
+ WeakBindOpcodes.size() + LazyBindOpcodes.size() +
+ ExportTrie.Children.size() + NameList.size() +
+ StringTable.size() + FunctionStarts.size();
}
namespace yaml {
@@ -165,6 +165,7 @@ void MappingTraits<MachOYAML::LinkEditData>::mapping(
IO.mapOptional("NameList", LinkEditData.NameList);
IO.mapOptional("StringTable", LinkEditData.StringTable);
IO.mapOptional("IndirectSymbols", LinkEditData.IndirectSymbols);
+ IO.mapOptional("FunctionStarts", LinkEditData.FunctionStarts);
}
void MappingTraits<MachOYAML::RebaseOpcode>::mapping(
diff --git a/llvm/test/ObjectYAML/MachO/function_starts.yaml b/llvm/test/ObjectYAML/MachO/function_starts.yaml
new file mode 100644
index 000000000000..fe939a68a0c1
--- /dev/null
+++ b/llvm/test/ObjectYAML/MachO/function_starts.yaml
@@ -0,0 +1,186 @@
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x0
+ filetype: 0x2
+ ncmds: 15
+ sizeofcmds: 728
+ flags: 0x200085
+ reserved: 0x0
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __PAGEZERO
+ vmaddr: 0
+ vmsize: 4294967296
+ fileoff: 0
+ filesize: 0
+ maxprot: 0
+ initprot: 0
+ nsects: 0
+ flags: 0
+ - cmd: LC_SEGMENT_64
+ cmdsize: 232
+ segname: __TEXT
+ vmaddr: 4294967296
+ vmsize: 16384
+ fileoff: 0
+ filesize: 16384
+ maxprot: 5
+ initprot: 5
+ nsects: 2
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x100003F80
+ size: 48
+ offset: 0x3F80
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: C0035FD6FF8300D1FD7B01A9FD43009108008052E80B00B9BFC31FB8F9FFFF97E00B40B9FD7B41A9FF830091C0035FD6
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0x100003FB0
+ size: 80
+ offset: 0x3FB0
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000803F00003400000034000000B13F00000000000034000000030000000C0002001400020000000001040000000000000400000002
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 4294983680
+ vmsize: 16384
+ fileoff: 16384
+ filesize: 208
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 16384
+ datasize: 56
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 16440
+ datasize: 56
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 16504
+ nsyms: 3
+ stroff: 16552
+ strsize: 40
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 3
+ iundefsym: 3
+ nundefsym: 0
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 0
+ nindirectsyms: 0
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_LOAD_DYLINKER
+ cmdsize: 32
+ name: 12
+ Content: '/usr/lib/dyld'
+ ZeroPadBytes: 7
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: E1953271-0EDC-3009-9BED-635C8BB3DFE7
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 786432
+ sdk: 786688
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 46596096
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_MAIN
+ cmdsize: 24
+ entryoff: 16260
+ stacksize: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 85917696
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 16496
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 16504
+ datasize: 0
+LinkEditData:
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 16
+ n_value: 4294967296
+ - n_strx: 22
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 4294983552
+ - n_strx: 27
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 4294983556
+ StringTable:
+ - ' '
+ - __mh_execute_header
+ - _foo
+ - _main
+ - ''
+ - ''
+ - ''
+ - ''
+ - ''
+ - ''
+ - ''
+ FunctionStarts: [ 0x3F80, 0x3F84 ]
+...
+
+# RUN: yaml2obj %s -o=%t
+# RUN obj2yaml %t | FileCheck %s
+# CHECK: FunctionStarts: [ 0x3F80, 0x3F84 ]
+
+# RUN: llvm-objdump --macho --function-starts %t | FileCheck %s --check-prefix=OBJDUMP-VERIFY
+# OBJDUMP-VERIFY: function_starts.yaml.tmp:
+# OBJDUMP-VERIFY: 0000000100003f80
+# OBJDUMP-VERIFY: 0000000100003f84
diff --git a/llvm/tools/obj2yaml/macho2yaml.cpp b/llvm/tools/obj2yaml/macho2yaml.cpp
index a6339b2663e9..a32b6bf13366 100644
--- a/llvm/tools/obj2yaml/macho2yaml.cpp
+++ b/llvm/tools/obj2yaml/macho2yaml.cpp
@@ -34,6 +34,7 @@ class MachODumper {
Error dumpLoadCommands(std::unique_ptr<MachOYAML::Object> &Y);
void dumpLinkEdit(std::unique_ptr<MachOYAML::Object> &Y);
void dumpRebaseOpcodes(std::unique_ptr<MachOYAML::Object> &Y);
+ void dumpFunctionStarts(std::unique_ptr<MachOYAML::Object> &Y);
void dumpBindOpcodes(std::vector<MachOYAML::BindOpcode> &BindOpcodes,
ArrayRef<uint8_t> OpcodeBuffer, bool Lazy = false);
void dumpExportTrie(std::unique_ptr<MachOYAML::Object> &Y);
@@ -353,6 +354,15 @@ void MachODumper::dumpLinkEdit(std::unique_ptr<MachOYAML::Object> &Y) {
dumpExportTrie(Y);
dumpSymbols(Y);
dumpIndirectSymbols(Y);
+ dumpFunctionStarts(Y);
+}
+
+void MachODumper::dumpFunctionStarts(std::unique_ptr<MachOYAML::Object> &Y) {
+ MachOYAML::LinkEditData &LEData = Y->LinkEdit;
+
+ auto FunctionStarts = Obj.getFunctionStarts();
+ for (auto Addr : FunctionStarts)
+ LEData.FunctionStarts.push_back(Addr);
}
void MachODumper::dumpRebaseOpcodes(std::unique_ptr<MachOYAML::Object> &Y) {
More information about the llvm-commits
mailing list