text: /* Copyright 2017 - 2022 R. Thomas
   * Copyright 2017 - 2022 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_ELF_SECTION_H_
  #define LIEF_ELF_SECTION_H_
  
  #include <string>
  #include <vector>
  #include <iostream>
  #include <set>
  
  #include "LIEF/visibility.h"
  
  #include "LIEF/Abstract/Section.hpp"
  
  #include "LIEF/ELF/enums.hpp"
  #include "LIEF/iterators.hpp"
  
  namespace LIEF {
  namespace ELF {
  
  namespace DataHandler {
  class Handler;
  }
  
  class Segment;
  class Parser;
  class Binary;
  class Builder;
  class ExeLayout;
  class ObjectFileLayout;
  
  namespace details {
  struct Elf64_Shdr;
  struct Elf32_Shdr;
  }
  
  //! Class wich represents an ELF Section
  class LIEF_API Section : public LIEF::Section {
    friend class Parser;
    friend class Binary;
    friend class Builder;
    friend class ExeLayout;
    friend class ObjectFileLayout;
  
    public:
    using segments_t        = std::vector<Segment*>;
    using it_segments       = ref_iterator<segments_t&>;
    using it_const_segments = const_ref_iterator<const segments_t&>;
  
    Section(const uint8_t *data, ELF_CLASS type);
    Section(const details::Elf64_Shdr& header);
    Section(const details::Elf32_Shdr& header);
    Section(const std::string& name, ELF_SECTION_TYPES type = ELF_SECTION_TYPES::SHT_PROGBITS);
  
    Section();
    ~Section() override;
  
    Section& operator=(Section other);
    Section(const Section& other);
    void swap(Section& other);
  
    ELF_SECTION_TYPES type() const;
  
    //! Section's content
    std::vector<uint8_t> content() const override;
  
    //! Set section content
    void content(const std::vector<uint8_t>& data) override;
  
    void content(std::vector<uint8_t>&& data);
  
    //! Section flags LIEF::ELF::ELF_SECTION_FLAGS
    uint64_t flags() const;
  
    //! ``True`` if the section has the given flag
    //!
    //! @param[in] flag flag to test
    bool has(ELF_SECTION_FLAGS flag) const;
  
    //! ``True`` if the section is wrapped by the given Segment
    bool has(const Segment& segment) const;
  
    //! Return section flags as a ``std::set``
    std::set<ELF_SECTION_FLAGS> flags_list() const;
  
    uint64_t size() const override;
  
    void size(uint64_t size) override;
  
    void offset(uint64_t offset) override;
  
    uint64_t offset() const override;
  
  
    //! @see offset
    uint64_t file_offset() const;
  
    //! Original size of the section's data.
    //!
    //! This value is used by the ELF::Builder to determines if it needs
    //! to be relocated to avoid an override of the data
    uint64_t original_size() const;
  
    //! Section file alignment
    uint64_t alignment() const;
  
    //! Section information.
    //! This meaning of this value depends on the section's type
    uint64_t information() const;
  
    //! This function returns the size of an element in the case of a section that contains
    //! an array.
    //
    //! For instance, the `.dynamic` section contains an array of DynamicEntry. As the
    //! size of the raw C structure of this entry is 0x10 (``sizeof(Elf64_Dyn)``)
    //! in a ELF64, the `entry_size` is set to this value.
    uint64_t entry_size() const;
  
    //! Index to another section
    uint32_t link() const;
  
    //! Clear the content of the section with the given ``value``
    Section& clear(uint8_t value = 0);
  
    //! Add the given ELF_SECTION_FLAGS
    void add(ELF_SECTION_FLAGS flag);
  
    //! Remove the given ELF_SECTION_FLAGS
    void remove(ELF_SECTION_FLAGS flag);
  
    void type(ELF_SECTION_TYPES type);
    void flags(uint64_t flags);
    void clear_flags();
    void file_offset(uint64_t offset);
    void link(uint32_t link);
    void information(uint32_t info);
    void alignment(uint64_t alignment);
    void entry_size(uint64_t entry_size);
  
    it_segments       segments();
    it_const_segments segments() const;
  
    void accept(Visitor& visitor) const override;
  
    Section& operator+=(ELF_SECTION_FLAGS c);
    Section& operator-=(ELF_SECTION_FLAGS c);
  
    bool operator==(const Section& rhs) const;
    bool operator!=(const Section& rhs) const;
  
    LIEF_API friend std::ostream& operator<<(std::ostream& os, const Section& section);
  
    private:
    ELF_SECTION_TYPES     type_;
    uint64_t              flags_;
    uint64_t              original_size_;
    uint32_t              link_;
    uint32_t              info_;
    uint64_t              address_align_;
    uint64_t              entry_size_;
    segments_t            segments_;
    DataHandler::Handler* datahandler_{nullptr};
    std::vector<uint8_t>  content_c_;
  };
  
  }
  }
  #endif /* _ELF_SECTION_H_ */
  