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