current commit
260929.11 · deps: update lief to 1.0.0
/* Copyright 2017 - 2026 R. Thomas
 * Copyright 2017 - 2026 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.
 */
#include "LIEF/Visitor.hpp"
#include "LIEF/MachO/ChainedBindingInfo.hpp"
#include "MachO/ChainedFixup.hpp"


namespace LIEF::MachO {

ChainedBindingInfo::ChainedBindingInfo(ChainedBindingInfo&&) noexcept = default;
ChainedBindingInfo&
    ChainedBindingInfo::operator=(ChainedBindingInfo&&) noexcept = default;

ChainedBindingInfo::ChainedBindingInfo(const ChainedBindingInfo& other) :
  BindingInfo(other),
  format_{other.format_},
  ptr_format_{other.ptr_format_},
  offset_{other.offset_},
  btypes_{other.btypes_} {

  switch (btypes_) {
    case BIND_TYPES::ARM64E_AUTH_BIND:
      arm64_auth_bind_ =
          new details::dyld_chained_ptr_arm64e_auth_bind{*other.arm64_auth_bind_};
      break;
    case BIND_TYPES::ARM64E_BIND:
      arm64_bind_ = new details::dyld_chained_ptr_arm64e_bind{*other.arm64_bind_};
      break;
    case BIND_TYPES::ARM64E_BIND24:
      arm64_bind24_ =
          new details::dyld_chained_ptr_arm64e_bind24{*other.arm64_bind24_};
      break;
    case BIND_TYPES::ARM64E_AUTH_BIND24:
      arm64_auth_bind24_ = new details::dyld_chained_ptr_arm64e_auth_bind24{
          *other.arm64_auth_bind24_
      };
      break;
    case BIND_TYPES::PTR32_BIND:
      p32_bind_ = new details::dyld_chained_ptr_32_bind{*other.p32_bind_};
      break;
    case BIND_TYPES::PTR64_BIND:
      p64_bind_ = new details::dyld_chained_ptr_64_bind{*other.p64_bind_};
      break;
    case BIND_TYPES::UNKNOWN:
    {
    }
  }
}

ChainedBindingInfo::ChainedBindingInfo(DYLD_CHAINED_FORMAT fmt, bool is_weak) :
  format_{fmt},
  ptr_format_{DYLD_CHAINED_PTR_FORMAT::NONE} {
  is_weak_import_ = is_weak;
}

ChainedBindingInfo::~ChainedBindingInfo() {
  clear();
}

ChainedBindingInfo&
    ChainedBindingInfo::operator=(const ChainedBindingInfo& other) {
  if (this == &other) {
    return *this;
  }

  BindingInfo::operator=(other);
  format_ = other.format_;
  ptr_format_ = other.ptr_format_;
  offset_ = other.offset_;
  btypes_ = other.btypes_;
  return *this;
}

void ChainedBindingInfo::accept(Visitor& visitor) const {
  visitor.visit(*this);
}

uint64_t ChainedBindingInfo::sign_extended_addend() const {
  switch (btypes_) {
    case BIND_TYPES::ARM64E_AUTH_BIND: return 0;
    case BIND_TYPES::ARM64E_BIND:
      return details::sign_extended_addend(*arm64_bind_);
    case BIND_TYPES::ARM64E_BIND24:
      return details::sign_extended_addend(*arm64_bind24_);
    case BIND_TYPES::ARM64E_AUTH_BIND24: return 0;
    case BIND_TYPES::PTR32_BIND: return p32_bind_->addend;
    case BIND_TYPES::PTR64_BIND: return details::sign_extended_addend(*p64_bind_);
    case BIND_TYPES::UNKNOWN: return 0;
  }
  return 0;
}


void ChainedBindingInfo::set(const details::dyld_chained_ptr_arm64e_bind& bind) {
  clear();
  btypes_ = BIND_TYPES::ARM64E_BIND;
  arm64_bind_ = new details::dyld_chained_ptr_arm64e_bind(bind);
}

void ChainedBindingInfo::set(
    const details::dyld_chained_ptr_arm64e_auth_bind& bind
) {
  clear();
  btypes_ = BIND_TYPES::ARM64E_AUTH_BIND;
  arm64_auth_bind_ = new details::dyld_chained_ptr_arm64e_auth_bind(bind);
}

void ChainedBindingInfo::set(const details::dyld_chained_ptr_arm64e_bind24& bind) {
  clear();
  btypes_ = BIND_TYPES::ARM64E_BIND24;
  arm64_bind24_ = new details::dyld_chained_ptr_arm64e_bind24(bind);
}

void ChainedBindingInfo::set(
    const details::dyld_chained_ptr_arm64e_auth_bind24& bind
) {
  clear();
  btypes_ = BIND_TYPES::ARM64E_AUTH_BIND24;
  arm64_auth_bind24_ = new details::dyld_chained_ptr_arm64e_auth_bind24(bind);
}

void ChainedBindingInfo::set(const details::dyld_chained_ptr_64_bind& bind) {
  clear();
  btypes_ = BIND_TYPES::PTR64_BIND;
  p64_bind_ = new details::dyld_chained_ptr_64_bind(bind);
}

void ChainedBindingInfo::set(const details::dyld_chained_ptr_32_bind& bind) {
  clear();
  btypes_ = BIND_TYPES::PTR32_BIND;
  p32_bind_ = new details::dyld_chained_ptr_32_bind(bind);
}


void ChainedBindingInfo::clear() {
  switch (btypes_) {
    case BIND_TYPES::ARM64E_AUTH_BIND: delete arm64_auth_bind_; break;
    case BIND_TYPES::ARM64E_BIND: delete arm64_bind_; break;
    case BIND_TYPES::ARM64E_BIND24: delete arm64_bind24_; break;
    case BIND_TYPES::ARM64E_AUTH_BIND24: delete arm64_auth_bind24_; break;
    case BIND_TYPES::PTR32_BIND: delete p32_bind_; break;
    case BIND_TYPES::PTR64_BIND: delete p64_bind_; break;
    case BIND_TYPES::UNKNOWN:
    {
    }
  }
  btypes_ = BIND_TYPES::UNKNOWN;
}

}