tell gcc to check printf format strings

add %ld %lld %u %lu %llu %lx %llx to kernel and user printf
This commit is contained in:
Robert Morris 2023-12-31 12:21:46 -05:00
parent 2b552503c0
commit dd2574bc10
8 changed files with 150 additions and 56 deletions

View file

@ -59,7 +59,14 @@ OBJDUMP = $(TOOLPREFIX)objdump
CFLAGS = -Wall -Werror -O -fno-omit-frame-pointer -ggdb -gdwarf-2 CFLAGS = -Wall -Werror -O -fno-omit-frame-pointer -ggdb -gdwarf-2
CFLAGS += -MD CFLAGS += -MD
CFLAGS += -mcmodel=medany 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 += -I.
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector) CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)

View file

@ -77,7 +77,7 @@ int piperead(struct pipe*, uint64, int);
int pipewrite(struct pipe*, uint64, int); int pipewrite(struct pipe*, uint64, int);
// printf.c // printf.c
void printf(char*, ...); int printf(char*, ...) __attribute__ ((format (printf, 1, 2)));
void panic(char*) __attribute__((noreturn)); void panic(char*) __attribute__((noreturn));
void printfinit(void); void printfinit(void);

View file

@ -26,13 +26,13 @@ static struct {
static char digits[] = "0123456789abcdef"; static char digits[] = "0123456789abcdef";
static void static void
printint(int xx, int base, int sign) printint(long long xx, int base, int sign)
{ {
char buf[16]; char buf[16];
int i; int i;
uint x; unsigned long long x;
if(sign && (sign = xx < 0)) if(sign && (sign = (xx < 0)))
x = -xx; x = -xx;
else else
x = xx; x = xx;
@ -59,30 +59,71 @@ printptr(uint64 x)
consputc(digits[x >> (sizeof(uint64) * 8 - 4)]); consputc(digits[x >> (sizeof(uint64) * 8 - 4)]);
} }
// Print to the console. only understands %d, %x, %p, %s. // Print to the console.
void int
printf(char *fmt, ...) printf(char *fmt, ...)
{ {
va_list ap; va_list ap;
int i, c, locking; int i, cx, c0, c1, c2, locking;
char *s; char *s;
locking = pr.locking; locking = pr.locking;
if(locking) if(locking)
acquire(&pr.lock); acquire(&pr.lock);
if (fmt == 0)
panic("null fmt");
va_start(ap, fmt); va_start(ap, fmt);
for(i = 0; (c = fmt[i] & 0xff) != 0; i++){ for(i = 0; (cx = fmt[i] & 0xff) != 0; i++){
if(c != '%'){ if(cx != '%'){
consputc(c); consputc(cx);
continue; continue;
} }
c = fmt[++i] & 0xff; i++;
if(c == 0) 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; break;
} else {
// Print unknown % sequence to draw attention.
consputc('%');
consputc(c0);
}
#if 0
switch(c){ switch(c){
case 'd': case 'd':
printint(va_arg(ap, int), 10, 1); printint(va_arg(ap, int), 10, 1);
@ -108,11 +149,14 @@ printf(char *fmt, ...)
consputc(c); consputc(c);
break; break;
} }
#endif
} }
va_end(ap); va_end(ap);
if(locking) if(locking)
release(&pr.lock); release(&pr.lock);
return 0;
} }
void void
@ -120,8 +164,7 @@ panic(char *s)
{ {
pr.locking = 0; pr.locking = 0;
printf("panic: "); printf("panic: ");
printf(s); printf("%s\n", s);
printf("\n");
panicked = 1; // freeze uart output from other CPUs panicked = 1; // freeze uart output from other CPUs
for(;;) for(;;)
; ;

View file

@ -68,8 +68,8 @@ usertrap(void)
} else if((which_dev = devintr()) != 0){ } else if((which_dev = devintr()) != 0){
// ok // ok
} else { } else {
printf("usertrap(): unexpected scause %p pid=%d\n", r_scause(), p->pid); printf("usertrap(): unexpected scause %lx pid=%d\n", r_scause(), p->pid);
printf(" sepc=%p stval=%p\n", r_sepc(), r_stval()); printf(" sepc=%lx stval=%lx\n", r_sepc(), r_stval());
setkilled(p); setkilled(p);
} }
@ -145,8 +145,8 @@ kerneltrap()
panic("kerneltrap: interrupts enabled"); panic("kerneltrap: interrupts enabled");
if((which_dev = devintr()) == 0){ if((which_dev = devintr()) == 0){
printf("scause %p\n", scause); printf("scause %lx\n", scause);
printf("sepc=%p stval=%p\n", r_sepc(), r_stval()); printf("sepc=%lx stval=%lx\n", r_sepc(), r_stval());
panic("kerneltrap"); panic("kerneltrap");
} }

