Skip to content

Commit

Permalink
tell gcc to check printf format strings
Browse files Browse the repository at this point in the history
add %ld %lld %u %lu %llu %lx %llx to kernel and user printf
  • Loading branch information
Robert Morris committed Dec 31, 2023
1 parent 2b55250 commit dd2574b
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 56 deletions.
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,14 @@ OBJDUMP = $(TOOLPREFIX)objdump
CFLAGS = -Wall -Werror -O -fno-omit-frame-pointer -ggdb -gdwarf-2
CFLAGS += -MD
CFLAGS += -mcmodel=medany
CFLAGS += -ffreestanding -fno-common -nostdlib -mno-relax
# CFLAGS += -ffreestanding -fno-common -nostdlib -mno-relax
CFLAGS += -fno-common -nostdlib -mno-relax
CFLAGS += -fno-builtin-strncpy -fno-builtin-strncmp -fno-builtin-strlen -fno-builtin-memset
CFLAGS += -fno-builtin-memmove -fno-builtin-memcmp -fno-builtin-log -fno-builtin-bzero
CFLAGS += -fno-builtin-strchr -fno-builtin-exit -fno-builtin-malloc -fno-builtin-putc
CFLAGS += -fno-builtin-free
CFLAGS += -fno-builtin-memcpy -Wno-main
CFLAGS += -fno-builtin-printf -fno-builtin-fprintf -fno-builtin-vprintf
CFLAGS += -I.
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)

Expand Down
2 changes: 1 addition & 1 deletion kernel/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ int piperead(struct pipe*, uint64, int);
int pipewrite(struct pipe*, uint64, int);

// printf.c
void printf(char*, ...);
int printf(char*, ...) __attribute__ ((format (printf, 1, 2)));
void panic(char*) __attribute__((noreturn));
void printfinit(void);

