19 #ifndef PSTORE_MCREPO_GENERIC_SECTION_HPP 20 #define PSTORE_MCREPO_GENERIC_SECTION_HPP 28 #include "pstore/mcrepo/section.hpp" 32 #include "pstore/support/gsl.hpp" 35 class indirect_string;
39 using relocation_type = std::uint8_t;
47 constexpr
internal_fixup (section_kind
const section_, relocation_type
const type_,
48 std::uint64_t
const offset_,
49 std::int64_t
const addend_) noexcept
60 return section == rhs.section && type == rhs.type && offset == rhs.offset &&
64 return !operator== (rhs);
70 std::uint16_t padding1 = 0;
71 std::uint32_t padding2 = 0;
77 static_assert (std::is_standard_layout<internal_fixup>::value,
78 "internal_fixup must satisfy StandardLayoutType");
81 "section offset differs from expected value");
83 "type offset differs from expected value");
85 "padding1 offset differs from expected value");
87 "padding2 offset differs from expected value");
89 "offset offset differs from expected value");
91 "addend offset differs from expected value");
93 "internal_fixup size differs from expected value");
95 std::ostream & operator<< (std::ostream & os,
internal_fixup const & xfx);
104 std::ostream & operator<< (std::ostream & os,
binding const & b);
114 relocation_type
const type_,
binding const strength,
115 std::uint64_t
const offset_,
116 std::int64_t
const addend_) noexcept
119 , is_weak{strength == binding::weak}
129 return name == rhs.name && type == rhs.type && is_weak == rhs.is_weak &&
130 offset == rhs.offset && addend == rhs.addend;
133 return !operator== (rhs);
136 constexpr
binding strength ()
const noexcept {
137 return is_weak ? binding::weak : binding::strong;
141 relocation_type type;
142 bool is_weak =
false;
144 std::uint16_t padding1 = 0;
145 std::uint32_t padding2 = 0;
146 std::uint64_t offset;
150 static_assert (std::is_standard_layout<external_fixup>::value,
151 "external_fixup must satisfy StandardLayoutType");
153 "name offset differs from expected value");
155 "type offset differs from expected value");
157 "is_weak offset differs from expected value");
159 "padding1 offset differs from expected value");
161 "padding2 offset differs from expected value");
163 "offset offset differs from expected value");
165 "addend offset differs from expected value");
166 static_assert (
alignof (
external_fixup) == 8,
"external_fixup alignment should be 8");
168 "external_fixup size differs from expected value");
170 std::ostream & operator<< (std::ostream & os,
external_fixup const & xfx);
179 void *
operator new (std::size_t
const size,
void *
const ptr) {
180 return ::operator
new (size, ptr);
182 void operator delete (
void *
const ptr,
void *
const p) { ::operator
delete (ptr, p); }
186 template <
typename DataRangeType,
typename IFixupRangeType,
typename XFixupRangeType>
188 DataRangeType data_range;
189 IFixupRangeType ifixups_range;
190 XFixupRangeType xfixups_range;
193 template <
typename DataRange,
typename IFixupRange,
typename XFixupRange>
194 static inline auto make_sources (DataRange
const & d, IFixupRange
const & i,
195 XFixupRange
const & x)
200 template <
typename DataRange,
typename IFixupRange,
typename XFixupRange>
201 generic_section (DataRange
const & d, IFixupRange
const & i, XFixupRange
const & x,
204 template <
typename DataRange,
typename IFixupRange,
typename XFixupRange>
207 :
generic_section (src.data_range, src.ifixups_range, src.xfixups_range,
216 unsigned align ()
const noexcept {
return 1U << align_; }
218 std::uint64_t
size () const noexcept {
return data_size_; }
221 auto const *
const begin = aligned_ptr<std::uint8_t> (
this + 1);
225 auto const *
const begin = aligned_ptr<internal_fixup> (payload ().end ());
229 auto const *
const begin = aligned_ptr<external_fixup> (ifixups ().end ());
238 std::size_t size_bytes ()
const;
242 static std::size_t size_bytes (std::size_t data_size, std::size_t num_ifixups,
243 std::size_t num_xfixups);
245 template <
typename DataRange,
typename IFixupRange,
typename XFixupRange>
246 static std::size_t size_bytes (DataRange
const & d, IFixupRange
const & i,
247 XFixupRange
const & x);
249 template <
typename DataRange,
typename IFixupRange,
typename XFixupRange>
252 return size_bytes (src.data_range, src.ifixups_range, src.xfixups_range);
261 void *
operator new (std::size_t) =
delete;
262 void *
operator new (std::size_t, std::nothrow_t
const &) noexcept =
delete;
263 void *
operator new[] (std::size_t) =
delete;
264 void *
operator new[] (std::size_t, std::nothrow_t
const &) =
delete;
265 void operator delete (
void *) noexcept =
delete;
266 void operator delete (
void * ptr, std::nothrow_t
const &) noexcept =
delete;
267 void operator delete[] (
void *) noexcept =
delete;
268 void operator delete[] (
void *, std::nothrow_t
const &) noexcept =
delete;
271 std::uint32_t field32_ = 0;
279 std::uint32_t num_xfixups_ = 0;
281 std::uint64_t data_size_ = 0;
283 std::uint32_t num_ifixups () const noexcept;
287 template <typename IntType, typename Iterator,
288 typename = typename
std::enable_if<
std::is_unsigned<IntType>::value>::type>
289 static IntType set_size (Iterator first, Iterator last);
296 template <typename Ty>
297 static inline
std::
size_t part_size_bytes (
std::
size_t pos,
std::
size_t const num) {
299 pos = aligned<Ty> (pos) + num *
sizeof (Ty);
307 template <
typename DataRange,
typename IFixupRange,
typename XFixupRange>
308 generic_section::generic_section (DataRange
const & d, IFixupRange
const & i,
309 XFixupRange
const & x, std::uint8_t
const align) {
310 align_ = bit_count::ctz (align);
311 num_ifixups_ = std::uint32_t{0};
313 PSTORE_STATIC_ASSERT (std::is_standard_layout<generic_section>::value);
326 auto *
const start =
reinterpret_cast<std::uint8_t
const *
> (
this);
329 auto * p =
reinterpret_cast<std::uint8_t *
> (
this + 1);
330 PSTORE_ASSERT (bit_count::pop_count (align) == 1);
332 if (d.first != d.second) {
333 data_size_ = generic_section::set_size<decltype (data_size_)> (d.first, d.second);
334 p = std::uninitialized_copy (d.first, d.second, p);
336 if (i.first != i.second) {
337 p =
reinterpret_cast<std::uint8_t *
> (
338 std::uninitialized_copy (i.first, i.second, aligned_ptr<internal_fixup> (p)));
339 num_ifixups_ = generic_section::set_size<decltype (num_ifixups_)::value_type> (
342 if (x.first != x.second) {
343 p =
reinterpret_cast<std::uint8_t *
> (
344 std::uninitialized_copy (x.first, x.second, aligned_ptr<external_fixup> (p)));
346 generic_section::set_size<decltype (num_xfixups_)> (x.first, x.second);
348 PSTORE_ASSERT (p >= start &&
349 static_cast<std::size_t> (p - start) == size_bytes (d, i, x));
354 template <
typename IntType,
typename Iterator,
typename>
355 inline IntType generic_section::set_size (Iterator first, Iterator last) {
356 auto const size = std::distance (first, last);
361 typename std::common_type<IntType,
362 typename std::make_unsigned<decltype (size)>::type>::type;
363 return static_cast<IntType
> (
364 std::min (static_cast<common> (size),
365 static_cast<common> (std::numeric_limits<IntType>::max ())));
370 template <
typename DataRange,
typename IFixupRange,
typename XFixupRange>
372 XFixupRange
const & x) {
373 auto const data_size = std::distance (d.first, d.second);
374 auto const num_ifixups = std::distance (i.first, i.second);
375 auto const num_xfixups = std::distance (x.first, x.second);
376 PSTORE_ASSERT (data_size >= 0 && num_ifixups >= 0 && num_xfixups >= 0);
377 return size_bytes (static_cast<std::size_t> (data_size),
378 static_cast<std::size_t> (num_ifixups),
379 static_cast<std::size_t> (num_xfixups));
384 inline std::uint32_t generic_section::num_ifixups ()
const noexcept {
return num_ifixups_; }
390 section_content (section_kind
const kind_, std::uint8_t
const align_) noexcept
398 template <
typename Iterator>
399 using range = std::pair<Iterator, Iterator>;
401 template <
typename Iterator>
402 static inline auto make_range (Iterator
begin, Iterator end) -> range<Iterator> {
406 section_kind kind = section_kind::text;
407 std::uint8_t align = 1;
409 std::vector<internal_fixup> ifixups;
410 std::vector<external_fixup> xfixups;
412 auto make_sources ()
const 414 range<decltype (ifixups)::const_iterator>,
415 range<decltype (xfixups)::const_iterator>> {
417 return generic_section::make_sources (
418 make_range (std::begin (data), std::end (data)),
419 make_range (std::begin (ifixups), std::end (ifixups)),
420 make_range (std::begin (xfixups), std::end (xfixups)));
426 std::ostream & operator<< (std::ostream & os,
section_content const & c);
429 inline unsigned section_alignment<pstore::repo::generic_section> (
434 inline std::uint64_t section_size<pstore::repo::generic_section> (
464 std::size_t size_bytes ()
const final;
467 std::uint8_t * write (std::uint8_t * out)
const final;
470 std::uintptr_t aligned_impl (std::uintptr_t in)
const final;
490 std::size_t size_bytes ()
const final {
return s_.size_bytes (); }
491 unsigned align ()
const final {
return s_.align (); }
492 std::size_t size ()
const final {
return s_.size (); }
509 #endif // PSTORE_MCREPO_GENERIC_SECTION_HPP Definition: generic_section.hpp:112
A portable bit-field type.
A simple wrapper around the elements of one of the three arrays that make up a section.
Definition: section.hpp:152
std::uint64_t size() const noexcept
The number of data bytes contained by this section.
Definition: generic_section.hpp:218
Definition: chunked_sequence.hpp:607
Maps from the type of data that is associated with a fragment's section to a "dispatcher" subclass wh...
Definition: section.hpp:146
transaction< transaction_lock > begin(database &db, transaction_lock &lock)
Creates a new transaction. Every operation performed on a transaction instance can be potentially und...
Definition: transaction.hpp:311
Describes the three members of a section as three pairs of iterators: one each for the data...
Definition: generic_section.hpp:187
This class is used to add virtual methods to a fragment's section.
Definition: section.hpp:195
Definition: address.hpp:231
Definition: generic_section.hpp:177
An empty class used as the base type for all sections.
Definition: section.hpp:69
Maps from the type of data that is associated with a fragment's section to a "dispatcher" subclass wh...
Definition: section.hpp:214
std::size_t size_bytes() const
A group of member functions which return the number of bytes occupied by a fragment instance...
Definition: generic_section.cpp:83
Definition: nonpod2.cpp:40
bit_field< std::uint32_t, 8, 24 > num_ifixups_
The number of internal fixups.
Definition: generic_section.hpp:276
Definition: generic_section.hpp:386
Implements portable functions for bit twiddling operations including counting leading and trailing ze...
Definition: generic_section.hpp:445
container< std::uint8_t > payload() const final
Return the data section stored in the object file.
Definition: generic_section.hpp:495
bit_field< std::uint32_t, 0, 8 > align_
The alignment of this section expressed as a power of two (i.e.
Definition: generic_section.hpp:274
Definition: generic_section.hpp:484
A section creation dispatcher is used to instantiate and construct each of a fragment's sections in p...
Definition: section.hpp:91
Provides a small, normally stack allocated, buffer but which can be resized dynamically when necessar...
Definition: generic_section.hpp:46
binding
Defines the strength of an external reference.
Definition: generic_section.hpp:99
Functions for aligning values and pointers.