Skip to content

Commit

Permalink
i#5383 mac a64, part 5: Get hello,world to run (#6184)
Browse files Browse the repository at this point in the history
Fixes global references in aarch64.asm which were loading the value
instead of the address (the Linux a64 assembler auto-magically gives the
address whether using ADD or LDR!).

Fixes and clarifies the Mac64 x86 and arm TLS slots vs offsets.

Uses gettimeofday() for query_time_seconds() instead of
SYS_gettimeofday.

Removes an invalid hardcoded 0 sysnum for global_do_syscall.

Issue: #5383
  • Loading branch information
derekbruening committed Jul 5, 2023
1 parent 092bc59 commit f3f909b
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 21 deletions.
19 changes: 12 additions & 7 deletions core/arch/aarch64/aarch64.asm
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2019-2022 Google, Inc. All rights reserved.
* Copyright (c) 2019-2023 Google, Inc. All rights reserved.
* Copyright (c) 2016 ARM Limited. All rights reserved.
* **********************************************************/

Expand Down Expand Up @@ -105,6 +105,12 @@ DECL_EXTERN(dr_setjmp_sigmask)

DECL_EXTERN(d_r_internal_error)

DECL_EXTERN(exiting_thread_count)
DECL_EXTERN(d_r_initstack)
DECL_EXTERN(initstack_mutex)
DECL_EXTERN(icache_op_struct)
DECL_EXTERN(linkstub_selfmod)

/* For debugging: report an error if the function called by call_switch_stack()
* unexpectedly returns. Also used elsewhere.
*/
Expand Down Expand Up @@ -325,7 +331,7 @@ GLOBAL_LABEL(cleanup_and_terminate:)
#endif

