[elf] Ressurect elf library

Resurrect the existing but unused ELF library in libraries/elf, and use
it instead of boot/elf.h for parsing ELF files in the bootloader.

Also adds a const version of offset_iterator called
const_offset_iterator.
This commit is contained in:
Justin C. Miller
2021-07-31 15:10:03 -07:00
parent 5e2cfab7ba
commit 363d30eadc
9 changed files with 189 additions and 250 deletions

View File

@@ -10,32 +10,63 @@ inline T* offset_ptr(S* input, ptrdiff_t offset) {
return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(input) + offset);
}
/// Iterator for an array of `T` whose size is known at runtime
/// Iterator for an array of `const T` whose size is known at runtime
/// \tparam T Type of the objects in the array, whose size might not be
/// what is returned by sizeof(T).
template <typename T>
class offset_iterator
class const_offset_iterator
{
public:
/// Constructor.
/// \arg t Pointer to the first item in the array
/// \arg off Offset applied to reach successive items. Default is 0,
/// which creates an effectively constant iterator.
offset_iterator(T* t, size_t off=0) : m_t(t), m_off(off) {}
const_offset_iterator(T const *t, size_t off=0) : m_t(t), m_off(off) {}
T* operator++() { m_t = offset_ptr<T>(m_t, m_off); return m_t; }
T* operator++(int) { T* tmp = m_t; operator++(); return tmp; }
const T * operator++() { m_t = offset_ptr<T>(m_t, m_off); return m_t; }
const T * operator++(int) { T* tmp = m_t; operator++(); return tmp; }
bool operator==(T* p) { return p == m_t; }
bool operator!=(T* p) { return p != m_t; }
bool operator==(offset_iterator<T> &i) { return i.m_t == m_t; }
bool operator!=(offset_iterator<T> &i) { return i.m_t != m_t; }
bool operator==(T* p) const { return p == m_t; }
bool operator!=(T* p) const { return p != m_t; }
bool operator==(const_offset_iterator<T> &i) const { return i.m_t == m_t; }
bool operator!=(const_offset_iterator<T> &i) const { return i.m_t != m_t; }
T& operator*() const { return *m_t; }
operator T& () const { return *m_t; }
T* operator->() const { return m_t; }
const T& operator*() const { return *m_t; }
operator const T& () const { return *m_t; }
const T* operator->() const { return m_t; }
private:
T* m_t;
T const *m_t;
size_t m_off;
};
/// iterator for an array of `const T` whose size is known at runtime
/// \tparam T type of the objects in the array, whose size might not be
/// what is returned by sizeof(T).
template <typename T>
class offset_iterator
{
public:
/// constructor.
/// \arg t pointer to the first item in the array
/// \arg off offset applied to reach successive items. default is 0,
/// which creates an effectively constant iterator.
offset_iterator(T *t, size_t off=0) : m_t(t), m_off(off) {}
T * operator++() { m_t = offset_ptr<T>(m_t, m_off); return m_t; }
T * operator++(int) { T* tmp = m_t; operator++(); return tmp; }
bool operator==(T *p) const { return p == m_t; }
bool operator!=(T *p) const { return p != m_t; }
bool operator==(offset_iterator<T> &i) const { return i.m_t == m_t; }
bool operator!=(offset_iterator<T> &i) const { return i.m_t != m_t; }
T & operator*() const { return *m_t; }
operator T & () const { return *m_t; }
T * operator->() const { return m_t; }
private:
T *m_t;
size_t m_off;
};