added Zydis source, asmjit source...

2.0 v1.1
_xeroxz 4 years ago
parent 0c915c05d3
commit 4af07664ce

@ -0,0 +1 @@
*.inc linguist-language=C

@ -0,0 +1 @@
github: flobernd

@ -0,0 +1,69 @@
name: GitHub Actions CI
on: [push, pull_request]
jobs:
build:
name: "Build Zydis (${{ matrix.image_name }}, ${{ matrix.no_libc }})"
runs-on: "${{ matrix.image_name }}"
strategy:
matrix:
image_name: ["macOS-latest", "windows-2016", "ubuntu-18.04"]
no_libc: ["", "-DZYAN_NO_LIBC=ON"]
include:
- image_name: "ubuntu-16.04"
no_libc: "-DCMAKE_BUILD_TYPE=Release"
dev_mode: "-DZYAN_DEV_MODE=ON"
steps:
- uses: "actions/checkout@v1"
- name: "Cloning submodules"
run: |
git submodule update --init
- name: "Configuring"
run: |
mkdir build
cd build
cmake ${{ matrix.dev_mode }} ${{ matrix.no_libc }} ..
- name: "Building"
run: |
cmake --build build --config Release
- name: "Running regression tests"
run: |
cd tests
python3 regression.py test ../build/ZydisInfo
if: "!matrix.no_libc && matrix.image_name != 'windows-2016'"
- name: "Running regression tests"
run: |
cd tests
python regression.py test ..\\build\\Release\\ZydisInfo.exe
if: "!matrix.no_libc && matrix.image_name == 'windows-2016'"
fuzzing:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sanitizer: [address, undefined, memory]
steps:
- name: Build Fuzzers (${{ matrix.sanitizer }})
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'zydis'
dry-run: false
sanitizer: ${{ matrix.sanitizer }}
- name: Run Fuzzers (${{ matrix.sanitizer }})
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'zydis'
fuzz-seconds: 600
dry-run: false
sanitizer: ${{ matrix.sanitizer }}
- name: Upload Crash
uses: actions/upload-artifact@v1
if: failure() && steps.build.outcome == 'success'
with:
name: ${{ matrix.sanitizer }}-artifacts
path: ./out/artifacts

@ -0,0 +1,101 @@
# Created by https://www.gitignore.io/api/c,c++,cmake
### C ###
# Object files
*.o
*.ko
*.obj
*.elf
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
### C++ ###
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
### CMake ###
CMakeCache.txt
CMakeFiles
CMakeScripts
Makefile
cmake_install.cmake
install_manifest.txt
CTestTestfile.cmake
# MacOS
.DS_Store
build*
# MSVC
.vs
*.vcxproj.user
*.suo
*.sdf
*.opensdf
*.VC.db
*.VC.opendb
msvc/**/*.user
msvc/**/obj/
msvc/**/bin/
doc/html
.vscode
.idea
cmake-build-debug

@ -0,0 +1,3 @@
[submodule "dependencies/zycore"]
path = dependencies/zycore
url = https://github.com/zyantific/zycore-c

