mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 23:55:39 +00:00
f336fc39eb
Our use of glib is now pervasive across QEMU. Move the include of glib-compat.h from qemu-common.h to osdep.h so that it is more widely accessible and doesn't get forgotten by accident. (Failure to include it will result in build failure on old versions of glib which is likely to be unnoticed by most developers.) Backports commit 529490e5d664a20d5c4223070dd7c03a0e02b6bd from qemu
293 lines
10 KiB
C
293 lines
10 KiB
C
|
|
/* Common header file that is included by all of QEMU.
|
|
*
|
|
* This file is supposed to be included only by .c files. No header file should
|
|
* depend on qemu-common.h, as this would easily lead to circular header
|
|
* dependencies.
|
|
*
|
|
* If a header file uses a definition from qemu-common.h, that definition
|
|
* must be moved to a separate header file, and the header that uses it
|
|
* must include that header.
|
|
*/
|
|
#ifndef QEMU_COMMON_H
|
|
#define QEMU_COMMON_H
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "qemu/typedefs.h"
|
|
#include "qemu/fprintf-fn.h"
|
|
#include "exec/cpu-common.h"
|
|
|
|
#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__) || defined(__ia64__)
|
|
#define WORDS_ALIGNED
|
|
#endif
|
|
|
|
#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
|
|
|
|
#include "unicorn/platform.h"
|
|
|
|
/* HOST_LONG_BITS is the size of a native pointer in bits. */
|
|
#if UINTPTR_MAX == UINT32_MAX
|
|
# define HOST_LONG_BITS 32
|
|
#elif UINTPTR_MAX == UINT64_MAX
|
|
# define HOST_LONG_BITS 64
|
|
#else
|
|
# error Unknown pointer size
|
|
#endif
|
|
|
|
#include "qemu/bswap.h"
|
|
|
|
/* FIXME: Remove NEED_CPU_H. */
|
|
#ifdef NEED_CPU_H
|
|
#include "cpu.h"
|
|
#endif /* !defined(NEED_CPU_H) */
|
|
|
|
/* util/cutils.c */
|
|
/**
|
|
* pstrcpy:
|
|
* @buf: buffer to copy string into
|
|
* @buf_size: size of @buf in bytes
|
|
* @str: string to copy
|
|
*
|
|
* Copy @str into @buf, including the trailing NUL, but do not
|
|
* write more than @buf_size bytes. The resulting buffer is
|
|
* always NUL terminated (even if the source string was too long).
|
|
* If @buf_size is zero or negative then no bytes are copied.
|
|
*
|
|
* This function is similar to strncpy(), but avoids two of that
|
|
* function's problems:
|
|
* * if @str fits in the buffer, pstrcpy() does not zero-fill the
|
|
* remaining space at the end of @buf
|
|
* * if @str is too long, pstrcpy() will copy the first @buf_size-1
|
|
* bytes and then add a NUL
|
|
*/
|
|
void pstrcpy(char *buf, int buf_size, const char *str);
|
|
/**
|
|
* strpadcpy:
|
|
* @buf: buffer to copy string into
|
|
* @buf_size: size of @buf in bytes
|
|
* @str: string to copy
|
|
* @pad: character to pad the remainder of @buf with
|
|
*
|
|
* Copy @str into @buf (but *not* its trailing NUL!), and then pad the
|
|
* rest of the buffer with the @pad character. If @str is too large
|
|
* for the buffer then it is truncated, so that @buf contains the
|
|
* first @buf_size characters of @str, with no terminator.
|
|
*/
|
|
void strpadcpy(char *buf, int buf_size, const char *str, char pad);
|
|
/**
|
|
* pstrcat:
|
|
* @buf: buffer containing existing string
|
|
* @buf_size: size of @buf in bytes
|
|
* @s: string to concatenate to @buf
|
|
*
|
|
* Append a copy of @s to the string already in @buf, but do not
|
|
* allow the buffer to overflow. If the existing contents of @buf
|
|
* plus @str would total more than @buf_size bytes, then write
|
|
* as much of @str as will fit followed by a NUL terminator.
|
|
*
|
|
* @buf must already contain a NUL-terminated string, or the
|
|
* behaviour is undefined.
|
|
*
|
|
* Returns: @buf.
|
|
*/
|
|
char *pstrcat(char *buf, int buf_size, const char *s);
|
|
/**
|
|
* strstart:
|
|
* @str: string to test
|
|
* @val: prefix string to look for
|
|
* @ptr: NULL, or pointer to be written to indicate start of
|
|
* the remainder of the string
|
|
*
|
|
* Test whether @str starts with the prefix @val.
|
|
* If it does (including the degenerate case where @str and @val
|
|
* are equal) then return true. If @ptr is not NULL then a
|
|
* pointer to the first character following the prefix is written
|
|
* to it. If @val is not a prefix of @str then return false (and
|
|
* @ptr is not written to).
|
|
*
|
|
* Returns: true if @str starts with prefix @val, false otherwise.
|
|
*/
|
|
int strstart(const char *str, const char *val, const char **ptr);
|
|
/**
|
|
* stristart:
|
|
* @str: string to test
|
|
* @val: prefix string to look for
|
|
* @ptr: NULL, or pointer to be written to indicate start of
|
|
* the remainder of the string
|
|
*
|
|
* Test whether @str starts with the case-insensitive prefix @val.
|
|
* This function behaves identically to strstart(), except that the
|
|
* comparison is made after calling qemu_toupper() on each pair of
|
|
* characters.
|
|
*
|
|
* Returns: true if @str starts with case-insensitive prefix @val,
|
|
* false otherwise.
|
|
*/
|
|
int stristart(const char *str, const char *val, const char **ptr);
|
|
/**
|
|
* qemu_strnlen:
|
|
* @s: string
|
|
* @max_len: maximum number of bytes in @s to scan
|
|
*
|
|
* Return the length of the string @s, like strlen(), but do not
|
|
* examine more than @max_len bytes of the memory pointed to by @s.
|
|
* If no NUL terminator is found within @max_len bytes, then return
|
|
* @max_len instead.
|
|
*
|
|
* This function has the same behaviour as the POSIX strnlen()
|
|
* function.
|
|
*
|
|
* Returns: length of @s in bytes, or @max_len, whichever is smaller.
|
|
*/
|
|
int qemu_strnlen(const char *s, int max_len);
|
|
/**
|
|
* qemu_strsep:
|
|
* @input: pointer to string to parse
|
|
* @delim: string containing delimiter characters to search for
|
|
*
|
|
* Locate the first occurrence of any character in @delim within
|
|
* the string referenced by @input, and replace it with a NUL.
|
|
* The location of the next character after the delimiter character
|
|
* is stored into @input.
|
|
* If the end of the string was reached without finding a delimiter
|
|
* character, then NULL is stored into @input.
|
|
* If @input points to a NULL pointer on entry, return NULL.
|
|
* The return value is always the original value of *@input (and
|
|
* so now points to a NUL-terminated string corresponding to the
|
|
* part of the input up to the first delimiter).
|
|
*
|
|
* This function has the same behaviour as the BSD strsep() function.
|
|
*
|
|
* Returns: the pointer originally in @input.
|
|
*/
|
|
char *qemu_strsep(char **input, const char *delim);
|
|
int qemu_strtol(const char *nptr, const char **endptr, int base,
|
|
long *result);
|
|
|
|
|
|
/*
|
|
* strtosz() suffixes used to specify the default treatment of an
|
|
* argument passed to strtosz() without an explicit suffix.
|
|
* These should be defined using upper case characters in the range
|
|
* A-Z, as strtosz() will use qemu_toupper() on the given argument
|
|
* prior to comparison.
|
|
*/
|
|
#define STRTOSZ_DEFSUFFIX_EB 'E'
|
|
#define STRTOSZ_DEFSUFFIX_PB 'P'
|
|
#define STRTOSZ_DEFSUFFIX_TB 'T'
|
|
#define STRTOSZ_DEFSUFFIX_GB 'G'
|
|
#define STRTOSZ_DEFSUFFIX_MB 'M'
|
|
#define STRTOSZ_DEFSUFFIX_KB 'K'
|
|
#define STRTOSZ_DEFSUFFIX_B 'B'
|
|
int64_t strtosz(const char *nptr, char **end);
|
|
int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix);
|
|
int64_t strtosz_suffix_unit(const char *nptr, char **end,
|
|
const char default_suffix, int64_t unit);
|
|
|
|
/* used to print char* safely */
|
|
#define STR_OR_NULL(str) ((str) ? (str) : "null")
|
|
|
|
#define qemu_isalnum(c) isalnum((unsigned char)(c))
|
|
#define qemu_isalpha(c) isalpha((unsigned char)(c))
|
|
#define qemu_iscntrl(c) iscntrl((unsigned char)(c))
|
|
#define qemu_isdigit(c) isdigit((unsigned char)(c))
|
|
#define qemu_isgraph(c) isgraph((unsigned char)(c))
|
|
#define qemu_islower(c) islower((unsigned char)(c))
|
|
#define qemu_isprint(c) isprint((unsigned char)(c))
|
|
#define qemu_ispunct(c) ispunct((unsigned char)(c))
|
|
#define qemu_isspace(c) isspace((unsigned char)(c))
|
|
#define qemu_isupper(c) isupper((unsigned char)(c))
|
|
#define qemu_isxdigit(c) isxdigit((unsigned char)(c))
|
|
#define qemu_tolower(c) tolower((unsigned char)(c))
|
|
#define qemu_toupper(c) toupper((unsigned char)(c))
|
|
#define qemu_isascii(c) isascii((unsigned char)(c))
|
|
#define qemu_toascii(c) toascii((unsigned char)(c))
|
|
|
|
void *qemu_oom_check(void *ptr);
|
|
|
|
#ifdef _WIN32
|
|
/* MinGW needs type casts for the 'buf' and 'optval' arguments. */
|
|
#define qemu_getsockopt(sockfd, level, optname, optval, optlen) \
|
|
getsockopt(sockfd, level, optname, (void *)optval, optlen)
|
|
#define qemu_setsockopt(sockfd, level, optname, optval, optlen) \
|
|
setsockopt(sockfd, level, optname, (const void *)optval, optlen)
|
|
#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, (void *)buf, len, flags)
|
|
#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
|
|
sendto(sockfd, (const void *)buf, len, flags, destaddr, addrlen)
|
|
#else
|
|
#define qemu_getsockopt(sockfd, level, optname, optval, optlen) \
|
|
getsockopt(sockfd, level, optname, optval, optlen)
|
|
#define qemu_setsockopt(sockfd, level, optname, optval, optlen) \
|
|
setsockopt(sockfd, level, optname, optval, optlen)
|
|
#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, buf, len, flags)
|
|
#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
|
|
sendto(sockfd, buf, len, flags, destaddr, addrlen)
|
|
#endif
|
|
|
|
/* Error handling. */
|
|
|
|
void tcg_exec_init(struct uc_struct *uc, unsigned long tb_size);
|
|
bool tcg_enabled(struct uc_struct *uc);
|
|
|
|
struct uc_struct;
|
|
void cpu_exec_init_all(struct uc_struct *uc);
|
|
|
|
/* Round number down to multiple */
|
|
#define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m))
|
|
|
|
/* Round number up to multiple */
|
|
#define QEMU_ALIGN_UP(n, m) QEMU_ALIGN_DOWN((n) + (m) - 1, (m))
|
|
|
|
#include "qemu/module.h"
|
|
|
|
/* vector definitions */
|
|
#ifdef __ALTIVEC__
|
|
#include <altivec.h>
|
|
/* The altivec.h header says we're allowed to undef these for
|
|
* C++ compatibility. Here we don't care about C++, but we
|
|
* undef them anyway to avoid namespace pollution.
|
|
*/
|
|
#undef vector
|
|
#undef pixel
|
|
#undef bool
|
|
#define VECTYPE __vector unsigned char
|
|
#define SPLAT(p) vec_splat(vec_ld(0, p), 0)
|
|
#define ALL_EQ(v1, v2) vec_all_eq(v1, v2)
|
|
#define VEC_OR(v1, v2) ((v1) | (v2))
|
|
/* altivec.h may redefine the bool macro as vector type.
|
|
* Reset it to POSIX semantics. */
|
|
#define bool _Bool
|
|
#elif defined __SSE2__
|
|
#include <emmintrin.h>
|
|
#define VECTYPE __m128i
|
|
#define SPLAT(p) _mm_set1_epi8(*(p))
|
|
#define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0xFFFF)
|
|
#define VEC_OR(v1, v2) (_mm_or_si128(v1, v2))
|
|
#else
|
|
#define VECTYPE unsigned long
|
|
#define SPLAT(p) (*(p) * (~0UL / 255))
|
|
#define ALL_EQ(v1, v2) ((v1) == (v2))
|
|
#define VEC_OR(v1, v2) ((v1) | (v2))
|
|
#endif
|
|
|
|
// support for calling functions before main code is executed.
|
|
#if defined(_MSC_VER)
|
|
#pragma section(".CRT$XCU",read)
|
|
#define INITIALIZER2_(f,p) \
|
|
static void f(void); \
|
|
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
|
|
__pragma(comment(linker,"/include:" p #f "_")) \
|
|
static void f(void)
|
|
#ifdef _WIN64
|
|
#define INITIALIZER(f) INITIALIZER2_(f,"")
|
|
#else
|
|
#define INITIALIZER(f) INITIALIZER2_(f,"_")
|
|
#endif
|
|
#else
|
|
#define INITIALIZER(f) \
|
|
static void f(void) __attribute__((constructor)); \
|
|
static void f(void)
|
|
#endif
|
|
|
|
#endif
|