Expand Down
75 changes: 59 additions & 16 deletions kernel/printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ static struct {
static char digits[] = "0123456789abcdef";

static void
printint(int xx, int base, int sign)
printint(long long xx, int base, int sign)
{
char buf[16];
int i;
uint x;
unsigned long long x;

if(sign && (sign = xx < 0))
if(sign && (sign = (xx < 0)))
x = -xx;
else
x = xx;
Expand All @@ -59,30 +59,71 @@ printptr(uint64 x)
consputc(digits[x >> (sizeof(uint64) * 8 - 4)]);
}

// Print to the console. only understands %d, %x, %p, %s.
void
// Print to the console.
int
printf(char *fmt, ...)
{
va_list ap;
int i, c, locking;
int i, cx, c0, c1, c2, locking;
char *s;

locking = pr.locking;
if(locking)
acquire(&pr.lock);

if (fmt == 0)
panic("null fmt");

va_start(ap, fmt);
for(i = 0; (c = fmt[i] & 0xff) != 0; i++){
if(c != '%'){
consputc(c);
for(i = 0; (cx = fmt[i] & 0xff) != 0; i++){
if(cx != '%'){
consputc(cx);
continue;
}
c = fmt[++i] & 0xff;
if(c == 0)
i++;
c0 = fmt[i+0] & 0xff;
c1 = c2 = 0;
if(c0) c1 = fmt[i+1] & 0xff;
if(c1) c2 = fmt[i+2] & 0xff;
if(c0 == 'd'){
printint(va_arg(ap, int), 10, 1);
} else if(c0 == 'l' && c1 == 'd'){
printint(va_arg(ap, uint64), 10, 1);
i += 1;
} else if(c0 == 'l' && c1 == 'l' && c2 == 'd'){
printint(va_arg(ap, uint64), 10, 1);
i += 2;
} else if(c0 == 'u'){
printint(va_arg(ap, int), 10, 0);
} else if(c0 == 'l' && c1 == 'u'){
printint(va_arg(ap, uint64), 10, 0);
i += 1;
} else if(c0 == 'l' && c1 == 'l' && c2 == 'u'){
printint(va_arg(ap, uint64), 10, 0);
i += 2;
} else if(c0 == 'x'){
printint(va_arg(ap, int), 16, 0);
} else if(c0 == 'l' && c1 == 'x'){
printint(va_arg(ap, uint64), 16, 0);
i += 1;
} else if(c0 == 'l' && c1 == 'l' && c2 == 'x'){
printint(va_arg(ap, uint64), 16, 0);
i += 2;
} else if(c0 == 'p'){
printptr(va_arg(ap, uint64));
} else if(c0 == 's'){
if((s = va_arg(ap, char*)) == 0)
s = "(null)";
for(; *s; s++)
consputc(*s);
} else if(c0 == '%'){
consputc('%');
} else if(c0 == 0){
break;
} else {
// Print unknown % sequence to draw attention.
consputc('%');
consputc(c0);
}

#if 0
switch(c){
case 'd':
printint(va_arg(ap, int), 10, 1);
Expand All @@ -108,20 +149,22 @@ printf(char *fmt, ...)
consputc(c);
break;
}
#endif
}
va_end(ap);

if(locking)
release(&pr.lock);

return 0;
}

void
panic(char *s)
{
pr.locking = 0;
printf("panic: ");
printf(s);
printf("\n");
printf("%s\n", s);
panicked = 1; // freeze uart output from other CPUs
for(;;)
;
Expand Down
8 changes: 4 additions & 4 deletions kernel/trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ usertrap(void)
} else if((which_dev = devintr()) != 0){
// ok
} else {
printf("usertrap(): unexpected scause %p pid=%d\n", r_scause(), p->pid);
printf(" sepc=%p stval=%p\n", r_sepc(), r_stval());
printf("usertrap(): unexpected scause %lx pid=%d\n", r_scause(), p->pid);
printf(" sepc=%lx stval=%lx\n", r_sepc(), r_stval());
setkilled(p);
}

Expand Down Expand Up @@ -145,8 +145,8 @@ kerneltrap()
panic("kerneltrap: interrupts enabled");

if((which_dev = devintr()) == 0){
printf("scause %p\n", scause);
printf("sepc=%p stval=%p\n", r_sepc(), r_stval());
printf("scause %lx\n", scause);
printf("sepc=%lx stval=%lx\n", r_sepc(), r_stval());
panic("kerneltrap");
}

Expand Down
4 changes: 2 additions & 2 deletions user/ls.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ ls(char *path)
switch(st.type){
case T_DEVICE:
case T_FILE:
printf("%s %d %d %l\n", fmtname(path), st.type, st.ino, st.size);
printf("%s %d %d %d\n", fmtname(path), st.type, st.ino, (int) st.size);
break;

case T_DIR:
Expand All @@ -65,7 +65,7 @@ ls(char *path)
printf("ls: cannot stat %s\n", buf);
continue;
}
printf("%s %d %d %d\n", fmtname(buf), st.type, st.ino, st.size);
printf("%s %d %d %d\n", fmtname(buf), st.type, st.ino, (int) st.size);
}
break;
}
Expand Down
52 changes: 48 additions & 4 deletions user/printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,61 @@ void
vprintf(int fd, const char *fmt, va_list ap)
{
char *s;
int c, i, state;
int c0, c1, c2, i, state;

state = 0;
for(i = 0; fmt[i]; i++){
c = fmt[i] & 0xff;
c0 = fmt[i] & 0xff;
if(state == 0){
if(c == '%'){
if(c0 == '%'){
state = '%';
} else {
putc(fd, c);
putc(fd, c0);
}
} else if(state == '%'){
c1 = c2 = 0;
if(c0) c1 = fmt[i+1] & 0xff;
if(c1) c2 = fmt[i+2] & 0xff;
if(c0 == 'd'){
printint(fd, va_arg(ap, int), 10, 1);
} else if(c0 == 'l' && c1 == 'd'){
printint(fd, va_arg(ap, uint64), 10, 1);
i += 1;
} else if(c0 == 'l' && c1 == 'l' && c2 == 'd'){
printint(fd, va_arg(ap, uint64), 10, 1);
i += 2;
} else if(c0 == 'u'){
printint(fd, va_arg(ap, int), 10, 0);
} else if(c0 == 'l' && c1 == 'u'){
printint(fd, va_arg(ap, uint64), 10, 0);
i += 1;
} else if(c0 == 'l' && c1 == 'l' && c2 == 'u'){
printint(fd, va_arg(ap, uint64), 10, 0);
i += 2;
} else if(c0 == 'x'){
printint(fd, va_arg(ap, int), 16, 0);
} else if(c0 == 'l' && c1 == 'x'){
printint(fd, va_arg(ap, uint64), 16, 0);
i += 1;
} else if(c0 == 'l' && c1 == 'l' && c2 == 'x'){
printint(fd, va_arg(ap, uint64), 16, 0);
i += 2;
} else if(c0 == 'p'){
printptr(fd, va_arg(ap, uint64));
} else if(c0 == 's'){
if((s = va_arg(ap, char*)) == 0)
s = "(null)";
for(; *s; s++)
putc(fd, *s);
} else if(c0 == '%'){
putc(fd, '%');
} else {
// Unknown % sequence. Print it to draw attention.
putc(fd, '%');
putc(fd, c0);
}

#if 0
if(c == 'd'){
printint(fd, va_arg(ap, int), 10, 1);
} else if(c == 'l') {
Expand All @@ -89,6 +132,7 @@ vprintf(int fd, const char *fmt, va_list ap)
putc(fd, '%');
putc(fd, c);
}
#endif
state = 0;
}
}
Expand Down
4 changes: 2 additions & 2 deletions user/user.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ char* strcpy(char*, const char*);
void *memmove(void*, const void*, int);
char* strchr(const char*, char c);
int strcmp(const char*, const char*);
void fprintf(int, const char*, ...);
void printf(const char*, ...);
void fprintf(int, const char*, ...) __attribute__ ((format (printf, 2, 3)));
void printf(const char*, ...) __attribute__ ((format (printf, 1, 2)));
char* gets(char*, int max);
uint strlen(const char*);
void* memset(void*, int, uint);
Expand Down
Loading

0 comments on commit dd2574b

Please sign in to comment.