blob: 0d1f0728820e19f69452f725bfc9f038dbeb2157 [file] [log] [blame]
/* Copyright (c) 2015 Google Inc.
* Kevin Klues <klueska@cs.berkeley.edu>
* See LICENSE for details.
*/
#include <libc-symbols.h>
#include <ros/common.h>
#include <ros/trapframe.h>
#include <ros/syscall.h>
#include <parlib/stdio.h>
#include <parlib/assert.h>
#include <parlib/spinlock.h>
#include <parlib/timing.h>
#include <parlib/uthread.h>
#include <parlib/dtls.h>
#include <stdbool.h>
/* Here we define functions and variables that are really defined in parlib, but
* we need them in libc in order to link it. We weak alias them here so that the
* parlib definitions will override them later.
*
* Unfortunately, this trick only works so long as we leave parlib as a static
* library. If we ever decide to make parlib a .so, then we will have to revisit
* this and use function pointers at runtime or something similar.
*
* This also doesn't work for ld.so, which doesn't link against parlib. That's
* probably a good thing (uthread constructors would be a mess for ld, I bet).
* But that does mean that these stubs need to actually do something for
* functions that ld.so calls.
*
* Also, be careful and paranoid. If you change or add functions in here,
* recompile apps that link against libc - even if they link dynamically.
* Otherwise, when they linked with libc.so, *libc itself* (not the actual
* program) would not find the parlib functions - it would still use these
* functions. I don't have a good explanation for it, but that's what seemed to
* happen.
*
* For an example, if you write(2, "foo\n", 4) on every lock acquisition, you'll
* see one foo per process, which I think comes from ld (back when it used
* spin_pdr locks for the rtld lock). Later functions that call spin_pdr_lock,
* whether from the app, parlib, or libc, do not output foo. This is not the
* case if the application was not rebuilt before this change (e.g. bash, ssh,
* etc). */
__thread int __weak_vcoreid = 0;
extern __thread int __vcoreid __attribute__ ((weak, alias ("__weak_vcoreid")));
__thread bool __weak_vcore_context = FALSE;
extern __thread bool __vcore_context
__attribute__ ((weak, alias ("__weak_vcore_context")));
int __akaros_printf(const char *format, ...)
{
assert(0);
return -1;
}
weak_alias(__akaros_printf, akaros_printf)
int __trace_printf(const char *format, ...)
{
assert(0);
return -1;
}
weak_alias(__trace_printf, trace_printf)
void __print_user_context(struct user_context *ctx)
{
assert(0);
}
weak_alias(__print_user_context, print_user_context)
void ___assert_failed(const char *file, int line, const char *msg)
{
breakpoint();
abort();
}
weak_alias(___assert_failed, _assert_failed)
uint64_t __nsec2tsc(uint64_t nsec)
{
assert(0);
}
weak_alias(__nsec2tsc, nsec2tsc)
uint64_t __tsc2nsec(uint64_t tsc_time)
{
assert(0);
}
weak_alias(__tsc2nsec, tsc2nsec)
void __spin_pdr_init(struct spin_pdr_lock *pdr_lock)
{
assert(0);
}
weak_alias(__spin_pdr_init, spin_pdr_init)
bool __spin_pdr_trylock(struct spin_pdr_lock *pdr_lock)
{
assert(0);
}
weak_alias(__spin_pdr_trylock, spin_pdr_trylock)
void __spin_pdr_lock(struct spin_pdr_lock *pdr_lock)
{
assert(0);
}
weak_alias(__spin_pdr_lock, spin_pdr_lock)
void __spin_pdr_unlock(struct spin_pdr_lock *pdr_lock)
{
assert(0);
}
weak_alias(__spin_pdr_unlock, spin_pdr_unlock)
void __cpu_relax_vc(uint32_t vcoreid)
{
cpu_relax();
}
weak_alias(__cpu_relax_vc, cpu_relax_vc)
void __uthread_sched_yield(void)
{
/* In the off-chance we're called before parlib is available, we'll do
* the single-threaded, SCP yield. */
ros_syscall(SYS_proc_yield, TRUE, 0, 0, 0, 0, 0);
}
weak_alias(__uthread_sched_yield, uthread_sched_yield)
void __uth_mutex_init(uth_mutex_t *m)
{
assert(0);
}
weak_alias(__uth_mutex_init, uth_mutex_init)
void __uth_mutex_destroy(uth_mutex_t *m)
{
assert(0);
}
weak_alias(__uth_mutex_destroy, uth_mutex_destroy)
void __uth_mutex_lock(uth_mutex_t *m)
{
assert(0);
}
weak_alias(__uth_mutex_lock, uth_mutex_lock)
bool __uth_mutex_trylock(uth_mutex_t *m)
{
assert(0);
}
weak_alias(__uth_mutex_trylock, uth_mutex_trylock)
void __uth_mutex_unlock(uth_mutex_t *m)
{
assert(0);
}
weak_alias(__uth_mutex_unlock, uth_mutex_unlock)
void __uth_recurse_mutex_init(uth_recurse_mutex_t *r_m)
{
assert(0);
}
weak_alias(__uth_recurse_mutex_init, uth_recurse_mutex_init)
void __uth_recurse_mutex_destroy(uth_recurse_mutex_t *r_m)
{
assert(0);
}
weak_alias(__uth_recurse_mutex_destroy, uth_recurse_mutex_destroy)
void __uth_recurse_mutex_lock(uth_recurse_mutex_t *r_m)
{
assert(0);
}
weak_alias(__uth_recurse_mutex_lock, uth_recurse_mutex_lock)
bool __uth_recurse_mutex_trylock(uth_recurse_mutex_t *r_m)
{
assert(0);
}
weak_alias(__uth_recurse_mutex_trylock, uth_recurse_mutex_trylock)
void __uth_recurse_mutex_unlock(uth_recurse_mutex_t *r_m)
{
assert(0);
}
weak_alias(__uth_recurse_mutex_unlock, uth_recurse_mutex_unlock)
void __uth_rwlock_init(uth_rwlock_t *rwl)
{
assert(0);
}
weak_alias(__uth_rwlock_init, uth_rwlock_init)
void __uth_rwlock_destroy(uth_rwlock_t *rwl)
{
assert(0);
}
weak_alias(__uth_rwlock_destroy, uth_rwlock_destroy)
void __uth_rwlock_rdlock(uth_rwlock_t *rwl)
{
assert(0);
}
weak_alias(__uth_rwlock_rdlock, uth_rwlock_rdlock)
bool __uth_rwlock_try_rdlock(uth_rwlock_t *rwl)
{
assert(0);
}
weak_alias(__uth_rwlock_try_rdlock, uth_rwlock_try_rdlock)
void __uth_rwlock_wrlock(uth_rwlock_t *rwl)
{
assert(0);
}
weak_alias(__uth_rwlock_wrlock, uth_rwlock_wrlock)
bool __uth_rwlock_try_wrlock(uth_rwlock_t *rwl)
{
assert(0);
}
weak_alias(__uth_rwlock_try_wrlock, uth_rwlock_try_wrlock)
void __uth_rwlock_unlock(uth_rwlock_t *rwl)
{
assert(0);
}
weak_alias(__uth_rwlock_unlock, uth_rwlock_unlock)
dtls_key_t __dtls_key_create(dtls_dtor_t dtor)
{
assert(0);
}
weak_alias(__dtls_key_create, dtls_key_create)
void __set_dtls(dtls_key_t key, const void *dtls)
{
assert(0);
}
weak_alias(__set_dtls, set_dtls)
void *__get_dtls(dtls_key_t key)
{
assert(0);
}
weak_alias(__get_dtls, get_dtls)