4 #define UNUSED __attribute__((unused))
7 #include <asm/uaccess.h> // copy_from_user
8 #include "debug.h" // //DPRINTF
17 static TYPE_ARGUMENT GetArgumentType (char ch)
52 static char *PackArguments (char *pBuffer, unsigned long nLen, const char *szFormat, va_list args)
54 TYPE_ARGUMENT nArgType = AT_UNKNOWN;
55 const char *pChar = NULL;
57 char *pResult = pBuffer;
58 unsigned long nLengthOfDescriptor = 0, nFree = nLen;
59 unsigned long nSizeOfDescriptor = 0;
62 nLengthOfDescriptor = strlen (szFormat) + 1;
63 nSizeOfDescriptor = ALIGN_VALUE(nLengthOfDescriptor);
64 if(nFree < nSizeOfDescriptor)
65 return NULL; // no space for descriptor
66 memcpy (pResult, szFormat, nLengthOfDescriptor);
67 pResult += nSizeOfDescriptor;
68 nFree -= nSizeOfDescriptor;
70 for (pChar = szFormat; (chCode = *pChar) != '\0'; pChar++)
72 nArgType = GetArgumentType(chCode);
77 int ch = va_arg (args, int);
78 if(nFree < sizeof(ch))
79 return NULL; // no space for arg
80 memcpy(pResult, &ch, sizeof (ch));
81 pResult += sizeof (ch);
87 int nShort = va_arg (args, int);
88 if(nFree < sizeof(nShort))
89 return NULL; // no space for arg
90 memcpy(pResult, &nShort, sizeof (nShort));
91 pResult += sizeof (nShort);
92 nFree -= sizeof (nShort);
97 int nInt = va_arg (args, int);
98 if(nFree < sizeof(nInt))
99 return NULL; // no space for arg
100 memcpy(pResult, &nInt, sizeof (nInt));
101 pResult += sizeof (nInt);
102 nFree -= sizeof (nInt);
107 long nLong = va_arg (args, long);
108 if(nFree < sizeof(nLong))
109 return NULL; // no space for arg
110 memcpy (pResult, &nLong, sizeof (nLong));
111 pResult += sizeof (nLong);
112 nFree -= sizeof (nLong);
117 void *p = va_arg (args, void *);
118 if(nFree < sizeof(p))
119 return NULL; // no space for arg
120 memcpy (pResult, &p, sizeof (p));
121 pResult += sizeof (p);
127 double fValue = va_arg (args, double);
128 if(nFree < sizeof(fValue))
129 return NULL; // no space for arg
130 memcpy (pResult, &fValue, sizeof (fValue));
131 pResult += sizeof (fValue);
132 nFree -= sizeof (fValue);
137 double fDouble = va_arg (args, double);
138 if(nFree < sizeof(fDouble))
139 return NULL; // no space for arg
140 memcpy (pResult, &fDouble, sizeof (fDouble));
141 pResult += sizeof (fDouble);
142 nFree -= sizeof (fDouble);
147 const char *s = va_arg (args, const char *);
148 int nLengthOfString = 0, nSizeOfString;
150 /* If string poiner is NULL then */
154 if((void *)s < (void *)TASK_SIZE) {
155 const char __user *user_s = (const char __user *)s;
156 nLengthOfString = strlen_user(user_s);
157 if(nFree < nLengthOfString)
158 return NULL; // no space for arg
159 if(strncpy_from_user(pResult,
161 nLengthOfString) != (nLengthOfString-1)) {
162 const char err_str[] =
163 "(failed strcpy_from_user)";
164 EPRINTF("failed to copy string from user %p, bytes %d",
165 user_s, nLengthOfString);
166 nLengthOfString = sizeof(err_str);
167 memcpy(pResult, err_str, nLengthOfString);
173 nLengthOfString = strlen (s) + 1;
174 if(nFree < nLengthOfString)
175 return NULL; // no space for arg
176 memcpy (pResult, s, nLengthOfString);
178 nSizeOfString = ALIGN_VALUE (nLengthOfString);
179 if(nFree < nSizeOfString)
180 return NULL; // no space for arg
181 pResult += nSizeOfString;
182 nFree -= nSizeOfString;
187 int nLength = va_arg (args, int);
190 nSize = ALIGN_VALUE (nLength);
192 return NULL; // no space for arg
193 memcpy (pResult, &nLength, sizeof (int));
194 pResult += sizeof (int);
195 p = va_arg (args, void *);
197 if((void *)p < (void *)TASK_SIZE) {
198 const void __user *P = (void __user *) va_arg(args, void*);
199 if(copy_from_user(pResult, P, nLength)!= 0)
200 EPRINTF ("failed to copy array from user %p, bytes %d", P, nLength);
204 memcpy (pResult, p, nLength);
216 static UNUSED TYPEOF_EVENT_LENGTH VPackEvent(char *buf, unsigned long buf_len, int mask, TYPEOF_PROBE_ID probe_id,
217 TYPEOF_EVENT_TYPE record_type, TYPEOF_TIME *tv, TYPEOF_PROCESS_ID pid,
218 TYPEOF_THREAD_ID tid, TYPEOF_CPU_NUMBER cpu, const char *fmt, va_list args)
221 SWAP_TYPE_EVENT_HEADER *pEventHeader = (SWAP_TYPE_EVENT_HEADER *)buf;
223 if(buf_len < sizeof(SWAP_TYPE_EVENT_HEADER))
224 return 0; // no space for header
226 pEventHeader->m_nLength = 0;
227 cur += sizeof(TYPEOF_EVENT_LENGTH);
228 pEventHeader->m_nType = record_type;
229 cur += sizeof(TYPEOF_EVENT_TYPE);
230 pEventHeader->m_nProbeID = probe_id;
231 cur += sizeof(TYPEOF_PROBE_ID);
232 //pEventHeader->m_time.tv_sec = tv->tv_sec;
233 //pEventHeader->m_time.tv_usec = tv->tv_usec;
234 if((probe_id == EVENT_FMT_PROBE_ID) || !(mask & IOCTL_EMASK_TIME)){
235 memcpy(cur, tv, sizeof(TYPEOF_TIME));
236 cur += sizeof(TYPEOF_TIME);
238 //pEventHeader->m_nProcessID = pid;
239 if((probe_id == EVENT_FMT_PROBE_ID) || !(mask & IOCTL_EMASK_PID)){
240 (*(TYPEOF_PROCESS_ID *)cur) = pid;
241 cur += sizeof(TYPEOF_PROCESS_ID);
243 //pEventHeader->m_nThreadID = tid;
244 if((probe_id == EVENT_FMT_PROBE_ID) || !(mask & IOCTL_EMASK_TID)){
245 (*(TYPEOF_THREAD_ID *)cur) = tid;
246 cur += sizeof(TYPEOF_THREAD_ID);
248 //pEventHeader->m_nCPU = cpu;
249 if((probe_id == EVENT_FMT_PROBE_ID) || !(mask & IOCTL_EMASK_CPU)){
250 (*(TYPEOF_CPU_NUMBER *)cur) = cpu;
251 cur += sizeof(TYPEOF_CPU_NUMBER);
253 // dyn lib event should have all args, it is for internal use and not visible to user
254 if((probe_id == EVENT_FMT_PROBE_ID) || (probe_id == DYN_LIB_PROBE_ID) || !(mask & IOCTL_EMASK_ARGS)){
255 (*(TYPEOF_NUMBER_OF_ARGS *)cur) = strlen(fmt);
256 cur += sizeof(TYPEOF_NUMBER_OF_ARGS);
257 cur = PackArguments(cur, buf_len-(cur-buf), fmt, args);
258 if(!cur) return 0; // no space for args
261 // user space and dynamic kernel probes should have at least one argument
263 if((probe_id == US_PROBE_ID) || (probe_id == VTP_PROBE_ID) || (probe_id == KS_PROBE_ID)){
265 (*(TYPEOF_NUMBER_OF_ARGS *)cur) = 1;
266 cur += sizeof(TYPEOF_NUMBER_OF_ARGS);
267 // pack args using format string for the 1st arg only
268 fmt2[0] = fmt[0]; fmt2[1] = '\0';
269 cur = PackArguments(cur, buf_len-(cur-buf), fmt2, args);
270 if(!cur) return 0; // no space for args
273 (*(TYPEOF_NUMBER_OF_ARGS *)cur) = 0;
274 cur += sizeof(TYPEOF_NUMBER_OF_ARGS);
278 pEventHeader->m_nLength = cur - buf + sizeof(TYPEOF_EVENT_LENGTH);
279 if(buf_len < pEventHeader->m_nLength)
280 return 0;// no space for back length
281 //memcpy(cur, &pEventHeader->m_nLength, sizeof(TYPEOF_EVENT_LENGTH));
282 *((TYPEOF_EVENT_LENGTH *)cur) = pEventHeader->m_nLength;
284 return pEventHeader->m_nLength;
287 /*static TYPEOF_EVENT_LENGTH PackEvent(char *buf, unsigned long buf_len, TYPEOF_PROBE_ID probe_id,
288 TYPEOF_EVENT_TYPE record_type, TYPEOF_TIME *tv, TYPEOF_PROCESS_ID pid,
289 TYPEOF_THREAD_ID tid, TYPEOF_CPU_NUMBER cpu, const char *fmt, ...)
292 TYPEOF_EVENT_LENGTH len;
294 va_start (args, fmt);
295 len = VPackEvent(buf, buf_len, probe_id, record_type, tv, pid, tid, cpu, fmt, args);