llvm/llvm/tools/obj2yaml/macho2yaml.cpp

//===------ macho2yaml.cpp - obj2yaml conversion tool -----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "obj2yaml.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/ObjectYAML/DWARFYAML.h"
#include "llvm/ObjectYAML/ObjectYAML.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/SystemZ/zOSSupport.h"

#include <string.h> // for memcpy

usingnamespacellvm;

class MachODumper {};

#define HANDLE_LOAD_COMMAND

template <typename SectionType>
Expected<MachOYAML::Section>
MachODumper::constructSectionCommon(SectionType Sec, size_t SecIndex) {}

template <>
Expected<MachOYAML::Section> MachODumper::constructSection(MachO::section Sec,
                                                           size_t SecIndex) {}

template <>
Expected<MachOYAML::Section>
MachODumper::constructSection(MachO::section_64 Sec, size_t SecIndex) {}

static Error dumpDebugSection(StringRef SecName, DWARFContext &DCtx,
                              DWARFYAML::Data &DWARF) {}

template <typename SectionType, typename SegmentType>
Expected<const char *> MachODumper::extractSections(
    const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
    std::vector<MachOYAML::Section> &Sections, MachOYAML::Object &Y) {}

template <typename StructType>
Expected<const char *> MachODumper::processLoadCommandData(
    MachOYAML::LoadCommand &LC,
    const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
    MachOYAML::Object &Y) {}

template <>
Expected<const char *>
MachODumper::processLoadCommandData<MachO::segment_command>(
    MachOYAML::LoadCommand &LC,
    const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
    MachOYAML::Object &Y) {}

template <>
Expected<const char *>
MachODumper::processLoadCommandData<MachO::segment_command_64>(
    MachOYAML::LoadCommand &LC,
    const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
    MachOYAML::Object &Y) {}

template <typename StructType>
const char *
readString(MachOYAML::LoadCommand &LC,
           const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd) {}

template <>
Expected<const char *>
MachODumper::processLoadCommandData<MachO::dylib_command>(
    MachOYAML::LoadCommand &LC,
    const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
    MachOYAML::Object &Y) {}

template <>
Expected<const char *>
MachODumper::processLoadCommandData<MachO::dylinker_command>(
    MachOYAML::LoadCommand &LC,
    const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
    MachOYAML::Object &Y) {}

template <>
Expected<const char *>
MachODumper::processLoadCommandData<MachO::rpath_command>(
    MachOYAML::LoadCommand &LC,
    const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
    MachOYAML::Object &Y) {}

template <>
Expected<const char *>
MachODumper::processLoadCommandData<MachO::build_version_command>(
    MachOYAML::LoadCommand &LC,
    const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
    MachOYAML::Object &Y) {}

Expected<std::unique_ptr<MachOYAML::Object>> MachODumper::dump() {}

void MachODumper::dumpHeader(std::unique_ptr<MachOYAML::Object> &Y) {}

Error MachODumper::dumpLoadCommands(std::unique_ptr<MachOYAML::Object> &Y) {}

void MachODumper::dumpLinkEdit(std::unique_ptr<MachOYAML::Object> &Y) {}

void MachODumper::dumpFunctionStarts(std::unique_ptr<MachOYAML::Object> &Y) {}

void MachODumper::dumpRebaseOpcodes(std::unique_ptr<MachOYAML::Object> &Y) {}

StringRef ReadStringRef(const uint8_t *Start) {}

void MachODumper::dumpBindOpcodes(
    std::vector<MachOYAML::BindOpcode> &BindOpcodes,
    ArrayRef<uint8_t> OpcodeBuffer, bool Lazy) {}

/*!
 * /brief processes a node from the export trie, and its children.
 *
 * To my knowledge there is no documentation of the encoded format of this data
 * other than in the heads of the Apple linker engineers. To that end hopefully
 * this comment and the implementation below can serve to light the way for
 * anyone crazy enough to come down this path in the future.
 *
 * This function reads and preserves the trie structure of the export trie. To
 * my knowledge there is no code anywhere else that reads the data and preserves
 * the Trie. LD64 (sources available at opensource.apple.com) has a similar
 * implementation that parses the export trie into a vector. That code as well
 * as LLVM's libObject MachO implementation were the basis for this.
 *
 * The export trie is an encoded trie. The node serialization is a bit awkward.
 * The below pseudo-code is the best description I've come up with for it.
 *
 * struct SerializedNode {
 *   ULEB128 TerminalSize;
 *   struct TerminalData { <-- This is only present if TerminalSize > 0
 *     ULEB128 Flags;
 *     ULEB128 Address; <-- Present if (! Flags & REEXPORT )
 *     ULEB128 Other; <-- Present if ( Flags & REEXPORT ||
 *                                     Flags & STUB_AND_RESOLVER )
 *     char[] ImportName; <-- Present if ( Flags & REEXPORT )
 *   }
 *   uint8_t ChildrenCount;
 *   Pair<char[], ULEB128> ChildNameOffsetPair[ChildrenCount];
 *   SerializedNode Children[ChildrenCount]
 * }
 *
 * Terminal nodes are nodes that represent actual exports. They can appear
 * anywhere in the tree other than at the root; they do not need to be leaf
 * nodes. When reading the data out of the trie this routine reads it in-order,
 * but it puts the child names and offsets directly into the child nodes. This
 * results in looping over the children twice during serialization and
 * de-serialization, but it makes the YAML representation more human readable.
 *
 * Below is an example of the graph from a "Hello World" executable:
 *
 * -------
 * | ''  |
 * -------
 *    |
 * -------
 * | '_' |
 * -------
 *    |
 *    |----------------------------------------|
 *    |                                        |
 *  ------------------------      ---------------------
 *  | '_mh_execute_header' |      | 'main'            |
 *  | Flags: 0x00000000    |      | Flags: 0x00000000 |
 *  | Addr:  0x00000000    |      | Addr:  0x00001160 |
 *  ------------------------      ---------------------
 *
 * This graph represents the trie for the exports "__mh_execute_header" and
 * "_main". In the graph only the "_main" and "__mh_execute_header" nodes are
 * terminal.
*/

const uint8_t *processExportNode(const uint8_t *Start, const uint8_t *CurrPtr,
                                 const uint8_t *const End,
                                 MachOYAML::ExportEntry &Entry) {}

void MachODumper::dumpExportTrie(std::unique_ptr<MachOYAML::Object> &Y) {}

template <typename nlist_t>
MachOYAML::NListEntry constructNameList(const nlist_t &nlist) {}

void MachODumper::dumpSymbols(std::unique_ptr<MachOYAML::Object> &Y) {}

void MachODumper::dumpIndirectSymbols(std::unique_ptr<MachOYAML::Object> &Y) {}

void MachODumper::dumpChainedFixups(std::unique_ptr<MachOYAML::Object> &Y) {}

void MachODumper::dumpDataInCode(std::unique_ptr<MachOYAML::Object> &Y) {}

Error macho2yaml(raw_ostream &Out, const object::MachOObjectFile &Obj,
                 unsigned RawSegments) {}

Error macho2yaml(raw_ostream &Out, const object::MachOUniversalBinary &Obj,
                 unsigned RawSegments) {}

Error macho2yaml(raw_ostream &Out, const object::Binary &Binary,
                 unsigned RawSegments) {}