View file

@ -45,7 +45,7 @@ ls(char *path)
switch(st.type){ switch(st.type){
case T_DEVICE: case T_DEVICE:
case T_FILE: 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; break;
case T_DIR: case T_DIR:
@ -65,7 +65,7 @@ ls(char *path)
printf("ls: cannot stat %s\n", buf); printf("ls: cannot stat %s\n", buf);
continue; 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; break;
} }

View file

@ -52,18 +52,61 @@ void
vprintf(int fd, const char *fmt, va_list ap) vprintf(int fd, const char *fmt, va_list ap)
{ {
char *s; char *s;
int c, i, state; int c0, c1, c2, i, state;
state = 0; state = 0;
for(i = 0; fmt[i]; i++){ for(i = 0; fmt[i]; i++){
c = fmt[i] & 0xff; c0 = fmt[i] & 0xff;
if(state == 0){ if(state == 0){
if(c == '%'){ if(c0 == '%'){
state = '%'; state = '%';
} else { } else {
putc(fd, c); putc(fd, c0);
} }
} else if(state == '%'){ } 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'){ if(c == 'd'){
printint(fd, va_arg(ap, int), 10, 1); printint(fd, va_arg(ap, int), 10, 1);
} else if(c == 'l') { } else if(c == 'l') {
@ -89,6 +132,7 @@ vprintf(int fd, const char *fmt, va_list ap)
putc(fd, '%'); putc(fd, '%');
putc(fd, c); putc(fd, c);
} }
#endif
state = 0; state = 0;
} }
} }

View file

@ -29,8 +29,8 @@ char* strcpy(char*, const char*);
void *memmove(void*, const void*, int); void *memmove(void*, const void*, int);
char* strchr(const char*, char c); char* strchr(const char*, char c);
int strcmp(const char*, const char*); int strcmp(const char*, const char*);
void fprintf(int, const char*, ...); void fprintf(int, const char*, ...) __attribute__ ((format (printf, 2, 3)));
void printf(const char*, ...); void printf(const char*, ...) __attribute__ ((format (printf, 1, 2)));
char* gets(char*, int max); char* gets(char*, int max);
uint strlen(const char*); uint strlen(const char*);
void* memset(void*, int, uint); void* memset(void*, int, uint);

View file

