forked from OSchip/llvm-project
Update __dfsw_s{,n}printf custom functions for new calling convention.
Differential Revision: http://reviews.llvm.org/D6029 llvm-svn: 220907
This commit is contained in:
parent
dd3486ece1
commit
b190e1b74b
|
@ -908,7 +908,8 @@ static int format_chunk(char *str, size_t off, bool has_size, size_t size,
|
|||
// out which bytes of the output string depends on which argument and thus to
|
||||
// propagate labels more precisely.
|
||||
static int format_buffer(char *str, bool has_size, size_t size,
|
||||
const char *format, va_list ap) {
|
||||
const char *format, dfsan_label *va_labels,
|
||||
dfsan_label *ret_label, va_list ap) {
|
||||
InternalMmapVector<Chunk> chunks(8);
|
||||
size_t off = 0;
|
||||
|
||||
|
@ -1055,16 +1056,8 @@ static int format_buffer(char *str, bool has_size, size_t size,
|
|||
off += status;
|
||||
}
|
||||
|
||||
// Consume the labels of the output buffer, (optional) size, and format
|
||||
// string.
|
||||
//
|
||||
// TODO(martignlo): Decide how to combine labels (e.g., whether to ignore or
|
||||
// not the label of the format string).
|
||||
va_arg(ap, dfsan_label_va);
|
||||
if (has_size) {
|
||||
va_arg(ap, dfsan_label_va);
|
||||
}
|
||||
va_arg(ap, dfsan_label_va);
|
||||
|
||||
// Label each output chunk according to the label supplied as argument to the
|
||||
// function. We need to go through all the chunks and arguments even if the
|
||||
|
@ -1077,17 +1070,17 @@ static int format_buffer(char *str, bool has_size, size_t size,
|
|||
dfsan_set_label(0, (void*) chunk.ptr, chunk.size);
|
||||
break;
|
||||
case Chunk::IGNORED:
|
||||
va_arg(ap, dfsan_label_va);
|
||||
va_labels++;
|
||||
dfsan_set_label(0, (void*) chunk.ptr, chunk.size);
|
||||
break;
|
||||
case Chunk::NUMERIC: {
|
||||
dfsan_label label = va_arg(ap, dfsan_label_va);
|
||||
dfsan_label label = *va_labels++;
|
||||
dfsan_set_label(label, (void*) chunk.ptr, chunk.size);
|
||||
break;
|
||||
}
|
||||
case Chunk::STRING: {
|
||||
// Consume the label of the pointer to the string
|
||||
va_arg(ap, dfsan_label_va);
|
||||
va_labels++;
|
||||
internal_memcpy(shadow_for((void *) chunk.ptr),
|
||||
shadow_for((void *) chunk.arg),
|
||||
sizeof(dfsan_label) * (strlen(chunk.arg)));
|
||||
|
@ -1096,27 +1089,31 @@ static int format_buffer(char *str, bool has_size, size_t size,
|
|||
}
|
||||
}
|
||||
|
||||
dfsan_label *ret_label_ptr = va_arg(ap, dfsan_label *);
|
||||
*ret_label_ptr = 0;
|
||||
*ret_label = 0;
|
||||
|
||||
// Number of bytes written in total.
|
||||
return off;
|
||||
}
|
||||
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
int __dfsw_sprintf(char *str, const char *format, ...) {
|
||||
int __dfsw_sprintf(char *str, const char *format, dfsan_label str_label,
|
||||
dfsan_label format_label, dfsan_label *va_labels,
|
||||
dfsan_label *ret_label, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
int ret = format_buffer(str, false, 0, format, ap);
|
||||
va_start(ap, ret_label);
|
||||
int ret = format_buffer(str, false, 0, format, va_labels, ret_label, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
int __dfsw_snprintf(char *str, size_t size, const char *format, ...) {
|
||||
int __dfsw_snprintf(char *str, size_t size, const char *format,
|
||||
dfsan_label str_label, dfsan_label size_label,
|
||||
dfsan_label format_label, dfsan_label *va_labels,
|
||||
dfsan_label *ret_label, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
int ret = format_buffer(str, true, size, format, ap);
|
||||
va_start(ap, ret_label);
|
||||
int ret = format_buffer(str, true, size, format, va_labels, ret_label, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -813,6 +813,11 @@ void test_sprintf() {
|
|||
assert(strcmp(buf, "Hello world!") == 0);
|
||||
ASSERT_READ_LABEL(buf, sizeof(buf), 0);
|
||||
|
||||
// Test for extra arguments.
|
||||
assert(sprintf(buf, "Hello world!", 42, "hello") == 12);
|
||||
assert(strcmp(buf, "Hello world!") == 0);
|
||||
ASSERT_READ_LABEL(buf, sizeof(buf), 0);
|
||||
|
||||
// Test formatting & label propagation (multiple conversion specifiers): %s,
|
||||
// %d, %n, %f, and %%.
|
||||
const char* s = "world";
|
||||
|
|
Loading…
Reference in New Issue