Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <syscall.h>
     18 #include <stdio.h>
     19 
     20 
     21 
     22 static uint32_t mTableStore[(sizeof(struct SyscallTable) + sizeof(union SyscallTableEntry[1 << SYSCALL_BITS_LEVEL_0]) + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
     23 static const uint8_t mLevelBits[] = {SYSCALL_BITS_LEVEL_0, SYSCALL_BITS_LEVEL_1, SYSCALL_BITS_LEVEL_2, SYSCALL_BITS_LEVEL_3, 0};
     24 static struct SyscallTable *mTable = (struct SyscallTable*)mTableStore;
     25 
     26 
     27 
     28 void syscallInit(void)
     29 {
     30     mTable->numEntries = 1 << SYSCALL_BITS_LEVEL_0;
     31 }
     32 
     33 bool syscallAddTable(uint32_t path, uint32_t level, struct SyscallTable *table)
     34 {
     35     struct SyscallTable** tabP = &mTable;
     36     const uint8_t *bits = mLevelBits;
     37 
     38     while (level--) {
     39         uint32_t idx = path >> (32 - *bits);
     40         path <<= *bits++;
     41 
     42         //cannot traverse
     43         if ((*tabP)->numEntries <= idx)
     44             return false;
     45 
     46         //cannot add table as final leaf
     47         if (*bits == 0)
     48             return false;
     49 
     50         tabP = &(*tabP)->entry[idx].subtable;
     51     }
     52 
     53     *tabP = table;
     54     return true;
     55 }
     56 
     57 static SyscallFunc* syscallFindHandlerLoc(uint32_t path)
     58 {
     59     struct SyscallTable* tab = mTable;
     60     const uint8_t *bits = mLevelBits;
     61 
     62     while (tab) {
     63         uint32_t idx = path >> (32 - *bits);
     64 
     65         path <<= *bits++;
     66 
     67         if (tab->numEntries <= idx)
     68             break;
     69 
     70         if (!*bits)
     71             return &tab->entry[idx].func;
     72         else
     73             tab = tab->entry[idx].subtable;
     74     }
     75 
     76     return NULL;
     77 }
     78 
     79 bool syscallAddFunc(uint32_t path, SyscallFunc func)
     80 {
     81     SyscallFunc *f = syscallFindHandlerLoc(path);
     82 
     83     if (!f)
     84         return false;
     85 
     86     *f = func;
     87     return true;
     88 }
     89 
     90 SyscallFunc syscallGetHandler(uint32_t path)
     91 {
     92     SyscallFunc *f = syscallFindHandlerLoc(path);
     93 
     94     return f ? *f : NULL;
     95 }
     96 
     97 
     98