summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/staprun/common.c112
-rw-r--r--runtime/syscall.h13
2 files changed, 17 insertions, 108 deletions
diff --git a/runtime/staprun/common.c b/runtime/staprun/common.c
index 6c199616..644dfa53 100644
--- a/runtime/staprun/common.c
+++ b/runtime/staprun/common.c
@@ -56,112 +56,15 @@ static char *get_abspath(char *path)
int stap_strfloctime(char *buf, size_t max, const char *fmt, time_t t)
{
- char *c = buf;
- const char *c2 = fmt, *end = buf + max;
- int ret, num;
struct tm tm;
+ size_t ret;
if (buf == NULL || fmt == NULL || max <= 1)
return -EINVAL;
localtime_r(&t, &tm);
-
- while (*c2 != '\0'){
- if (c + 1 >= end)
- return -EINVAL;
- if (*c2 != '%') {
- *c++ = *c2++;
- continue;
- }
- c2++;
- switch (*c2++) {
- case '%':
- *c++ = '%';
- break;
- case 'Y':
- num = tm.tm_year + 1900;
- goto numbering;
- case 'y':
- num = tm.tm_year % 100;
- goto numbering02;
- case 'C':
- num = ((tm.tm_year + 1900) / 100);
- goto numbering;
- case 'm':
- num = tm.tm_mon + 1;
- goto numbering02;
- case 'd':
- num = tm.tm_mday;
- goto numbering02;
- case 'e':
- num = tm.tm_mday;
- goto numbering;
- case 'F':
- ret = snprintf(c, end - c, "%d-%02d-%02d",
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
- if (ret < 0) return ret;
- c += ret;
- break;
- case 'H':
- num = tm.tm_hour;
- goto numbering02;
- case 'I':
- num = tm.tm_hour % 12;
- if (num == 0) num = 12;
- goto numbering02;
- case 'j':
- ret = snprintf(c, end - c, "%03d", tm.tm_yday + 1);
- if (ret < 0) return ret;
- c += ret;
- break;
- case 'k':
- num = tm.tm_hour;
- goto numbering;
- case 'l':
- num = tm.tm_hour % 12;
- if (num == 0) num = 12;
- ret = snprintf(c, end - c, "%2d", num);
- if (ret < 0) return ret;
- c += ret;
- break;
- case 'M':
- num = tm.tm_min;
- goto numbering02;
- case 'S':
- num = tm.tm_sec;
- goto numbering02;
- case 'R':
- ret = snprintf(c, end - c, "%02d:%02d",
- tm.tm_hour, tm.tm_min);
- if (ret < 0) return ret;
- c += ret;
- break;
- case 'T':
- ret = snprintf(c, end - c, "%02d:%02d:%02d",
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- if (ret < 0) return ret;
- c += ret;
- break;
- case 'u':
- num = tm.tm_wday == 0 ? 7 : tm.tm_wday;
- goto numbering;
- case 'w':
- num = tm.tm_wday;
- goto numbering;
- default:
- return -EINVAL;
- }
- continue;
-numbering:
- ret = snprintf(c, end - c, "%d", num);
- if (ret < 0) return ret;
- c += ret;
- continue;
-numbering02:
- ret = snprintf(c, end - c, "%02d", num);
- if (ret < 0) return ret;
- c += ret;
- }
- *c = '\0';
- return c - buf;
+ ret = strftime(buf, max, fmt, &tm);
+ if (ret == 0)
+ return -EINVAL;
+ return (int)ret;
}
void parse_args(int argc, char **argv)
@@ -310,9 +213,8 @@ void usage(char *prog)
err(" exit when it does. The '_stp_target' variable\n");
err(" will contain the pid for the command.\n");
err("-x pid Sets the '_stp_target' variable to pid.\n");
- err("-o FILE Send output to FILE. This supports a subset of\n");
- err(" strftime(3) (%%%%,%%C,%%Y,%%y,%%m,%%d,%%e,%%F,%%H,%%I\n");
- err(" %%j,%%k,%%l,%%M,%%S,%%R,%%T,%%u,%%w) for FILE.\n");
+ err("-o FILE Send output to FILE. This supports strftime(3)\n");
+ err(" formats for FILE.\n");
err("-b buffer size The systemtap module specifies a buffer size.\n");
err(" Setting one here will override that value. The\n");
err(" value should be an integer between 1 and 4095 \n");
diff --git a/runtime/syscall.h b/runtime/syscall.h
index ffc21efc..38b523e1 100644
--- a/runtime/syscall.h
+++ b/runtime/syscall.h
@@ -345,6 +345,10 @@ struct syscall_get_set_args {
int rw;
};
+#define CFM_SOF(cfm) ((cfm) & 0x7f) /* Size of frame */
+#define CFM_SOL(cfm) (((cfm) >> 7) & 0x7f) /* Size of locals */
+#define CFM_OUT(cfm) (CFM_SOF(cfm) - CFM_SOL(cfm)) /* Size of outputs */
+
static void syscall_get_set_args_cb(struct unw_frame_info *info, void *data)
{
struct syscall_get_set_args *args = data;
@@ -361,15 +365,18 @@ static void syscall_get_set_args_cb(struct unw_frame_info *info, void *data)
count = 0;
if (in_syscall(pt))
- count = min_t(int, args->n, cfm & 0x7f);
+ /* args->i + args->n must be less equal than nr outputs */
+ count = min_t(int, args->n, CFM_OUT(cfm) - args->i);
for (i = 0; i < count; i++) {
+ /* Skips dirties and locals */
if (args->rw)
- *ia64_rse_skip_regs(krbs, ndirty + i + args->i) =
+ *ia64_rse_skip_regs(krbs,
+ ndirty + CFM_SOL(cfm) + args->i + i) =
args->args[i];
else
args->args[i] = *ia64_rse_skip_regs(krbs,
- ndirty + i + args->i);
+ ndirty + CFM_SOL(cfm) + args->i + i);
}
if (!args->rw) {