[ld.so] Add a minimal dynamic linker
This commit includes a number of changes to enable loading of PIE executables: - The loader in srv.init checks for a `PT_INTERP` segment in the program its loading, and if it exists, loads the specified interpreter and passes control to it instead of the program itself. - Added ld.so the dynamic linker executable and set it as the interpreter for all user-target programs. - Program initial stack changed again to now contain a number of possible tagged structures, including a new one for ld.so's arguments, and for passing handles tagged with protocol ids. - Added a stub for a new VFS protocol. Unused so far, but srv.init will need to serve VFS requests from ld.so once I transition libraries to shared libs for user-target programs. (Right now all executables are PIE but statically linked, so they only need internal relocations.) - Added 16 and 8 bit variants of `util::bitset`. This ended up not being used, but could be useful.
This commit is contained in:
@@ -179,7 +179,126 @@ private:
|
||||
uint32_t m_bits;
|
||||
};
|
||||
|
||||
/// A statically-sized templated bitset
|
||||
template <>
|
||||
class bitset<16>
|
||||
{
|
||||
template <typename T>
|
||||
static constexpr uint16_t bit_or(T b) { return 1u << uint16_t(b); }
|
||||
|
||||
template <typename T, typename ...Args>
|
||||
static constexpr uint16_t bit_or(T b, Args... bs) { return (1u << uint16_t(b)) | bit_or(bs...); }
|
||||
|
||||
public:
|
||||
bitset(uint16_t v = 0) : m_bits {v} {}
|
||||
|
||||
bitset(const bitset<16> &o) : m_bits {o.m_bits} {}
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr bitset(Args... args) : m_bits(bit_or(args...)) {}
|
||||
|
||||
template <typename T>
|
||||
inline bitset & operator=(T v) { m_bits = static_cast<uint16_t>(v); return *this; }
|
||||
|
||||
inline constexpr operator uint16_t () const { return m_bits; }
|
||||
|
||||
template <typename T>
|
||||
__attribute__ ((force_inline))
|
||||
inline constexpr bool get(T i) const {
|
||||
return m_bits & bit(i);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__attribute__ ((force_inline))
|
||||
inline bitset & set(T i) {
|
||||
m_bits |= bit(i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__attribute__ ((force_inline))
|
||||
inline bitset & clear(T i) {
|
||||
m_bits &= ~bit(i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__attribute__ ((force_inline))
|
||||
inline bool operator[](T i) const { return get(i); }
|
||||
|
||||
inline bool empty() const { return m_bits == 0; }
|
||||
|
||||
inline constexpr uint16_t value() const { return m_bits; }
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
inline uint16_t bit(T i) const { return (1u << static_cast<uint16_t>(i)); }
|
||||
|
||||
uint16_t m_bits;
|
||||
};
|
||||
|
||||
|
||||
/// A statically-sized templated bitset
|
||||
template <>
|
||||
class bitset<8>
|
||||
{
|
||||
template <typename T>
|
||||
static constexpr uint8_t bit_or(T b) { return 1u << uint8_t(b); }
|
||||
|
||||
template <typename T, typename ...Args>
|
||||
static constexpr uint8_t bit_or(T b, Args... bs) { return (1u << uint8_t(b)) | bit_or(bs...); }
|
||||
|
||||
public:
|
||||
bitset(uint8_t v = 0) : m_bits {v} {}
|
||||
|
||||
bitset(const bitset<8> &o) : m_bits {o.m_bits} {}
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr bitset(Args... args) : m_bits(bit_or(args...)) {}
|
||||
|
||||
template <typename T>
|
||||
inline bitset & operator=(T v) { m_bits = static_cast<uint8_t>(v); return *this; }
|
||||
|
||||
inline constexpr operator uint8_t () const { return m_bits; }
|
||||
|
||||
template <typename T>
|
||||
__attribute__ ((force_inline))
|
||||
inline constexpr bool get(T i) const {
|
||||
return m_bits & bit(i);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__attribute__ ((force_inline))
|
||||
inline bitset & set(T i) {
|
||||
m_bits |= bit(i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__attribute__ ((force_inline))
|
||||
inline bitset & clear(T i) {
|
||||
m_bits &= ~bit(i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__attribute__ ((force_inline))
|
||||
inline bool operator[](T i) const { return get(i); }
|
||||
|
||||
inline bool empty() const { return m_bits == 0; }
|
||||
|
||||
inline constexpr uint8_t value() const { return m_bits; }
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
inline uint8_t bit(T i) const { return (1u << static_cast<uint8_t>(i)); }
|
||||
|
||||
uint8_t m_bits;
|
||||
};
|
||||
|
||||
using bitset64 = bitset<64>;
|
||||
using bitset32 = bitset<32>;
|
||||
using bitset16 = bitset<16>;
|
||||
using bitset8 = bitset<8>;
|
||||
|
||||
} // namespace util
|
||||
|
||||
Reference in New Issue
Block a user