Initial import of s390 codegen, codebase is copyed from x86_64.
[cacao.git] / src / vm / access.c
1 /* vm/access.c - checking access rights
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Edwin Steiner
28
29    Changes:
30
31    $Id: access.c 5846 2006-10-28 13:02:19Z edwin $
32
33 */
34
35
36 #include "config.h"
37
38 #include <assert.h>
39
40 #include "vm/types.h"
41
42 #include "vm/access.h"
43 #include "vm/builtin.h"
44 #include "vm/class.h"
45 #include "vm/exceptions.h"
46 #include "vm/stringlocal.h"
47
48
49 /****************************************************************************/
50 /* ACCESS CHECKS                                                            */
51 /****************************************************************************/
52
53 /* access_is_accessible_class **************************************************
54  
55    Check if a class is accessible from another class
56   
57    IN:
58        referer..........the class containing the reference
59        cls..............the result of resolving the reference
60   
61    RETURN VALUE:
62        true.............access permitted
63        false............access denied
64    
65    NOTE:
66        This function performs the checks listed in section 5.4.4.
67            "Access Control" of "The Java(TM) Virtual Machine Specification,
68            Second Edition".
69
70 *******************************************************************************/
71
72 bool access_is_accessible_class(classinfo *referer, classinfo *cls)
73 {
74         assert(referer);
75         assert(cls);
76
77         /* public classes are always accessible */
78         if (cls->flags & ACC_PUBLIC)
79                 return true;
80
81         /* a class in the same package is always accessible */
82         if (SAME_PACKAGE(referer, cls))
83                 return true;
84
85         /* a non-public class in another package is not accessible */
86         return false;
87 }
88
89
90
91
92 /* access_is_accessible_member *************************************************
93  
94    Check if a field or method is accessible from a given class
95   
96    IN:
97        referer..........the class containing the reference
98        declarer.........the class declaring the member
99        memberflags......the access flags of the member
100   
101    RETURN VALUE:
102        true.............access permitted
103        false............access denied
104
105    NOTE:
106        This function only performs the checks listed in section 5.4.4.
107            "Access Control" of "The Java(TM) Virtual Machine Specification,
108            Second Edition".
109
110            In particular a special condition for protected access with is
111            part of the verification process according to the spec is not
112            checked in this function.
113    
114 *******************************************************************************/
115
116 bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
117                                                                  s4 memberflags)
118 {
119         assert(referer);
120         assert(declarer);
121         
122         /* public members are accessible */
123         if (memberflags & ACC_PUBLIC)
124                 return true;
125
126         /* {declarer is not an interface} */
127
128         /* private members are only accessible by the class itself */
129         if (memberflags & ACC_PRIVATE)
130                 return (referer == declarer);
131
132         /* {the member is protected or package private} */
133
134         /* protected and package private members are accessible in the same package */
135         if (SAME_PACKAGE(referer,declarer))
136                 return true;
137
138         /* package private members are not accessible outside the package */
139         if (!(memberflags & ACC_PROTECTED))
140                 return false;
141
142         /* {the member is protected and declarer is in another package} */
143
144         /* a necessary condition for access is that referer is a subclass of declarer */
145         assert((referer->state & CLASS_LINKED) && (declarer->state & CLASS_LINKED));
146         if (builtin_isanysubclass(referer,declarer))
147                 return true;
148
149         return false;
150 }
151
152
153 /* access_check_caller *********************************************************
154  
155    Check if the (indirect) caller has access rights to a member.
156   
157    IN:
158        declarer.........the class declaring the member
159        memberflags......the access flags of the member
160            calldepth........number of callers to ignore
161                             For example if the stacktrace looks like this:
162
163                                            java.lang.reflect.Method.invokeNative (Native Method)
164                                    [0] java.lang.reflect.Method.invoke (Method.java:329)
165                                    [1] <caller>
166
167                                         you must specify 1 so the access rights of <caller> 
168                                                 are checked.
169   
170    RETURN VALUE:
171        true.............access permitted
172        false............access denied, an exception has been thrown
173    
174 *******************************************************************************/
175
176 bool access_check_caller(classinfo *declarer, s4 memberflags, s4 calldepth)
177 {
178         java_objectarray *oa;
179         classinfo        *callerclass;
180
181         /* if everything is public, there is nothing to check */
182
183         if ((declarer->flags & ACC_PUBLIC) && (memberflags & ACC_PUBLIC))
184                 return true;
185
186         /* get the caller's class */
187
188         oa = stacktrace_getClassContext();
189         if (!oa)
190                 return false;
191
192         assert(calldepth >= 0 && calldepth < oa->header.size);
193
194         callerclass = (classinfo *) oa->data[calldepth];
195
196         /* check access rights */
197
198         if (!access_is_accessible_class(callerclass, declarer)
199                 || !access_is_accessible_member(callerclass, declarer, memberflags))
200         {
201                 *exceptionptr =
202                         new_exception(string_java_lang_IllegalAccessException);
203                 return false;
204         }
205
206         /* access granted */
207
208         return true;
209 }
210
211 /*
212  * These are local overrides for various environment variables in Emacs.
213  * Please do not remove this and leave it at the end of the file, where
214  * Emacs will automagically detect them.
215  * ---------------------------------------------------------------------
216  * Local variables:
217  * mode: c
218  * indent-tabs-mode: t
219  * c-basic-offset: 4
220  * tab-width: 4
221  * End:
222  * vim:noexpandtab:sw=4:ts=4:
223  */
224