pstore2
bss_section.hpp
1 //===- include/pstore/mcrepo/bss_section.hpp --------------*- mode: C++ -*-===//
2 //* _ _ _ *
3 //* | |__ ___ ___ ___ ___ ___| |_(_) ___ _ __ *
4 //* | '_ \/ __/ __| / __|/ _ \/ __| __| |/ _ \| '_ \ *
5 //* | |_) \__ \__ \ \__ \ __/ (__| |_| | (_) | | | | *
6 //* |_.__/|___/___/ |___/\___|\___|\__|_|\___/|_| |_| *
7 //* *
8 //===----------------------------------------------------------------------===//
9 //
10 // Part of the pstore project, under the Apache License v2.0 with LLVM Exceptions.
11 // See https://github.com/SNSystems/pstore/blob/master/LICENSE.txt for license
12 // information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //===----------------------------------------------------------------------===//
16 #ifndef PSTORE_MCREPO_BSS_SECTION_HPP
17 #define PSTORE_MCREPO_BSS_SECTION_HPP
18 
20 #include "pstore/mcrepo/repo_error.hpp"
21 #include "pstore/support/gsl.hpp"
22 
23 namespace pstore {
24  namespace repo {
25 
26  //* _ _ _ *
27  //* | |__ ______ ___ ___ __| |_(_)___ _ _ *
28  //* | '_ (_-<_-< (_-</ -_) _| _| / _ \ ' \ *
29  //* |_.__/__/__/ /__/\___\__|\__|_\___/_||_| *
30  //* *
31  class bss_section : public section_base {
32  public:
33  using size_type = std::uint32_t;
34 
37  bss_section (unsigned const align, size_type const size) {
38  PSTORE_STATIC_ASSERT (std::is_standard_layout<bss_section>::value);
39  PSTORE_STATIC_ASSERT (offsetof (bss_section, field64_) == 0);
40  PSTORE_STATIC_ASSERT (sizeof (bss_section) == 8);
41  PSTORE_STATIC_ASSERT (alignof (bss_section) == 8);
42 
43  PSTORE_ASSERT (bit_count::pop_count (align) == 1);
44  align_ = bit_count::ctz (align);
45  PSTORE_STATIC_ASSERT (decltype (size_)::last_bit - decltype (size_)::first_bit ==
46  sizeof (size_type) * 8);
47  size_ = size;
48  }
49 
50  bss_section (bss_section const &) = delete;
51  bss_section (bss_section &&) = delete;
52 
53  ~bss_section () noexcept = default;
54 
55  bss_section & operator= (bss_section const &) = delete;
56  bss_section & operator= (bss_section &&) = delete;
57 
58  unsigned align () const noexcept { return 1U << align_.value (); }
59  size_type size () const noexcept { return static_cast<size_type> (size_.value ()); }
60 
61  static container<internal_fixup> ifixups () { return {}; }
62  static container<external_fixup> xfixups () { return {}; }
63 
65  static std::size_t size_bytes () noexcept { return sizeof (bss_section); }
66 
67  private:
68  union {
69  std::uint64_t field64_ = 0;
76  };
77  };
78 
79  template <>
80  inline unsigned section_alignment<pstore::repo::bss_section> (
81  pstore::repo::bss_section const & section) noexcept {
82  return section.align ();
83  }
84  template <>
85  inline std::uint64_t
86  section_size<pstore::repo::bss_section> (pstore::repo::bss_section const & section) noexcept {
87  return section.size ();
88  }
89 
90  //* _ _ _ _ _ _ *
91  //* __ _ _ ___ __ _| |_(_)___ _ _ __| (_)____ __ __ _| |_ __| |_ ___ _ _ *
92  //* / _| '_/ -_) _` | _| / _ \ ' \ / _` | (_-< '_ \/ _` | _/ _| ' \/ -_) '_| *
93  //* \__|_| \___\__,_|\__|_\___/_||_| \__,_|_/__/ .__/\__,_|\__\__|_||_\___|_| *
94  //* |_| *
96  public:
98  : section_creation_dispatcher (section_kind::bss) {}
101  : section_creation_dispatcher (section_kind::bss)
102  , section_{sec} {
103  validate (sec);
104  }
105  bss_section_creation_dispatcher (section_kind const kind,
108  (void) kind;
109  PSTORE_ASSERT (kind == section_kind::bss);
110  }
111 
114 
115  ~bss_section_creation_dispatcher () noexcept override = default;
116 
118  bss_section_creation_dispatcher & operator= (bss_section_creation_dispatcher && ) noexcept = delete;
119 
120  void set_content (gsl::not_null<section_content const *> const sec) {
121  validate (sec);
122  section_ = sec;
123  }
124 
125  std::size_t size_bytes () const final;
126 
127  std::uint8_t * write (std::uint8_t * out) const final;
128 
129  private:
130  section_content const * section_ = nullptr;
131 
132  std::uintptr_t aligned_impl (std::uintptr_t in) const final;
133 
134  static void validate (gsl::not_null<section_content const *> const sec) {
135  PSTORE_ASSERT (sec->ifixups.empty () && sec->xfixups.empty ());
136  if (sec->data.size () > std::numeric_limits<bss_section::size_type>::max ()) {
137  raise (error_code::bss_section_too_large);
138  }
139  }
140  };
141 
142  template <>
145  };
146 
147  //* _ _ _ _ _ _ *
148  //* ___ ___ __| |_(_)___ _ _ __| (_)____ __ __ _| |_ __| |_ ___ _ _ *
149  //* (_-</ -_) _| _| / _ \ ' \ / _` | (_-< '_ \/ _` | _/ _| ' \/ -_) '_| *
150  //* /__/\___\__|\__|_\___/_||_| \__,_|_/__/ .__/\__,_|\__\__|_||_\___|_| *
151  //* |_| *
152  class bss_section_dispatcher final : public dispatcher {
153  public:
154  explicit bss_section_dispatcher (bss_section const & b) noexcept
155  : b_{b} {}
156  bss_section_dispatcher (unsigned const align, bss_section::size_type const size)
157  : bss_section_dispatcher (bss_section{align, size}) {}
159  bss_section_dispatcher (bss_section_dispatcher && ) noexcept = delete;
160 
161  ~bss_section_dispatcher () noexcept override;
162 
163  bss_section_dispatcher & operator= (bss_section_dispatcher const & ) = delete;
164  bss_section_dispatcher & operator= (bss_section_dispatcher && ) = delete;
165 
166  std::size_t size_bytes () const final { return bss_section::size_bytes (); }
167  unsigned align () const final { return b_.align (); }
168  std::size_t size () const final { return b_.size (); }
169  container<internal_fixup> ifixups () const final { return {}; }
170  container<external_fixup> xfixups () const final { return {}; }
171  container<std::uint8_t> payload () const final { return {}; }
172 
173  private:
174  bss_section const & b_;
175  };
176 
177 
178  template <>
181  };
182 
183  } // end namespace repo
184 } // end namespace pstore
185 
186 #endif // PSTORE_MCREPO_BSS_SECTION_HPP
Declares the generic section.
A simple wrapper around the elements of one of the three arrays that make up a section.
Definition: section.hpp:152
Maps from the type of data that is associated with a fragment&#39;s section to a "dispatcher" subclass wh...
Definition: section.hpp:146
bit_field< std::uint64_t, 8, 32 > size_
The number of bytes in the BSS section&#39;s data payload.
Definition: bss_section.hpp:75
This class is used to add virtual methods to a fragment&#39;s section.
Definition: section.hpp:195
An empty class used as the base type for all sections.
Definition: section.hpp:69
Definition: gsl.hpp:589
bss_section(unsigned const align, size_type const size)
Definition: bss_section.hpp:37
Maps from the type of data that is associated with a fragment&#39;s section to a "dispatcher" subclass wh...
Definition: section.hpp:214
container< std::uint8_t > payload() const final
Return the data section stored in the object file.
Definition: bss_section.hpp:171
bit_field< std::uint64_t, 0, 8 > align_
The alignment of this section expressed as a power of two (i.e.
Definition: bss_section.hpp:73
Definition: bss_section.hpp:95
Definition: bss_section.hpp:31
Definition: bss_section.hpp:152
Definition: nonpod2.cpp:40
Definition: generic_section.hpp:386
static std::size_t size_bytes() noexcept
Returns the number of bytes occupied by this section.
Definition: bss_section.hpp:65
A section creation dispatcher is used to instantiate and construct each of a fragment&#39;s sections in p...
Definition: section.hpp:91