#ifndef __SCC_MCODE_H__ #define __SCC_MCODE_H__ #include typedef enum { SCC_MCODE_ARCH_NONE, SCC_MCODE_ARCH_X86_64, } scc_mcode_arch_t; typedef SCC_VEC(u8) scc_mcode_buff_t; typedef struct { cbool is_littel_endian; scc_mcode_arch_t arch; scc_mcode_buff_t code; } scc_mcode_t; static inline void scc_mcode_init(scc_mcode_t *mcode, scc_mcode_arch_t arch) { scc_vec_init(mcode->code); mcode->arch = arch; mcode->is_littel_endian = true; } static inline char *scc_mcode_unsafe_data(scc_mcode_t *mcode) { return (char *)scc_vec_unsafe_get_data(mcode->code); } static inline usize scc_mcode_size(scc_mcode_t *mcode) { return scc_vec_size(mcode->code); } static inline void scc_mcode_drop(scc_mcode_t *mcode) { scc_vec_free(mcode->code); mcode->arch = SCC_MCODE_ARCH_NONE; mcode->is_littel_endian = true; } /** * @brief 接管一个现有缓冲区的所有权作为 mcode 的代码数据 * * 释放 mcode 原有的 code 缓冲区, 然后将 buf 的内部指针/容量/大小 * 转移到 mcode->code。调用后 buf 被重新初始化(空向量)。 * 避免拷贝大块代码数据。 */ static inline void scc_mcode_adopt_buf(scc_mcode_t *mcode, scc_mcode_buff_t *buf) { scc_vec_free(mcode->code); mcode->code.size = buf->size; mcode->code.cap = buf->cap; mcode->code.data = buf->data; buf->size = 0; buf->cap = 0; buf->data = NULL; } /** * @brief 释放 mcode 内部 code 缓冲区的所有权到目标向量 * * 将 mcode->code 的数据指针/容量/大小转移到 out 向量, * 然后 mcode->code 被重新初始化(空向量)。 * 避免拷贝大块代码数据。 */ static inline void scc_mcode_disown_buf(scc_mcode_t *mcode, scc_mcode_buff_t *out) { scc_vec_free(*out); out->size = mcode->code.size; out->cap = mcode->code.cap; out->data = mcode->code.data; mcode->code.size = 0; mcode->code.cap = 0; mcode->code.data = NULL; } static inline void scc_mcode_add_u8(scc_mcode_t *mcode, u8 data) { scc_vec_push(mcode->code, data); } static inline void scc_mcode_add_u16(scc_mcode_t *mcode, u16 data) { if (mcode->is_littel_endian) { scc_vec_push(mcode->code, (u8)(data & 0xFF)); scc_vec_push(mcode->code, (u8)(data >> 8)); } else { scc_vec_push(mcode->code, (u8)(data >> 8)); scc_vec_push(mcode->code, (u8)(data & 0xFF)); } } static inline void scc_mcode_add_u32(scc_mcode_t *mcode, u32 data) { if (mcode->is_littel_endian) { scc_vec_push(mcode->code, (u8)(data & 0xFF)); scc_vec_push(mcode->code, (u8)(data >> 8)); scc_vec_push(mcode->code, (u8)(data >> 16)); scc_vec_push(mcode->code, (u8)(data >> 24)); } else { scc_vec_push(mcode->code, (u8)(data >> 24)); scc_vec_push(mcode->code, (u8)(data >> 16)); scc_vec_push(mcode->code, (u8)(data >> 8)); scc_vec_push(mcode->code, (u8)(data & 0xFF)); } } static inline void scc_mcode_add_u64(scc_mcode_t *mcode, uint64_t data) { if (mcode->is_littel_endian) { scc_vec_push(mcode->code, (u8)(data & 0xFF)); scc_vec_push(mcode->code, (u8)(data >> 8)); scc_vec_push(mcode->code, (u8)(data >> 16)); scc_vec_push(mcode->code, (u8)(data >> 24)); scc_vec_push(mcode->code, (u8)(data >> 32)); scc_vec_push(mcode->code, (u8)(data >> 40)); scc_vec_push(mcode->code, (u8)(data >> 48)); scc_vec_push(mcode->code, (u8)(data >> 56)); } else { scc_vec_push(mcode->code, (u8)(data >> 56)); scc_vec_push(mcode->code, (u8)(data >> 48)); scc_vec_push(mcode->code, (u8)(data >> 40)); scc_vec_push(mcode->code, (u8)(data >> 32)); scc_vec_push(mcode->code, (u8)(data >> 24)); scc_vec_push(mcode->code, (u8)(data >> 16)); scc_vec_push(mcode->code, (u8)(data >> 8)); scc_vec_push(mcode->code, (u8)(data & 0xFF)); } } #endif /* __SCC_MCODE_H__ */