LCOV - code coverage report
Current view: top level - include/client/syscalls - syscall.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 40 40 100.0 %
Date: 2024-04-30 13:21:35 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   Copyright 2018-2024, Barcelona Supercomputing Center (BSC), Spain
       3             :   Copyright 2015-2024, Johannes Gutenberg Universitaet Mainz, Germany
       4             : 
       5             :   This software was partially supported by the
       6             :   EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu).
       7             : 
       8             :   This software was partially supported by the
       9             :   ADA-FS project under the SPPEXA project funded by the DFG.
      10             : 
      11             :   This file is part of GekkoFS' POSIX interface.
      12             : 
      13             :   GekkoFS' POSIX interface is free software: you can redistribute it and/or
      14             :   modify it under the terms of the GNU Lesser General Public License as
      15             :   published by the Free Software Foundation, either version 3 of the License,
      16             :   or (at your option) any later version.
      17             : 
      18             :   GekkoFS' POSIX interface is distributed in the hope that it will be useful,
      19             :   but WITHOUT ANY WARRANTY; without even the implied warranty of
      20             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      21             :   GNU Lesser General Public License for more details.
      22             : 
      23             :   You should have received a copy of the GNU Lesser General Public License
      24             :   along with GekkoFS' POSIX interface.  If not, see
      25             :   <https://www.gnu.org/licenses/>.
      26             : 
      27             :   SPDX-License-Identifier: LGPL-3.0-or-later
      28             : */
      29             : 
      30             : // This file uses special C formatting for a better overview
      31             : // clang-format off
      32             : 
      33             : #ifndef GKFS_SYSCALL_HPP
      34             : #define GKFS_SYSCALL_HPP
      35             : 
      36             : #include <client/syscalls/args.hpp>
      37             : #include <client/syscalls/rets.hpp>
      38             : #include <client/syscalls/errno.hpp>
      39             : #include <client/syscalls/detail/syscall_info.h>
      40             : 
      41             : namespace gkfs::syscall {
      42             : 
      43             : static const auto constexpr MAX_ARGS = 6u;
      44             : using arg_list = std::array<arg::desc, MAX_ARGS>;
      45             : 
      46             : struct descriptor : private ::syscall_info {
      47             : 
      48             :     long
      49         494 :     number() const {
      50         494 :         return s_nr;
      51             :     }
      52             : 
      53             :     const char*
      54     1172597 :     name() const {
      55     1172597 :         return s_name;
      56             :     }
      57             : 
      58             :     int
      59     7869245 :     num_args() const {
      60     7869245 :         return s_nargs;
      61             :     }
      62             : 
      63             :     arg_list
      64             :     args() const {
      65             : 
      66             :         std::array<arg::desc, MAX_ARGS> args;
      67             : 
      68    23439733 :         for(auto i = 0u; i < MAX_ARGS; ++i) {
      69    20091173 :             args[i] = {static_cast<arg::type>(s_args[i].a_type),
      70    20091173 :                        s_args[i].a_name};
      71             :         }
      72             : 
      73     3348560 :         return args;
      74             :     }
      75             : 
      76             :     ret::desc
      77     2339348 :     return_type() const {
      78      581193 :         return ret::desc{static_cast<ret::type>(s_return_type.r_type)};
      79             :     }
      80             : };
      81             : 
      82             : static inline descriptor
      83     1758199 : lookup_by_number(const long syscall_number) {
      84     1758199 :     const auto* info = ::get_syscall_info(syscall_number, nullptr);
      85     1758168 :     return *reinterpret_cast<const descriptor*>(info);
      86             : }
      87             : 
      88             : static inline descriptor
      89     1172082 : lookup_by_number(const long syscall_number, const long argv[MAX_ARGS]) {
      90     1172082 :     const auto* info = ::get_syscall_info(syscall_number, argv);
      91     1172082 :     return *reinterpret_cast<const descriptor*>(info);
      92             : }
      93             : 
      94             : static inline descriptor
      95         494 : lookup_by_name(const std::string syscall_name) {
      96         494 :     const auto* info = ::get_syscall_info_by_name(syscall_name.c_str());
      97         494 :     return *reinterpret_cast<const descriptor*>(info);
      98             : }
      99             : 
     100             : static inline bool
     101     1758212 : never_returns(const long syscall_number) {
     102     1758212 :     const auto desc = lookup_by_number(syscall_number);
     103     1758155 :     return desc.return_type() == ret::none;
     104             : }
     105             : 
     106             : static inline bool
     107             : always_returns(const long syscall_number) {
     108             :     return !never_returns(syscall_number);
     109             : }
     110             : 
     111             : static inline bool
     112     1172079 : may_not_return(const long syscall_number) {
     113     1172079 :     return syscall_number == SYS_execve 
     114             : #ifdef SYS_execveat
     115     1172079 :         || syscall_number == SYS_execveat
     116             : #endif
     117             :         ;
     118             : }
     119             : 
     120             : 
     121             : // information about a syscall
     122             : enum class info : int {
     123             :     unknown        = 0x00000000, // no info (reset)
     124             :     
     125             :     // syscall origin
     126             :     internal       = 0x00000001, // syscall originates from GekkoFS' internals
     127             :     external       = 0x00000002, // syscall originates from client application
     128             : 
     129             :     // syscall target
     130             :     kernel         = 0x00000010, // syscall forwarded to the kernel
     131             :     hook           = 0x00000020, // syscall handled by GekkoFS
     132             : 
     133             :     // syscall state
     134             :     executed       = 0x00000100, // syscall has been executed
     135             :     not_executed   = 0x00000000, // syscall has not been executed
     136             : 
     137             :     // masks
     138             :     origin_mask    = 0x00000003, // mask for syscall's origin information
     139             :     target_mask    = 0x7ffffefc, // mask for syscall's target information
     140             :     execution_mask = 0x00000100 // mask for syscall's execution state
     141             : };
     142             : 
     143             : 
     144             : inline constexpr info
     145     4101642 : operator&(info t1, info t2) {
     146     4101642 :     return info(static_cast<int>(t1) & static_cast<int>(t2));
     147             : }
     148             : 
     149             : inline constexpr info
     150    10773511 : operator|(info t1, info t2) {
     151    10773511 :     return info(static_cast<int>(t1) | static_cast<int>(t2));
     152             : }
     153             : 
     154             : inline constexpr info
     155             : operator^(info t1, info t2) {
     156             :     return info(static_cast<int>(t1) ^ static_cast<int>(t2));
     157             : }
     158             : 
     159             : inline constexpr info
     160             : operator~(info t1) {
     161             :     return info(~static_cast<int>(t1));
     162             : }
     163             : 
     164             : inline const info&
     165             : operator|=(info& t1, info t2) {
     166             :     return t1 = t1 | t2;
     167             : }
     168             : 
     169             : inline const info&
     170             : operator&=(info& t1, info t2) {
     171             :     return t1 = t1 & t2;
     172             : }
     173             : 
     174             : inline const info&
     175             : operator^=(info& t1, info t2) {
     176             :     return t1 = t1 ^ t2;
     177             : }
     178             : 
     179             : 
     180             : static const auto constexpr no_info            = info::unknown;
     181             : static const auto constexpr from_internal_code = info::internal;
     182             : static const auto constexpr from_external_code = info::external;
     183             : static const auto constexpr to_kernel          = info::kernel;
     184             : static const auto constexpr to_hook            = info::hook;
     185             : 
     186             : static const auto constexpr executed           = info::executed;
     187             : static const auto constexpr not_executed       = info::not_executed;
     188             : 
     189             : static const auto constexpr origin_mask        = info::origin_mask;
     190             : static const auto constexpr target_mask        = info::target_mask;
     191             : static const auto constexpr execution_mask     = info::execution_mask;
     192             : 
     193             : enum {
     194             :     hooked            = 0x0,
     195             :     forward_to_kernel = 0x1
     196             : };
     197             : 
     198             : static constexpr auto
     199     1172097 : origin(syscall::info info) {
     200     1172097 :     return info & origin_mask;
     201             : }
     202             : 
     203             : static constexpr auto
     204     1172097 : target(syscall::info info) {
     205     1172097 :     return info & target_mask;
     206             : }
     207             : 
     208             : static constexpr bool
     209             : is_handled_by_kernel(syscall::info info) {
     210             :     return (info & target_mask) == to_kernel;
     211             : }
     212             : 
     213             : static constexpr auto
     214     1757448 : execution_is_pending(syscall::info info) {
     215     1757448 :     return (info & execution_mask) == not_executed;
     216             : }
     217             : 
     218             : /*
     219             :  * error_code - examines a return value from a syscall execution
     220             :  * and returns an error code if said return value indicates an error.
     221             :  */
     222             : static inline int
     223      586168 : error_code(long result) {
     224      586168 :     if(result < 0 && result >= -0x1000)
     225        4976 :         return (int) -result;
     226             : 
     227             :     return 0;
     228             : }
     229             : 
     230             : } // namespace gkfs::syscall
     231             : 
     232             : #endif // GKFS_SYSCALL_HPP
     233             : 
     234             : // clang-format on

Generated by: LCOV version 1.16