Section* Binary::add_section(const SegmentCommand& segment, const Section& section) {

  const auto it_segment = std::find_if(
      std::begin(segments_), std::end(segments_),
      [&segment] (const SegmentCommand* s) {
        return segment == *s;
      });

  if (it_segment == std::end(segments_)) {
    LIEF_ERR("Unable to find segment: '{}'", segment.name());
    return nullptr;
  }
  SegmentCommand* target_segment = *it_segment;

  span<const uint8_t> content_ref = section.content();
  Section::content_t content = {std::begin(content_ref), std::end(content_ref)};

  const size_t sec_size = is64_ ? sizeof(details::section_64) :
                                  sizeof(details::section_32);
  const size_t data_size = content.size();
  const int32_t needed_size = align(sec_size + data_size, page_size());
  if (available_command_space_ < needed_size) {
    shift(needed_size);
    available_command_space_ += needed_size;
    return add_section(segment, section);
  }

  if (!extend(*target_segment, sec_size)) {
    LIEF_ERR("Unable to extend segment '{}' by 0x{:x}", segment.name(), sec_size);
    return nullptr;
  }

  available_command_space_ -= needed_size;

  auto new_section = std::make_unique<Section>(section);
  // Compute offset, virtual address etc for the new section
  // =======================================================

  // Section raw data will be located just after commands table
  if (section.offset() == 0) {
    uint64_t new_offset = is64_ ? sizeof(details::mach_header_64) :
                                  sizeof(details::mach_header);
    new_offset += header().sizeof_cmds();
    new_offset += available_command_space_;
    new_section->offset(new_offset);
  }

  if (section.size() == 0) {
    new_section->size(data_size);
  }

  if (section.virtual_address() == 0) {
    new_section->virtual_address(target_segment->virtual_address() + new_section->offset());
  }

  new_section->segment_ = target_segment;
  target_segment->numberof_sections(target_segment->numberof_sections() + 1);

  // Copy the new section in the cache
  sections_.push_back(new_section.get());

  // Copy data to segment
  const size_t relative_offset = new_section->offset() - target_segment->file_offset();

  std::move(std::begin(content), std::end(content),
            std::begin(target_segment->data_) + relative_offset);

  target_segment->sections_.push_back(std::move(new_section));
  return target_segment->sections_.back().get();
}
Section* Binary::add_section(const SegmentCommand& segment, const Section& section) {

  const auto it_segment = std::find_if(
      std::begin(segments_), std::end(segments_),
      [&segment] (const SegmentCommand* s) {
        return segment == *s;
      });

  if (it_segment == std::end(segments_)) {
    LIEF_ERR("Unable to find segment: '{}'", segment.name());
    return nullptr;
  }
  SegmentCommand* target_segment = *it_segment;

  span<const uint8_t> content_ref = section.content();
  Section::content_t content = {std::begin(content_ref), std::end(content_ref)};

  const size_t sec_size = is64_ ? sizeof(details::section_64) :
                                  sizeof(details::section_32);
  const size_t data_size = content.size();
  const int32_t needed_size = align(sec_size + data_size, page_size());
  if (available_command_space_ < needed_size) {
    shift(needed_size);
    available_command_space_ += needed_size;
    return add_section(segment, section);
  }

  if (!extend(*target_segment, sec_size)) {
    LIEF_ERR("Unable to extend segment '{}' by 0x{:x}", segment.name(), sec_size);
    return nullptr;
  }

  available_command_space_ -= needed_size;

  auto new_section = std::make_unique<Section>(section);
   
   

   
  if (section.offset() == 0) {
    uint64_t new_offset = is64_ ? sizeof(details::mach_header_64) :
                                  sizeof(details::mach_header);
    new_offset += header().sizeof_cmds();
    new_offset += available_command_space_;
    new_section->offset(new_offset);
  }

  if (section.size() == 0) {
    new_section->size(data_size);
  }

  if (section.virtual_address() == 0) {
    new_section->virtual_address(target_segment->virtual_address() + new_section->offset());
  }

  new_section->segment_ = target_segment;
  target_segment->numberof_sections(target_segment->numberof_sections() + 1);

   
  sections_.push_back(new_section.get());

   
  const size_t relative_offset = new_section->offset() - target_segment->file_offset();

  std::move(std::begin(content), std::end(content),
            std::begin(target_segment->data_) + relative_offset);

  target_segment->sections_.push_back(std::move(new_section));
  return target_segment->sections_.back().get();
}