Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
README.md
/build

# Prerequisites
*.d
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ set(SOURCE_FILES
co_epoll.cpp
co_hook_sys_call.cpp
co_routine.cpp
co_comm.cpp
coctx.cpp
coctx_swap.S)

Expand Down
9 changes: 8 additions & 1 deletion co_hook_sys_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,18 @@ static pthread_rwlock_unlock_pfn_t g_sys_pthread_rwlock_unlock_func

static inline unsigned long long get_tick_count()
{
#if defined(__APPLE__) || defined(__FreeBSD__)
// On macOS/FreeBSD, use mach_absolute_time or similar
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec * 1000000ULL + tv.tv_usec;
#else
uint32_t lo, hi;
__asm__ __volatile__ (
"rdtscp" : "=a"(lo), "=d"(hi)
);
return ((unsigned long long)lo) | (((unsigned long long)hi) << 32);
#endif
}

struct rpchook_connagent_head_t
Expand Down Expand Up @@ -939,7 +946,7 @@ int gethostbyname_r(const char* __restrict name,
HOOK_SYS_FUNC(gethostbyname_r);

#if defined( __APPLE__ ) || defined( __FreeBSD__ )
return g_sys_gethostbyname_r_func( name );
return g_sys_gethostbyname_r_func( name, __result_buf, __buf, __buflen, __result, __h_errnop );
#else
if (!co_is_enable_sys_hook()) {
return g_sys_gethostbyname_r_func(name, __result_buf, __buf, __buflen,
Expand Down
41 changes: 41 additions & 0 deletions coctx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,45 @@ int coctx_init(coctx_t* ctx) {
return 0;
}

#elif defined(__aarch64__) || defined(__arm64__)

enum {
kX19 = 0,
kX20 = 1,
kX21 = 2,
kX22 = 3,
kX23 = 4,
kX24 = 5,
kX25 = 6,
kX26 = 7,
kX27 = 8,
kX28 = 9,
kFP = 10, // x29 frame pointer
kLR = 11, // x30 link register
kSP = 12, // stack pointer
};

int coctx_make(coctx_t* ctx, coctx_pfn_t pfn, const void* s, const void* s1) {
char* sp = ctx->ss_sp + ctx->ss_size - sizeof(void*);
sp = (char*)((unsigned long)sp & ~15ULL); // 16-byte alignment

memset(ctx->regs, 0, sizeof(ctx->regs));

ctx->regs[kSP] = sp;
ctx->regs[kLR] = (char*)pfn; // Link register holds return address

// Pass arguments in x0 and x1 according to ARM64 calling convention
// Note: These will be passed when the coroutine starts
// Store them in callee-saved registers temporarily
ctx->regs[kX19] = (char*)s; // First argument
ctx->regs[kX20] = (char*)s1; // Second argument

return 0;
}

int coctx_init(coctx_t* ctx) {
memset(ctx, 0, sizeof(*ctx));
return 0;
}

#endif
41 changes: 41 additions & 0 deletions coctx_swap.S
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,45 @@ coctx_swap:

movq 64(%rsi), %rsi
ret

#elif defined(__aarch64__) || defined(__arm64__)
// ARM64 implementation
// Save context to x0 (first parameter)
// x0-x18: general purpose, x19-x28: callee-saved
// x29: frame pointer, x30: link register, sp: stack pointer

// Save callee-saved registers
stp x19, x20, [x0, #0]
stp x21, x22, [x0, #16]
stp x23, x24, [x0, #32]
stp x25, x26, [x0, #48]
stp x27, x28, [x0, #64]
stp x29, x30, [x0, #80]
mov x2, sp
str x2, [x0, #96]

// Save floating point registers (d8-d15 are callee-saved)
stp d8, d9, [x0, #112]
stp d10, d11, [x0, #128]
stp d12, d13, [x0, #144]
stp d14, d15, [x0, #160]

// Restore context from x1 (second parameter)
ldp x19, x20, [x1, #0]
ldp x21, x22, [x1, #16]
ldp x23, x24, [x1, #32]
ldp x25, x26, [x1, #48]
ldp x27, x28, [x1, #64]
ldp x29, x30, [x1, #80]
ldr x2, [x1, #96]
mov sp, x2

// Restore floating point registers
ldp d8, d9, [x1, #112]
ldp d10, d11, [x1, #128]
ldp d12, d13, [x1, #144]
ldp d14, d15, [x1, #160]

ret

#endif