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 EPRINTF("failed to copy string from user %p, bytes %d",
163 user_s, nLengthOfString);
169 nLengthOfString = strlen (s) + 1;
170 if(nFree < nLengthOfString)
171 return NULL; // no space for arg
172 memcpy (pResult, s, nLengthOfString);
174 nSizeOfString = ALIGN_VALUE (nLengthOfString);
175 if(nFree < nSizeOfString)
176 return NULL; // no space for arg
177 pResult += nSizeOfString;
178 nFree -= nSizeOfString;
183 int nLength = va_arg (args, int);
186 nSize = ALIGN_VALUE (nLength);
188 return NULL; // no space for arg
189 memcpy (pResult, &nLength, sizeof (int));
190 pResult += sizeof (int);
191 p = va_arg (args, void *);
193 if((void *)p < (void *)TASK_SIZE) {
194 const void __user *P = (void __user *) va_arg(args, void*);
195 if(copy_from_user(pResult, P, nLength)!= 0)
196 EPRINTF ("failed to copy array from user %p, bytes %d", P, nLength);
200 memcpy (pResult, p, nLength);
212 static UNUSED TYPEOF_EVENT_LENGTH VPackEvent(char *buf, unsigned long buf_len, int mask, TYPEOF_PROBE_ID probe_id,
213 TYPEOF_EVENT_TYPE record_type, TYPEOF_TIME *tv, TYPEOF_PROCESS_ID pid,
214 TYPEOF_THREAD_ID tid, TYPEOF_CPU_NUMBER cpu, const char *fmt, va_list args)
217 SWAP_TYPE_EVENT_HEADER *pEventHeader = (SWAP_TYPE_EVENT_HEADER *)buf;
219 if(buf_len < sizeof(SWAP_TYPE_EVENT_HEADER))
220 return 0; // no space for header
222 pEventHeader->m_nLength = 0;
223 cur += sizeof(TYPEOF_EVENT_LENGTH);
224 pEventHeader->m_nType = record_type;
225 cur += sizeof(TYPEOF_EVENT_TYPE);
226 pEventHeader->m_nProbeID = probe_id;
227 cur += sizeof(TYPEOF_PROBE_ID);
228 //pEventHeader->m_time.tv_sec = tv->tv_sec;
229 //pEventHeader->m_time.tv_usec = tv->tv_usec;
230 if((probe_id == EVENT_FMT_PROBE_ID) || !(mask & IOCTL_EMASK_TIME)){
231 memcpy(cur, tv, sizeof(TYPEOF_TIME));
232 cur += sizeof(TYPEOF_TIME);
234 //pEventHeader->m_nProcessID = pid;
235 if((probe_id == EVENT_FMT_PROBE_ID) || !(mask & IOCTL_EMASK_PID)){
236 (*(TYPEOF_PROCESS_ID *)cur) = pid;
237 cur += sizeof(TYPEOF_PROCESS_ID);
239 //pEventHeader->m_nThreadID = tid;
240 if((probe_id == EVENT_FMT_PROBE_ID) || !(mask & IOCTL_EMASK_TID)){
241 (*(TYPEOF_THREAD_ID *)cur) = tid;
242 cur += sizeof(TYPEOF_THREAD_ID);
244 //pEventHeader->m_nCPU = cpu;
245 if((probe_id == EVENT_FMT_PROBE_ID) || !(mask & IOCTL_EMASK_CPU)){
246 (*(TYPEOF_CPU_NUMBER *)cur) = cpu;
247 cur += sizeof(TYPEOF_CPU_NUMBER);
249 // dyn lib event should have all args, it is for internal use and not visible to user
250 if((probe_id == EVENT_FMT_PROBE_ID) || (probe_id == DYN_LIB_PROBE_ID) || !(mask & IOCTL_EMASK_ARGS)){
251 (*(TYPEOF_NUMBER_OF_ARGS *)cur) = strlen(fmt);
252 cur += sizeof(TYPEOF_NUMBER_OF_ARGS);
253 cur = PackArguments(cur, buf_len-(cur-buf), fmt, args);
254 if(!cur) return 0; // no space for args
257 // user space and dynamic kernel probes should have at least one argument
259 if((probe_id == US_PROBE_ID) || (probe_id == VTP_PROBE_ID) || (probe_id == KS_PROBE_ID)){
261 (*(TYPEOF_NUMBER_OF_ARGS *)cur) = 1;
262 cur += sizeof(TYPEOF_NUMBER_OF_ARGS);
263 // pack args using format string for the 1st arg only
264 fmt2[0] = fmt[0]; fmt2[1] = '\0';
265 cur = PackArguments(cur, buf_len-(cur-buf), fmt2, args);
266 if(!cur) return 0; // no space for args
269 (*(TYPEOF_NUMBER_OF_ARGS *)cur) = 0;
270 cur += sizeof(TYPEOF_NUMBER_OF_ARGS);
274 pEventHeader->m_nLength = cur - buf + sizeof(TYPEOF_EVENT_LENGTH);
275 if(buf_len < pEventHeader->m_nLength)
276 return 0;// no space for back length
277 //memcpy(cur, &pEventHeader->m_nLength, sizeof(TYPEOF_EVENT_LENGTH));
278 *((TYPEOF_EVENT_LENGTH *)cur) = pEventHeader->m_nLength;
280 return pEventHeader->m_nLength;
283 /*static TYPEOF_EVENT_LENGTH PackEvent(char *buf, unsigned long buf_len, TYPEOF_PROBE_ID probe_id,
284 TYPEOF_EVENT_TYPE record_type, TYPEOF_TIME *tv, TYPEOF_PROCESS_ID pid,
285 TYPEOF_THREAD_ID tid, TYPEOF_CPU_NUMBER cpu, const char *fmt, ...)
288 TYPEOF_EVENT_LENGTH len;
290 va_start (args, fmt);
291 len = VPackEvent(buf, buf_len, probe_id, record_type, tv, pid, tid, cpu, fmt, args);