Fixes to stream formatting of doubles, they weren't being streamed before. Implemented the chk versions of printf and such, so that they all route through the logging interface as well. Implemented the concretization APIs.

This commit is contained in:
Peter Goodman
2017-11-01 17:56:54 -04:00
parent d2bc82fc35
commit 4f914e4eee
7 changed files with 216 additions and 76 deletions
+9 -6
View File
@@ -186,14 +186,17 @@ int DeepState_IsSymbolicUInt(uint32_t x) {
}
/* Defined in Stream.c */
extern void _DeepState_StreamInt(enum DeepState_LogLevel level, const char *format,
const char *unpack, uint64_t *val);
extern void _DeepState_StreamInt(enum DeepState_LogLevel level,
const char *format,
const char *unpack, uint64_t *val);
extern void _DeepState_StreamFloat(enum DeepState_LogLevel level, const char *format,
const char *unpack, double *val);
extern void _DeepState_StreamFloat(enum DeepState_LogLevel level,
const char *format,
const char *unpack, double *val);
extern void _DeepState_StreamString(enum DeepState_LogLevel level, const char *format,
const char *str);
extern void _DeepState_StreamString(enum DeepState_LogLevel level,
const char *format,
const char *str);
/* A DeepState-specific symbol that is needed for hooking. */
struct DeepState_IndexEntry {
+86 -24
View File
@@ -14,12 +14,31 @@
* limitations under the License.
*/
/* Helps to avoid conflicting declaration types of `__printf_chk`. */
#define printf printf_foo
#define vprintf vprintf_foo
#define fprintf fprintf_foo
#define vfprintf vfprintf_foo
#define __printf_chk __printf_chk_foo
#define __vprintf_chk __vprintf_chk_foo
#define __fprintf_chk __fprintf_chk_foo
#define __vfprintf_chk __vfprintf_chk_foo
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "deepstate/DeepState.h"
#undef printf
#undef vprintf
#undef fprintf
#undef vfprintf
#undef __printf_chk
#undef __vprintf_chk
#undef __fprintf_chk
#undef __vfprintf_chk
DEEPSTATE_BEGIN_EXTERN_C
/* Returns a printable string version of the log level. */
@@ -47,9 +66,10 @@ enum {
char DeepState_LogBuf[DeepState_LogBufSize + 1] = {};
/* Log a C string. */
DEEPSTATE_NOINLINE
void DeepState_Log(enum DeepState_LogLevel level, const char *str) {
memset(DeepState_LogBuf, 0, DeepState_LogBufSize);
snprintf(DeepState_LogBuf, DeepState_LogBufSize, "%s: %s",
snprintf(DeepState_LogBuf, DeepState_LogBufSize, "%s: %s\n",
DeepState_LogLevelStr(level), str);
fputs(DeepState_LogBuf, stderr);
@@ -61,48 +81,90 @@ void DeepState_Log(enum DeepState_LogLevel level, const char *str) {
}
/* Log some formatted output. */
void DeepState_LogFormat(enum DeepState_LogLevel level, const char *format, ...) {
DEEPSTATE_NOINLINE
void DeepState_LogVFormat(enum DeepState_LogLevel level,
const char *format, va_list args) {
DeepState_LogStream(level);
va_list args;
va_start(args, format);
DeepState_StreamVFormat(level, format, args);
va_end(args);
DeepState_LogStream(level);
}
/* Log some formatted output. */
void DeepState_LogVFormat(enum DeepState_LogLevel level,
const char *format, va_list args) {
DeepState_LogStream(level);
DeepState_StreamVFormat(level, format, args);
DeepState_LogStream(level);
DEEPSTATE_NOINLINE
void DeepState_LogFormat(enum DeepState_LogLevel level,
const char *format, ...) {
va_list args;
va_start(args, format);
DeepState_LogVFormat(level, format, args);
va_end(args);
}
/* Override libc! */
DEEPSTATE_NOINLINE
int printf(const char *format, ...) {
DeepState_LogStream(DeepState_LogInfo);
va_list args;
va_start(args, format);
DeepState_StreamVFormat(DeepState_LogInfo, format, args);
DeepState_LogVFormat(DeepState_LogInfo, format, args);
va_end(args);
DeepState_LogStream(DeepState_LogInfo);
return 0;
}
int fprintf(FILE *file, const char *format, ...) {
enum DeepState_LogLevel level = DeepState_LogInfo;
if (stderr == file) {
level = DeepState_LogDebug;
} else if (stdout != file) {
return 0; /* TODO(pag): This is probably evil. */
}
DeepState_LogStream(level);
DEEPSTATE_NOINLINE
int __printf_chk(int flag, const char *format, ...) {
va_list args;
va_start(args, format);
DeepState_StreamVFormat(level, format, args);
DeepState_LogVFormat(DeepState_LogInfo, format, args);
va_end(args);
DeepState_LogStream(level);
return 0;
}
DEEPSTATE_NOINLINE
int vprintf(const char *format, va_list args) {
DeepState_LogVFormat(DeepState_LogInfo, format, args);
return 0;
}
DEEPSTATE_NOINLINE
int __vprintf_chk(int flag, const char *format, va_list args) {
DeepState_LogVFormat(DeepState_LogInfo, format, args);
return 0;
}
DEEPSTATE_NOINLINE
int vfprintf(FILE *file, const char *format, va_list args) {
if (stderr == file) {
DeepState_LogVFormat(DeepState_LogDebug, format, args);
} else if (stdout == file) {
DeepState_LogVFormat(DeepState_LogInfo, format, args);
} else {
DeepState_LogStream(DeepState_LogWarning);
DeepState_Log(DeepState_LogWarning,
"Ignorning vfprintf with non-stdout/stderr stream.");
}
return 0;
}
DEEPSTATE_NOINLINE
int fprintf(FILE *file, const char *format, ...) {
va_list args;
va_start(args, format);
vfprintf(file, format, args);
va_end(args);
return 0;
}
DEEPSTATE_NOINLINE
int __fprintf_chk(int flag, FILE *file, const char *format, ...) {
va_list args;
va_start(args, format);
vfprintf(file, format, args);
va_end(args);
return 0;
}
DEEPSTATE_NOINLINE
int __vfprintf_chk(int flag, FILE *file, const char *format, va_list args) {
vfprintf(file, format, args);
return 0;
}
+11 -5
View File
@@ -255,8 +255,7 @@ void DeepState_StreamDouble(enum DeepState_LogLevel level, double val) {
void DeepState_LogStream(enum DeepState_LogLevel level) {
struct DeepState_Stream *stream = &(DeepState_Streams[level]);
if (stream->size) {
stream->message[stream->size] = '\n';
stream->message[stream->size + 1] = '\0';
stream->message[stream->size] = '\0';
stream->message[DeepState_StreamSize] = '\0';
DeepState_Log(level, stream->message);
memset(stream->message, 0, DeepState_StreamSize);
@@ -501,6 +500,8 @@ get_length_char:
stream->value.as_fp64 = va_arg(args, double);
}
DeepState_StreamUnpack(stream, 'd');
_DeepState_StreamFloat(level, format_buf, stream->unpack,
&(stream->value.as_fp64));
break;
case 's':
@@ -527,14 +528,19 @@ void DeepState_StreamVFormat(enum DeepState_LogLevel level, const char *format_,
va_list args) {
char *begin = NULL;
char *end = NULL;
char *format = DeepState_Format;
char *format = &(DeepState_Format[0]);
int i = 0;
char ch = '\0';
char next_ch = '\0';
size_t len = strlen(format_);
strncpy(format, format_, DeepState_StreamSize);
format[DeepState_StreamSize] = '\0';
if (len >= DeepState_StreamSize) {
DeepState_Abandon("Format string is too long.");
}
/* Concretize the string format. */
memcpy(format, format_, len);
format[len] = '\0';
DeepState_ConcretizeCStr(format);
for (i = 0; '\0' != (ch = format[i]); ) {