/* inc exiting_thread_count to avoid being killed once off all_threads list */
AARCH64_ADRP_GOT_LDR(GLOBAL_REF(exiting_thread_count), x0)
AARCH64_ADRP_GOT(GLOBAL_REF(exiting_thread_count), x0)
CALLC2(GLOBAL_REF(atomic_add), x0, #1)

/* save dcontext->dstack for freeing later and set dcontext->is_exiting */
Expand All @@ -349,7 +355,7 @@ cat_thread_only:
CALLC0(GLOBAL_REF(dynamo_thread_exit))
cat_no_thread:
/* switch to d_r_initstack for cleanup of dstack */
AARCH64_ADRP_GOT_LDR(GLOBAL_REF(initstack_mutex), x26)
AARCH64_ADRP_GOT(GLOBAL_REF(initstack_mutex), x26)
cat_spin:
CALLC2(GLOBAL_REF(atomic_swap), x26, #1)
cbz w0, cat_have_lock
Expand All @@ -358,20 +364,20 @@ cat_spin:

cat_have_lock:
/* switch stack */
AARCH64_ADRP_GOT_LDR(GLOBAL_REF(d_r_initstack), x0)
AARCH64_ADRP_GOT(GLOBAL_REF(d_r_initstack), x0)
ldr x0, [x0]
mov sp, x0

/* free dstack and call the EXIT_DR_HOOK */
CALLC1(GLOBAL_REF(dynamo_thread_stack_free_and_exit), x24) /* pass dstack */

/* give up initstack_mutex */
AARCH64_ADRP_GOT_LDR(GLOBAL_REF(initstack_mutex), x0)
AARCH64_ADRP_GOT(GLOBAL_REF(initstack_mutex), x0)
mov x1, #0
str x1, [x0]

/* dec exiting_thread_count (allows another thread to kill us) */
AARCH64_ADRP_GOT_LDR(GLOBAL_REF(exiting_thread_count), x0)
AARCH64_ADRP_GOT(GLOBAL_REF(exiting_thread_count), x0)
CALLC2(GLOBAL_REF(atomic_add), x0, #-1)

/* put system call number in x8 */
Expand Down Expand Up @@ -401,7 +407,6 @@ GLOBAL_LABEL(atomic_add:)
DECLARE_FUNC(global_do_syscall_int)
GLOBAL_LABEL(global_do_syscall_int:)
#ifdef MACOS
mov x16, #0
svc #0x80
#else
/* FIXME i#1569: NYI on AArch64 */
Expand Down
5 changes: 1 addition & 4 deletions core/arch/aarchxx/emit_utils.c
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2014-2022 Google, Inc. All rights reserved.
* Copyright (c) 2014-2023 Google, Inc. All rights reserved.
* Copyright (c) 2016 ARM Limited. All rights reserved.
* **********************************************************/

Expand Down Expand Up @@ -66,9 +66,6 @@ insert_load_dr_tls_base(dcontext_t *dcontext, instrlist_t *ilist, instr_t *where
/* ldr dr_reg_stolen, [reg_base, DR_TLS_BASE_OFFSET] */
PRE(ilist, where,
XINST_CREATE_load(dcontext, opnd_create_reg(dr_reg_stolen),
/* TODO i#5383: For MACOS && AARCH64 we need to verify the
* offset: PR #5497 had an 8x multiplier here.
*/
OPND_CREATE_MEMPTR(reg_base, DR_TLS_BASE_OFFSET)));
}

Expand Down
2 changes: 1 addition & 1 deletion core/ir/aarch64/codec.c
Expand Up @@ -9168,7 +9168,7 @@ decode_common(dcontext_t *dcontext, byte *pc, byte *orig_pc, instr_t *instr)
*/
if ((enc & 0xfffff01f) == 0xd503201f) {
SYSLOG_INTERNAL_WARNING("Undefined HINT instruction found: "
"encoding 0x%x (CRm:op2 0x%x)\n",
"encoding 0x%x (CRm:op2 0x%x)",
enc, (enc & 0xfe0) >> 5);
instr_set_opcode(instr, OP_nop);
instr_set_num_opnds(dcontext, instr, 0, 0);
Expand Down
16 changes: 13 additions & 3 deletions core/unix/os.c
Expand Up @@ -1329,14 +1329,22 @@ uint
query_time_seconds(void)
{
struct timeval current_time;
#if defined(MACOS) && defined(AARCH64)
/* TODO i#5383: Replace with a system call (unless we're sure this library call
* is re-entrant, just a simple load from commpage).
*/
# undef gettimeofday /* Remove "gettimeofday_forbidden_function". */
uint64 val = gettimeofday(&current_time, NULL);
#else
uint64 val = dynamorio_syscall(SYS_gettimeofday, 2, &current_time, NULL);
#ifdef MACOS
# ifdef MACOS
/* MacOS before Sierra returns usecs:secs and does not set the timeval struct. */
if (macos_version < MACOS_VERSION_SIERRA) {
if ((int)val < 0)
return 0;
return (uint)val + UTC_TO_EPOCH_SECONDS;
}
# endif
#endif
if ((int)val >= 0) {
return current_time.tv_sec + UTC_TO_EPOCH_SECONDS;
Expand All @@ -1358,7 +1366,9 @@ query_time_millis()
#if !(defined(MACOS) && defined(AARCH64))
uint64 val = dynamorio_syscall(SYS_gettimeofday, 2, &current_time, NULL);
#else
/* TODO i#5383: Replace with a system call. */
/* TODO i#5383: Replace with a system call (unless we're sure this library call
* is re-entrant, just a simple load from commpage).
*/
# undef gettimeofday /* Remove "gettimeofday_forbidden_function". */
uint64 val = gettimeofday(&current_time, NULL);
#endif
Expand Down Expand Up @@ -2103,7 +2113,7 @@ get_segment_base(uint seg)
{
#if defined(MACOS64) && defined(X86)
ptr_uint_t *pthread_self = (ptr_uint_t *)read_thread_register(seg);
return (byte *)&pthread_self[SEG_TLS_BASE_OFFSET];
return (byte *)&pthread_self[SEG_TLS_BASE_SLOT];
#elif defined(X86)
if (seg == SEG_CS || seg == SEG_SS || seg == SEG_DS || seg == SEG_ES)
return NULL;
Expand Down
7 changes: 4 additions & 3 deletions core/unix/os_exports.h
Expand Up @@ -152,10 +152,11 @@
* limited interoperability w/ code targeting the Windows x64 ABI. We steal slot 6
* for our own use.
*/
# define SEG_TLS_BASE_OFFSET 28 /* offset from pthread_t struct to segment base */
# define DR_TLS_BASE_SLOT 6 /* the TLS slot for DR's TLS base */
/* XXX i#5383: This is used as *8 so it's really a slot not a byte offset. */
# define SEG_TLS_BASE_SLOT 28 /* offset from pthread_t struct to segment base */
# define DR_TLS_BASE_SLOT 6 /* the TLS slot for DR's TLS base */
/* offset from pthread_t struct to slot 6 */
# define DR_TLS_BASE_OFFSET (SEG_TLS_BASE_OFFSET + DR_TLS_BASE_SLOT)
# define DR_TLS_BASE_OFFSET (sizeof(void *) * (SEG_TLS_BASE_SLOT + DR_TLS_BASE_SLOT))
#endif

#if defined(AARCHXX) && !defined(MACOS64)
Expand Down
11 changes: 8 additions & 3 deletions core/unix/tls_macos.c
@@ -1,5 +1,5 @@
/* *******************************************************************************
* Copyright (c) 2013-2022 Google, Inc. All rights reserved.
* Copyright (c) 2013-2023 Google, Inc. All rights reserved.
* *******************************************************************************/

/*
Expand Down Expand Up @@ -185,7 +185,7 @@ tls_get_dr_addr(void)
byte **
get_app_tls_swap_slot_addr(void)
{
byte **app_tls_base = (byte **)read_thread_register(TLS_REG_LIB);
byte *app_tls_base = (byte *)read_thread_register(TLS_REG_LIB);
if (app_tls_base == NULL) {
ASSERT_NOT_IMPLEMENTED(false);
}
Expand All @@ -199,7 +199,12 @@ tls_thread_init(os_local_state_t *os_tls, byte *segment)
#ifdef X64
/* For now we have both a directly-addressable os_local_state_t and a pointer to
* it in slot 6. If we settle on always doing the full os_local_state_t in slots,
* we would probably get rid of the use of slot 6.
* we would probably get rid of the use of slot 6 on x86 (on aarch64 the
* os_local_state_t slots are not directly addressible; we rely on the stolen
* register, whose value is populated from the pointer in slot 6 -- which could
* be moved to a slot right before os_local_state_t or something I suppose, or
* we could move the whole os_local_state_t to our own mmap since we access
* through a pointer anyway).
*/
byte **tls_swap_slot;
ASSERT((byte *)(os_tls->self) == segment);
Expand Down

0 comments on commit f3f909b

Please sign in to comment.