VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/include/cr_unpack.h@ 78375

Last change on this file since 78375 was 78375, checked in by vboxsync, 6 years ago

Additions/common/crOpengl,GuestHost/OpenGL,HostServices/SharedOpenGL: Eliminate all global variables from the state tracker library (state_tracker) in preparation of the SPU DLL merging, bugref:9435

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 7.7 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved.
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#ifndef CR_UNPACK_H
8#define CR_UNPACK_H
9
10#include "cr_compiler.h"
11#include "cr_spu.h"
12#include "cr_protocol.h"
13#include "cr_mem.h"
14#include "cr_opcodes.h"
15#include "cr_glstate.h"
16
17#include <iprt/types.h>
18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23/**
24 * Unpacker state.
25 */
26typedef struct CrUnpackerState
27{
28 /** Opcodes which are going to be unpacked. */
29 const uint8_t *pbOpcodes;
30 /** NUmber of Opcodes to unpack. */
31 size_t cOpcodes;
32 /** Start of the data buffer to unpack. */
33 const uint8_t *pbUnpackData;
34 /** Number of bytes remaining the inpack buffer. */
35 size_t cbUnpackDataLeft;
36 /** Return pointer. */
37 CRNetworkPointer *pReturnPtr;
38 /** Writeback pointer. */
39 CRNetworkPointer *pWritebackPtr;
40 /** Pointer to the dispatch table to use. */
41 SPUDispatchTable *pDispatchTbl;
42 /** Status code from the unpacker (mostly returns VERR_BUFFER_OVERFLOW
43 * on error if one unpacker detected out of bounds buffer access). */
44 int rcUnpack;
45 /** Attached state tracker. */
46 PCRStateTracker pStateTracker;
47} CrUnpackerState;
48/** Pointer to an unpacker state. */
49typedef CrUnpackerState *PCrUnpackerState;
50/** Pointer to a const unpacker state. */
51typedef const CrUnpackerState *PCCrUnpackerState;
52
53DECLEXPORT(void) crUnpack(PCrUnpackerState pState);
54
55typedef enum
56{
57 CR_UNPACK_BUFFER_TYPE_GENERIC = 0,
58 CR_UNPACK_BUFFER_TYPE_CMDBLOCK_BEGIN,
59 CR_UNPACK_BUFFER_TYPE_CMDBLOCK_FLUSH,
60 CR_UNPACK_BUFFER_TYPE_CMDBLOCK_END
61} CR_UNPACK_BUFFER_TYPE;
62
63DECLEXPORT(CR_UNPACK_BUFFER_TYPE) crUnpackGetBufferType(const void *opcodes, unsigned int num_opcodes);
64
65#if defined(LINUX) || defined(WINDOWS)
66#define CR_UNALIGNED_ACCESS_OKAY
67#else
68#undef CR_UNALIGNED_ACCESS_OKAY
69#endif
70DECLEXPORT(double) crReadUnalignedDouble( const void *buffer );
71
72/**
73 * Paranoid helper for debug builds to make sure the buffer size is validated correctly.
74 */
75DECLINLINE(const void *) crUnpackAccessChk(PCCrUnpackerState pState, size_t cbAccessVerified,
76 size_t offAccess, size_t cbType)
77{
78 AssertMsg(offAccess + cbType <= cbAccessVerified,
79 ("CHECK_BUFFER_SIZE_STATIC() has a wrong size given (verified %zu bytes vs tried access %zu)!\n",
80 cbAccessVerified, offAccess + cbType));
81 RT_NOREF(cbAccessVerified, cbType);
82 return pState->pbUnpackData + offAccess;
83}
84
85/**
86 * Does a one time check whether the buffer has sufficient data to access at least a_cbAccess
87 * bytes. Sets an error for the state and returns.
88 *
89 * @note Should only be used in the prologue of a method.
90 * @remark The introduction of int_cbAccessVerified makes sure CHECK_BUFFER_SIZE_STATIC() is there in each method for at least
91 * some rudimentary sanity check (fails to compile otherwise).
92 */
93#define CHECK_BUFFER_SIZE_STATIC(a_pState, a_cbAccess) \
94 if (RT_UNLIKELY((a_pState)->cbUnpackDataLeft < (a_cbAccess))) \
95 { \
96 (a_pState)->rcUnpack = VERR_BUFFER_OVERFLOW; \
97 return; \
98 } \
99 size_t int_cbAccessVerified = (a_cbAccess); RT_NOREF(int_cbAccessVerified)
100
101#define CHECK_BUFFER_SIZE_STATIC_LAST(a_pState, a_offAccessLast, a_Type) CHECK_BUFFER_SIZE_STATIC(a_pState, (a_offAccessLast) + sizeof( a_Type ))
102
103#define CHECK_BUFFER_SIZE_STATIC_UPDATE(a_pState, a_cbAccess) \
104 do \
105 { \
106 if (RT_UNLIKELY((a_pState)->cbUnpackDataLeft < (size_t)(a_cbAccess))) \
107 { \
108 (a_pState)->rcUnpack = VERR_BUFFER_OVERFLOW; \
109 return; \
110 } \
111 int_cbAccessVerified = (a_cbAccess); \
112 } \
113 while (0)
114
115#define CHECK_BUFFER_SIZE_STATIC_UPDATE_LAST(a_pState, a_offAccessLast, a_Type) CHECK_BUFFER_SIZE_STATIC_UPDATE(a_pState, (a_offAccessLast) + sizeof( a_Type ))
116
117#define CHECK_ARRAY_SIZE_FROM_PTR_UPDATE_LAST(a_pState, a_pArrayStart, a_cElements, a_Type) \
118 CHECK_BUFFER_SIZE_STATIC_UPDATE(a_pState, ((const uint8_t *)a_pArrayStart - (a_pState)->pbUnpackData) + (a_cElements) * sizeof(a_Type))
119#define CHECK_ARRAY_SIZE_FROM_PTR_UPDATE_SZ_LAST(a_pState, a_pArrayStart, a_cElements, a_cbType) \
120 CHECK_BUFFER_SIZE_STATIC_UPDATE(a_pState, ((const uint8_t *)a_pArrayStart - (a_pState)->pbUnpackData) + (a_cElements) * (a_cbType))
121
122
123DECLINLINE(size_t) crUnpackAcccessChkStrUpdate(PCrUnpackerState pState, const char *psz, size_t *pcbVerified)
124{
125 size_t cchStr = 0;
126 size_t cbChkMax = pState->cbUnpackDataLeft - ((const uint8_t *)psz - pState->pbUnpackData);
127 void *pv = memchr((void *)psz, '\0', cbChkMax);
128 if (!pv)
129 {
130 pState->rcUnpack = VERR_BUFFER_OVERFLOW;
131 return ~(size_t)0;
132 }
133
134 cchStr = (uint8_t *)pv - pState->pbUnpackData + 1;
135 *pcbVerified = cchStr;
136
137 return cchStr;
138}
139
140#define CHECK_STRING_FROM_PTR_UPDATE_NO_RETURN(a_pState, a_pszStr) crUnpackAcccessChkStrUpdate((a_pState), (a_pszStr), &int_cbAccessVerified);
141
142#define CHECK_STRING_FROM_PTR_UPDATE_NO_SZ(a_pState, a_pszStr) \
143 do \
144 { \
145 size_t cchStr = crUnpackAcccessChkStrUpdate((a_pState), (a_pszStr), &int_cbAccessVerified); \
146 if (RT_UNLIKELY(cchStr == ~(size_t)0)) \
147 return; \
148 } \
149 while (0)
150
151/**
152 * Reads data at the given offset of the given type from the supplied data buffer.
153 */
154#define READ_DATA(a_pState, offset, type ) *(const type *)crUnpackAccessChk((a_pState), int_cbAccessVerified, (offset), sizeof( type ))
155
156#ifdef CR_UNALIGNED_ACCESS_OKAY
157#define READ_DOUBLE(a_pState, offset ) READ_DATA(a_pState, offset, GLdouble )
158#else
159#define READ_DOUBLE(a_pState, offset ) crReadUnalignedDouble(crUnpackAccessChk((a_pState), int_cbAccessVerified, (offset), sizeof( GLdouble ) ))
160#endif
161
162#define READ_NETWORK_POINTER(a_pState, offset ) (uint8_t *)crUnpackAccessChk((a_pState), int_cbAccessVerified, (offset), 0)
163#define DATA_POINTER(a_pState, offset, type ) ((type *) (crUnpackAccessChk((a_pState), int_cbAccessVerified, (offset), 0)) )
164
165#define DATA_POINTER_CHECK(a_pState, offset ) ((size_t)(offset) < (a_pState)->cbUnpackDataLeft)
166
167#define INCR_DATA_PTR(a_pState, delta ) \
168 do \
169 { \
170 if (RT_UNLIKELY((a_pState)->cbUnpackDataLeft < (size_t)(delta))) \
171 { \
172 (a_pState)->rcUnpack = VERR_BUFFER_OVERFLOW; \
173 return; \
174 } \
175 (a_pState)->pbUnpackData += (delta); \
176 (a_pState)->cbUnpackDataLeft -= (delta); \
177 } while(0)
178
179#define INCR_DATA_PTR_NO_ARGS(a_pState) INCR_DATA_PTR(a_pState, 4 )
180
181#define INCR_VAR_PTR(a_pState) INCR_DATA_PTR(a_pState, *((int *)(a_pState)->pbUnpackData) )
182
183#define SET_RETURN_PTR(a_pState, offset ) \
184 do \
185 { \
186 CRDBGPTR_CHECKZ((a_pState)->pReturnPtr); \
187 if (!DATA_POINTER_CHECK(a_pState, offset + sizeof(*(a_pState)->pReturnPtr))) \
188 { \
189 crError("%s: SET_RETURN_PTR(%u) offset out of bounds\n", __FUNCTION__, offset); \
190 return; \
191 } \
192 crMemcpy((a_pState)->pReturnPtr, crUnpackAccessChk((a_pState), int_cbAccessVerified, (offset), sizeof( *(a_pState)->pReturnPtr )), sizeof( *(a_pState)->pReturnPtr ) ); \
193 } while (0)
194
195#define SET_WRITEBACK_PTR(a_pState, offset ) \
196 do \
197 { \
198 CRDBGPTR_CHECKZ((a_pState)->pWritebackPtr); \
199 if (!DATA_POINTER_CHECK(a_pState, offset + sizeof(*(a_pState)->pWritebackPtr))) \
200 { \
201 crError("%s: SET_RETURN_PTR(%u) offset out of bounds\n", __FUNCTION__, offset); \
202 return; \
203 } \
204 crMemcpy((a_pState)->pWritebackPtr, crUnpackAccessChk((a_pState), int_cbAccessVerified, (offset), sizeof( *(a_pState)->pWritebackPtr )), sizeof( *(a_pState)->pWritebackPtr) ); \
205 } while (0);
206
207#ifdef __cplusplus
208}
209#endif
210
211#endif /* CR_UNPACK_H */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette