From dac13ba4bbaccfd6f8e64466bb27826a18d7e7f1 Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Mon, 24 Feb 2020 16:58:40 +0100 Subject: [PATCH] Add string format checking to err.h functions And fix all problems this detected... oops --- include/extern/err.h | 16 ++++++++-------- include/helpers.h | 3 +++ src/asm/main.c | 9 +++++---- src/link/assign.c | 2 +- src/link/object.c | 5 +++-- src/link/patch.c | 2 +- src/link/section.c | 2 +- 7 files changed, 22 insertions(+), 17 deletions(-) diff --git a/include/extern/err.h b/include/extern/err.h index 7a6e9e50..cc5ff3a0 100644 --- a/include/extern/err.h +++ b/include/extern/err.h @@ -29,15 +29,15 @@ #define errx rgbds_errx #define verrx rgbds_verrx -void warn(const char *fmt, ...); -void vwarn(const char *fmt, va_list ap); -void warnx(const char *fmt, ...); -void vwarnx(const char *fmt, va_list ap); +void warn(const char *fmt, ...) format_(printf, 1, 2); +void vwarn(const char *fmt, va_list ap) format_(printf, 1, 0); +void warnx(const char *fmt, ...) format_(printf, 1, 2); +void vwarnx(const char *fmt, va_list ap) format_(printf, 1, 0); -noreturn_ void err(int status, const char *fmt, ...); -noreturn_ void verr(int status, const char *fmt, va_list ap); -noreturn_ void errx(int status, const char *fmt, ...); -noreturn_ void verrx(int status, const char *fmt, va_list ap); +noreturn_ void err(int status, const char *fmt, ...) format_(printf, 2, 3); +noreturn_ void verr(int status, const char *fmt, va_list ap) format_(printf, 2, 0); +noreturn_ void errx(int status, const char *fmt, ...) format_(printf, 2, 3); +noreturn_ void verrx(int status, const char *fmt, va_list ap) format_(printf, 2, 0); #endif /* ERR_IN_LIBC */ diff --git a/include/helpers.h b/include/helpers.h index d88c73ff..d34c7b62 100644 --- a/include/helpers.h +++ b/include/helpers.h @@ -11,11 +11,14 @@ #ifdef __GNUC__ /* GCC or compatible */ + #define format_(archetype, str_index, first_arg) \ + __attribute__ ((format (archetype, str_index, first_arg))) #define noreturn_ __attribute__ ((noreturn)) #define unused_ __attribute__ ((unused)) #define trap_ __builtin_trap() #else /* Unsupported, but no need to throw a fit */ + #define format_(archetype, str_index, first_arg) #define noreturn_ #define unused_ #define trap_ diff --git a/src/asm/main.c b/src/asm/main.c index 26eafa15..2e544f7b 100644 --- a/src/asm/main.c +++ b/src/asm/main.c @@ -6,7 +6,9 @@ * SPDX-License-Identifier: MIT */ +#include #include +#include #include #include #include @@ -14,7 +16,6 @@ #include #include #include -#include #include "asm/symbol.h" #include "asm/fstack.h" @@ -532,15 +533,15 @@ int main(int argc, char *argv[]) opt_SetCurrentOptions(&DefaultOptions); if (yyparse() != 0 || nbErrors != 0) - errx(1, "Assembly aborted (%ld errors)!", nbErrors); + errx(1, "Assembly aborted (%u errors)!", nbErrors); if (dependfile) fclose(dependfile); if (nIFDepth != 0) - errx(1, "Unterminated IF construct (%ld levels)!", nIFDepth); + errx(1, "Unterminated IF construct (%u levels)!", nIFDepth); if (nUnionDepth != 0) { - errx(1, "Unterminated UNION construct (%ld levels)!", + errx(1, "Unterminated UNION construct (%u levels)!", nUnionDepth); } diff --git a/src/link/assign.c b/src/link/assign.c index 0c4e8083..c63d5320 100644 --- a/src/link/assign.c +++ b/src/link/assign.c @@ -412,7 +412,7 @@ void assign_AssignSections(void) /* Overlaying requires only fully-constrained sections */ verbosePrint("Assigning other sections...\n"); if (overlayFileName) - errx(1, "All sections must be fixed when using an overlay file; %u %sn't", + errx(1, "All sections must be fixed when using an overlay file; %lu %sn't", nbSectionsToAssign, nbSectionsToAssign == 1 ? "is" : "are"); /* Assign all remaining sections by decreasing constraint order */ diff --git a/src/link/object.c b/src/link/object.c index 9dcb1451..770ad4af 100644 --- a/src/link/object.c +++ b/src/link/object.c @@ -226,7 +226,8 @@ static void readPatch(FILE *file, struct Patch *patch, if (nbElementsRead != patch->rpnSize) errx(1, "%s: Cannot read \"%s\"'s patch #%u's RPN expression: %s", - fileName, sectName, i); + fileName, sectName, i, + feof(file) ? "Unexpected end of file" : strerror(errno)); patch->rpnExpression = rpnExpression; } @@ -255,7 +256,7 @@ static void readSection(FILE *file, struct Section *section, fileName, section->name); section->isAddressFixed = tmp >= 0; if (tmp > UINT16_MAX) - errx(1, "\"%s\" is too large (%d)", tmp); + errx(1, "\"%s\"'s org' is too large (%d)", section->name, tmp); section->org = tmp; tryReadlong(tmp, file, "%s: Cannot read \"%s\"'s bank: %s", fileName, section->name); diff --git a/src/link/patch.c b/src/link/patch.c index be30541d..82f3ed34 100644 --- a/src/link/patch.c +++ b/src/link/patch.c @@ -243,7 +243,7 @@ static int32_t computeRPNExpr(struct Patch const *patch, struct Symbol const *symbolDefinition = sym_GetSymbol(symbol->name); if (!symbolDefinition) - errx(1, "%s(%d): Unknown symbol \"%s\"", + errx(1, "%s: Unknown symbol \"%s\"", patch->fileName, symbol->name); symbol = symbolDefinition; } diff --git a/src/link/section.c b/src/link/section.c index 02ee418f..d1c35640 100644 --- a/src/link/section.c +++ b/src/link/section.c @@ -111,7 +111,7 @@ static void doSanityChecks(struct Section *section, void *ptr) /* Check if section has a chance to be placed */ if (section->size > maxsize[section->type]) fail("Section \"%s\" is bigger than the max size for that type: %#x > %#x", - section->size, maxsize[section->type]); + section->name, section->size, maxsize[section->type]); /* Translate loose constraints to strong ones when they're equivalent */