text: /* Copyright 2017 R. Thomas
   * Copyright 2017 Quarkslab
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  #ifndef LIEF_MACHO_BINARY_PARSER_H_
  #define LIEF_MACHO_BINARY_PARSER_H_
  #include <memory>
  #include <string>
  #include <vector>
  #include <limits>
  
  #include "LIEF/types.hpp"
  #include "LIEF/visibility.h"
  #include "LIEF/BinaryStream/VectorStream.hpp"
  
  #include "LIEF/Abstract/Parser.hpp"
  
  #include "LIEF/MachO/ParserConfig.hpp"
  #include "LIEF/MachO/Structures.hpp"
  #include "LIEF/MachO/Binary.hpp"
  #include "LIEF/MachO/LoadCommand.hpp"
  #include "LIEF/MachO/EnumToString.hpp"
  
  namespace LIEF {
  namespace MachO {
  
  class Parser;
  
  //! @brief Class used to parse **single** binary (i.e. **not** FAT)
  //! @see MachO::Parser
  class LIEF_API BinaryParser : public LIEF::Parser {
  
    friend class MachO::Parser;
  
    //! @brief Maximum number of relocations
    constexpr static size_t MAX_RELOCATIONS = std::numeric_limits<uint16_t>::max();
    constexpr static size_t MAX_COMMANDS    = std::numeric_limits<uint8_t>::max();
  
    public:
      BinaryParser(const std::string& file, const ParserConfig& conf = ParserConfig::deep());
      BinaryParser(const std::vector<uint8_t>& data, uint64_t fat_offset = 0, const ParserConfig& conf = ParserConfig::deep());
      BinaryParser(void);
  
      BinaryParser& operator=(const BinaryParser& copy) = delete;
      BinaryParser(const BinaryParser& copy) = delete;
  
      ~BinaryParser(void);
  
      Binary* get_binary(void);
  
    private:
      BinaryParser(std::unique_ptr<VectorStream>&& stream, uint64_t fat_offset = 0, const ParserConfig& conf = ParserConfig::deep());
  
      void init(void);
  
      template<class MACHO_T>
      void parse(void);
  
      template<class MACHO_T>
      void parse_header(void);
  
      template<class MACHO_T>
      void parse_load_commands(void);
  
      template<class MACHO_T>
      void parse_relocations(Section& section);
  
      // Dyld info parser
      // ================
  
      // Rebase
      // ------
      template<class MACHO_T>
      void parse_dyldinfo_rebases(void);
  
      // Bindings
      // --------
      template<class MACHO_T>
      void parse_dyldinfo_binds(void);
  
      template<class MACHO_T>
      void parse_dyldinfo_generic_bind(void);
  
      template<class MACHO_T>
      void parse_dyldinfo_weak_bind(void);
  
      template<class MACHO_T>
      void parse_dyldinfo_lazy_bind(void);
  
      template<class MACHO_T>
      void do_bind(BINDING_CLASS cls,
          uint8_t type,
          uint8_t segment_idx,
          uint64_t segment_offset,
          const std::string& symbol_name,
          int32_t ord,
          int64_t addend,
          bool is_weak,
          bool is_non_weak_definition,
          it_segments& segments);
  
  
      template<class MACHO_T>
      void do_rebase(uint8_t type, uint8_t segment_idx, uint64_t segment_address);
  
      // Exports
      // -------
      void parse_dyldinfo_export(void);
  
      void parse_export_trie(uint64_t start, uint64_t end, const std::string& prefix);
  
      std::unique_ptr<VectorStream> stream_;
      Binary*                       binary_ ;
      MACHO_TYPES                   type_;
      bool                          is64_;
      ParserConfig                  config_;
  };
  
  
  } // namespace MachO
  } // namespace LIEF
  #endif
  