note: print without relying on format strings
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
This commit is contained in:
parent
57a385a994
commit
5d8cdeaea8
@ -87,6 +87,11 @@ config DRIVERS_NOTERAM_CRASH_DUMP
|
||||
|
||||
endif # DRIVERS_NOTERAM
|
||||
|
||||
config DRIVERS_NOTE_STRIP_FORMAT
|
||||
bool "Strip sched_note_printf format string"
|
||||
---help---
|
||||
Strip sched_note_printf format string.
|
||||
|
||||
config DRIVERS_NOTELOG
|
||||
bool "Note syslog driver"
|
||||
---help---
|
||||
|
@ -1483,39 +1483,14 @@ void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event,
|
||||
}
|
||||
}
|
||||
|
||||
void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip,
|
||||
FAR const char *fmt, va_list va)
|
||||
void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt,
|
||||
uint32_t type, va_list va)
|
||||
{
|
||||
FAR struct note_printf_s *note;
|
||||
FAR struct note_driver_s **driver;
|
||||
bool formatted = false;
|
||||
uint8_t data[255];
|
||||
begin_packed_struct union
|
||||
{
|
||||
int i;
|
||||
long l;
|
||||
#ifdef CONFIG_HAVE_LONG_LONG
|
||||
long long ll;
|
||||
#endif
|
||||
intmax_t im;
|
||||
size_t sz;
|
||||
ptrdiff_t ptr;
|
||||
FAR void *p;
|
||||
#ifdef CONFIG_HAVE_DOUBLE
|
||||
double d;
|
||||
# ifdef CONFIG_HAVE_LONG_DOUBLE
|
||||
long double ld;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
end_packed_struct *var;
|
||||
|
||||
char c;
|
||||
size_t length;
|
||||
size_t next = 0;
|
||||
bool infmt = false;
|
||||
FAR const char *p = fmt;
|
||||
size_t length = 0;
|
||||
FAR struct tcb_s *tcb = this_task();
|
||||
|
||||
if (!note_isenabled_dump(tag))
|
||||
@ -1539,146 +1514,236 @@ void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip,
|
||||
|
||||
if (!formatted)
|
||||
{
|
||||
begin_packed_struct union
|
||||
{
|
||||
int i;
|
||||
long l;
|
||||
#ifdef CONFIG_HAVE_LONG_LONG
|
||||
long long ll;
|
||||
#endif
|
||||
intmax_t im;
|
||||
size_t sz;
|
||||
ptrdiff_t ptr;
|
||||
FAR void *p;
|
||||
FAR const char *s;
|
||||
#ifdef CONFIG_HAVE_DOUBLE
|
||||
double d;
|
||||
# ifdef CONFIG_HAVE_LONG_DOUBLE
|
||||
long double ld;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
end_packed_struct *var;
|
||||
size_t next = 0;
|
||||
formatted = true;
|
||||
note = (FAR struct note_printf_s *)data;
|
||||
length = sizeof(data) - SIZEOF_NOTE_PRINTF(0);
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
if (type)
|
||||
{
|
||||
if (c != '%' && !infmt)
|
||||
size_t count = NOTE_PRINTF_GET_COUNT(type);
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
continue;
|
||||
var = (FAR void *)¬e->npt_data[next];
|
||||
switch (NOTE_PRINTF_GET_TYPE(type, i))
|
||||
{
|
||||
case NOTE_PRINTF_UINT32:
|
||||
{
|
||||
var->i = va_arg(va, int);
|
||||
if (next + sizeof(var->i) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
next += sizeof(var->i);
|
||||
}
|
||||
break;
|
||||
case NOTE_PRINTF_UINT64:
|
||||
{
|
||||
if (next + sizeof(var->ll) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->ll = va_arg(va, long long);
|
||||
next += sizeof(var->ll);
|
||||
}
|
||||
break;
|
||||
case NOTE_PRINTF_STRING:
|
||||
{
|
||||
size_t len;
|
||||
var->s = va_arg(va, FAR const char *);
|
||||
len = strlen(var->s) + 1;
|
||||
if (next + len > length)
|
||||
{
|
||||
len = length - next;
|
||||
}
|
||||
|
||||
strlcpy(note->npt_data + next, var->s, len);
|
||||
next += len;
|
||||
}
|
||||
break;
|
||||
case NOTE_PRINTF_DOUBLE:
|
||||
{
|
||||
var->d = va_arg(va, double);
|
||||
if (next + sizeof(var->d) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
next += sizeof(var->d);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FAR const char *p = fmt;
|
||||
bool infmt = false;
|
||||
char c;
|
||||
|
||||
infmt = true;
|
||||
var = (FAR void *)¬e->npt_data[next];
|
||||
|
||||
if (c == 'c' || c == 'd' || c == 'i' || c == 'u' ||
|
||||
c == 'o' || c == 'x' || c == 'X')
|
||||
while ((c = *p++) != '\0')
|
||||
{
|
||||
if (*(p - 2) == 'j')
|
||||
if (c != '%' && !infmt)
|
||||
{
|
||||
if (next + sizeof(var->im) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->im = va_arg(va, intmax_t);
|
||||
next += sizeof(var->im);
|
||||
continue;
|
||||
}
|
||||
|
||||
infmt = true;
|
||||
var = (FAR void *)¬e->npt_data[next];
|
||||
|
||||
if (c == 'c' || c == 'd' || c == 'i' || c == 'u' ||
|
||||
c == 'o' || c == 'x' || c == 'X')
|
||||
{
|
||||
if (*(p - 2) == 'j')
|
||||
{
|
||||
if (next + sizeof(var->im) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->im = va_arg(va, intmax_t);
|
||||
next += sizeof(var->im);
|
||||
}
|
||||
#ifdef CONFIG_HAVE_LONG_LONG
|
||||
else if (*(p - 2) == 'l' && *(p - 3) == 'l')
|
||||
{
|
||||
if (next + sizeof(var->ll) > length)
|
||||
else if (*(p - 2) == 'l' && *(p - 3) == 'l')
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (next + sizeof(var->ll) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->ll = va_arg(va, long long);
|
||||
next += sizeof(var->ll);
|
||||
}
|
||||
var->ll = va_arg(va, long long);
|
||||
next += sizeof(var->ll);
|
||||
}
|
||||
#endif
|
||||
else if (*(p - 2) == 'l')
|
||||
{
|
||||
if (next + sizeof(var->l) > length)
|
||||
else if (*(p - 2) == 'l')
|
||||
{
|
||||
break;
|
||||
if (next + sizeof(var->l) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->l = va_arg(va, long);
|
||||
next += sizeof(var->l);
|
||||
}
|
||||
else if (*(p - 2) == 'z')
|
||||
{
|
||||
if (next + sizeof(var->sz) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->sz = va_arg(va, size_t);
|
||||
next += sizeof(var->sz);
|
||||
}
|
||||
else if (*(p - 2) == 't')
|
||||
{
|
||||
if (next + sizeof(var->ptr) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->ptr = va_arg(va, ptrdiff_t);
|
||||
next += sizeof(var->ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (next + sizeof(var->i) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->i = va_arg(va, int);
|
||||
next += sizeof(var->i);
|
||||
}
|
||||
|
||||
var->l = va_arg(va, long);
|
||||
next += sizeof(var->l);
|
||||
infmt = false;
|
||||
}
|
||||
else if (*(p - 2) == 'z')
|
||||
else if (c == 'e' || c == 'f' || c == 'g' || c == 'a' ||
|
||||
c == 'A' || c == 'E' || c == 'F' || c == 'G')
|
||||
{
|
||||
if (next + sizeof(var->sz) > length)
|
||||
#ifdef CONFIG_HAVE_DOUBLE
|
||||
# ifdef CONFIG_HAVE_LONG_DOUBLE
|
||||
if (*(p - 2) == 'L')
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (next + sizeof(var->ld) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->sz = va_arg(va, size_t);
|
||||
next += sizeof(var->sz);
|
||||
var->ld = va_arg(va, long double);
|
||||
next += sizeof(var->ld);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
if (next + sizeof(var->d) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->d = va_arg(va, double);
|
||||
next += sizeof(var->d);
|
||||
}
|
||||
#endif
|
||||
|
||||
infmt = false;
|
||||
}
|
||||
else if (*(p - 2) == 't')
|
||||
else if (c == '*')
|
||||
{
|
||||
if (next + sizeof(var->ptr) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->ptr = va_arg(va, ptrdiff_t);
|
||||
next += sizeof(var->ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (next + sizeof(var->i) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->i = va_arg(va, int);
|
||||
next += sizeof(var->i);
|
||||
}
|
||||
|
||||
infmt = false;
|
||||
}
|
||||
else if (c == 'e' || c == 'f' || c == 'g' || c == 'a' ||
|
||||
c == 'A' || c == 'E' || c == 'F' || c == 'G')
|
||||
{
|
||||
#ifdef CONFIG_HAVE_DOUBLE
|
||||
# ifdef CONFIG_HAVE_LONG_DOUBLE
|
||||
if (*(p - 2) == 'L')
|
||||
else if (c == 's')
|
||||
{
|
||||
if (next + sizeof(var->ld) > length)
|
||||
size_t len;
|
||||
var->s = va_arg(va, FAR char *);
|
||||
len = strlen(var->s) + 1;
|
||||
if (next + len > length)
|
||||
{
|
||||
len = length - next;
|
||||
}
|
||||
|
||||
strlcpy(note->npt_data + next, var->s, len);
|
||||
next += len;
|
||||
infmt = false;
|
||||
}
|
||||
else if (c == 'p')
|
||||
{
|
||||
if (next + sizeof(var->p) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->ld = va_arg(va, long double);
|
||||
next += sizeof(var->ld);
|
||||
var->p = va_arg(va, FAR void *);
|
||||
next += sizeof(var->p);
|
||||
infmt = false;
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
if (next + sizeof(var->d) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->d = va_arg(va, double);
|
||||
next += sizeof(var->d);
|
||||
}
|
||||
#endif
|
||||
|
||||
infmt = false;
|
||||
}
|
||||
else if (c == '*')
|
||||
{
|
||||
var->i = va_arg(va, int);
|
||||
next += sizeof(var->i);
|
||||
}
|
||||
else if (c == 's')
|
||||
{
|
||||
FAR char *str = (FAR char *)va_arg(va, FAR char *);
|
||||
size_t len = strlen(str) + 1;
|
||||
if (next + len > length)
|
||||
{
|
||||
len = length - next;
|
||||
}
|
||||
|
||||
strlcpy(¬e->npt_data[next], str, len);
|
||||
next += len;
|
||||
infmt = false;
|
||||
}
|
||||
else if (c == 'p')
|
||||
{
|
||||
if (next + sizeof(var->p) > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var->p = va_arg(va, FAR void *);
|
||||
next += sizeof(var->p);
|
||||
infmt = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1686,6 +1751,7 @@ void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip,
|
||||
note_common(tcb, ¬e->npt_cmn, length, NOTE_DUMP_PRINTF);
|
||||
note->npt_ip = ip;
|
||||
note->npt_fmt = fmt;
|
||||
note->npt_type = type;
|
||||
}
|
||||
|
||||
/* Add the note to circular buffer */
|
||||
@ -1694,12 +1760,12 @@ void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip,
|
||||
}
|
||||
}
|
||||
|
||||
void sched_note_printf_ip(uint32_t tag, uintptr_t ip,
|
||||
FAR const char *fmt, ...)
|
||||
void sched_note_printf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt,
|
||||
uint32_t type, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
sched_note_vprintf_ip(tag, ip, fmt, va);
|
||||
va_start(va, type);
|
||||
sched_note_vprintf_ip(tag, ip, fmt, type, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
|
@ -728,7 +728,8 @@ static int noteram_dump_printf(FAR struct lib_outstream_s *s,
|
||||
intmax_t im;
|
||||
size_t sz;
|
||||
ptrdiff_t pd;
|
||||
uintptr_t p;
|
||||
FAR void *p;
|
||||
FAR const char *s;
|
||||
#ifdef CONFIG_HAVE_DOUBLE
|
||||
double d;
|
||||
# ifdef CONFIG_HAVE_LONG_DOUBLE
|
||||
@ -738,117 +739,169 @@ static int noteram_dump_printf(FAR struct lib_outstream_s *s,
|
||||
}
|
||||
|
||||
end_packed_struct *var;
|
||||
FAR const char *p = note->npt_fmt;
|
||||
FAR char *data = note->npt_data;
|
||||
char fmtstr[64];
|
||||
bool infmt = false;
|
||||
size_t offset = 0;
|
||||
size_t ret = 0;
|
||||
size_t len = 0;
|
||||
char c;
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
if (note->npt_type == 0)
|
||||
{
|
||||
if (c != '%' && !infmt)
|
||||
{
|
||||
lib_stream_putc(s, c);
|
||||
ret++;
|
||||
continue;
|
||||
}
|
||||
FAR const char *p = note->npt_fmt;
|
||||
bool infmt = false;
|
||||
char fmtstr[64];
|
||||
char c;
|
||||
|
||||
if (!infmt)
|
||||
while ((c = *p++) != '\0')
|
||||
{
|
||||
len = 0;
|
||||
infmt = true;
|
||||
memset(fmtstr, 0, sizeof(fmtstr));
|
||||
}
|
||||
|
||||
var = (FAR void *)(note->npt_data + offset);
|
||||
fmtstr[len++] = c;
|
||||
|
||||
if (c == 'c' || c == 'd' || c == 'i' || c == 'u' ||
|
||||
c == 'o' || c == 'x' || c == 'X')
|
||||
{
|
||||
if (*(p - 2) == 'j')
|
||||
if (c != '%' && !infmt)
|
||||
{
|
||||
offset += sizeof(var->im);
|
||||
ret += lib_sprintf(s, fmtstr, var->im);
|
||||
lib_stream_putc(s, c);
|
||||
ret++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!infmt)
|
||||
{
|
||||
len = 0;
|
||||
infmt = true;
|
||||
memset(fmtstr, 0, sizeof(fmtstr));
|
||||
}
|
||||
|
||||
var = (FAR void *)(note->npt_data + offset);
|
||||
fmtstr[len++] = c;
|
||||
|
||||
if (c == 'c' || c == 'd' || c == 'i' || c == 'u' ||
|
||||
c == 'o' || c == 'x' || c == 'X')
|
||||
{
|
||||
if (*(p - 2) == 'j')
|
||||
{
|
||||
offset += sizeof(var->im);
|
||||
ret += lib_sprintf(s, fmtstr, var->im);
|
||||
}
|
||||
#ifdef CONFIG_HAVE_LONG_LONG
|
||||
else if (*(p - 2) == 'l' && *(p - 3) == 'l')
|
||||
{
|
||||
offset += sizeof(var->ll);
|
||||
ret += lib_sprintf(s, fmtstr, var->ll);
|
||||
}
|
||||
else if (*(p - 2) == 'l' && *(p - 3) == 'l')
|
||||
{
|
||||
offset += sizeof(var->ll);
|
||||
ret += lib_sprintf(s, fmtstr, var->ll);
|
||||
}
|
||||
#endif
|
||||
else if (*(p - 2) == 'l')
|
||||
{
|
||||
offset += sizeof(var->l);
|
||||
ret += lib_sprintf(s, fmtstr, var->l);
|
||||
}
|
||||
else if (*(p - 2) == 'z')
|
||||
{
|
||||
offset += sizeof(var->sz);
|
||||
ret += lib_sprintf(s, fmtstr, var->sz);
|
||||
}
|
||||
else if (*(p - 2) == 't')
|
||||
{
|
||||
offset += sizeof(var->pd);
|
||||
ret += lib_sprintf(s, fmtstr, var->pd);
|
||||
}
|
||||
else
|
||||
{
|
||||
offset += sizeof(var->i);
|
||||
ret += lib_sprintf(s, fmtstr, var->i);
|
||||
}
|
||||
else if (*(p - 2) == 'l')
|
||||
{
|
||||
offset += sizeof(var->l);
|
||||
ret += lib_sprintf(s, fmtstr, var->l);
|
||||
}
|
||||
else if (*(p - 2) == 'z')
|
||||
{
|
||||
offset += sizeof(var->sz);
|
||||
ret += lib_sprintf(s, fmtstr, var->sz);
|
||||
}
|
||||
else if (*(p - 2) == 't')
|
||||
{
|
||||
offset += sizeof(var->pd);
|
||||
ret += lib_sprintf(s, fmtstr, var->pd);
|
||||
}
|
||||
else
|
||||
{
|
||||
offset += sizeof(var->i);
|
||||
ret += lib_sprintf(s, fmtstr, var->i);
|
||||
}
|
||||
|
||||
infmt = false;
|
||||
}
|
||||
else if (c == 'e' || c == 'f' || c == 'g' || c == 'a' ||
|
||||
c == 'A' || c == 'E' || c == 'F' || c == 'G')
|
||||
{
|
||||
infmt = false;
|
||||
}
|
||||
else if (c == 'e' || c == 'f' || c == 'g' || c == 'a' ||
|
||||
c == 'A' || c == 'E' || c == 'F' || c == 'G')
|
||||
{
|
||||
#ifdef CONFIG_HAVE_DOUBLE
|
||||
# ifdef CONFIG_HAVE_LONG_DOUBLE
|
||||
if (*(p - 2) == 'L')
|
||||
{
|
||||
offset += sizeof(var->ld);
|
||||
ret += lib_sprintf(s, fmtstr, var->ld);
|
||||
}
|
||||
else
|
||||
if (*(p - 2) == 'L')
|
||||
{
|
||||
offset += sizeof(var->ld);
|
||||
ret += lib_sprintf(s, fmtstr, var->ld);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
offset += sizeof(var->d);
|
||||
ret += lib_sprintf(s, fmtstr, var->d);
|
||||
}
|
||||
{
|
||||
offset += sizeof(var->d);
|
||||
ret += lib_sprintf(s, fmtstr, var->d);
|
||||
}
|
||||
|
||||
infmt = false;
|
||||
}
|
||||
infmt = false;
|
||||
}
|
||||
#endif
|
||||
else if (c == '*')
|
||||
{
|
||||
itoa(var->i, fmtstr + len - 1, 10);
|
||||
len = strlen(fmtstr);
|
||||
offset += sizeof(var->i);
|
||||
else if (c == '*')
|
||||
{
|
||||
itoa(var->i, fmtstr + len - 1, 10);
|
||||
len = strlen(fmtstr);
|
||||
offset += sizeof(var->i);
|
||||
}
|
||||
else if (c == 's')
|
||||
{
|
||||
const char *str = note->npt_data + offset;
|
||||
offset += strlen(str) + 1;
|
||||
ret += lib_sprintf(s, fmtstr, str);
|
||||
infmt = false;
|
||||
}
|
||||
else if (c == 'p')
|
||||
{
|
||||
offset += sizeof(var->p);
|
||||
ret += lib_sprintf(s, fmtstr, var->p);
|
||||
infmt = false;
|
||||
}
|
||||
}
|
||||
else if (c == 's')
|
||||
|
||||
if (*(p - 2) != '\n')
|
||||
{
|
||||
FAR const char *value = data + offset;
|
||||
offset += strlen(value) + 1;
|
||||
ret += lib_sprintf(s, fmtstr, value);
|
||||
infmt = false;
|
||||
}
|
||||
else if (c == 'p')
|
||||
{
|
||||
offset += sizeof(var->p);
|
||||
ret += lib_sprintf(s, fmtstr, var->p);
|
||||
infmt = false;
|
||||
lib_stream_putc(s, '\n');
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
|
||||
if (*(p - 2) != '\n')
|
||||
else
|
||||
{
|
||||
lib_stream_putc(s, '\n');
|
||||
ret++;
|
||||
size_t count = NOTE_PRINTF_GET_COUNT(note->npt_type);
|
||||
size_t i;
|
||||
|
||||
len = strlen(note->npt_fmt);
|
||||
if (note->npt_fmt[len - 1] == '\n')
|
||||
{
|
||||
len--;
|
||||
}
|
||||
|
||||
ret += lib_sprintf(s, "%p", note->npt_fmt);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
int type = NOTE_PRINTF_GET_TYPE(note->npt_type, i);
|
||||
var = (FAR void *)(note->npt_data + offset);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NOTE_PRINTF_UINT32:
|
||||
{
|
||||
offset += sizeof(var->i);
|
||||
ret += lib_sprintf(s, " %u", var->i);
|
||||
}
|
||||
break;
|
||||
case NOTE_PRINTF_UINT64:
|
||||
{
|
||||
offset += sizeof(var->ll);
|
||||
ret += lib_sprintf(s, " %llu", var->ll);
|
||||
}
|
||||
break;
|
||||
case NOTE_PRINTF_STRING:
|
||||
{
|
||||
const char *str = note->npt_data + offset;
|
||||
offset += strlen(str) + 1;
|
||||
ret += lib_sprintf(s, " %s", str);
|
||||
}
|
||||
break;
|
||||
case NOTE_PRINTF_DOUBLE:
|
||||
{
|
||||
offset += sizeof(var->d);
|
||||
ret += lib_sprintf(s, " %f", var->d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lib_stream_putc(s, '\n');
|
||||
ret++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -172,7 +172,7 @@
|
||||
* unnecessary "weak" functions can be excluded from the link.
|
||||
*/
|
||||
|
||||
#undef CONFIG_HAVE_WEAKFUNCTIONS
|
||||
# undef CONFIG_HAVE_WEAKFUNCTIONS
|
||||
|
||||
# if !defined(__CYGWIN__) && !defined(CONFIG_ARCH_GNU_NO_WEAKFUNCTIONS)
|
||||
# define CONFIG_HAVE_WEAKFUNCTIONS 1
|
||||
@ -344,6 +344,7 @@
|
||||
# define syslog_like(a, b) __attribute__((__format__(__syslog__, a, b)))
|
||||
# define scanf_like(a, b) __attribute__((__format__(__scanf__, a, b)))
|
||||
# define strftime_like(a) __attribute__((__format__(__strftime__, a, 0)))
|
||||
# define object_size(o, t) __builtin_object_size(o, t)
|
||||
|
||||
/* GCC does not use storage classes to qualify addressing */
|
||||
|
||||
@ -612,6 +613,7 @@
|
||||
# define syslog_like(a, b)
|
||||
# define scanf_like(a, b)
|
||||
# define strftime_like(a)
|
||||
# define object_size(o, t) ((size_t)-1)
|
||||
|
||||
/* The reentrant attribute informs SDCC that the function
|
||||
* must be reentrant. In this case, SDCC will store input
|
||||
@ -756,6 +758,7 @@
|
||||
# define syslog_like(a, b)
|
||||
# define scanf_like(a, b)
|
||||
# define strftime_like(a)
|
||||
# define object_size(o, t) ((size_t)-1)
|
||||
|
||||
/* REVISIT: */
|
||||
|
||||
@ -871,6 +874,7 @@
|
||||
# define syslog_like(a, b)
|
||||
# define scanf_like(a, b)
|
||||
# define strftime_like(a)
|
||||
# define object_size(o, t) ((size_t)-1)
|
||||
|
||||
# define FAR
|
||||
# define NEAR
|
||||
@ -1049,6 +1053,7 @@
|
||||
# define syslog_like(a, b)
|
||||
# define scanf_like(a, b)
|
||||
# define strftime_like(a)
|
||||
# define object_size(o, t) ((size_t)-1)
|
||||
|
||||
# define FAR
|
||||
# define NEAR
|
||||
@ -1118,6 +1123,7 @@
|
||||
# define syslog_like(a, b)
|
||||
# define scanf_like(a, b)
|
||||
# define strftime_like(a)
|
||||
# define object_size(o, t) ((size_t)-1)
|
||||
|
||||
# define FAR
|
||||
# define NEAR
|
||||
|
140
include/nuttx/macro.h
Normal file
140
include/nuttx/macro.h
Normal file
@ -0,0 +1,140 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/macro.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_MACRO_H
|
||||
#define __INCLUDE_NUTTX_MACRO_H
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define GET_ARG_VALUE(_00, _01, _02, _03, _04, _05, _06, _07, \
|
||||
_08, _09, _10, _11, _12, _13, _14, _15, \
|
||||
_16, _17, _18, _19, _20, _21, _22, _23, \
|
||||
_24, _25, _26, _27, _28, _29, _30, _31, \
|
||||
_32, name, ...) name
|
||||
|
||||
/* Get the number of arguments (up to 32) */
|
||||
|
||||
#define GET_ARG_COUNT(...) \
|
||||
GET_ARG_VALUE(_0, ##__VA_ARGS__, 32, 31, 30, \
|
||||
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
|
||||
19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
|
||||
9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||
|
||||
/* Reverse the arguments */
|
||||
|
||||
#define EXPAND(x) x
|
||||
|
||||
#define REVERSE_00()
|
||||
#define REVERSE_01(a) a
|
||||
#define REVERSE_02(a,b) b,a
|
||||
#define REVERSE_03(a,...) EXPAND(REVERSE_02(__VA_ARGS__)),a
|
||||
#define REVERSE_04(a,...) EXPAND(REVERSE_03(__VA_ARGS__)),a
|
||||
#define REVERSE_05(a,...) EXPAND(REVERSE_04(__VA_ARGS__)),a
|
||||
#define REVERSE_06(a,...) EXPAND(REVERSE_05(__VA_ARGS__)),a
|
||||
#define REVERSE_07(a,...) EXPAND(REVERSE_06(__VA_ARGS__)),a
|
||||
#define REVERSE_08(a,...) EXPAND(REVERSE_07(__VA_ARGS__)),a
|
||||
#define REVERSE_09(a,...) EXPAND(REVERSE_08(__VA_ARGS__)),a
|
||||
#define REVERSE_10(a,...) EXPAND(REVERSE_09(__VA_ARGS__)),a
|
||||
#define REVERSE_11(a,...) EXPAND(REVERSE_10(__VA_ARGS__)),a
|
||||
#define REVERSE_12(a,...) EXPAND(REVERSE_11(__VA_ARGS__)),a
|
||||
#define REVERSE_13(a,...) EXPAND(REVERSE_12(__VA_ARGS__)),a
|
||||
#define REVERSE_14(a,...) EXPAND(REVERSE_13(__VA_ARGS__)),a
|
||||
#define REVERSE_15(a,...) EXPAND(REVERSE_14(__VA_ARGS__)),a
|
||||
#define REVERSE_16(a,...) EXPAND(REVERSE_15(__VA_ARGS__)),a
|
||||
#define REVERSE_17(a,...) EXPAND(REVERSE_16(__VA_ARGS__)),a
|
||||
#define REVERSE_18(a,...) EXPAND(REVERSE_17(__VA_ARGS__)),a
|
||||
#define REVERSE_19(a,...) EXPAND(REVERSE_18(__VA_ARGS__)),a
|
||||
#define REVERSE_20(a,...) EXPAND(REVERSE_19(__VA_ARGS__)),a
|
||||
#define REVERSE_21(a,...) EXPAND(REVERSE_20(__VA_ARGS__)),a
|
||||
#define REVERSE_22(a,...) EXPAND(REVERSE_21(__VA_ARGS__)),a
|
||||
#define REVERSE_23(a,...) EXPAND(REVERSE_22(__VA_ARGS__)),a
|
||||
#define REVERSE_24(a,...) EXPAND(REVERSE_23(__VA_ARGS__)),a
|
||||
#define REVERSE_25(a,...) EXPAND(REVERSE_24(__VA_ARGS__)),a
|
||||
#define REVERSE_26(a,...) EXPAND(REVERSE_25(__VA_ARGS__)),a
|
||||
#define REVERSE_27(a,...) EXPAND(REVERSE_26(__VA_ARGS__)),a
|
||||
#define REVERSE_28(a,...) EXPAND(REVERSE_27(__VA_ARGS__)),a
|
||||
#define REVERSE_29(a,...) EXPAND(REVERSE_28(__VA_ARGS__)),a
|
||||
#define REVERSE_30(a,...) EXPAND(REVERSE_29(__VA_ARGS__)),a
|
||||
#define REVERSE_31(a,...) EXPAND(REVERSE_30(__VA_ARGS__)),a
|
||||
#define REVERSE_32(a,...) EXPAND(REVERSE_31(__VA_ARGS__)),a
|
||||
|
||||
#define REVERSE_ARG_(...) \
|
||||
GET_ARG_VALUE(0, ##__VA_ARGS__, \
|
||||
REVERSE_32, REVERSE_31, REVERSE_30, REVERSE_29, REVERSE_28, REVERSE_27, \
|
||||
REVERSE_26, REVERSE_25, REVERSE_24, REVERSE_23, REVERSE_22, REVERSE_21, \
|
||||
REVERSE_20, REVERSE_19, REVERSE_18, REVERSE_17, REVERSE_16, REVERSE_15, \
|
||||
REVERSE_14, REVERSE_13, REVERSE_12, REVERSE_11, REVERSE_10, REVERSE_09, \
|
||||
REVERSE_08, REVERSE_07, REVERSE_06, REVERSE_05, REVERSE_04, REVERSE_03, \
|
||||
REVERSE_02, REVERSE_01, REVERSE_00)(__VA_ARGS__)
|
||||
|
||||
#define REVERSE_ARG(...) REVERSE_ARG_(##__VA_ARGS__)
|
||||
|
||||
/* Apply the macro to each argument */
|
||||
|
||||
#define FOREACH_00(action, count, ...) 0
|
||||
#define FOREACH_01(action, count, arg, ...) action(arg, count - 1 )
|
||||
#define FOREACH_02(action, count, arg, ...) action(arg, count - 2 ) FOREACH_01(action, count, __VA_ARGS__)
|
||||
#define FOREACH_03(action, count, arg, ...) action(arg, count - 3 ) FOREACH_02(action, count, __VA_ARGS__)
|
||||
#define FOREACH_04(action, count, arg, ...) action(arg, count - 4 ) FOREACH_03(action, count, __VA_ARGS__)
|
||||
#define FOREACH_05(action, count, arg, ...) action(arg, count - 5 ) FOREACH_04(action, count, __VA_ARGS__)
|
||||
#define FOREACH_06(action, count, arg, ...) action(arg, count - 6 ) FOREACH_05(action, count, __VA_ARGS__)
|
||||
#define FOREACH_07(action, count, arg, ...) action(arg, count - 7 ) FOREACH_06(action, count, __VA_ARGS__)
|
||||
#define FOREACH_08(action, count, arg, ...) action(arg, count - 8 ) FOREACH_07(action, count, __VA_ARGS__)
|
||||
#define FOREACH_09(action, count, arg, ...) action(arg, count - 9 ) FOREACH_08(action, count, __VA_ARGS__)
|
||||
#define FOREACH_10(action, count, arg, ...) action(arg, count - 10) FOREACH_09(action, count, __VA_ARGS__)
|
||||
#define FOREACH_11(action, count, arg, ...) action(arg, count - 11) FOREACH_10(action, count, __VA_ARGS__)
|
||||
#define FOREACH_12(action, count, arg, ...) action(arg, count - 12) FOREACH_11(action, count, __VA_ARGS__)
|
||||
#define FOREACH_13(action, count, arg, ...) action(arg, count - 13) FOREACH_12(action, count, __VA_ARGS__)
|
||||
#define FOREACH_14(action, count, arg, ...) action(arg, count - 14) FOREACH_13(action, count, __VA_ARGS__)
|
||||
#define FOREACH_15(action, count, arg, ...) action(arg, count - 15) FOREACH_14(action, count, __VA_ARGS__)
|
||||
#define FOREACH_16(action, count, arg, ...) action(arg, count - 16) FOREACH_15(action, count, __VA_ARGS__)
|
||||
#define FOREACH_17(action, count, arg, ...) action(arg, count - 17) FOREACH_16(action, count, __VA_ARGS__)
|
||||
#define FOREACH_18(action, count, arg, ...) action(arg, count - 18) FOREACH_17(action, count, __VA_ARGS__)
|
||||
#define FOREACH_19(action, count, arg, ...) action(arg, count - 19) FOREACH_18(action, count, __VA_ARGS__)
|
||||
#define FOREACH_20(action, count, arg, ...) action(arg, count - 20) FOREACH_19(action, count, __VA_ARGS__)
|
||||
#define FOREACH_21(action, count, arg, ...) action(arg, count - 21) FOREACH_20(action, count, __VA_ARGS__)
|
||||
#define FOREACH_22(action, count, arg, ...) action(arg, count - 22) FOREACH_21(action, count, __VA_ARGS__)
|
||||
#define FOREACH_23(action, count, arg, ...) action(arg, count - 23) FOREACH_22(action, count, __VA_ARGS__)
|
||||
#define FOREACH_24(action, count, arg, ...) action(arg, count - 24) FOREACH_23(action, count, __VA_ARGS__)
|
||||
#define FOREACH_25(action, count, arg, ...) action(arg, count - 25) FOREACH_24(action, count, __VA_ARGS__)
|
||||
#define FOREACH_26(action, count, arg, ...) action(arg, count - 26) FOREACH_25(action, count, __VA_ARGS__)
|
||||
#define FOREACH_27(action, count, arg, ...) action(arg, count - 27) FOREACH_26(action, count, __VA_ARGS__)
|
||||
#define FOREACH_28(action, count, arg, ...) action(arg, count - 28) FOREACH_27(action, count, __VA_ARGS__)
|
||||
#define FOREACH_29(action, count, arg, ...) action(arg, count - 29) FOREACH_28(action, count, __VA_ARGS__)
|
||||
#define FOREACH_30(action, count, arg, ...) action(arg, count - 30) FOREACH_29(action, count, __VA_ARGS__)
|
||||
#define FOREACH_31(action, count, arg, ...) action(arg, count - 31) FOREACH_30(action, count, __VA_ARGS__)
|
||||
#define FOREACH_32(action, count, arg, ...) action(arg, count - 32) FOREACH_31(action, count, __VA_ARGS__)
|
||||
|
||||
#define FOREACH_ARG_(action, count, ...) \
|
||||
GET_ARG_VALUE(0, ##__VA_ARGS__, \
|
||||
FOREACH_32, FOREACH_31, FOREACH_30, FOREACH_29, FOREACH_28, FOREACH_27, \
|
||||
FOREACH_26, FOREACH_25, FOREACH_24, FOREACH_23, FOREACH_22, FOREACH_21, \
|
||||
FOREACH_20, FOREACH_19, FOREACH_18, FOREACH_17, FOREACH_16, FOREACH_15, \
|
||||
FOREACH_14, FOREACH_13, FOREACH_12, FOREACH_11, FOREACH_10, FOREACH_09, \
|
||||
FOREACH_08, FOREACH_07, FOREACH_06, FOREACH_05, FOREACH_04, FOREACH_03, \
|
||||
FOREACH_02, FOREACH_01, FOREACH_00)(action, count, ##__VA_ARGS__)
|
||||
|
||||
#define FOREACH_ARG(action, ...) \
|
||||
FOREACH_ARG_(action, GET_ARG_COUNT(__VA_ARGS__), ##__VA_ARGS__)
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_MACRO_H */
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <nuttx/macro.h>
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
@ -125,15 +126,83 @@
|
||||
# define NOTE_FILTER_TAGMASK_ZERO(s)
|
||||
#endif
|
||||
|
||||
/* Printf argument type */
|
||||
|
||||
#define NOTE_PRINTF_UINT32 0
|
||||
#define NOTE_PRINTF_UINT64 1
|
||||
#define NOTE_PRINTF_DOUBLE 2
|
||||
#define NOTE_PRINTF_STRING 3
|
||||
|
||||
/* Get/set printf tag. each parameter occupies 2 bits. The highest
|
||||
* four bits are used to represent the number of parameters, So up to
|
||||
* 14 variable arguments can be passed.
|
||||
*/
|
||||
|
||||
#define NOTE_PRINTF_GET_TYPE(tag, index) (((tag) >> (index) * 2) & 0x03)
|
||||
#define NOTE_PRINTF_GET_COUNT(tag) (((tag) >> 28) & 0x0f)
|
||||
|
||||
/* Check if a variable is 32-bit or 64-bit */
|
||||
|
||||
#define NOTE_PRINTF_INT_TYPE(arg) (sizeof((arg) + 0) <= sizeof(uint32_t) ? \
|
||||
NOTE_PRINTF_UINT32 : NOTE_PRINTF_UINT64)
|
||||
|
||||
/* Use object_size to mark strings of known size */
|
||||
|
||||
#define NOTE_PRINTF_OBJECT_SIZE(arg) object_size((FAR void *)(uintptr_t)(arg), 2)
|
||||
|
||||
/* Use _Generic to determine the type of the parameter */
|
||||
|
||||
#define NOTE_PRINTF_ARG_TYPE(__arg__) \
|
||||
_Generic((__arg__) + 0, \
|
||||
float : NOTE_PRINTF_DOUBLE, \
|
||||
double: NOTE_PRINTF_DOUBLE, \
|
||||
char *: ({NOTE_PRINTF_OBJECT_SIZE(__arg__) > 0 ? \
|
||||
NOTE_PRINTF_STRING : \
|
||||
NOTE_PRINTF_INT_TYPE(__arg__);}), \
|
||||
const char *: ({NOTE_PRINTF_OBJECT_SIZE(__arg__) > 0 ? \
|
||||
NOTE_PRINTF_STRING : \
|
||||
NOTE_PRINTF_INT_TYPE(__arg__);}), \
|
||||
default: NOTE_PRINTF_INT_TYPE(__arg__))
|
||||
|
||||
/* Set the type of each parameter */
|
||||
|
||||
#define NOTE_PRINTF_TYPE(arg, index) + ((NOTE_PRINTF_ARG_TYPE(arg) << (index) * 2))
|
||||
#define NOTE_PRINTF_TYPES(...) FOREACH_ARG(NOTE_PRINTF_TYPE, ##__VA_ARGS__)
|
||||
|
||||
/* Using macro expansion to calculate the expression of tag, tag will
|
||||
* be a constant at compile time, which will reduce the number of
|
||||
* size in the code.
|
||||
*/
|
||||
|
||||
#define NOTE_PRINTF_TAG(...) \
|
||||
((GET_ARG_COUNT(__VA_ARGS__) << 28) + NOTE_PRINTF_TYPES(__VA_ARGS__))
|
||||
|
||||
#define SCHED_NOTE_IP \
|
||||
({ __label__ __here; __here: (unsigned long)&&__here; })
|
||||
|
||||
#define sched_note_event(tag, event, buf, len) \
|
||||
sched_note_event_ip(tag, SCHED_NOTE_IP, event, buf, len)
|
||||
#define sched_note_vprintf(tag, fmt, va) \
|
||||
sched_note_vprintf_ip(tag, SCHED_NOTE_IP, fmt, va)
|
||||
#define sched_note_printf(tag, fmt, ...) \
|
||||
sched_note_printf_ip(tag, SCHED_NOTE_IP, fmt, ##__VA_ARGS__)
|
||||
sched_note_vprintf_ip(tag, SCHED_NOTE_IP, fmt, 0, va)
|
||||
|
||||
#ifdef CONFIG_DRIVERS_NOTE_STRIP_FORMAT
|
||||
# define sched_note_printf(tag, fmt, ...) \
|
||||
do \
|
||||
{ \
|
||||
static const locate_data(".printf_format") \
|
||||
char __fmt__[] = fmt; \
|
||||
uint32_t __type__ = NOTE_PRINTF_TAG(__VA_ARGS__); \
|
||||
static_assert(GET_ARG_COUNT(__VA_ARGS__) <= 14, \
|
||||
"The number of sched_note_nprintf " \
|
||||
"parameters needs to be less than 14"); \
|
||||
sched_note_printf_ip(tag, SCHED_NOTE_IP, __fmt__, \
|
||||
__type__, ##__VA_ARGS__); \
|
||||
} \
|
||||
while (0)
|
||||
#else
|
||||
# define sched_note_printf(tag, fmt, ...) \
|
||||
sched_note_printf_ip(tag, SCHED_NOTE_IP, fmt, 0, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define sched_note_begin(tag) \
|
||||
sched_note_event(tag, NOTE_DUMP_BEGIN, NULL, 0)
|
||||
@ -410,6 +479,7 @@ struct note_printf_s
|
||||
struct note_common_s npt_cmn; /* Common note parameters */
|
||||
uintptr_t npt_ip; /* Instruction pointer called from */
|
||||
FAR const char *npt_fmt; /* Printf format string */
|
||||
uint32_t npt_type; /* Printf parameter type */
|
||||
char npt_data[1]; /* Print arguments */
|
||||
};
|
||||
|
||||
@ -585,13 +655,13 @@ void sched_note_heap(uint8_t event, FAR void *heap, FAR void *mem,
|
||||
void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event,
|
||||
FAR const void *buf, size_t len);
|
||||
void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt,
|
||||
va_list va) printf_like(3, 0);
|
||||
void sched_note_printf_ip(uint32_t tag, uintptr_t ip,
|
||||
FAR const char *fmt, ...) printf_like(3, 4);
|
||||
uint32_t type, va_list va) printf_like(3, 0);
|
||||
void sched_note_printf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt,
|
||||
uint32_t type, ...) printf_like(3, 5);
|
||||
#else
|
||||
# define sched_note_event_ip(t,ip,e,b,l)
|
||||
# define sched_note_vprintf_ip(t,ip,f,v)
|
||||
# define sched_note_printf_ip(t,ip,f,...)
|
||||
# define sched_note_vprintf_ip(t,ip,f,p,v)
|
||||
# define sched_note_printf_ip(t,ip,f,p,...)
|
||||
#endif /* CONFIG_SCHED_INSTRUMENTATION_DUMP */
|
||||
|
||||
#if defined(__KERNEL__) || defined(CONFIG_BUILD_FLAT)
|
||||
|
@ -1307,8 +1307,8 @@ config SCHED_INSTRUMENTATION_DUMP
|
||||
Use note dump for instrumentation.
|
||||
|
||||
void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event, FAR const void *buf, size_t len);
|
||||
void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt, va_list va) printf_like(3, 0);
|
||||
void sched_note_printf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt, ...) printf_like(3, 4);
|
||||
void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt, uint32_t type, va_list va) printf_like(3, 0);
|
||||
void sched_note_printf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt, uint32_t type, ...) printf_like(3, 5);
|
||||
|
||||
config SCHED_INSTRUMENTATION_FUNCTION
|
||||
bool "Enable function auto-tracing"
|
||||
|
Loading…
Reference in New Issue
Block a user