diff --git a/llvm/include/llvm/ObjectYAML/MachOYAML.h b/llvm/include/llvm/ObjectYAML/MachOYAML.h --- a/llvm/include/llvm/ObjectYAML/MachOYAML.h +++ b/llvm/include/llvm/ObjectYAML/MachOYAML.h @@ -113,6 +113,12 @@ std::vector Children; }; +struct DataInCodeEntry { + llvm::yaml::Hex32 Offset; + uint16_t Length; + llvm::yaml::Hex16 Kind; +}; + struct LinkEditData { std::vector RebaseOpcodes; std::vector BindOpcodes; @@ -123,6 +129,7 @@ std::vector StringTable; std::vector IndirectSymbols; std::vector FunctionStarts; + std::vector DataInCode; bool isEmpty() const; }; @@ -169,6 +176,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::NListEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Object) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::FatArch) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::DataInCodeEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachO::build_tool_version) namespace llvm { @@ -234,6 +242,10 @@ static void mapping(IO &IO, MachO::build_tool_version &tool); }; +template <> struct MappingTraits { + static void mapping(IO &IO, MachOYAML::DataInCodeEntry &DataInCodeEntry); +}; + #define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \ io.enumCase(value, #LCName, MachO::LCName); diff --git a/llvm/lib/ObjectYAML/MachOEmitter.cpp b/llvm/lib/ObjectYAML/MachOEmitter.cpp --- a/llvm/lib/ObjectYAML/MachOEmitter.cpp +++ b/llvm/lib/ObjectYAML/MachOEmitter.cpp @@ -56,6 +56,7 @@ void writeExportTrie(raw_ostream &OS); void writeDynamicSymbolTable(raw_ostream &OS); void writeFunctionStarts(raw_ostream &OS); + void writeDataInCode(raw_ostream &OS); void dumpExportEntry(raw_ostream &OS, MachOYAML::ExportEntry &Entry); void ZeroToOffset(raw_ostream &OS, size_t offset); @@ -486,6 +487,7 @@ MachO::symtab_command *SymtabCmd = nullptr; MachO::dysymtab_command *DSymtabCmd = nullptr; MachO::linkedit_data_command *FunctionStartsCmd = nullptr; + MachO::linkedit_data_command *DataInCodeCmd = nullptr; for (auto &LC : Obj.LoadCommands) { switch (LC.Data.load_command_data.cmd) { case MachO::LC_SYMTAB: @@ -518,6 +520,11 @@ WriteQueue.push_back(std::make_pair(FunctionStartsCmd->dataoff, &MachOWriter::writeFunctionStarts)); break; + case MachO::LC_DATA_IN_CODE: + DataInCodeCmd = &LC.Data.linkedit_data_command_data; + WriteQueue.push_back(std::make_pair(DataInCodeCmd->dataoff, + &MachOWriter::writeDataInCode)); + break; } } @@ -585,6 +592,16 @@ OS.write('\0'); } +void MachOWriter::writeDataInCode(raw_ostream &OS) { + for (const auto &Entry : Obj.LinkEdit.DataInCode) { + MachO::data_in_code_entry DICE{Entry.Offset, Entry.Length, Entry.Kind}; + if (Obj.IsLittleEndian != sys::IsLittleEndianHost) + MachO::swapStruct(DICE); + OS.write(reinterpret_cast(&DICE), + sizeof(MachO::data_in_code_entry)); + } +} + class UniversalWriter { public: UniversalWriter(yaml::YamlObjectFile &ObjectFile) diff --git a/llvm/lib/ObjectYAML/MachOYAML.cpp b/llvm/lib/ObjectYAML/MachOYAML.cpp --- a/llvm/lib/ObjectYAML/MachOYAML.cpp +++ b/llvm/lib/ObjectYAML/MachOYAML.cpp @@ -29,7 +29,8 @@ return 0 == RebaseOpcodes.size() + BindOpcodes.size() + WeakBindOpcodes.size() + LazyBindOpcodes.size() + ExportTrie.Children.size() + NameList.size() + - StringTable.size() + FunctionStarts.size(); + StringTable.size() + FunctionStarts.size() + + DataInCode.size(); } namespace yaml { @@ -166,6 +167,7 @@ IO.mapOptional("StringTable", LinkEditData.StringTable); IO.mapOptional("IndirectSymbols", LinkEditData.IndirectSymbols); IO.mapOptional("FunctionStarts", LinkEditData.FunctionStarts); + IO.mapOptional("DataInCode", LinkEditData.DataInCode); } void MappingTraits::mapping( @@ -205,6 +207,13 @@ IO.mapRequired("n_value", NListEntry.n_value); } +void MappingTraits::mapping( + IO &IO, MachOYAML::DataInCodeEntry &DataInCodeEntry) { + IO.mapRequired("Offset", DataInCodeEntry.Offset); + IO.mapRequired("Length", DataInCodeEntry.Length); + IO.mapRequired("Kind", DataInCodeEntry.Kind); +} + template void mapLoadCommandData(IO &IO, MachOYAML::LoadCommand &LoadCommand) {} diff --git a/llvm/test/ObjectYAML/MachO/data-in-code.yaml b/llvm/test/ObjectYAML/MachO/data-in-code.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/ObjectYAML/MachO/data-in-code.yaml @@ -0,0 +1,218 @@ +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x1000007 + cpusubtype: 0x3 + filetype: 0x2 + ncmds: 14 + sizeofcmds: 744 + 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: 0x100003FB0 + size: 8 + offset: 0x3FB0 + align: 4 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: C30F1F0000000000 + - sectname: __unwind_info + segname: __TEXT + addr: 0x100003FB8 + size: 72 + offset: 0x3FB8 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000000000001C000000000000001C00000002000000B03F00003400000034000000B93F00000000000034000000030000000C000100100001000000000000000000 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4294983680 + vmsize: 16384 + fileoff: 16384 + filesize: 160 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_DYLD_INFO_ONLY + cmdsize: 48 + rebase_off: 0 + rebase_size: 0 + bind_off: 0 + bind_size: 0 + weak_bind_off: 0 + weak_bind_size: 0 + lazy_bind_off: 0 + lazy_bind_size: 0 + export_off: 16384 + export_size: 48 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 16448 + nsyms: 3 + stroff: 16496 + strsize: 48 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 2 + iundefsym: 2 + nundefsym: 1 + 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: 003A202C-BBD0-3633-81AC-48AD5F9CDE61 + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 786432 + sdk: 787200 + ntools: 1 + Tools: + - tool: 3 + version: 50069504 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_MAIN + cmdsize: 24 + entryoff: 16304 + stacksize: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 85943299 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 16432 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 16440 + datasize: 8 +LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 0 + NodeOffset: 5 + Name: _ + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 2 + NodeOffset: 33 + Name: _mh_execute_header + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + - TerminalSize: 3 + NodeOffset: 37 + Name: main + Flags: 0x0 + Address: 0x3FB0 + Other: 0x0 + ImportName: '' + 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: 4294983600 + - n_strx: 28 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - __mh_execute_header + - _main + - dyld_stub_binder + - '' + - '' + - '' + FunctionStarts: [ 0x3FB0 ] + DataInCode: + - Offset: 0x3FB4 + Length: 4 + Kind: 0x4 +... + +# RUN: yaml2obj %s | obj2yaml | FileCheck %s +# CHECK: DataInCode: +# CHECK-NEXT: - Offset: 0x3FB4 +# CHECK-NEXT: Length: 4 +# CHECK-NEXT: Kind: 0x4 diff --git a/llvm/tools/obj2yaml/macho2yaml.cpp b/llvm/tools/obj2yaml/macho2yaml.cpp --- a/llvm/tools/obj2yaml/macho2yaml.cpp +++ b/llvm/tools/obj2yaml/macho2yaml.cpp @@ -41,6 +41,7 @@ void dumpExportTrie(std::unique_ptr &Y); void dumpSymbols(std::unique_ptr &Y); void dumpIndirectSymbols(std::unique_ptr &Y); + void dumpDataInCode(std::unique_ptr &Y); template Expected constructSectionCommon(SectionType Sec, @@ -356,6 +357,7 @@ dumpSymbols(Y); dumpIndirectSymbols(Y); dumpFunctionStarts(Y); + dumpDataInCode(Y); } void MachODumper::dumpFunctionStarts(std::unique_ptr &Y) { @@ -620,6 +622,19 @@ LEData.IndirectSymbols.push_back(Obj.getIndirectSymbolTableEntry(DLC, i)); } +void MachODumper::dumpDataInCode(std::unique_ptr &Y) { + MachOYAML::LinkEditData &LEData = Y->LinkEdit; + + MachO::linkedit_data_command DIC = Obj.getDataInCodeLoadCommand(); + uint32_t NumEntries = DIC.datasize / sizeof(MachO::data_in_code_entry); + for (uint32_t Idx = 0; Idx < NumEntries; ++Idx) { + MachO::data_in_code_entry DICE = + Obj.getDataInCodeTableEntry(DIC.dataoff, Idx); + MachOYAML::DataInCodeEntry Entry{DICE.offset, DICE.length, DICE.kind}; + LEData.DataInCode.emplace_back(Entry); + } +} + Error macho2yaml(raw_ostream &Out, const object::MachOObjectFile &Obj, unsigned RawSegments) { std::unique_ptr DCtx = DWARFContext::create(Obj);