@ -44,7 +44,7 @@ copyin(char *s)
} }
int n = write(fd, (void*)addr, 8192); int n = write(fd, (void*)addr, 8192);
if(n >= 0){ if(n >= 0){
printf("write(fd, %p, 8192) returned %d, not -1\n", addr, n); printf("write(fd, %p, 8192) returned %d, not -1\n", (void*)addr, n);
exit(1); exit(1);
} }
close(fd); close(fd);
@ -52,7 +52,7 @@ copyin(char *s)
n = write(1, (char*)addr, 8192); n = write(1, (char*)addr, 8192);
if(n > 0){ if(n > 0){
printf("write(1, %p, 8192) returned %d, not -1 or 0\n", addr, n); printf("write(1, %p, 8192) returned %d, not -1 or 0\n", (void*)addr, n);
exit(1); exit(1);
} }
@ -63,7 +63,7 @@ copyin(char *s)
} }
n = write(fds[1], (char*)addr, 8192); n = write(fds[1], (char*)addr, 8192);
if(n > 0){ if(n > 0){
printf("write(pipe, %p, 8192) returned %d, not -1 or 0\n", addr, n); printf("write(pipe, %p, 8192) returned %d, not -1 or 0\n", (void*)addr, n);
exit(1); exit(1);
} }
close(fds[0]); close(fds[0]);
@ -88,7 +88,7 @@ copyout(char *s)
} }
int n = read(fd, (void*)addr, 8192); int n = read(fd, (void*)addr, 8192);
if(n > 0){ if(n > 0){
printf("read(fd, %p, 8192) returned %d, not -1 or 0\n", addr, n); printf("read(fd, %p, 8192) returned %d, not -1 or 0\n", (void*)addr, n);
exit(1); exit(1);
} }
close(fd); close(fd);
@ -105,7 +105,7 @@ copyout(char *s)
} }
n = read(fds[0], (void*)addr, 8192); n = read(fds[0], (void*)addr, 8192);
if(n > 0){ if(n > 0){
printf("read(pipe, %p, 8192) returned %d, not -1 or 0\n", addr, n); printf("read(pipe, %p, 8192) returned %d, not -1 or 0\n", (void*)addr, n);
exit(1); exit(1);
} }
close(fds[0]); close(fds[0]);
@ -124,7 +124,7 @@ copyinstr1(char *s)
int fd = open((char *)addr, O_CREATE|O_WRONLY); int fd = open((char *)addr, O_CREATE|O_WRONLY);
if(fd >= 0){ if(fd >= 0){
printf("open(%p) returned %d, not -1\n", addr, fd); printf("open(%p) returned %d, not -1\n", (void*)addr, fd);
exit(1); exit(1);
} }
} }
@ -264,7 +264,7 @@ rwsbrk()
} }
n = write(fd, (void*)(a+4096), 1024); n = write(fd, (void*)(a+4096), 1024);
if(n >= 0){ if(n >= 0){
printf("write(fd, %p, 1024) returned %d, not -1\n", a+4096, n); printf("write(fd, %p, 1024) returned %d, not -1\n", (void*)a+4096, n);
exit(1); exit(1);
} }
close(fd); close(fd);
@ -277,7 +277,7 @@ rwsbrk()
} }
n = read(fd, (void*)(a+4096), 10); n = read(fd, (void*)(a+4096), 10);
if(n >= 0){ if(n >= 0){
printf("read(fd, %p, 10) returned %d, not -1\n", a+4096, n); printf("read(fd, %p, 10) returned %d, not -1\n", (void*)a+4096, n);
exit(1); exit(1);
} }
close(fd); close(fd);
@ -589,7 +589,7 @@ writebig(char *s)
for(i = 0; i < MAXFILE; i++){ for(i = 0; i < MAXFILE; i++){
((int*)buf)[0] = i; ((int*)buf)[0] = i;
if(write(fd, buf, BSIZE) != BSIZE){ if(write(fd, buf, BSIZE) != BSIZE){
printf("%s: error: write big file failed\n", s, i); printf("%s: error: write big file failed i=%d\n", s, i);
exit(1); exit(1);
} }
} }
@ -773,7 +773,7 @@ pipe1(char *s)
cc = sizeof(buf); cc = sizeof(buf);
} }
if(total != N * SZ){ if(total != N * SZ){
printf("%s: pipe1 oops 3 total %d\n", total); printf("%s: pipe1 oops 3 total %d\n", s, total);
exit(1); exit(1);
} }
close(fds[0]); close(fds[0]);
@ -1069,7 +1069,7 @@ mem(char *s)
} }
m1 = malloc(1024*20); m1 = malloc(1024*20);
if(m1 == 0){ if(m1 == 0){
printf("couldn't allocate mem?!!\n", s); printf("%s: couldn't allocate mem?!!\n", s);
exit(1); exit(1);
} }
free(m1); free(m1);
@ -1161,14 +1161,14 @@ fourfiles(char *s)
pid = fork(); pid = fork();
if(pid < 0){ if(pid < 0){
printf("fork failed\n", s); printf("%s: fork failed\n", s);
exit(1); exit(1);
} }
if(pid == 0){ if(pid == 0){
fd = open(fname, O_CREATE | O_RDWR); fd = open(fname, O_CREATE | O_RDWR);
if(fd < 0){ if(fd < 0){
printf("create failed\n", s); printf("%s: create failed\n", s);
exit(1); exit(1);
} }
@ -1197,7 +1197,7 @@ fourfiles(char *s)
while((n = read(fd, buf, sizeof(buf))) > 0){ while((n = read(fd, buf, sizeof(buf))) > 0){
for(j = 0; j < n; j++){ for(j = 0; j < n; j++){
if(buf[j] != '0'+i){ if(buf[j] != '0'+i){
printf("wrong char\n", s); printf("%s: wrong char\n", s);
exit(1); exit(1);
} }
} }
@ -1223,7 +1223,7 @@ createdelete(char *s)
for(pi = 0; pi < NCHILD; pi++){ for(pi = 0; pi < NCHILD; pi++){
pid = fork(); pid = fork();
if(pid < 0){ if(pid < 0){
printf("fork failed\n", s); printf("%s: fork failed\n", s);
exit(1); exit(1);
} }
@ -1544,7 +1544,7 @@ subdir(char *s)
} }
if(mkdir("/dd/dd") != 0){ if(mkdir("/dd/dd") != 0){
printf("subdir mkdir dd/dd failed\n", s); printf("%s: subdir mkdir dd/dd failed\n", s);
exit(1); exit(1);
} }
@ -1569,7 +1569,7 @@ subdir(char *s)
close(fd); close(fd);
if(link("dd/dd/ff", "dd/dd/ffff") != 0){ if(link("dd/dd/ff", "dd/dd/ffff") != 0){
printf("link dd/dd/ff dd/dd/ffff failed\n", s); printf("%s: link dd/dd/ff dd/dd/ffff failed\n", s);
exit(1); exit(1);
} }
@ -1591,7 +1591,7 @@ subdir(char *s)
exit(1); exit(1);
} }
if(chdir("dd/../../../dd") != 0){ if(chdir("dd/../../../dd") != 0){
printf("chdir dd/../../dd failed\n", s); printf("%s: chdir dd/../../dd failed\n", s);
exit(1); exit(1);
} }
if(chdir("./..") != 0){ if(chdir("./..") != 0){
@ -2034,7 +2034,7 @@ sbrkbasic(char *s)
for(i = 0; i < 5000; i++){ for(i = 0; i < 5000; i++){
b = sbrk(1); b = sbrk(1);
if(b != a){ if(b != a){
printf("%s: sbrk test failed %d %x %x\n", s, i, a, b); printf("%s: sbrk test failed %d %p %p\n", s, i, a, b);
exit(1); exit(1);
} }
*b = 1; *b = 1;
@ -2092,7 +2092,7 @@ sbrkmuch(char *s)
} }
c = sbrk(0); c = sbrk(0);
if(c != a - PGSIZE){ if(c != a - PGSIZE){
printf("%s: sbrk deallocation produced wrong address, a %x c %x\n", s, a, c); printf("%s: sbrk deallocation produced wrong address, a %p c %p\n", s, a, c);
exit(1); exit(1);
} }
@ -2100,7 +2100,7 @@ sbrkmuch(char *s)
a = sbrk(0); a = sbrk(0);
c = sbrk(PGSIZE); c = sbrk(PGSIZE);
if(c != a || sbrk(0) != a + PGSIZE){ if(c != a || sbrk(0) != a + PGSIZE){
printf("%s: sbrk re-allocation failed, a %x c %x\n", s, a, c); printf("%s: sbrk re-allocation failed, a %p c %p\n", s, a, c);
exit(1); exit(1);
} }
if(*lastaddr == 99){ if(*lastaddr == 99){
@ -2112,7 +2112,7 @@ sbrkmuch(char *s)
a = sbrk(0); a = sbrk(0);
c = sbrk(-(sbrk(0) - oldbrk)); c = sbrk(-(sbrk(0) - oldbrk));
if(c != a){ if(c != a){
printf("%s: sbrk downsize failed, a %x c %x\n", s, a, c); printf("%s: sbrk downsize failed, a %p c %p\n", s, a, c);
exit(1); exit(1);
} }
} }
@ -2131,7 +2131,7 @@ kernmem(char *s)
exit(1); exit(1);
} }
if(pid == 0){ if(pid == 0){
printf("%s: oops could read %x = %x\n", s, a, *a); printf("%s: oops could read %p = %x\n", s, a, *a);
exit(1); exit(1);
} }
int xstatus; int xstatus;
@ -2155,7 +2155,7 @@ MAXVAplus(char *s)
} }
if(pid == 0){ if(pid == 0){
*(char*)a = 99; *(char*)a = 99;
printf("%s: oops wrote %x\n", s, a); printf("%s: oops wrote %p\n", s, (void*)a);
exit(1); exit(1);
} }
int xstatus; int xstatus;
@ -2408,7 +2408,7 @@ stacktest(char *s)
char *sp = (char *) r_sp(); char *sp = (char *) r_sp();
sp -= PGSIZE; sp -= PGSIZE;
// the *sp should cause a trap. // the *sp should cause a trap.
printf("%s: stacktest: read below stack %p\n", s, *sp); printf("%s: stacktest: read below stack %d\n", s, *sp);
exit(1); exit(1);
} else if(pid < 0){ } else if(pid < 0){
printf("%s: fork failed\n", s); printf("%s: fork failed\n", s);
@ -2868,7 +2868,7 @@ diskfull(char *s)
// this mkdir() is expected to fail. // this mkdir() is expected to fail.
if(mkdir("diskfulldir") == 0) if(mkdir("diskfulldir") == 0)
printf("%s: mkdir(diskfulldir) unexpectedly succeeded!\n"); printf("%s: mkdir(diskfulldir) unexpectedly succeeded!\n", s);
unlink("diskfulldir"); unlink("diskfulldir");