@ -0,0 +1,296 @@
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
project(Zydis VERSION 3.1.0.0 LANGUAGES C CXX)
include(GenerateExportHeader)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
# =============================================================================================== #
# Overridable options #
# =============================================================================================== #
# Features
option(ZYDIS_MINIMAL_MODE
"Enable minimal mode (forces ZYDIS_DECODER_MODE_MINIMAL runtime option)"
OFF)
option(ZYDIS_FEATURE_DECODER
"Enable instruction decoding functionality"
ON)
option(ZYDIS_FEATURE_FORMATTER
"Enable instruction formatting functionality"
ON)
option(ZYDIS_FEATURE_AVX512
"Enable support for AVX-512 instructions"
ON)
option(ZYDIS_FEATURE_KNC
"Enable support for KNC instructions"
ON)
# Build configuration
option(ZYDIS_BUILD_SHARED_LIB
"Build shared library"
OFF)
option(ZYDIS_BUILD_EXAMPLES
"Build examples"
ON)
option(ZYDIS_BUILD_TOOLS
"Build tools"
ON)
option(ZYDIS_FUZZ_AFL_FAST
"Enables AFL persistent mode and reduces prints in ZydisFuzzIn"
OFF)
option(ZYDIS_LIBFUZZER
"Enables LLVM libfuzzer mode and reduces prints in ZydisFuzzIn"
OFF)
set(ZYDIS_ZYCORE_PATH
"${CMAKE_CURRENT_LIST_DIR}/dependencies/zycore"
CACHE
PATH
"The path to look for Zycore")
# =============================================================================================== #
# Dependencies #
# =============================================================================================== #
# Try to initialize the Zycore submodule using Git
if (NOT EXISTS "${ZYDIS_ZYCORE_PATH}/CMakeLists.txt" AND
"${ZYDIS_ZYCORE_PATH}" STREQUAL "${CMAKE_CURRENT_LIST_DIR}/dependencies/zycore")
find_package(Git QUIET)
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
execute_process(
COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endif()
endif ()
if (NOT EXISTS "${ZYDIS_ZYCORE_PATH}/CMakeLists.txt")
message(
FATAL_ERROR
"Can't find zycore submodule. Please make sure to clone the repo recursively.\n"
"You can fix this by running\n"
" git submodule update --init\n"
"or by cloning using\n"
" git clone --recursive <url>\n"
"Alternatively, you can manually clone zycore to some path and set ZYDIS_ZYCORE_PATH."
)
endif ()
add_subdirectory(${ZYDIS_ZYCORE_PATH} "zycore" EXCLUDE_FROM_ALL)
# =============================================================================================== #
# Library configuration #
# =============================================================================================== #
if (ZYDIS_BUILD_SHARED_LIB)
add_library("Zydis" SHARED)
else ()
add_library("Zydis" STATIC)
endif ()
target_link_libraries("Zydis" PUBLIC "Zycore")
target_include_directories("Zydis"
PUBLIC "include" ${PROJECT_BINARY_DIR}
PRIVATE "src")
target_compile_definitions("Zydis" PRIVATE "_CRT_SECURE_NO_WARNINGS" "ZYDIS_EXPORTS")
zyan_set_common_flags("Zydis")
zyan_maybe_enable_wpo_for_lib("Zydis")
generate_export_header("Zydis" BASE_NAME "ZYDIS" EXPORT_FILE_NAME "ZydisExportConfig.h")
if (ZYDIS_FEATURE_FORMATTER AND NOT ZYDIS_FEATURE_DECODER)
message(
FATAL_ERROR
"\nZYDIS_FEATURE_FORMATTER requires ZYDIS_FEATURE_DECODER to be enabled"
)
endif ()
if (ZYDIS_MINIMAL_MODE)
target_compile_definitions("Zydis" PUBLIC "ZYDIS_MINIMAL_MODE")
endif ()
if (NOT ZYDIS_FEATURE_DECODER)
target_compile_definitions("Zydis" PUBLIC "ZYDIS_DISABLE_DECODER")
endif ()
if (NOT ZYDIS_FEATURE_FORMATTER)
target_compile_definitions("Zydis" PUBLIC "ZYDIS_DISABLE_FORMATTER")
endif ()
if (NOT ZYDIS_FEATURE_AVX512)
target_compile_definitions("Zydis" PUBLIC "ZYDIS_DISABLE_AVX512")
endif ()
if (NOT ZYDIS_FEATURE_KNC)
target_compile_definitions("Zydis" PUBLIC "ZYDIS_DISABLE_KNC")
endif ()
target_sources("Zydis"
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/MetaInfo.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Mnemonic.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Register.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/SharedTypes.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/ShortString.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Status.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Utils.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Zydis.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/SharedData.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/String.h"
"src/MetaInfo.c"
"src/Mnemonic.c"
"src/Register.c"
"src/SharedData.c"
"src/String.c"
"src/Utils.c"
"src/Zydis.c")
if (ZYDIS_FEATURE_DECODER)
target_sources("Zydis"
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Decoder.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/DecoderTypes.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/DecoderData.h"
"src/Decoder.c"
"src/DecoderData.c")
if (ZYDIS_FEATURE_FORMATTER AND (NOT ZYDIS_MINIMAL_MODE))
target_sources("Zydis"
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Formatter.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/FormatterBuffer.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/FormatterATT.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/FormatterBase.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/FormatterIntel.h"
"src/Formatter.c"
"src/FormatterBuffer.c"
"src/FormatterATT.c"
"src/FormatterBase.c"
"src/FormatterIntel.c")
endif ()
endif ()
if (ZYDIS_BUILD_SHARED_LIB AND WIN32)
target_sources("Zydis" PRIVATE "resources/VersionInfo.rc")
endif ()
zyan_set_source_group("Zydis")
configure_package_config_file(cmake/zydis-config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/zydis-config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/cmake"
)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/zydis-config.cmake"
DESTINATION "${CMAKE_INSTALL_PREFIX}/cmake"
)
install(TARGETS "Zydis"
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES
"${PROJECT_BINARY_DIR}/ZydisExportConfig.h"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(DIRECTORY "include/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
function (_maybe_set_emscripten_cfg target)
if (EMSCRIPTEN)
# Yep, that madness below is how Emscripten likes its quotes.
set_target_properties("${target}"
PROPERTIES COMPILE_FLAGS
"-s \"EXPORT_NAME='${target}'\" -s MODULARIZE=1")
set_target_properties("${target}"
PROPERTIES LINK_FLAGS_RELEASE
"-s \"EXPORT_NAME='${target}'\" -s MODULARIZE=1")
endif ()
endfunction ()
# =============================================================================================== #
# Examples #
# =============================================================================================== #
if (ZYDIS_BUILD_EXAMPLES AND NOT ZYAN_NO_LIBC)
if (ZYDIS_FEATURE_DECODER AND ZYDIS_FEATURE_FORMATTER AND (NOT ZYDIS_MINIMAL_MODE))
add_executable("Formatter01" "examples/Formatter01.c")
target_link_libraries("Formatter01" "Zydis")
set_target_properties("Formatter01" PROPERTIES FOLDER "Examples/Formatter")
target_compile_definitions("Formatter01" PRIVATE "_CRT_SECURE_NO_WARNINGS")
zyan_set_common_flags("Formatter01")
zyan_maybe_enable_wpo("Formatter01")
_maybe_set_emscripten_cfg("Formatter01")
add_executable("Formatter02" "examples/Formatter02.c")
target_link_libraries("Formatter02" "Zydis")
set_target_properties("Formatter02" PROPERTIES FOLDER "Examples/Formatter")
target_compile_definitions("Formatter02" PRIVATE "_CRT_SECURE_NO_WARNINGS")
zyan_set_common_flags("Formatter02")
zyan_maybe_enable_wpo("Formatter02")
_maybe_set_emscripten_cfg("Formatter02")
add_executable("Formatter03" "examples/Formatter03.c")
target_link_libraries("Formatter03" "Zydis")
set_target_properties("Formatter03" PROPERTIES FOLDER "Examples/Formatter")
target_compile_definitions("Formatter03" PRIVATE "_CRT_SECURE_NO_WARNINGS")
zyan_set_common_flags("Formatter03")
zyan_maybe_enable_wpo("Formatter03")
_maybe_set_emscripten_cfg("Formatter03")
add_executable("ZydisPerfTest" "examples/ZydisPerfTest.c")
target_link_libraries("ZydisPerfTest" "Zydis")
set_target_properties("ZydisPerfTest" PROPERTIES FOLDER "Examples")
target_compile_definitions("ZydisPerfTest" PRIVATE "_CRT_SECURE_NO_WARNINGS")
zyan_set_common_flags("ZydisPerfTest")
zyan_maybe_enable_wpo("ZydisPerfTest")
_maybe_set_emscripten_cfg("ZydisPerfTest")
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux"
OR ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
target_compile_definitions("ZydisPerfTest" PRIVATE "_GNU_SOURCE")
find_package(Threads REQUIRED)
target_link_libraries("ZydisPerfTest" Threads::Threads)
endif ()
endif ()
endif ()
# =============================================================================================== #
# Tools #
# =============================================================================================== #
if (ZYDIS_BUILD_TOOLS AND NOT ZYAN_NO_LIBC)
if (ZYDIS_FEATURE_DECODER AND ZYDIS_FEATURE_FORMATTER AND (NOT ZYDIS_MINIMAL_MODE))
add_executable("ZydisDisasm" "tools/ZydisDisasm.c")
target_link_libraries("ZydisDisasm" "Zydis")
set_target_properties ("ZydisDisasm" PROPERTIES FOLDER "Tools")
target_compile_definitions("ZydisDisasm" PRIVATE "_CRT_SECURE_NO_WARNINGS")
zyan_set_common_flags("ZydisDisasm")
zyan_maybe_enable_wpo("ZydisDisasm")
_maybe_set_emscripten_cfg("ZydisDisasm")
install(TARGETS "ZydisDisasm" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
add_executable("ZydisFuzzIn" "tools/ZydisFuzzIn.c")
target_link_libraries("ZydisFuzzIn" "Zydis")
set_target_properties("ZydisFuzzIn" PROPERTIES FOLDER "Tools")
target_compile_definitions("ZydisFuzzIn" PRIVATE "_CRT_SECURE_NO_WARNINGS")
zyan_set_common_flags("ZydisFuzzIn")
zyan_maybe_enable_wpo("ZydisFuzzIn")
_maybe_set_emscripten_cfg("ZydisFuzzIn")
if (ZYDIS_FUZZ_AFL_FAST)
target_compile_definitions("ZydisFuzzIn" PRIVATE "ZYDIS_FUZZ_AFL_FAST")
endif ()
if (ZYDIS_LIBFUZZER)
target_compile_definitions("ZydisFuzzIn" PRIVATE "ZYDIS_LIBFUZZER")
endif ()
add_executable("ZydisInfo" "tools/ZydisInfo.c")
target_link_libraries("ZydisInfo" "Zydis")
set_target_properties ("ZydisInfo" PROPERTIES FOLDER "Tools")
target_compile_definitions("ZydisInfo" PRIVATE "_CRT_SECURE_NO_WARNINGS")
zyan_set_common_flags("ZydisInfo")
zyan_maybe_enable_wpo("ZydisInfo")
_maybe_set_emscripten_cfg("ZydisInfo")
install(TARGETS "ZydisInfo" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
add_executable("ZydisPE" "tools/ZydisPE.c")
target_link_libraries("ZydisPE" "Zydis")
set_target_properties ("ZydisPE" PROPERTIES FOLDER "Tools")
target_compile_definitions("ZydisPE" PRIVATE "_CRT_SECURE_NO_WARNINGS")
zyan_set_common_flags("ZydisPE")
zyan_maybe_enable_wpo("ZydisPE")
_maybe_set_emscripten_cfg("ZydisPE")
endif ()
endif ()

File diff suppressed because it is too large Load Diff

@ -0,0 +1,7 @@
@INCLUDE = Doxyfile
GENERATE_HTML = NO
GENERATE_XML = YES
XML_PROGRAMLISTING = NO
##!M_LINKS_NAVBAR1 = modules files
##!M_LINKS_NAVBAR2 =
##!M_FILE_TREE_EXPAND_LEVELS = 2

@ -0,0 +1,23 @@
The MIT License (MIT)
Copyright (c) 2014-2020 Florian Bernd
Copyright (c) 2014-2020 Joel Höner
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,175 @@
<p align="center">
<img alt="zydis logo" src="https://zydis.re/img/logo.svg" width="400px">
</p>
<p align="center">
<img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT">
<a href="https://github.com/zyantific/zydis/actions"><img src="https://github.com/zyantific/zydis/workflows/GitHub%20Actions%20CI/badge.svg" alt="GitHub Actions"></a>
<a href="https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:zydis"><img src="https://oss-fuzz-build-logs.storage.googleapis.com/badges/zydis.svg" alt="Fuzzing Status"></a>
<a href="https://gitter.im/zyantific/zydis?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge"><img src="https://badges.gitter.im/zyantific/zyan-disassembler-engine.svg" alt="Gitter"></a>
<a href="https://discord.zyantific.com/"><img src="https://img.shields.io/discord/390136917779415060.svg?logo=discord&label=Discord" alt="Discord"></a>
</p>
<p align="center">Fast and lightweight x86/x86-64 disassembler library.</p>
## Features
- Supports all x86 and x86-64 (AMD64) instructions and [extensions](./include/Zydis/Generated/EnumISAExt.h)
- Optimized for high performance
- No dynamic memory allocation ("malloc")
- Thread-safe by design
- Very small file-size overhead compared to other common disassembler libraries
- [Complete doxygen documentation](https://zydis.re/doc/3/)
- Absolutely no third party dependencies — not even libc
- Should compile on any platform with a working C99 compiler
- Tested on Windows, macOS, FreeBSD, Linux and UEFI, both user and kernel mode
## Quick Example
The following example program uses Zydis to disassemble a given memory buffer and prints the output to the console ([more examples here](./examples/)).
```C
#include <stdio.h>
#include <inttypes.h>
#include <Zydis/Zydis.h>
int main()
{
ZyanU8 data[] =
{
0x51, 0x8D, 0x45, 0xFF, 0x50, 0xFF, 0x75, 0x0C, 0xFF, 0x75,
0x08, 0xFF, 0x15, 0xA0, 0xA5, 0x48, 0x76, 0x85, 0xC0, 0x0F,
0x88, 0xFC, 0xDA, 0x02, 0x00
};
// Initialize decoder context
ZydisDecoder decoder;
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64);
// Initialize formatter. Only required when you actually plan to do instruction
// formatting ("disassembling"), like we do here
ZydisFormatter formatter;
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);
// Loop over the instructions in our buffer.
// The runtime-address (instruction pointer) is chosen arbitrary here in order to better
// visualize relative addressing
ZyanU64 runtime_address = 0x007FFFFFFF400000;
ZyanUSize offset = 0;
const ZyanUSize length = sizeof(data);
ZydisDecodedInstruction instruction;
while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, data + offset, length - offset,
&instruction)))
{
// Print current instruction pointer.
printf("%016" PRIX64 " ", runtime_address);
// Format & print the binary instruction structure to human readable format
char buffer[256];
ZydisFormatterFormatInstruction(&formatter, &instruction, buffer, sizeof(buffer),
runtime_address);
puts(buffer);
offset += instruction.length;
runtime_address += instruction.length;
}
}
```
## Sample Output
The above example program generates the following output:
```asm
007FFFFFFF400000 push rcx
007FFFFFFF400001 lea eax, [rbp-0x01]
007FFFFFFF400004 push rax
007FFFFFFF400005 push qword ptr [rbp+0x0C]
007FFFFFFF400008 push qword ptr [rbp+0x08]
007FFFFFFF40000B call [0x008000007588A5B1]
007FFFFFFF400011 test eax, eax
007FFFFFFF400013 js 0x007FFFFFFF42DB15
```
## Build
#### Unix
Zydis builds cleanly on most platforms without any external dependencies. You can use CMake to generate project files for your favorite C99 compiler.
```bash
git clone --recursive 'https://github.com/zyantific/zydis.git'
cd zydis
mkdir build && cd build
cmake ..
make
```
#### Windows
Either use the [Visual Studio 2017 project](./msvc/) or build Zydis using [CMake](https://cmake.org/download/) ([video guide](https://www.youtube.com/watch?v=fywLDK1OAtQ)).
#### Building Zydis - Using vcpkg
You can download and install Zydis using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
```bash
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
vcpkg install zydis
```
The Zydis port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
## Using Zydis in a CMake project
An example on how to use Zydis in your own CMake based project [can be found in this repo](https://github.com/zyantific/zydis-submodule-example).
## `ZydisInfo` tool
![ZydisInfo](./assets/screenshots/ZydisInfo.png)
## Bindings
Official bindings exist for a selection of languages:
- [Pascal](https://github.com/zyantific/zydis-pascal)
- [Python 3](https://github.com/zyantific/zydis-py)
- [Rust](https://github.com/zyantific/zydis-rs)
Unofficial but actively maintained bindings:
- [Go](https://github.com/jpap/go-zydis)
- [LuaJIT](https://github.com/Wiladams/lj2zydis)
- [Haskell](https://github.com/nerded1337/zydiskell)
## Versions
#### Scheme
Versions follow the [semantic versioning scheme](https://semver.org/). All stability guarantees apply to the API only — ABI stability between patches cannot be assumed unless explicitly mentioned in the release notes.
#### Branches & Tags
- `master` holds the bleeding edge code of the next, unreleased Zydis version. Elevated amounts of bugs and issues must be expected, API stability is not guaranteed outside of tagged commits.
- Stable and preview versions are annotated with git tags
- beta and other preview versions have `-beta`, `-rc`, etc. suffixes
- `maintenance/v2` contains the code of the latest legacy release of v2
- v2 is now deprecated, but will receive security fixes until 2021
## Credits
- Intel (for open-sourcing [XED](https://github.com/intelxed/xed), allowing for automatic comparision of our tables against theirs, improving both)
- [LLVM](https://llvm.org) (for providing pretty solid instruction data as well)
- Christian Ludloff (http://sandpile.org, insanely helpful)
- [LekoArts](https://www.lekoarts.de/) (for creating the project logo)
- Our [contributors on GitHub](https://github.com/zyantific/zydis/graphs/contributors)
## Troubleshooting
#### `-fPIC` for shared library builds
```
/usr/bin/ld: ./libfoo.a(foo.c.o): relocation R_X86_64_PC32 against symbol `bar' can not be used when making a shared object; recompile with -fPIC
```
Under some circumstances (e.g. when building Zydis as a static library using
CMake and then using Makefiles to manually link it into a shared library), CMake
might fail to detect that relocation information must be emitted. This can be forced
by passing `-DCMAKE_POSITION_INDEPENDENT_CODE=ON` to the CMake invocation.
## Donations
Since GitHub Sponsors currently doesn't support sponsoring teams directly, donations are collected and distributed using [flobernd](https://github.com/users/flobernd/sponsorship)s account.
## License
Zydis is licensed under the MIT license.

@ -0,0 +1,41 @@
#ifndef ZYDIS_EXPORT_H
#define ZYDIS_EXPORT_H
#ifdef ZYDIS_STATIC_DEFINE
# define ZYDIS_EXPORT
# define ZYDIS_NO_EXPORT
#else
# ifndef ZYDIS_EXPORT
# ifdef Zydis_EXPORTS
/* We are building this library */
# define ZYDIS_EXPORT
# else
/* We are using this library */
# define ZYDIS_EXPORT
# endif
# endif
# ifndef ZYDIS_NO_EXPORT
# define ZYDIS_NO_EXPORT
# endif
#endif
#ifndef ZYDIS_DEPRECATED
# define ZYDIS_DEPRECATED __attribute__ ((__deprecated__))
#endif
#ifndef ZYDIS_DEPRECATED_EXPORT
# define ZYDIS_DEPRECATED_EXPORT ZYDIS_EXPORT ZYDIS_DEPRECATED
#endif
#ifndef ZYDIS_DEPRECATED_NO_EXPORT
# define ZYDIS_DEPRECATED_NO_EXPORT ZYDIS_NO_EXPORT ZYDIS_DEPRECATED
#endif
#define DEFINE_NO_DEPRECATED 0
#if DEFINE_NO_DEPRECATED
# define ZYDIS_NO_DEPRECATED
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

@ -0,0 +1,4 @@
- CMakeLists (VERSION)
- Doxyfile
- resources/VersionInfo.rc (4 locations)
- include/Zydis/Zydis.h (ZYDIS_VERSION macro)

@ -0,0 +1,8 @@
set(zydis_VERSION @PROJECT_VERSION@)
@PACKAGE_INIT@
set_and_check(zydis_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@")
set_and_check(zydis_LIB_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@")
check_required_components(zydis)

@ -0,0 +1,100 @@
# Created by https://www.gitignore.io/api/c,c++,cmake
### C ###
# Object files
*.o
*.ko
*.obj
*.elf
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
### C++ ###
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
### CMake ###
CMakeCache.txt
CMakeFiles
CMakeScripts
Makefile
cmake_install.cmake
install_manifest.txt
CTestTestfile.cmake
# MacOS
.DS_Store
build*
# MSVC
.vs
*.vcxproj.user
*.suo
*.sdf
*.opensdf
*.VC.db
*.VC.opendb
msvc/**/obj/
msvc/**/bin/
doc/html
/.vscode
/.idea
/cmake-build-*

@ -0,0 +1,266 @@
if (TARGET Zycore)
return()
endif ()
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
include(GenerateExportHeader)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
project(Zycore VERSION 1.0.0.0 LANGUAGES C CXX)
# =============================================================================================== #
# Overridable options #
# =============================================================================================== #
# Global configuration
option(ZYAN_WHOLE_PROGRAM_OPTIMIZATION
"Enable whole program optimization (all targets)"
OFF)
option(ZYAN_NO_LIBC
"Don't use any C standard library functions (for exotic build-envs like kernel drivers)"
OFF)
option(ZYAN_DEV_MODE
"Enable developer mode (-Wall, -Werror, ...)"
OFF)
# Build configuration
option(ZYCORE_BUILD_SHARED_LIB
"Build shared library"
OFF)
option(ZYCORE_BUILD_EXAMPLES
"Build examples"
OFF)
option(ZYCORE_BUILD_TESTS
"Build tests"
OFF)
# =============================================================================================== #
# GoogleTest #
# =============================================================================================== #
# Download and unpack googletest
if (ZYCORE_BUILD_TESTS)
if (NOT DEFINED ZYCORE_DOWNLOADED_GTEST)
configure_file("CMakeLists.txt.in" "${CMAKE_BINARY_DIR}/gtest/download/CMakeLists.txt")
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/gtest/download")
if (result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/gtest/download")
if (result)
message(FATAL_ERROR "Build step for googletest failed: ${result}")
endif()
set(ZYCORE_DOWNLOADED_GTEST TRUE CACHE BOOL "")
mark_as_advanced(ZYCORE_DOWNLOADED_GTEST)
endif ()
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
add_subdirectory("${CMAKE_BINARY_DIR}/gtest/src" "${CMAKE_BINARY_DIR}/gtest/build"
EXCLUDE_FROM_ALL)
endif ()
# =============================================================================================== #
# Exported functions #
# =============================================================================================== #
function (zyan_set_common_flags target)
if (NOT MSVC)
target_compile_options("${target}" PRIVATE "-std=c99")
endif ()
if (ZYAN_DEV_MODE)
# If in developer mode, be pedantic.
if (MSVC)
target_compile_options("${target}" PUBLIC "/WX" "/W4")
else ()
target_compile_options("${target}" PUBLIC "-Wall" "-pedantic" "-Wextra" "-Werror")
endif ()
endif ()
endfunction ()
function (zyan_set_source_group target)
if (ZYAN_DEV_MODE)
if (((CMAKE_MAJOR_VERSION GREATER 3) OR (CMAKE_MAJOR_VERSION EQUAL 3)) AND
((CMAKE_MINOR_VERSION GREATER 8) OR (CMAKE_MINOR_VERSION EQUAL 8)))
# Mirror directory structure in project files
get_property("TARGET_SOURCE_FILES" TARGET "${target}" PROPERTY SOURCES)
source_group(TREE "${CMAKE_CURRENT_LIST_DIR}" FILES ${TARGET_SOURCE_FILES})
endif ()
endif ()
endfunction ()
function (zyan_maybe_enable_wpo target)
if (ZYAN_WHOLE_PROGRAM_OPTIMIZATION AND MSVC)
set_target_properties("${target}" PROPERTIES COMPILE_FLAGS "/GL")
set_target_properties("${target}" PROPERTIES LINK_FLAGS_RELEASE "/LTCG")
endif ()
endfunction ()
function (zyan_maybe_enable_wpo_for_lib target)
if (ZYAN_WHOLE_PROGRAM_OPTIMIZATION AND MSVC)
set_target_properties("${target}" PROPERTIES COMPILE_FLAGS "/GL")
set_target_properties("${target}" PROPERTIES LINK_FLAGS_RELEASE "/LTCG")
set_target_properties("${target}" PROPERTIES STATIC_LIBRARY_FLAGS_RELEASE "/LTCG")
endif ()
endfunction ()
# =============================================================================================== #
# Library configuration #
# =============================================================================================== #
if (ZYCORE_BUILD_SHARED_LIB)
add_library("Zycore" SHARED)
else ()
add_library("Zycore" STATIC)
endif ()
set_target_properties("Zycore" PROPERTIES LINKER_LANGUAGE C)
target_include_directories("Zycore"
PUBLIC "include" ${PROJECT_BINARY_DIR}
PRIVATE "src")
target_compile_definitions("Zycore" PRIVATE "_CRT_SECURE_NO_WARNINGS" "ZYCORE_EXPORTS")
zyan_set_common_flags("Zycore")
zyan_maybe_enable_wpo_for_lib("Zycore")
generate_export_header("Zycore" BASE_NAME "ZYCORE" EXPORT_FILE_NAME "ZycoreExportConfig.h")
if (ZYAN_NO_LIBC)
target_compile_definitions("Zycore" PUBLIC "ZYAN_NO_LIBC")
if (UNIX)
set_target_properties("Zycore" PROPERTIES LINK_FLAGS "-nostdlib -nodefaultlibs")
endif ()
endif ()
target_sources("Zycore"
PRIVATE
# API
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/API/Memory.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/API/Process.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/API/Synchronization.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/API/Terminal.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/API/Thread.h"
# Common
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Allocator.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/ArgParse.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Bitset.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Comparison.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Defines.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Format.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/LibC.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/List.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Object.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Status.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/String.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Types.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Vector.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Zycore.h"
# Common
"src/Allocator.c"
"src/ArgParse.c"
"src/Bitset.c"
"src/Format.c"
"src/List.c"
"src/String.c"
"src/Vector.c"
"src/Zycore.c")
if (NOT ZYAN_NO_LIBC)
target_sources("Zycore"
PRIVATE
# API
"src/API/Memory.c"
"src/API/Process.c"
"src/API/Synchronization.c"
"src/API/Terminal.c"
"src/API/Thread.c")
endif ()
if (ZYCORE_BUILD_SHARED_LIB AND WIN32)
target_sources("Zycore" PRIVATE "resources/VersionInfo.rc")
endif ()
zyan_set_source_group("Zycore")
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND NOT ZYAN_NO_LIBC)
target_compile_definitions("Zycore" PRIVATE "_GNU_SOURCE")
find_package(Threads REQUIRED)
target_link_libraries("Zycore" Threads::Threads)
endif ()
configure_package_config_file(cmake/zycore-config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/zycore-config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/cmake"
)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/zycore-config.cmake"
DESTINATION "${CMAKE_INSTALL_PREFIX}/cmake"
)
install(TARGETS "Zycore"
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES
"${PROJECT_BINARY_DIR}/ZycoreExportConfig.h"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(DIRECTORY "include/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# =============================================================================================== #
# Developer mode #
# =============================================================================================== #
if (ZYAN_DEV_MODE)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
endif ()
# =============================================================================================== #
# Examples #
# =============================================================================================== #
if (ZYCORE_BUILD_EXAMPLES)
add_executable("String" "examples/String.c")
zyan_set_common_flags("String" "Zycore")
target_link_libraries("String" "Zycore")
set_target_properties("String" PROPERTIES FOLDER "Examples")
target_compile_definitions("String" PRIVATE "_CRT_SECURE_NO_WARNINGS")
zyan_maybe_enable_wpo("String")
add_executable("Vector" "examples/Vector.c")
zyan_set_common_flags("Vector" "Zycore")
target_link_libraries("Vector" "Zycore")
set_target_properties("Vector" PROPERTIES FOLDER "Examples")
target_compile_definitions("Vector" PRIVATE "_CRT_SECURE_NO_WARNINGS")
zyan_maybe_enable_wpo("Vector")
endif ()
# =============================================================================================== #
# Tests #
# =============================================================================================== #
function (zyan_add_test test)
add_executable("Test${test}" "tests/${test}.cpp")
if (NOT MSVC)
target_compile_options("Test${test}" PRIVATE "-std=c++17")
endif ()
target_link_libraries("Test${test}" "Zycore")
target_link_libraries("Test${test}" "gtest")
set_target_properties("Test${test}" PROPERTIES FOLDER "Tests")
target_compile_definitions("Test${test}" PRIVATE "_CRT_SECURE_NO_WARNINGS")
zyan_maybe_enable_wpo("Test${test}")
endfunction ()
if (ZYCORE_BUILD_TESTS)
zyan_add_test("String")
zyan_add_test("Vector")
zyan_add_test("ArgParse")
endif ()
# =============================================================================================== #

@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 2.8.2)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG ee3aa831172090fd5442820f215cb04ab6062756
SOURCE_DIR "${CMAKE_BINARY_DIR}/gtest/src"
BINARY_DIR "${CMAKE_BINARY_DIR}/gtest/build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)

@ -0,0 +1,23 @@
The MIT License (MIT)
Copyright (c) 2018-2020 Florian Bernd
Copyright (c) 2018-2020 Joel Höner
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,25 @@
# Zyan Core Library for C
Internal library providing platform independent types, macros and a fallback for environments without LibC.
## Features
- Platform independent types
- Integer types (`ZyanU8`, `ZyanI32`, `ZyanUSize`, ...)
- `ZyanBool` (+ `ZYAN_FALSE`, `ZYAN_TRUE`)
- `ZYAN_NULL`
- Macros
- Compiler/Platform/Architecture detection
- Asserts and static asserts
- Utils (`ARRAY_LENGTH`, `FALLTHROUGH`, `UNUSED`, ...)
- Common types
- `ZyanBitset`
- `ZyanString`/`ZyanStringView`
- Container types
- `ZyanVector`
- `ZyanList`
- LibC abstraction (WiP)
## License
Zycore is licensed under the MIT license.

@ -0,0 +1,8 @@
set(zycore_VERSION @PROJECT_VERSION@)
@PACKAGE_INIT@
set_and_check(zycore_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@")
set_and_check(zycore_LIB_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@")
check_required_components(zycore)

@ -0,0 +1,192 @@
/***************************************************************************************************
Zyan Core Library (Zycore-C)
Original Author : Florian Bernd
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/
/**
* @file
* Demonstrates the `String` implementation.
*/
#include <stdio.h>
#include <Zycore/Allocator.h>
#include <Zycore/Defines.h>
#include <Zycore/LibC.h>
#include <Zycore/String.h>
#include <Zycore/Types.h>
/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */
/* ============================================================================================== */
/* Helper functions */
/* ============================================================================================== */
/* ============================================================================================== */
/* Tests */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Basic tests */
/* ---------------------------------------------------------------------------------------------- */
/**
* Performs some basic test on the given `ZyanString` instance.
*
* @param string A pointer to the `ZyanString` instance.
*
* @return A zyan status code.
*/
static ZyanStatus PerformBasicTests(ZyanString* string)
{
ZYAN_ASSERT(string);
ZYAN_UNUSED(string);
return ZYAN_STATUS_SUCCESS;
}
/**
* Performs basic tests on a string that dynamically manages memory.
*
* @return A zyan status code.
*/
static ZyanStatus TestDynamic(void)
{
PerformBasicTests(ZYAN_NULL);
return ZYAN_STATUS_SUCCESS;
}
/**
* Performs basic tests on a string that uses a static buffer.
*
* @return A zyan status code.
*/
static ZyanStatus TestStatic(void)
{
PerformBasicTests(ZYAN_NULL);
return ZYAN_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------------------------- */
/* Custom allocator */
/* ---------------------------------------------------------------------------------------------- */
//static ZyanStatus AllocatorAllocate(ZyanAllocator* allocator, void** p, ZyanUSize element_size,
// ZyanUSize n)
//{
// ZYAN_ASSERT(allocator);
// ZYAN_ASSERT(p);
// ZYAN_ASSERT(element_size);
// ZYAN_ASSERT(n);
//
// ZYAN_UNUSED(allocator);
//
// *p = ZYAN_MALLOC(element_size * n);
// if (!*p)
// {
// return ZYAN_STATUS_NOT_ENOUGH_MEMORY;
// }
//
// return ZYAN_STATUS_SUCCESS;
//}
//
//static ZyanStatus AllocatorReallocate(ZyanAllocator* allocator, void** p, ZyanUSize element_size,
// ZyanUSize n)
//{
// ZYAN_ASSERT(allocator);
// ZYAN_ASSERT(p);
// ZYAN_ASSERT(element_size);
// ZYAN_ASSERT(n);
//
// ZYAN_UNUSED(allocator);
//
// void* const x = ZYAN_REALLOC(*p, element_size * n);
// if (!x)
// {
// return ZYAN_STATUS_NOT_ENOUGH_MEMORY;
// }
// *p = x;
//
// return ZYAN_STATUS_SUCCESS;
//}
//
//static ZyanStatus AllocatorDeallocate(ZyanAllocator* allocator, void* p, ZyanUSize element_size,
// ZyanUSize n)
//{
// ZYAN_ASSERT(allocator);
// ZYAN_ASSERT(p);
// ZYAN_ASSERT(element_size);
// ZYAN_ASSERT(n);
//
// ZYAN_UNUSED(allocator);
// ZYAN_UNUSED(element_size);
// ZYAN_UNUSED(n);
//
// ZYAN_FREE(p);
//
// return ZYAN_STATUS_SUCCESS;
//}
/* ---------------------------------------------------------------------------------------------- */
/**
* Performs basic tests on a vector that dynamically manages memory using a custom
* allocator and modified growth-factor/shrink-threshold.
*
* @return A zyan status code.
*/
static ZyanStatus TestAllocator(void)
{
return ZYAN_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
/* Entry point */
/* ============================================================================================== */
int main()
{
if (!ZYAN_SUCCESS(TestDynamic()))
{
return EXIT_FAILURE;
}
if (!ZYAN_SUCCESS(TestStatic()))
{
return EXIT_FAILURE;
}
if (!ZYAN_SUCCESS(TestAllocator()))
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
/* ============================================================================================== */

@ -0,0 +1,395 @@
/***************************************************************************************************
Zyan Core Library (Zycore-C)
Original Author : Florian Bernd
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/
/**
* @file
* Demonstrates the `ZyanVector` implementation.
*/
#include <inttypes.h>
#include <stdio.h>
#include <time.h>
#include <Zycore/Allocator.h>
#include <Zycore/Defines.h>
#include <Zycore/LibC.h>
#include <Zycore/Types.h>
#include <Zycore/Vector.h>
/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */
/**
* Defines the `TestStruct` struct that represents a single element in the vector.
*/
typedef struct TestStruct_
{
ZyanU32 u32;
ZyanU64 u64;
float f;
} TestStruct;
/* ============================================================================================== */
/* Helper functions */
/* ============================================================================================== */
/**
* Initializes the given `TestStruct` struct.
*
* @param data A pointer to the `TestStruct` struct.
* @param n The number to initialize the struct with.
*/
static void InitTestdata(TestStruct* data, ZyanU32 n)
{
ZYAN_ASSERT(data);
data->u32 = n;
data->u64 = n;
data->f = (float)n;
}
/* ============================================================================================== */
/* Tests */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Basic tests */
/* ---------------------------------------------------------------------------------------------- */
/**
* Performs some basic test on the given `ZyanVector` instance.
*
* @param vector A pointer to the `ZyanVector` instance.
*
* @return A zyan status code.
*/
static ZyanStatus PerformBasicTests(ZyanVector* vector)
{
ZYAN_ASSERT(vector);
static TestStruct e_v;
static const TestStruct* e_p;
// Insert `20` elements. The vector automatically manages its size
for (ZyanU32 i = 0; i < 20; ++i)
{
InitTestdata(&e_v, i);
ZYAN_CHECK(ZyanVectorPushBack(vector, &e_v));
}
// Remove elements `#05..#09`
ZYAN_CHECK(ZyanVectorDeleteRange(vector, 5, 5));
// Insert a new element at index `#05`
InitTestdata(&e_v, 12345678);
ZYAN_CHECK(ZyanVectorInsert(vector, 5, &e_v));
// Change value of element `#15`
InitTestdata(&e_v, 87654321);
ZYAN_CHECK(ZyanVectorSet(vector, 10, &e_v));
// Print `u64` of all vector elements
ZyanUSize value;
ZYAN_CHECK(ZyanVectorGetSize(vector, &value));
puts("ELEMENTS");
for (ZyanUSize i = 0; i < value; ++i)
{
ZYAN_CHECK(ZyanVectorGetPointer(vector, i, (const void**)&e_p));
printf(" Element #%02" PRIuPTR ": %08" PRIu64 "\n", i, e_p->u64);
}
// Print infos
puts("INFO");
printf(" Size : %08" PRIuPTR "\n", value);
ZYAN_CHECK(ZyanVectorGetCapacity(vector, &value));
printf(" Capacity : %08" PRIuPTR "\n\n", value);
return ZYAN_STATUS_SUCCESS;
}
/**
* A dummy comparison function for the `TestStruct` that uses the `u32` field as key
* value.
*
* @param left A pointer to the first element.
* @param right A pointer to the second element.
*
* @return Returns values in the following range:
* `left == right -> result == 0`
* `left < right -> result < 0`
* `left > right -> result > 0`
*/
static ZyanI32 TestDataComparison(const TestStruct* left, const TestStruct* right)
{
ZYAN_ASSERT(left);
ZYAN_ASSERT(right);
if (left->u32 < right->u32)
{
return -1;
}
if (left->u32 > right->u32)
{
return 1;
}
return 0;
}
/**
* Tests the binary-search functionality of the given `ZyanVector` instance.
*
* @param vector A pointer to the `ZyanVector` instance.
*
* @return A zyan status code.
*/
static ZyanStatus PerformBinarySearchTest(ZyanVector* vector)
{
ZYAN_ASSERT(vector);
static TestStruct e_v;
static const TestStruct* e_p;
ZyanUSize value;
ZYAN_CHECK(ZyanVectorGetCapacity(vector, &value));
// Create a sorted test vector
for (ZyanUSize i = 0; i < value; ++i)
{
const ZyanU32 n = rand() % 100;
InitTestdata(&e_v, n);
ZyanUSize found_index;
ZYAN_CHECK(ZyanVectorBinarySearch(vector, &e_v, &found_index,
(ZyanComparison)&TestDataComparison));
ZYAN_CHECK(ZyanVectorInsert(vector, found_index, &e_v));
}
// Print `u32` of all vector elements
ZYAN_CHECK(ZyanVectorGetSize(vector, &value));
puts("ELEMENTS");
for (ZyanUSize i = 0; i < value; ++i)
{
ZYAN_CHECK(ZyanVectorGetPointer(vector, i, (const void**)&e_p));
printf(" Element #%02" PRIuPTR ": %08" PRIu32 "\n", i, e_p->u32);
}
return ZYAN_STATUS_SUCCESS;
}
/**
* Performs basic tests on a vector that dynamically manages memory.
*
* @return A zyan status code.
*/
static ZyanStatus TestDynamic(void)
{
// Initialize vector with a base capacity of `10` elements
ZyanVector vector;
ZYAN_CHECK(ZyanVectorInit(&vector, sizeof(TestStruct), 10, ZYAN_NULL));
ZYAN_CHECK(PerformBasicTests(&vector));
ZYAN_CHECK(ZyanVectorClear(&vector));
ZYAN_CHECK(ZyanVectorReserve(&vector, 20));
ZYAN_CHECK(PerformBinarySearchTest(&vector));
// Cleanup
return ZyanVectorDestroy(&vector);
}
/**
* Performs basic tests on a vector that uses a static buffer.
*
* @return A zyan status code.
*/
static ZyanStatus TestStatic(void)
{
static TestStruct buffer[20];
// Initialize vector to use a static buffer with a total capacity of `20` elements.
ZyanVector vector;
ZYAN_CHECK(ZyanVectorInitCustomBuffer(&vector, sizeof(TestStruct), buffer,
ZYAN_ARRAY_LENGTH(buffer), ZYAN_NULL));
// Compare elements
ZyanUSize size;
ZYAN_CHECK(ZyanVectorGetSize(&vector, &size));
for (ZyanUSize i = 0; i < size; ++i)
{
static TestStruct* element;
ZYAN_CHECK(ZyanVectorGetPointer(&vector, i, (const void**)&element));
if (element->u64 != buffer[i].u64)
{
return ZYAN_STATUS_INVALID_OPERATION;
}
}
ZYAN_CHECK(PerformBasicTests(&vector));
ZYAN_CHECK(ZyanVectorClear(&vector));
ZYAN_CHECK(PerformBinarySearchTest(&vector));
// Cleanup
return ZyanVectorDestroy(&vector);
}
/* ---------------------------------------------------------------------------------------------- */
/* Custom allocator */
/* ---------------------------------------------------------------------------------------------- */
static ZyanStatus AllocatorAllocate(ZyanAllocator* allocator, void** p, ZyanUSize element_size,
ZyanUSize n)
{
ZYAN_ASSERT(allocator);
ZYAN_ASSERT(p);
ZYAN_ASSERT(element_size);
ZYAN_ASSERT(n);
ZYAN_UNUSED(allocator);
*p = ZYAN_MALLOC(element_size * n);
if (!*p)
{
return ZYAN_STATUS_NOT_ENOUGH_MEMORY;
}
return ZYAN_STATUS_SUCCESS;
}
static ZyanStatus AllocatorReallocate(ZyanAllocator* allocator, void** p, ZyanUSize element_size,
ZyanUSize n)
{
ZYAN_ASSERT(allocator);
ZYAN_ASSERT(p);
ZYAN_ASSERT(element_size);
ZYAN_ASSERT(n);
ZYAN_UNUSED(allocator);
void* const x = ZYAN_REALLOC(*p, element_size * n);
if (!x)
{
return ZYAN_STATUS_NOT_ENOUGH_MEMORY;
}
*p = x;
return ZYAN_STATUS_SUCCESS;
}
static ZyanStatus AllocatorDeallocate(ZyanAllocator* allocator, void* p, ZyanUSize element_size,
ZyanUSize n)
{
ZYAN_ASSERT(allocator);
ZYAN_ASSERT(p);
ZYAN_ASSERT(element_size);
ZYAN_ASSERT(n);
ZYAN_UNUSED(allocator);
ZYAN_UNUSED(element_size);
ZYAN_UNUSED(n);
ZYAN_FREE(p);
return ZYAN_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------------------------- */
/**
* Performs basic tests on a vector that dynamically manages memory using a custom
* allocator and modified growth-factor/shrink-threshold.
*
* @return A zyan status code.
*/
static ZyanStatus TestAllocator(void)
{
ZyanAllocator allocator;
ZYAN_CHECK(ZyanAllocatorInit(&allocator, &AllocatorAllocate, &AllocatorReallocate,
&AllocatorDeallocate));
// Initialize vector with a base capacity of `10` elements. Growth-factor is set to 10 and
// dynamic shrinking is disabled
ZyanVector vector;
ZYAN_CHECK(ZyanVectorInitEx(&vector, sizeof(TestStruct), 5, ZYAN_NULL, &allocator,
10.0f, 0.0f));
static TestStruct e_v;
// Insert `10` elements. The vector automatically manages its size
for (ZyanU32 i = 0; i < 10; ++i)
{
InitTestdata(&e_v, i);
ZYAN_CHECK(ZyanVectorPushBack(&vector, &e_v));
}
// Check capacity
ZyanUSize value;
ZYAN_CHECK(ZyanVectorGetCapacity(&vector, &value));
if (value != 60) // (5 + 1) * 10.0f
{
return ZYAN_STATUS_INVALID_OPERATION;
}
// Remove all elements
ZYAN_CHECK(ZyanVectorClear(&vector));
// Print infos
puts("INFO");
ZYAN_CHECK(ZyanVectorGetSize(&vector, &value));
printf(" Size : %08" PRIuPTR "\n", value);
ZYAN_CHECK(ZyanVectorGetCapacity(&vector, &value));
printf(" Capacity : %08" PRIuPTR "\n\n", value);
// Cleanup
return ZyanVectorDestroy(&vector);
}
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
/* Entry point */
/* ============================================================================================== */
int main()
{
time_t t;
srand((unsigned)time(&t));
if (!ZYAN_SUCCESS(TestDynamic()))
{
return EXIT_FAILURE;
}
if (!ZYAN_SUCCESS(TestStatic()))
{
return EXIT_FAILURE;
}
if (!ZYAN_SUCCESS(TestAllocator()))
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
/* ============================================================================================== */

@ -0,0 +1,128 @@
/***************************************************************************************************
Zyan Core Library (Zycore-C)
Original Author : Florian Bernd
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/
#include <Zycore/API/Memory.h>
#if defined(ZYAN_WINDOWS)
#elif defined(ZYAN_POSIX)
# include <unistd.h>
#else
# error "Unsupported platform detected"
#endif
/* ============================================================================================== */
/* Exported functions */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* General */
/* ---------------------------------------------------------------------------------------------- */
ZyanU32 ZyanMemoryGetSystemPageSize()
{
#if defined(ZYAN_WINDOWS)
SYSTEM_INFO system_info;
GetSystemInfo(&system_info);
return system_info.dwPageSize;
#elif defined(ZYAN_POSIX)
return sysconf(_SC_PAGE_SIZE);
#endif
}
ZyanU32 ZyanMemoryGetSystemAllocationGranularity()
{
#if defined(ZYAN_WINDOWS)
SYSTEM_INFO system_info;
GetSystemInfo(&system_info);
return system_info.dwAllocationGranularity;
#elif defined(ZYAN_POSIX)
return sysconf(_SC_PAGE_SIZE);
#endif
}
/* ---------------------------------------------------------------------------------------------- */
/* Memory management */
/* ---------------------------------------------------------------------------------------------- */
ZyanStatus ZyanMemoryVirtualProtect(void* address, ZyanUSize size,
ZyanMemoryPageProtection protection)
{
#if defined(ZYAN_WINDOWS)
DWORD old;
if (!VirtualProtect(address, size, protection, &old))
{
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
#elif defined(ZYAN_POSIX)
if (mprotect(address, size, protection))
{
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
#endif
return ZYAN_STATUS_SUCCESS;
}
ZyanStatus ZyanMemoryVirtualFree(void* address, ZyanUSize size)
{
#if defined(ZYAN_WINDOWS)
ZYAN_UNUSED(size);
if (!VirtualFree(address, 0, MEM_RELEASE))
{
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
#elif defined(ZYAN_POSIX)
if (munmap(address, size))
{
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
#endif
return ZYAN_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */

@ -0,0 +1,68 @@
/***************************************************************************************************
Zyan Core Library (Zycore-C)
Original Author : Florian Bernd
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/
#include <Zycore/Defines.h>
#if defined(ZYAN_WINDOWS)
# include <windows.h>
#elif defined(ZYAN_POSIX)
# include <sys/mman.h>
#else
# error "Unsupported platform detected"
#endif
#include <Zycore/API/Process.h>
/* ============================================================================================== */
/* Exported functions */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* General */
/* ---------------------------------------------------------------------------------------------- */
ZyanStatus ZyanProcessFlushInstructionCache(void* address, ZyanUSize size)
{
#if defined(ZYAN_WINDOWS)
if (!FlushInstructionCache(GetCurrentProcess(), address, size))
{
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
#elif defined(ZYAN_POSIX)
if (msync(address, size, MS_SYNC | MS_INVALIDATE))
{
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
#endif
return ZYAN_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */

@ -0,0 +1,200 @@
/***************************************************************************************************
Zyan Core Library (Zycore-C)
Original Author : Florian Bernd
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/
#include <Zycore/API/Synchronization.h>
/* ============================================================================================== */
/* Internal functions */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* */
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
/* Exported functions */
/* ============================================================================================== */
#if defined(ZYAN_POSIX)
#include <errno.h>
/* ---------------------------------------------------------------------------------------------- */
/* Critical Section */
/* ---------------------------------------------------------------------------------------------- */
ZyanStatus ZyanCriticalSectionInitialize(ZyanCriticalSection* critical_section)
{
pthread_mutexattr_t attribute;
int error = pthread_mutexattr_init(&attribute);
if (error != 0)
{
if (error == ENOMEM)
{
return ZYAN_STATUS_NOT_ENOUGH_MEMORY;
}
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
pthread_mutexattr_settype(&attribute, PTHREAD_MUTEX_RECURSIVE);
error = pthread_mutex_init(critical_section, &attribute);
pthread_mutexattr_destroy(&attribute);
if (error != 0)
{
if (error == EAGAIN)
{
return ZYAN_STATUS_OUT_OF_RESOURCES;
}
if (error == ENOMEM)
{
return ZYAN_STATUS_NOT_ENOUGH_MEMORY;
}
if (error == EPERM)
{
return ZYAN_STATUS_ACCESS_DENIED;
}
if ((error == EBUSY) || (error == EINVAL))
{
return ZYAN_STATUS_INVALID_ARGUMENT;
}
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
return ZYAN_STATUS_SUCCESS;
}
ZyanStatus ZyanCriticalSectionEnter(ZyanCriticalSection* critical_section)
{
const int error = pthread_mutex_lock(critical_section);
if (error != 0)
{
if (error == EINVAL)
{
return ZYAN_STATUS_INVALID_ARGUMENT;
}
if (error == EAGAIN)
{
return ZYAN_STATUS_INVALID_OPERATION;
}
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
return ZYAN_STATUS_SUCCESS;
}
ZyanBool ZyanCriticalSectionTryEnter(ZyanCriticalSection* critical_section)
{
// No fine grained error handling for this one
return pthread_mutex_trylock(critical_section) ? ZYAN_FALSE : ZYAN_TRUE;
}
ZyanStatus ZyanCriticalSectionLeave(ZyanCriticalSection* critical_section)
{
const int error = pthread_mutex_unlock(critical_section);
if (error != 0)
{
if (error == EINVAL)
{
return ZYAN_STATUS_INVALID_ARGUMENT;
}
if (error == EPERM)
{
return ZYAN_STATUS_INVALID_OPERATION;
}
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
return ZYAN_STATUS_SUCCESS;
}
ZyanStatus ZyanCriticalSectionDelete(ZyanCriticalSection* critical_section)
{
const int error = pthread_mutex_destroy(critical_section);
if (error != 0)
{
if ((error == EBUSY) || (error == EINVAL))
{
return ZYAN_STATUS_INVALID_ARGUMENT;
}
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
return ZYAN_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------------------------- */
#elif defined(ZYAN_WINDOWS)
/* ---------------------------------------------------------------------------------------------- */
/* General */
/* ---------------------------------------------------------------------------------------------- */
ZyanStatus ZyanCriticalSectionInitialize(ZyanCriticalSection* critical_section)
{
InitializeCriticalSection(critical_section);
return ZYAN_STATUS_SUCCESS;
}
ZyanStatus ZyanCriticalSectionEnter(ZyanCriticalSection* critical_section)
{
EnterCriticalSection(critical_section);
return ZYAN_STATUS_SUCCESS;
}
ZyanBool ZyanCriticalSectionTryEnter(ZyanCriticalSection* critical_section)
{
return TryEnterCriticalSection(critical_section) ? ZYAN_TRUE : ZYAN_FALSE;
}
ZyanStatus ZyanCriticalSectionLeave(ZyanCriticalSection* critical_section)
{
LeaveCriticalSection(critical_section);
return ZYAN_STATUS_SUCCESS;
}
ZyanStatus ZyanCriticalSectionDelete(ZyanCriticalSection* critical_section)
{
DeleteCriticalSection(critical_section);
return ZYAN_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------------------------- */
#else
# error "Unsupported platform detected"
#endif
/* ============================================================================================== */

@ -0,0 +1,156 @@
/***************************************************************************************************
Zyan Core Library (Zycore-C)
Original Author : Florian Bernd
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/
#include <Zycore/API/Terminal.h>
#if defined(ZYAN_POSIX)
# include <unistd.h>
#elif defined(ZYAN_WINDOWS)
# include <windows.h>
# include <io.h>
#else
# error "Unsupported platform detected"
#endif
// Provide fallback for old SDK versions
#ifdef ZYAN_WINDOWS
# ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
# define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
# endif
#endif
/* ============================================================================================== */
/* Exported functions */
/* ============================================================================================== */
ZyanStatus ZyanTerminalEnableVT100(ZyanStandardStream stream)
{
if ((stream != ZYAN_STDSTREAM_OUT) && (stream != ZYAN_STDSTREAM_ERR))
{
return ZYAN_STATUS_INVALID_ARGUMENT;
}
#ifdef ZYAN_WINDOWS
// Get file descriptor
int file;
switch (stream)
{
case ZYAN_STDSTREAM_OUT:
file = _fileno(ZYAN_STDOUT);
break;
case ZYAN_STDSTREAM_ERR:
file = _fileno(ZYAN_STDERR);
break;
default:
ZYAN_UNREACHABLE;
}
if (file < 0)
{
return ZYAN_STATUS_INVALID_ARGUMENT;
}
HANDLE const handle = (HANDLE)_get_osfhandle(file);
if (handle == INVALID_HANDLE_VALUE)
{
return ZYAN_STATUS_INVALID_ARGUMENT;
}
DWORD mode;
if (!GetConsoleMode(handle, &mode))
{
// The given standard stream is not bound to a terminal
return ZYAN_STATUS_INVALID_ARGUMENT;
}
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(handle, mode))
{
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
#endif
return ZYAN_STATUS_SUCCESS;
}
ZyanStatus ZyanTerminalIsTTY(ZyanStandardStream stream)
{
// Get file descriptor
int file;
#ifdef ZYAN_WINDOWS
switch (stream)
{
case ZYAN_STDSTREAM_IN:
file = _fileno(ZYAN_STDIN);
break;
case ZYAN_STDSTREAM_OUT:
file = _fileno(ZYAN_STDOUT);
break;
case ZYAN_STDSTREAM_ERR:
file = _fileno(ZYAN_STDERR);
break;
default:
ZYAN_UNREACHABLE;
}
if (file < 0)
{
return ZYAN_STATUS_INVALID_ARGUMENT;
}
#else
switch (stream)
{
case ZYAN_STDSTREAM_IN:
file = STDIN_FILENO;
break;
case ZYAN_STDSTREAM_OUT:
file = STDOUT_FILENO;
break;
case ZYAN_STDSTREAM_ERR:
file = STDERR_FILENO;
break;
default:
ZYAN_UNREACHABLE;
}
#endif
#ifdef ZYAN_WINDOWS
if (_isatty(file))
#else
if ( isatty(file))
#endif
{
return ZYAN_STATUS_TRUE;
}
if (ZYAN_ERRNO == EBADF)
{
// Invalid file descriptor
return ZYAN_STATUS_INVALID_ARGUMENT;
}
//ZYAN_ASSERT((errno == EINVAL) || (errno == ENOTTY));
return ZYAN_STATUS_FALSE;
}
/* ============================================================================================== */

@ -0,0 +1,194 @@
/***************************************************************************************************
Zyan Core Library (Zycore-C)
Original Author : Florian Bernd
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/
#include <Zycore/API/Thread.h>
/* ============================================================================================== */
/* Internal functions */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* */
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
/* Exported functions */
/* ============================================================================================== */
#if defined(ZYAN_POSIX)
#include <errno.h>
/* ---------------------------------------------------------------------------------------------- */
/* General */
/* ---------------------------------------------------------------------------------------------- */
ZyanStatus ZyanThreadGetCurrentThread(ZyanThread* thread)
{
*thread = pthread_self();
return ZYAN_STATUS_SUCCESS;
}
ZYAN_STATIC_ASSERT(sizeof(ZyanThreadId) <= sizeof(ZyanU64));
ZyanStatus ZyanThreadGetCurrentThreadId(ZyanThreadId* thread_id)
{
// TODO: Use `pthread_getthreadid_np` on platforms where it is available
pthread_t ptid = pthread_self();
*thread_id = *(ZyanThreadId*)ptid;
return ZYAN_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------------------------- */
/* Thread Local Storage */
/* ---------------------------------------------------------------------------------------------- */
ZyanStatus ZyanThreadTlsAlloc(ZyanThreadTlsIndex* index, ZyanThreadTlsCallback destructor)
{
ZyanThreadTlsIndex value;
const int error = pthread_key_create(&value, destructor);
if (error != 0)
{
if (error == EAGAIN)
{
return ZYAN_STATUS_OUT_OF_RESOURCES;
}
if (error == ENOMEM)
{
return ZYAN_STATUS_NOT_ENOUGH_MEMORY;
}
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
*index = value;
return ZYAN_STATUS_SUCCESS;
}
ZyanStatus ZyanThreadTlsFree(ZyanThreadTlsIndex index)
{
return !pthread_key_delete(index) ? ZYAN_STATUS_SUCCESS : ZYAN_STATUS_BAD_SYSTEMCALL;
}
ZyanStatus ZyanThreadTlsGetValue(ZyanThreadTlsIndex index, void** data)
{
*data = pthread_getspecific(index);
return ZYAN_STATUS_SUCCESS;
}
ZyanStatus ZyanThreadTlsSetValue(ZyanThreadTlsIndex index, void* data)
{
const int error = pthread_setspecific(index, data);
if (error != 0)
{
if (error == EINVAL)
{
return ZYAN_STATUS_INVALID_ARGUMENT;
}
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
return ZYAN_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------------------------- */
#elif defined(ZYAN_WINDOWS)
/* ---------------------------------------------------------------------------------------------- */
/* General */
/* ---------------------------------------------------------------------------------------------- */
ZyanStatus ZyanThreadGetCurrentThread(ZyanThread* thread)
{
*thread = GetCurrentThread();
return ZYAN_STATUS_SUCCESS;
}
ZyanStatus ZyanThreadGetCurrentThreadId(ZyanThreadId* thread_id)
{
*thread_id = GetCurrentThreadId();
return ZYAN_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------------------------- */
/* Thread Local Storage (TLS) */
/* ---------------------------------------------------------------------------------------------- */
ZyanStatus ZyanThreadTlsAlloc(ZyanThreadTlsIndex* index, ZyanThreadTlsCallback destructor)
{
const ZyanThreadTlsIndex value = FlsAlloc(destructor);
if (value == FLS_OUT_OF_INDEXES)
{
return ZYAN_STATUS_OUT_OF_RESOURCES;
}
*index = value;
return ZYAN_STATUS_SUCCESS;
}
ZyanStatus ZyanThreadTlsFree(ZyanThreadTlsIndex index)
{
return FlsFree(index) ? ZYAN_STATUS_SUCCESS : ZYAN_STATUS_BAD_SYSTEMCALL;
}
ZyanStatus ZyanThreadTlsGetValue(ZyanThreadTlsIndex index, void** data)
{
*data = FlsGetValue(index);
return ZYAN_STATUS_SUCCESS;
}
ZyanStatus ZyanThreadTlsSetValue(ZyanThreadTlsIndex index, void* data)
{
if (!FlsSetValue(index, data))
{
const DWORD error = GetLastError();
if (error == ERROR_INVALID_PARAMETER)
{
return ZYAN_STATUS_INVALID_ARGUMENT;
}
return ZYAN_STATUS_BAD_SYSTEMCALL;
}
return ZYAN_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------------------------- */
#else
# error "Unsupported platform detected"
#endif
/* ============================================================================================== */

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save