Refactor error reporting to simplify BSD-style err (#949)

This commit is contained in:
Rangi
2021-11-21 16:16:54 -05:00
committed by GitHub
parent 54293a9184
commit bdcef6f252
24 changed files with 262 additions and 297 deletions

View File

@@ -72,9 +72,9 @@ rgbasm_obj := \
src/asm/symbol.o \ src/asm/symbol.o \
src/asm/util.o \ src/asm/util.o \
src/asm/warning.o \ src/asm/warning.o \
src/extern/err.o \
src/extern/getopt.o \ src/extern/getopt.o \
src/extern/utf8decoder.o \ src/extern/utf8decoder.o \
src/error.o \
src/hashmap.o \ src/hashmap.o \
src/linkdefs.o \ src/linkdefs.o \
src/opmath.o src/opmath.o
@@ -90,23 +90,23 @@ rgblink_obj := \
src/link/script.o \ src/link/script.o \
src/link/section.o \ src/link/section.o \
src/link/symbol.o \ src/link/symbol.o \
src/extern/err.o \
src/extern/getopt.o \ src/extern/getopt.o \
src/error.o \
src/hashmap.o \ src/hashmap.o \
src/linkdefs.o \ src/linkdefs.o \
src/opmath.o src/opmath.o
rgbfix_obj := \ rgbfix_obj := \
src/fix/main.o \ src/fix/main.o \
src/extern/err.o \ src/extern/getopt.o \
src/extern/getopt.o src/error.o
rgbgfx_obj := \ rgbgfx_obj := \
src/gfx/gb.o \ src/gfx/gb.o \
src/gfx/main.o \ src/gfx/main.o \
src/gfx/makepng.o \ src/gfx/makepng.o \
src/extern/err.o \ src/extern/getopt.o \
src/extern/getopt.o src/error.o
rgbasm: ${rgbasm_obj} rgbasm: ${rgbasm_obj}
$Q${CC} ${REALLDFLAGS} -o $@ ${rgbasm_obj} ${REALCFLAGS} src/version.c -lm $Q${CC} ${REALLDFLAGS} -o $@ ${rgbasm_obj} ${REALCFLAGS} src/version.c -lm

21
include/error.h Normal file
View File

@@ -0,0 +1,21 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2021, RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_ERROR_H
#define RGBDS_ERROR_H
#include "helpers.h"
#include "platform.h"
void warn(char const NONNULL(fmt), ...) format_(printf, 1, 2);
void warnx(char const NONNULL(fmt), ...) format_(printf, 1, 2);
_Noreturn void err(char const NONNULL(fmt), ...) format_(printf, 1, 2);
_Noreturn void errx(char const NONNULL(fmt), ...) format_(printf, 1, 2);
#endif /* RGBDS_ERROR_H */

44
include/extern/err.h vendored
View File

@@ -1,44 +0,0 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef EXTERN_ERR_H
#define EXTERN_ERR_H
#ifdef ERR_IN_LIBC
#include <err.h>
#else /* ERR_IN_LIBC */
#include <stdarg.h>
#include "helpers.h"
#define warn rgbds_warn
#define vwarn rgbds_vwarn
#define warnx rgbds_warnx
#define vwarnx rgbds_vwarnx
#define err rgbds_err
#define verr rgbds_verr
#define errx rgbds_errx
#define verrx rgbds_verrx
void warn(char const *fmt, ...) format_(printf, 1, 2);
void vwarn(char const *fmt, va_list ap) format_(printf, 1, 0);
void warnx(char const *fmt, ...) format_(printf, 1, 2);
void vwarnx(char const *fmt, va_list ap) format_(printf, 1, 0);
_Noreturn void err(int status, char const *fmt, ...) format_(printf, 2, 3);
_Noreturn void verr(int status, char const *fmt, va_list ap) format_(printf, 2, 0);
_Noreturn void errx(int status, char const *fmt, ...) format_(printf, 2, 3);
_Noreturn void verrx(int status, char const *fmt, va_list ap) format_(printf, 2, 0);
#endif /* ERR_IN_LIBC */
#endif /* EXTERN_ERR_H */

View File

@@ -13,7 +13,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "extern/err.h" #include "error.h"
struct Options { struct Options {
bool debug; bool debug;

View File

@@ -7,7 +7,7 @@
# #
set(common_src set(common_src
"extern/err.c" "error.c"
"extern/getopt.c" "extern/getopt.c"
"version.c" "version.c"
) )

View File

@@ -30,10 +30,10 @@
#include "asm/warning.h" #include "asm/warning.h"
#include "parser.h" #include "parser.h"
#include "extern/err.h"
#include "extern/getopt.h" #include "extern/getopt.h"
#include "helpers.h" #include "helpers.h"
#include "error.h"
#include "version.h" #include "version.h"
#ifdef __clang__ #ifdef __clang__
@@ -74,7 +74,7 @@ static char *make_escape(char const *str)
char *dest = escaped_str; char *dest = escaped_str;
if (escaped_str == NULL) if (escaped_str == NULL)
err(1, "%s: Failed to allocate memory", __func__); err("%s: Failed to allocate memory", __func__);
while (*str) { while (*str) {
/* All dollars needs to be doubled */ /* All dollars needs to be doubled */
@@ -192,7 +192,7 @@ int main(int argc, char *argv[])
if (strlen(musl_optarg) == 2) if (strlen(musl_optarg) == 2)
opt_B(&musl_optarg[1]); opt_B(&musl_optarg[1]);
else else
errx(1, "Must specify exactly 2 characters for option 'b'"); errx("Must specify exactly 2 characters for option 'b'");
break; break;
char *equals; char *equals;
@@ -214,7 +214,7 @@ int main(int argc, char *argv[])
if (strlen(musl_optarg) == 4) if (strlen(musl_optarg) == 4)
opt_G(&musl_optarg[1]); opt_G(&musl_optarg[1]);
else else
errx(1, "Must specify exactly 4 characters for option 'g'"); errx("Must specify exactly 4 characters for option 'g'");
break; break;
case 'h': case 'h':
@@ -235,7 +235,7 @@ int main(int argc, char *argv[])
else else
dependfile = fopen(musl_optarg, "w"); dependfile = fopen(musl_optarg, "w");
if (dependfile == NULL) if (dependfile == NULL)
err(1, "Could not open dependfile %s", musl_optarg); err("Could not open dependfile %s", musl_optarg);
break; break;
case 'o': case 'o':
@@ -247,10 +247,10 @@ int main(int argc, char *argv[])
fill = strtoul(musl_optarg, &ep, 0); fill = strtoul(musl_optarg, &ep, 0);
if (musl_optarg[0] == '\0' || *ep != '\0') if (musl_optarg[0] == '\0' || *ep != '\0')
errx(1, "Invalid argument for option 'p'"); errx("Invalid argument for option 'p'");
if (fill < 0 || fill > 0xFF) if (fill < 0 || fill > 0xFF)
errx(1, "Argument for option 'p' must be between 0 and 0xFF"); errx("Argument for option 'p' must be between 0 and 0xFF");
opt_P(fill); opt_P(fill);
break; break;
@@ -259,7 +259,7 @@ int main(int argc, char *argv[])
maxDepth = strtoul(musl_optarg, &ep, 0); maxDepth = strtoul(musl_optarg, &ep, 0);
if (musl_optarg[0] == '\0' || *ep != '\0') if (musl_optarg[0] == '\0' || *ep != '\0')
errx(1, "Invalid argument for option 'r'"); errx("Invalid argument for option 'r'");
break; break;
case 'V': case 'V':
@@ -299,7 +299,7 @@ int main(int argc, char *argv[])
targetFileName = realloc(targetFileName, targetFileName = realloc(targetFileName,
targetFileNameLen + newTargetLen + 1); targetFileNameLen + newTargetLen + 1);
if (targetFileName == NULL) if (targetFileName == NULL)
err(1, "Cannot append new file to target file list"); err("Cannot append new file to target file list");
memcpy(&targetFileName[targetFileNameLen], newTarget, newTargetLen); memcpy(&targetFileName[targetFileNameLen], newTarget, newTargetLen);
if (depType == 'Q') if (depType == 'Q')
free(newTarget); free(newTarget);
@@ -336,7 +336,7 @@ int main(int argc, char *argv[])
if (dependfile) { if (dependfile) {
if (!targetFileName) if (!targetFileName)
errx(1, "Dependency files can only be created if a target file is specified with either -o, -MQ or -MT"); errx("Dependency files can only be created if a target file is specified with either -o, -MQ or -MT");
fprintf(dependfile, "%s: %s\n", targetFileName, mainFileName); fprintf(dependfile, "%s: %s\n", targetFileName, mainFileName);
} }
@@ -357,7 +357,7 @@ int main(int argc, char *argv[])
sect_CheckUnionClosed(); sect_CheckUnionClosed();
if (nbErrors != 0) if (nbErrors != 0)
errx(1, "Assembly aborted (%u error%s)!", nbErrors, errx("Assembly aborted (%u error%s)!", nbErrors,
nbErrors == 1 ? "" : "s"); nbErrors == 1 ? "" : "s");
// If parse aborted due to missing an include, and `-MG` was given, exit normally // If parse aborted due to missing an include, and `-MG` was given, exit normally

View File

@@ -27,8 +27,7 @@
#include "asm/symbol.h" #include "asm/symbol.h"
#include "asm/warning.h" #include "asm/warning.h"
#include "extern/err.h" #include "error.h"
#include "linkdefs.h" #include "linkdefs.h"
#include "platform.h" // strdup #include "platform.h" // strdup
@@ -528,7 +527,7 @@ void out_WriteObject(void)
f = fdopen(1, "wb"); f = fdopen(1, "wb");
if (!f) if (!f)
err(1, "Couldn't write file '%s'", objectName); err("Couldn't write file '%s'", objectName);
/* Also write symbols that weren't written above */ /* Also write symbols that weren't written above */
sym_ForEach(registerUnregisteredSymbol, NULL); sym_ForEach(registerUnregisteredSymbol, NULL);

View File

@@ -15,7 +15,7 @@
#include "asm/symbol.h" #include "asm/symbol.h"
#include "asm/warning.h" #include "asm/warning.h"
#include "extern/err.h" #include "error.h"
#include "platform.h" // strdup #include "platform.h" // strdup
uint8_t fillByte; uint8_t fillByte;

View File

@@ -29,8 +29,7 @@
#include "asm/util.h" #include "asm/util.h"
#include "asm/warning.h" #include "asm/warning.h"
#include "extern/err.h" #include "error.h"
#include "hashmap.h" #include "hashmap.h"
#include "helpers.h" #include "helpers.h"
#include "version.h" #include "version.h"

View File

@@ -18,7 +18,7 @@
#include "asm/main.h" #include "asm/main.h"
#include "asm/warning.h" #include "asm/warning.h"
#include "extern/err.h" #include "error.h"
unsigned int nbErrors = 0; unsigned int nbErrors = 0;
@@ -215,7 +215,7 @@ void processWarningFlag(char *flag)
if (!strcmp(flag, warningFlags[id])) { if (!strcmp(flag, warningFlags[id])) {
/* We got a match! */ /* We got a match! */
if (setError) if (setError)
errx(1, "Cannot make meta warning \"%s\" into an error", errx("Cannot make meta warning \"%s\" into an error",
flag); flag);
for (uint8_t const *ptr = metaWarningCommands[id - META_WARNINGS_START]; for (uint8_t const *ptr = metaWarningCommands[id - META_WARNINGS_START];

87
src/error.c Normal file
View File

@@ -0,0 +1,87 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2005-2021, Rich Felker and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "error.h"
#include "platform.h"
static void vwarn(char const NONNULL(fmt), va_list ap)
{
fprintf(stderr, "warning: ");
vfprintf(stderr, fmt, ap);
fputs(": ", stderr);
perror(NULL);
}
static void vwarnx(char const NONNULL(fmt), va_list ap)
{
fprintf(stderr, "warning");
fputs(": ", stderr);
vfprintf(stderr, fmt, ap);
putc('\n', stderr);
}
_Noreturn static void verr(char const NONNULL(fmt), va_list ap)
{
fprintf(stderr, "error: ");
vfprintf(stderr, fmt, ap);
fputs(": ", stderr);
fputs(strerror(errno), stderr);
putc('\n', stderr);
exit(1);
}
_Noreturn static void verrx(char const NONNULL(fmt), va_list ap)
{
fprintf(stderr, "error");
fputs(": ", stderr);
vfprintf(stderr, fmt, ap);
putc('\n', stderr);
exit(1);
}
void warn(char const NONNULL(fmt), ...)
{
va_list ap;
va_start(ap, fmt);
vwarn(fmt, ap);
va_end(ap);
}
void warnx(char const NONNULL(fmt), ...)
{
va_list ap;
va_start(ap, fmt);
vwarnx(fmt, ap);
va_end(ap);
}
_Noreturn void err(char const NONNULL(fmt), ...)
{
va_list ap;
va_start(ap, fmt);
verr(fmt, ap);
va_end(ap);
}
_Noreturn void errx(char const NONNULL(fmt), ...)
{
va_list ap;
va_start(ap, fmt);
verrx(fmt, ap);
va_end(ap);
}

94
src/extern/err.c vendored
View File

@@ -1,94 +0,0 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2005-2018, Rich Felker and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "extern/err.h"
void rgbds_vwarn(char const *fmt, va_list ap)
{
fprintf(stderr, "warning: ");
if (fmt) {
vfprintf(stderr, fmt, ap);
fputs(": ", stderr);
}
perror(NULL);
}
void rgbds_vwarnx(char const *fmt, va_list ap)
{
fprintf(stderr, "warning");
if (fmt) {
fputs(": ", stderr);
vfprintf(stderr, fmt, ap);
}
putc('\n', stderr);
}
_Noreturn void rgbds_verr(int status, char const *fmt, va_list ap)
{
fprintf(stderr, "error: ");
if (fmt) {
vfprintf(stderr, fmt, ap);
fputs(": ", stderr);
}
fputs(strerror(errno), stderr);
putc('\n', stderr);
exit(status);
}
_Noreturn void rgbds_verrx(int status, char const *fmt, va_list ap)
{
fprintf(stderr, "error");
if (fmt) {
fputs(": ", stderr);
vfprintf(stderr, fmt, ap);
}
putc('\n', stderr);
exit(status);
}
void rgbds_warn(char const *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vwarn(fmt, ap);
va_end(ap);
}
void rgbds_warnx(char const *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vwarnx(fmt, ap);
va_end(ap);
}
_Noreturn void rgbds_err(int status, char const *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
verr(status, fmt, ap);
va_end(ap);
}
_Noreturn void rgbds_errx(int status, char const *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
verrx(status, fmt, ap);
va_end(ap);
}

View File

@@ -20,7 +20,7 @@ void transpose_tiles(struct GBImage *gb, int width)
newdata = calloc(gb->size, 1); newdata = calloc(gb->size, 1);
if (!newdata) if (!newdata)
err(1, "%s: Failed to allocate memory for new data", __func__); err("%s: Failed to allocate memory for new data", __func__);
for (i = 0; i < gb->size; i++) { for (i = 0; i < gb->size; i++) {
newbyte = i / (8 * depth) * width * 8 * depth; newbyte = i / (8 * depth) * width * 8 * depth;
@@ -65,7 +65,7 @@ void output_file(const struct Options *opts, const struct GBImage *gb)
f = fopen(opts->outfile, "wb"); f = fopen(opts->outfile, "wb");
if (!f) if (!f)
err(1, "%s: Opening output file '%s' failed", __func__, err("%s: Opening output file '%s' failed", __func__,
opts->outfile); opts->outfile);
fwrite(gb->data, 1, gb->size - gb->trim * 8 * depth, f); fwrite(gb->data, 1, gb->size - gb->trim * 8 * depth, f);
@@ -141,7 +141,7 @@ int get_mirrored_tile_index(uint8_t *tile, uint8_t **tiles, int num_tiles,
tile_yflip = malloc(tile_size); tile_yflip = malloc(tile_size);
if (!tile_yflip) if (!tile_yflip)
err(1, "%s: Failed to allocate memory for Y flip of tile", err("%s: Failed to allocate memory for Y flip of tile",
__func__); __func__);
yflip(tile, tile_yflip, tile_size); yflip(tile, tile_yflip, tile_size);
index = get_tile_index(tile_yflip, tiles, num_tiles, tile_size); index = get_tile_index(tile_yflip, tiles, num_tiles, tile_size);
@@ -153,7 +153,7 @@ int get_mirrored_tile_index(uint8_t *tile, uint8_t **tiles, int num_tiles,
tile_xflip = malloc(tile_size); tile_xflip = malloc(tile_size);
if (!tile_xflip) if (!tile_xflip)
err(1, "%s: Failed to allocate memory for X flip of tile", err("%s: Failed to allocate memory for X flip of tile",
__func__); __func__);
xflip(tile, tile_xflip, tile_size); xflip(tile, tile_xflip, tile_size);
index = get_tile_index(tile_xflip, tiles, num_tiles, tile_size); index = get_tile_index(tile_xflip, tiles, num_tiles, tile_size);
@@ -198,13 +198,13 @@ void create_mapfiles(const struct Options *opts, struct GBImage *gb,
tiles = calloc(max_tiles, sizeof(*tiles)); tiles = calloc(max_tiles, sizeof(*tiles));
if (!tiles) if (!tiles)
err(1, "%s: Failed to allocate memory for tiles", __func__); err("%s: Failed to allocate memory for tiles", __func__);
num_tiles = 0; num_tiles = 0;
if (*opts->tilemapfile) { if (*opts->tilemapfile) {
tilemap->data = calloc(max_tiles, sizeof(*tilemap->data)); tilemap->data = calloc(max_tiles, sizeof(*tilemap->data));
if (!tilemap->data) if (!tilemap->data)
err(1, "%s: Failed to allocate memory for tilemap data", err("%s: Failed to allocate memory for tilemap data",
__func__); __func__);
tilemap->size = 0; tilemap->size = 0;
} }
@@ -212,7 +212,7 @@ void create_mapfiles(const struct Options *opts, struct GBImage *gb,
if (*opts->attrmapfile) { if (*opts->attrmapfile) {
attrmap->data = calloc(max_tiles, sizeof(*attrmap->data)); attrmap->data = calloc(max_tiles, sizeof(*attrmap->data));
if (!attrmap->data) if (!attrmap->data)
err(1, "%s: Failed to allocate memory for attrmap data", err("%s: Failed to allocate memory for attrmap data",
__func__); __func__);
attrmap->size = 0; attrmap->size = 0;
} }
@@ -222,7 +222,7 @@ void create_mapfiles(const struct Options *opts, struct GBImage *gb,
flags = 0; flags = 0;
tile = malloc(tile_size); tile = malloc(tile_size);
if (!tile) if (!tile)
err(1, "%s: Failed to allocate memory for tile", err("%s: Failed to allocate memory for tile",
__func__); __func__);
/* /*
* If the input image doesn't fill the last tile, * If the input image doesn't fill the last tile,
@@ -269,7 +269,7 @@ void create_mapfiles(const struct Options *opts, struct GBImage *gb,
free(gb->data); free(gb->data);
gb->data = malloc(tile_size * num_tiles); gb->data = malloc(tile_size * num_tiles);
if (!gb->data) if (!gb->data)
err(1, "%s: Failed to allocate memory for tile data", err("%s: Failed to allocate memory for tile data",
__func__); __func__);
for (i = 0; i < num_tiles; i++) { for (i = 0; i < num_tiles; i++) {
tile = tiles[i]; tile = tiles[i];
@@ -292,7 +292,7 @@ void output_tilemap_file(const struct Options *opts,
f = fopen(opts->tilemapfile, "wb"); f = fopen(opts->tilemapfile, "wb");
if (!f) if (!f)
err(1, "%s: Opening tilemap file '%s' failed", __func__, err("%s: Opening tilemap file '%s' failed", __func__,
opts->tilemapfile); opts->tilemapfile);
fwrite(tilemap->data, 1, tilemap->size, f); fwrite(tilemap->data, 1, tilemap->size, f);
@@ -309,7 +309,7 @@ void output_attrmap_file(const struct Options *opts,
f = fopen(opts->attrmapfile, "wb"); f = fopen(opts->attrmapfile, "wb");
if (!f) if (!f)
err(1, "%s: Opening attrmap file '%s' failed", __func__, err("%s: Opening attrmap file '%s' failed", __func__,
opts->attrmapfile); opts->attrmapfile);
fwrite(attrmap->data, 1, attrmap->size, f); fwrite(attrmap->data, 1, attrmap->size, f);
@@ -352,7 +352,7 @@ void output_palette_file(const struct Options *opts,
f = fopen(opts->palfile, "wb"); f = fopen(opts->palfile, "wb");
if (!f) if (!f)
err(1, "%s: Opening palette file '%s' failed", __func__, err("%s: Opening palette file '%s' failed", __func__,
opts->palfile); opts->palfile);
for (i = 0; i < raw_image->num_colors; i++) { for (i = 0; i < raw_image->num_colors; i++) {

View File

@@ -167,7 +167,7 @@ int main(int argc, char *argv[])
opts.infile = argv[argc - 1]; opts.infile = argv[argc - 1];
if (depth != 1 && depth != 2) if (depth != 1 && depth != 2)
errx(1, "Depth option must be either 1 or 2."); errx("Depth option must be either 1 or 2.");
colors = 1 << depth; colors = 1 << depth;
@@ -200,17 +200,17 @@ int main(int argc, char *argv[])
opts.trim = png_options.trim; opts.trim = png_options.trim;
if (raw_image->width % 8) { if (raw_image->width % 8) {
errx(1, "Input PNG file %s not sized correctly. The image's width must be a multiple of 8.", errx("Input PNG file %s not sized correctly. The image's width must be a multiple of 8.",
opts.infile); opts.infile);
} }
if (raw_image->width / 8 > 1 && raw_image->height % 8) { if (raw_image->width / 8 > 1 && raw_image->height % 8) {
errx(1, "Input PNG file %s not sized correctly. If the image is more than 1 tile wide, its height must be a multiple of 8.", errx("Input PNG file %s not sized correctly. If the image is more than 1 tile wide, its height must be a multiple of 8.",
opts.infile); opts.infile);
} }
if (opts.trim && if (opts.trim &&
opts.trim > (raw_image->width / 8) * (raw_image->height / 8) - 1) { opts.trim > (raw_image->width / 8) * (raw_image->height / 8) - 1) {
errx(1, "Trim (%d) for input raw_image file '%s' too large (max: %u)", errx("Trim (%d) for input raw_image file '%s' too large (max: %u)",
opts.trim, opts.infile, opts.trim, opts.infile,
(raw_image->width / 8) * (raw_image->height / 8) - 1); (raw_image->width / 8) * (raw_image->height / 8) - 1);
} }

View File

@@ -32,7 +32,7 @@ struct RawIndexedImage *input_png_file(const struct Options *opts,
f = fopen(opts->infile, "rb"); f = fopen(opts->infile, "rb");
if (!f) if (!f)
err(1, "Opening input png file '%s' failed", opts->infile); err("Opening input png file '%s' failed", opts->infile);
initialize_png(&img, f); initialize_png(&img, f);
@@ -54,7 +54,7 @@ struct RawIndexedImage *input_png_file(const struct Options *opts,
raw_image = truecolor_png_to_raw(&img); break; raw_image = truecolor_png_to_raw(&img); break;
default: default:
/* Shouldn't happen, but might as well handle just in case. */ /* Shouldn't happen, but might as well handle just in case. */
errx(1, "Input PNG file is of invalid color type."); errx("Input PNG file is of invalid color type.");
} }
get_text(&img, png_options); get_text(&img, png_options);
@@ -83,7 +83,7 @@ void output_png_file(const struct Options *opts,
if (opts->debug) { if (opts->debug) {
outfile = malloc(strlen(opts->infile) + 5); outfile = malloc(strlen(opts->infile) + 5);
if (!outfile) if (!outfile)
err(1, "%s: Failed to allocate memory for outfile", err("%s: Failed to allocate memory for outfile",
__func__); __func__);
strcpy(outfile, opts->infile); strcpy(outfile, opts->infile);
strcat(outfile, ".out"); strcat(outfile, ".out");
@@ -93,16 +93,16 @@ void output_png_file(const struct Options *opts,
f = fopen(outfile, "wb"); f = fopen(outfile, "wb");
if (!f) if (!f)
err(1, "Opening output png file '%s' failed", outfile); err("Opening output png file '%s' failed", outfile);
img.png = png_create_write_struct(PNG_LIBPNG_VER_STRING, img.png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL); NULL, NULL, NULL);
if (!img.png) if (!img.png)
errx(1, "Creating png structure failed"); errx("Creating png structure failed");
img.info = png_create_info_struct(img.png); img.info = png_create_info_struct(img.png);
if (!img.info) if (!img.info)
errx(1, "Creating png info structure failed"); errx("Creating png info structure failed");
if (setjmp(png_jmpbuf(img.png))) if (setjmp(png_jmpbuf(img.png)))
exit(1); exit(1);
@@ -115,7 +115,7 @@ void output_png_file(const struct Options *opts,
png_palette = malloc(sizeof(*png_palette) * raw_image->num_colors); png_palette = malloc(sizeof(*png_palette) * raw_image->num_colors);
if (!png_palette) if (!png_palette)
err(1, "%s: Failed to allocate memory for PNG palette", err("%s: Failed to allocate memory for PNG palette",
__func__); __func__);
for (i = 0; i < raw_image->num_colors; i++) { for (i = 0; i < raw_image->num_colors; i++) {
png_palette[i].red = raw_image->palette[i].red; png_palette[i].red = raw_image->palette[i].red;
@@ -159,11 +159,11 @@ static void initialize_png(struct PNGImage *img, FILE *f)
img->png = png_create_read_struct(PNG_LIBPNG_VER_STRING, img->png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL); NULL, NULL, NULL);
if (!img->png) if (!img->png)
errx(1, "Creating png structure failed"); errx("Creating png structure failed");
img->info = png_create_info_struct(img->png); img->info = png_create_info_struct(img->png);
if (!img->info) if (!img->info)
errx(1, "Creating png info structure failed"); errx("Creating png info structure failed");
if (setjmp(png_jmpbuf(img->png))) if (setjmp(png_jmpbuf(img->png)))
exit(1); exit(1);
@@ -215,13 +215,13 @@ static struct RawIndexedImage *indexed_png_to_raw(struct PNGImage *img)
original_palette = palette; original_palette = palette;
palette = malloc(sizeof(*palette) * colors_in_PLTE); palette = malloc(sizeof(*palette) * colors_in_PLTE);
if (!palette) if (!palette)
err(1, "%s: Failed to allocate memory for palette", err("%s: Failed to allocate memory for palette",
__func__); __func__);
colors_in_new_palette = 0; colors_in_new_palette = 0;
old_to_new_palette = malloc(sizeof(*old_to_new_palette) old_to_new_palette = malloc(sizeof(*old_to_new_palette)
* colors_in_PLTE); * colors_in_PLTE);
if (!old_to_new_palette) if (!old_to_new_palette)
err(1, "%s: Failed to allocate memory for new palette", err("%s: Failed to allocate memory for new palette",
__func__); __func__);
for (i = 0; i < num_trans; i++) { for (i = 0; i < num_trans; i++) {
@@ -243,7 +243,7 @@ static struct RawIndexedImage *indexed_png_to_raw(struct PNGImage *img)
sizeof(*palette) * sizeof(*palette) *
colors_in_new_palette); colors_in_new_palette);
if (!palette) if (!palette)
err(1, "%s: Failed to allocate memory for palette", err("%s: Failed to allocate memory for palette",
__func__); __func__);
} }
@@ -372,7 +372,7 @@ static void rgba_build_palette(struct PNGImage *img,
*/ */
*palette_ptr_ptr = calloc(colors, sizeof(**palette_ptr_ptr)); *palette_ptr_ptr = calloc(colors, sizeof(**palette_ptr_ptr));
if (!*palette_ptr_ptr) if (!*palette_ptr_ptr)
err(1, "%s: Failed to allocate memory for palette", __func__); err("%s: Failed to allocate memory for palette", __func__);
palette = *palette_ptr_ptr; palette = *palette_ptr_ptr;
*num_colors = 0; *num_colors = 0;
@@ -429,7 +429,7 @@ static void update_built_palette(png_color *palette,
} }
if (!color_exists) { if (!color_exists) {
if (*num_colors == colors) { if (*num_colors == colors) {
errx(1, "Too many colors in input PNG file to fit into a %d-bit palette (max %d).", errx("Too many colors in input PNG file to fit into a %d-bit palette (max %d).",
depth, colors); depth, colors);
} }
palette[*num_colors] = *pixel_color; palette[*num_colors] = *pixel_color;
@@ -445,9 +445,9 @@ static int fit_grayscale_palette(png_color *palette, int *num_colors)
int i, shade_index; int i, shade_index;
if (!fitted_palette) if (!fitted_palette)
err(1, "%s: Failed to allocate memory for palette", __func__); err("%s: Failed to allocate memory for palette", __func__);
if (!set_indices) if (!set_indices)
err(1, "%s: Failed to allocate memory for indices", __func__); err("%s: Failed to allocate memory for indices", __func__);
fitted_palette[0].red = 0xFF; fitted_palette[0].red = 0xFF;
fitted_palette[0].green = 0xFF; fitted_palette[0].green = 0xFF;
@@ -508,7 +508,7 @@ static void order_color_palette(png_color *palette, int num_colors)
malloc(sizeof(*palette_with_luminance) * num_colors); malloc(sizeof(*palette_with_luminance) * num_colors);
if (!palette_with_luminance) if (!palette_with_luminance)
err(1, "%s: Failed to allocate memory for palette", __func__); err("%s: Failed to allocate memory for palette", __func__);
for (i = 0; i < num_colors; i++) { for (i = 0; i < num_colors; i++) {
/* /*
@@ -600,7 +600,7 @@ static uint8_t palette_index_of(png_color const *palette,
return i; return i;
} }
} }
errx(1, "The input PNG file contains colors that don't appear in its embedded palette."); errx("The input PNG file contains colors that don't appear in its embedded palette.");
} }
static void read_png(struct PNGImage *img) static void read_png(struct PNGImage *img)
@@ -611,12 +611,12 @@ static void read_png(struct PNGImage *img)
img->data = malloc(sizeof(*img->data) * img->height); img->data = malloc(sizeof(*img->data) * img->height);
if (!img->data) if (!img->data)
err(1, "%s: Failed to allocate memory for image data", err("%s: Failed to allocate memory for image data",
__func__); __func__);
for (y = 0; y < img->height; y++) { for (y = 0; y < img->height; y++) {
img->data[y] = malloc(png_get_rowbytes(img->png, img->info)); img->data[y] = malloc(png_get_rowbytes(img->png, img->info));
if (!img->data[y]) if (!img->data[y])
err(1, "%s: Failed to allocate memory for image data", err("%s: Failed to allocate memory for image data",
__func__); __func__);
} }
@@ -632,7 +632,7 @@ static struct RawIndexedImage *create_raw_image(int width, int height,
raw_image = malloc(sizeof(*raw_image)); raw_image = malloc(sizeof(*raw_image));
if (!raw_image) if (!raw_image)
err(1, "%s: Failed to allocate memory for raw image", err("%s: Failed to allocate memory for raw image",
__func__); __func__);
raw_image->width = width; raw_image->width = width;
@@ -641,18 +641,18 @@ static struct RawIndexedImage *create_raw_image(int width, int height,
raw_image->palette = malloc(sizeof(*raw_image->palette) * num_colors); raw_image->palette = malloc(sizeof(*raw_image->palette) * num_colors);
if (!raw_image->palette) if (!raw_image->palette)
err(1, "%s: Failed to allocate memory for raw image palette", err("%s: Failed to allocate memory for raw image palette",
__func__); __func__);
raw_image->data = malloc(sizeof(*raw_image->data) * height); raw_image->data = malloc(sizeof(*raw_image->data) * height);
if (!raw_image->data) if (!raw_image->data)
err(1, "%s: Failed to allocate memory for raw image data", err("%s: Failed to allocate memory for raw image data",
__func__); __func__);
for (y = 0; y < height; y++) { for (y = 0; y < height; y++) {
raw_image->data[y] = malloc(sizeof(*raw_image->data[y]) raw_image->data[y] = malloc(sizeof(*raw_image->data[y])
* width); * width);
if (!raw_image->data[y]) if (!raw_image->data[y])
err(1, "%s: Failed to allocate memory for raw image data", err("%s: Failed to allocate memory for raw image data",
__func__); __func__);
} }
@@ -665,7 +665,7 @@ static void set_raw_image_palette(struct RawIndexedImage *raw_image,
int i; int i;
if (num_colors > raw_image->num_colors) { if (num_colors > raw_image->num_colors) {
errx(1, "Too many colors in input PNG file's palette to fit into a %d-bit palette (%d in input palette, max %d).", errx("Too many colors in input PNG file's palette to fit into a %d-bit palette (%d in input palette, max %d).",
raw_image->num_colors >> 1, raw_image->num_colors >> 1,
num_colors, raw_image->num_colors); num_colors, raw_image->num_colors);
} }
@@ -740,7 +740,7 @@ static void set_text(const struct PNGImage *img,
text = malloc(sizeof(*text)); text = malloc(sizeof(*text));
if (!text) if (!text)
err(1, "%s: Failed to allocate memory for PNG text", err("%s: Failed to allocate memory for PNG text",
__func__); __func__);
if (png_options->horizontal) { if (png_options->horizontal) {

View File

@@ -12,8 +12,8 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include "error.h"
#include "hashmap.h" #include "hashmap.h"
#include "extern/err.h"
/* /*
* The lower half of the hash is used to index the "master" table, * The lower half of the hash is used to index the "master" table,
@@ -53,7 +53,7 @@ void **hash_AddElement(HashMap map, char const *key, void *element)
struct HashMapEntry *newEntry = malloc(sizeof(*newEntry)); struct HashMapEntry *newEntry = malloc(sizeof(*newEntry));
if (!newEntry) if (!newEntry)
err(1, "%s: Failed to allocate new entry", __func__); err("%s: Failed to allocate new entry", __func__);
newEntry->hash = hashedKey >> HALF_HASH_NB_BITS; newEntry->hash = hashedKey >> HALF_HASH_NB_BITS;
newEntry->key = key; newEntry->key = key;

View File

@@ -19,7 +19,7 @@
#include "link/script.h" #include "link/script.h"
#include "link/output.h" #include "link/output.h"
#include "extern/err.h" #include "error.h"
#include "helpers.h" #include "helpers.h"
struct MemoryLocation { struct MemoryLocation {
@@ -46,13 +46,13 @@ static void initFreeSpace(void)
for (enum SectionType type = 0; type < SECTTYPE_INVALID; type++) { for (enum SectionType type = 0; type < SECTTYPE_INVALID; type++) {
memory[type] = malloc(sizeof(*memory[type]) * nbbanks(type)); memory[type] = malloc(sizeof(*memory[type]) * nbbanks(type));
if (!memory[type]) if (!memory[type])
err(1, "Failed to init free space for region %d", type); err("Failed to init free space for region %d", type);
for (uint32_t bank = 0; bank < nbbanks(type); bank++) { for (uint32_t bank = 0; bank < nbbanks(type); bank++) {
memory[type][bank].next = memory[type][bank].next =
malloc(sizeof(*memory[type][0].next)); malloc(sizeof(*memory[type][0].next));
if (!memory[type][bank].next) if (!memory[type][bank].next)
err(1, "Failed to init free space for region %d bank %" PRIu32, err("Failed to init free space for region %d bank %" PRIu32,
type, bank); type, bank);
memory[type][bank].next->address = startaddr[type]; memory[type][bank].next->address = startaddr[type];
memory[type][bank].next->size = maxsize[type]; memory[type][bank].next->size = maxsize[type];
@@ -301,7 +301,7 @@ static void placeSection(struct Section *section)
struct FreeSpace *newSpace = malloc(sizeof(*newSpace)); struct FreeSpace *newSpace = malloc(sizeof(*newSpace));
if (!newSpace) if (!newSpace)
err(1, "Failed to split new free space"); err("Failed to split new free space");
/* Append the new space after the chosen one */ /* Append the new space after the chosen one */
newSpace->prev = freeSpace; newSpace->prev = freeSpace;
newSpace->next = freeSpace->next; newSpace->next = freeSpace->next;
@@ -352,16 +352,16 @@ static void placeSection(struct Section *section)
/* If a section failed to go to several places, nothing we can report */ /* If a section failed to go to several places, nothing we can report */
if (!section->isBankFixed || !section->isAddressFixed) if (!section->isBankFixed || !section->isAddressFixed)
errx(1, "Unable to place \"%s\" (%s section) %s", errx("Unable to place \"%s\" (%s section) %s",
section->name, typeNames[section->type], where); section->name, typeNames[section->type], where);
/* If the section just can't fit the bank, report that */ /* If the section just can't fit the bank, report that */
else if (section->org + section->size > endaddr(section->type) + 1) else if (section->org + section->size > endaddr(section->type) + 1)
errx(1, "Unable to place \"%s\" (%s section) %s: section runs past end of region ($%04x > $%04x)", errx("Unable to place \"%s\" (%s section) %s: section runs past end of region ($%04x > $%04x)",
section->name, typeNames[section->type], where, section->name, typeNames[section->type], where,
section->org + section->size, endaddr(section->type) + 1); section->org + section->size, endaddr(section->type) + 1);
/* Otherwise there is overlap with another section */ /* Otherwise there is overlap with another section */
else else
errx(1, "Unable to place \"%s\" (%s section) %s: section overlaps with \"%s\"", errx("Unable to place \"%s\" (%s section) %s: section overlaps with \"%s\"",
section->name, typeNames[section->type], where, section->name, typeNames[section->type], where,
out_OverlappingSection(section)->name); out_OverlappingSection(section)->name);
} }
@@ -418,7 +418,7 @@ void assign_AssignSections(void)
/* Generate linked lists of sections to assign */ /* Generate linked lists of sections to assign */
sections = malloc(sizeof(*sections) * nbSectionsToAssign + 1); sections = malloc(sizeof(*sections) * nbSectionsToAssign + 1);
if (!sections) if (!sections)
err(1, "Failed to allocate memory for section assignment"); err("Failed to allocate memory for section assignment");
initFreeSpace(); initFreeSpace();
@@ -447,7 +447,7 @@ void assign_AssignSections(void)
/* Overlaying requires only fully-constrained sections */ /* Overlaying requires only fully-constrained sections */
verbosePrint("Assigning other sections...\n"); verbosePrint("Assigning other sections...\n");
if (overlayFileName) if (overlayFileName)
errx(1, "All sections must be fixed when using an overlay file; %" PRIu64 " %sn't", errx("All sections must be fixed when using an overlay file; %" PRIu64 " %sn't",
nbSectionsToAssign, nbSectionsToAssign == 1 ? "is" : "are"); nbSectionsToAssign, nbSectionsToAssign == 1 ? "is" : "are");
/* Assign all remaining sections by decreasing constraint order */ /* Assign all remaining sections by decreasing constraint order */

View File

@@ -25,8 +25,9 @@
#include "link/patch.h" #include "link/patch.h"
#include "link/output.h" #include "link/output.h"
#include "extern/err.h"
#include "extern/getopt.h" #include "extern/getopt.h"
#include "error.h"
#include "platform.h" #include "platform.h"
#include "version.h" #include "version.h"
@@ -156,7 +157,7 @@ FILE *openFile(char const *fileName, char const *mode)
file = fdopen(1, mode); file = fdopen(1, mode);
if (!file) if (!file)
err(1, "Could not open file \"%s\"", fileName); err("Could not open file \"%s\"", fileName);
return file; return file;
} }

View File

@@ -21,7 +21,7 @@
#include "link/section.h" #include "link/section.h"
#include "link/symbol.h" #include "link/symbol.h"
#include "extern/err.h" #include "error.h"
#include "helpers.h" #include "helpers.h"
#include "linkdefs.h" #include "linkdefs.h"
@@ -50,7 +50,7 @@ static struct Assertion *assertions;
type tmpVal = func(tmpFile); \ type tmpVal = func(tmpFile); \
/* TODO: maybe mark the condition as `unlikely`; how to do that portably? */ \ /* TODO: maybe mark the condition as `unlikely`; how to do that portably? */ \
if (tmpVal == (errval)) { \ if (tmpVal == (errval)) { \
errx(1, __VA_ARGS__, feof(tmpFile) \ errx(__VA_ARGS__, feof(tmpFile) \
? "Unexpected end of file" \ ? "Unexpected end of file" \
: strerror(errno)); \ : strerror(errno)); \
} \ } \
@@ -289,13 +289,13 @@ static void readPatch(FILE *file, struct Patch *patch, char const *fileName, cha
patch->rpnExpression = malloc(sizeof(*patch->rpnExpression) * patch->rpnSize); patch->rpnExpression = malloc(sizeof(*patch->rpnExpression) * patch->rpnSize);
if (!patch->rpnExpression) if (!patch->rpnExpression)
err(1, "%s: Failed to alloc \"%s\"'s patch #%" PRIu32 "'s RPN expression", err("%s: Failed to alloc \"%s\"'s patch #%" PRIu32 "'s RPN expression",
fileName, sectName, i); fileName, sectName, i);
size_t nbElementsRead = fread(patch->rpnExpression, sizeof(*patch->rpnExpression), size_t nbElementsRead = fread(patch->rpnExpression, sizeof(*patch->rpnExpression),
patch->rpnSize, file); patch->rpnSize, file);
if (nbElementsRead != patch->rpnSize) if (nbElementsRead != patch->rpnSize)
errx(1, "%s: Cannot read \"%s\"'s patch #%" PRIu32 "'s RPN expression: %s", errx("%s: Cannot read \"%s\"'s patch #%" PRIu32 "'s RPN expression: %s",
fileName, sectName, i, fileName, sectName, i,
feof(file) ? "Unexpected end of file" : strerror(errno)); feof(file) ? "Unexpected end of file" : strerror(errno));
} }
@@ -327,7 +327,7 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam
tryReadlong(tmp, file, "%s: Cannot read \"%s\"'s' size: %s", tryReadlong(tmp, file, "%s: Cannot read \"%s\"'s' size: %s",
fileName, section->name); fileName, section->name);
if (tmp < 0 || tmp > UINT16_MAX) if (tmp < 0 || tmp > UINT16_MAX)
errx(1, "\"%s\"'s section size (%" PRId32 ") is invalid", errx("\"%s\"'s section size (%" PRId32 ") is invalid",
section->name, tmp); section->name, tmp);
section->size = tmp; section->size = tmp;
section->offset = 0; section->offset = 0;
@@ -373,13 +373,13 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam
uint8_t *data = malloc(sizeof(*data) * section->size + 1); uint8_t *data = malloc(sizeof(*data) * section->size + 1);
if (!data) if (!data)
err(1, "%s: Unable to read \"%s\"'s data", fileName, err("%s: Unable to read \"%s\"'s data", fileName,
section->name); section->name);
if (section->size) { if (section->size) {
size_t nbElementsRead = fread(data, sizeof(*data), size_t nbElementsRead = fread(data, sizeof(*data),
section->size, file); section->size, file);
if (nbElementsRead != section->size) if (nbElementsRead != section->size)
errx(1, "%s: Cannot read \"%s\"'s data: %s", errx("%s: Cannot read \"%s\"'s data: %s",
fileName, section->name, fileName, section->name,
feof(file) ? "Unexpected end of file" feof(file) ? "Unexpected end of file"
: strerror(errno)); : strerror(errno));
@@ -394,7 +394,7 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam
malloc(sizeof(*patches) * section->nbPatches + 1); malloc(sizeof(*patches) * section->nbPatches + 1);
if (!patches) if (!patches)
err(1, "%s: Unable to read \"%s\"'s patches", fileName, section->name); err("%s: Unable to read \"%s\"'s patches", fileName, section->name);
for (uint32_t i = 0; i < section->nbPatches; i++) for (uint32_t i = 0; i < section->nbPatches; i++)
readPatch(file, &patches[i], fileName, section->name, i, fileNodes); readPatch(file, &patches[i], fileName, section->name, i, fileNodes);
section->patches = patches; section->patches = patches;
@@ -462,7 +462,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
FILE *file = strcmp("-", fileName) ? fopen(fileName, "rb") : stdin; FILE *file = strcmp("-", fileName) ? fopen(fileName, "rb") : stdin;
if (!file) if (!file)
err(1, "Could not open file %s", fileName); err("Could not open file %s", fileName);
/* Begin by reading the magic bytes and version number */ /* Begin by reading the magic bytes and version number */
unsigned versionNumber; unsigned versionNumber;
@@ -470,13 +470,13 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
&versionNumber); &versionNumber);
if (matchedElems != 1) if (matchedElems != 1)
errx(1, "\"%s\" is not a RGBDS object file", fileName); errx("\"%s\" is not a RGBDS object file", fileName);
verbosePrint("Reading object file %s, version %u\n", verbosePrint("Reading object file %s, version %u\n",
fileName, versionNumber); fileName, versionNumber);
if (versionNumber != RGBDS_OBJECT_VERSION_NUMBER) if (versionNumber != RGBDS_OBJECT_VERSION_NUMBER)
errx(1, "\"%s\" is an incompatible version %u object file", errx("\"%s\" is an incompatible version %u object file",
fileName, versionNumber); fileName, versionNumber);
uint32_t revNum; uint32_t revNum;
@@ -484,7 +484,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
tryReadlong(revNum, file, "%s: Cannot read revision number: %s", tryReadlong(revNum, file, "%s: Cannot read revision number: %s",
fileName); fileName);
if (revNum != RGBDS_OBJECT_REV) if (revNum != RGBDS_OBJECT_REV)
errx(1, "%s is a revision 0x%04" PRIx32 " object file; only 0x%04x is supported", errx("%s is a revision 0x%04" PRIx32 " object file; only 0x%04x is supported",
fileName, revNum, RGBDS_OBJECT_REV); fileName, revNum, RGBDS_OBJECT_REV);
uint32_t nbSymbols; uint32_t nbSymbols;
@@ -500,7 +500,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
tryReadlong(nodes[fileID].nbNodes, file, "%s: Cannot read number of nodes: %s", fileName); tryReadlong(nodes[fileID].nbNodes, file, "%s: Cannot read number of nodes: %s", fileName);
nodes[fileID].nodes = calloc(nodes[fileID].nbNodes, sizeof(nodes[fileID].nodes[0])); nodes[fileID].nodes = calloc(nodes[fileID].nbNodes, sizeof(nodes[fileID].nodes[0]));
if (!nodes[fileID].nodes) if (!nodes[fileID].nodes)
err(1, "Failed to get memory for %s's nodes", fileName); err("Failed to get memory for %s's nodes", fileName);
verbosePrint("Reading %u nodes...\n", nodes[fileID].nbNodes); verbosePrint("Reading %u nodes...\n", nodes[fileID].nbNodes);
for (uint32_t i = nodes[fileID].nbNodes; i--; ) for (uint32_t i = nodes[fileID].nbNodes; i--; )
readFileStackNode(file, nodes[fileID].nodes, i, fileName); readFileStackNode(file, nodes[fileID].nodes, i, fileName);
@@ -510,12 +510,12 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
malloc(sizeof(*fileSymbols) * nbSymbols + 1); malloc(sizeof(*fileSymbols) * nbSymbols + 1);
if (!fileSymbols) if (!fileSymbols)
err(1, "Failed to get memory for %s's symbols", fileName); err("Failed to get memory for %s's symbols", fileName);
struct SymbolList *symbolList = malloc(sizeof(*symbolList)); struct SymbolList *symbolList = malloc(sizeof(*symbolList));
if (!symbolList) if (!symbolList)
err(1, "Failed to register %s's symbol list", fileName); err("Failed to register %s's symbol list", fileName);
symbolList->symbolList = fileSymbols; symbolList->symbolList = fileSymbols;
symbolList->nbSymbols = nbSymbols; symbolList->nbSymbols = nbSymbols;
symbolList->next = symbolLists; symbolList->next = symbolLists;
@@ -530,7 +530,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
struct Symbol *symbol = malloc(sizeof(*symbol)); struct Symbol *symbol = malloc(sizeof(*symbol));
if (!symbol) if (!symbol)
err(1, "%s: Couldn't create new symbol", fileName); err("%s: Couldn't create new symbol", fileName);
readSymbol(file, symbol, fileName, nodes[fileID].nodes); readSymbol(file, symbol, fileName, nodes[fileID].nodes);
fileSymbols[i] = symbol; fileSymbols[i] = symbol;
@@ -549,7 +549,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
/* Read section */ /* Read section */
fileSections[i] = malloc(sizeof(*fileSections[i])); fileSections[i] = malloc(sizeof(*fileSections[i]));
if (!fileSections[i]) if (!fileSections[i])
err(1, "%s: Couldn't create new section", fileName); err("%s: Couldn't create new section", fileName);
fileSections[i]->nextu = NULL; fileSections[i]->nextu = NULL;
readSection(file, fileSections[i], fileName, nodes[fileID].nodes); readSection(file, fileSections[i], fileName, nodes[fileID].nodes);
@@ -558,7 +558,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
fileSections[i]->symbols = malloc(nbSymPerSect[i] fileSections[i]->symbols = malloc(nbSymPerSect[i]
* sizeof(*fileSections[i]->symbols)); * sizeof(*fileSections[i]->symbols));
if (!fileSections[i]->symbols) if (!fileSections[i]->symbols)
err(1, "%s: Couldn't link to symbols", err("%s: Couldn't link to symbols",
fileName); fileName);
} else { } else {
fileSections[i]->symbols = NULL; fileSections[i]->symbols = NULL;
@@ -609,7 +609,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
struct Assertion *assertion = malloc(sizeof(*assertion)); struct Assertion *assertion = malloc(sizeof(*assertion));
if (!assertion) if (!assertion)
err(1, "%s: Couldn't create new assertion", fileName); err("%s: Couldn't create new assertion", fileName);
readAssertion(file, assertion, fileName, i, nodes[fileID].nodes); readAssertion(file, assertion, fileName, i, nodes[fileID].nodes);
linkPatchToPCSect(&assertion->patch, fileSections); linkPatchToPCSect(&assertion->patch, fileSections);
assertion->fileSymbols = fileSymbols; assertion->fileSymbols = fileSymbols;

View File

@@ -16,10 +16,8 @@
#include "link/section.h" #include "link/section.h"
#include "link/symbol.h" #include "link/symbol.h"
#include "extern/err.h" #include "error.h"
#include "linkdefs.h" #include "linkdefs.h"
#include "platform.h" // MIN_NB_ELMS #include "platform.h" // MIN_NB_ELMS
#define BANK_SIZE 0x4000 #define BANK_SIZE 0x4000
@@ -77,7 +75,7 @@ void out_AddSection(struct Section const *section)
uint32_t minNbBanks = targetBank + 1; uint32_t minNbBanks = targetBank + 1;
if (minNbBanks > maxNbBanks[section->type]) if (minNbBanks > maxNbBanks[section->type])
errx(1, "Section \"%s\" has an invalid bank range (%" PRIu32 " > %" PRIu32 ")", errx("Section \"%s\" has an invalid bank range (%" PRIu32 " > %" PRIu32 ")",
section->name, section->bank, section->name, section->bank,
maxNbBanks[section->type] - 1); maxNbBanks[section->type] - 1);
@@ -92,7 +90,7 @@ void out_AddSection(struct Section const *section)
sections[section->type].nbBanks = minNbBanks; sections[section->type].nbBanks = minNbBanks;
} }
if (!sections[section->type].banks) if (!sections[section->type].banks)
err(1, "Failed to realloc banks"); err("Failed to realloc banks");
struct SortedSection *newSection = malloc(sizeof(*newSection)); struct SortedSection *newSection = malloc(sizeof(*newSection));
struct SortedSection **ptr = section->size struct SortedSection **ptr = section->size
@@ -100,7 +98,7 @@ void out_AddSection(struct Section const *section)
: &sections[section->type].banks[targetBank].zeroLenSections; : &sections[section->type].banks[targetBank].zeroLenSections;
if (!newSection) if (!newSection)
err(1, "Failed to add new section \"%s\"", section->name); err("Failed to add new section \"%s\"", section->name);
newSection->section = section; newSection->section = section;
while (*ptr && (*ptr)->section->org < section->org) while (*ptr && (*ptr)->section->org < section->org)
@@ -145,15 +143,15 @@ static uint32_t checkOverlaySize(void)
fseek(overlayFile, 0, SEEK_SET); fseek(overlayFile, 0, SEEK_SET);
if (overlaySize % BANK_SIZE) if (overlaySize % BANK_SIZE)
errx(1, "Overlay file must have a size multiple of 0x4000"); errx("Overlay file must have a size multiple of 0x4000");
uint32_t nbOverlayBanks = overlaySize / BANK_SIZE; uint32_t nbOverlayBanks = overlaySize / BANK_SIZE;
if (is32kMode && nbOverlayBanks != 2) if (is32kMode && nbOverlayBanks != 2)
errx(1, "Overlay must be exactly 0x8000 bytes large"); errx("Overlay must be exactly 0x8000 bytes large");
if (nbOverlayBanks < 2) if (nbOverlayBanks < 2)
errx(1, "Overlay must be at least 0x8000 bytes large"); errx("Overlay must be at least 0x8000 bytes large");
return nbOverlayBanks; return nbOverlayBanks;
} }
@@ -178,7 +176,7 @@ static void coverOverlayBanks(uint32_t nbOverlayBanks)
realloc(sections[SECTTYPE_ROMX].banks, realloc(sections[SECTTYPE_ROMX].banks,
sizeof(*sections[SECTTYPE_ROMX].banks) * nbUncoveredBanks); sizeof(*sections[SECTTYPE_ROMX].banks) * nbUncoveredBanks);
if (!sections[SECTTYPE_ROMX].banks) if (!sections[SECTTYPE_ROMX].banks)
err(1, "Failed to realloc banks for overlay"); err("Failed to realloc banks for overlay");
for (uint32_t i = sections[SECTTYPE_ROMX].nbBanks; i < nbUncoveredBanks; i++) { for (uint32_t i = sections[SECTTYPE_ROMX].nbBanks; i < nbUncoveredBanks; i++) {
sections[SECTTYPE_ROMX].banks[i].sections = NULL; sections[SECTTYPE_ROMX].banks[i].sections = NULL;
sections[SECTTYPE_ROMX].banks[i].zeroLenSections = NULL; sections[SECTTYPE_ROMX].banks[i].zeroLenSections = NULL;
@@ -317,7 +315,7 @@ static void writeSymBank(struct SortedSections const *bankSections,
struct SortedSymbol *symList = malloc(sizeof(*symList) * nbSymbols); struct SortedSymbol *symList = malloc(sizeof(*symList) * nbSymbols);
if (!symList) if (!symList)
err(1, "Failed to allocate symbol list"); err("Failed to allocate symbol list");
uint32_t idx = 0; uint32_t idx = 0;

View File

@@ -17,11 +17,10 @@
#include "link/section.h" #include "link/section.h"
#include "link/symbol.h" #include "link/symbol.h"
#include "error.h"
#include "linkdefs.h" #include "linkdefs.h"
#include "opmath.h" #include "opmath.h"
#include "extern/err.h"
/* /*
* This is an "empty"-type stack. Apart from the actual values, we also remember * This is an "empty"-type stack. Apart from the actual values, we also remember
* whether the value is a placeholder inserted for error recovery. This allows * whether the value is a placeholder inserted for error recovery. This allows
@@ -43,7 +42,7 @@ static void initRPNStack(void)
stack.values = malloc(sizeof(*stack.values) * stack.capacity); stack.values = malloc(sizeof(*stack.values) * stack.capacity);
stack.errorFlags = malloc(sizeof(*stack.errorFlags) * stack.capacity); stack.errorFlags = malloc(sizeof(*stack.errorFlags) * stack.capacity);
if (!stack.values || !stack.errorFlags) if (!stack.values || !stack.errorFlags)
err(1, "Failed to init RPN stack"); err("Failed to init RPN stack");
} }
static void clearRPNStack(void) static void clearRPNStack(void)
@@ -57,7 +56,7 @@ static void pushRPN(int32_t value, bool comesFromError)
static const size_t increase_factor = 2; static const size_t increase_factor = 2;
if (stack.capacity > SIZE_MAX / increase_factor) if (stack.capacity > SIZE_MAX / increase_factor)
errx(1, "Overflow in RPN stack resize"); errx("Overflow in RPN stack resize");
stack.capacity *= increase_factor; stack.capacity *= increase_factor;
stack.values = stack.values =
@@ -70,7 +69,7 @@ static void pushRPN(int32_t value, bool comesFromError)
* the overflow check above. Hence the stringent check below. * the overflow check above. Hence the stringent check below.
*/ */
if (!stack.values || !stack.errorFlags || !stack.capacity) if (!stack.values || !stack.errorFlags || !stack.capacity)
err(1, "Failed to resize RPN stack"); err("Failed to resize RPN stack");
} }
stack.values[stack.size] = value; stack.values[stack.size] = value;

View File

@@ -17,7 +17,7 @@
#include "link/script.h" #include "link/script.h"
#include "link/section.h" #include "link/section.h"
#include "extern/err.h" #include "error.h"
FILE *linkerScript; FILE *linkerScript;
char *includeFileName; char *includeFileName;
@@ -36,7 +36,7 @@ static uint32_t fileStackIndex;
static void pushFile(char *newFileName) static void pushFile(char *newFileName)
{ {
if (fileStackIndex == UINT32_MAX) if (fileStackIndex == UINT32_MAX)
errx(1, "%s(%" PRIu32 "): INCLUDE recursion limit reached", errx("%s(%" PRIu32 "): INCLUDE recursion limit reached",
linkerScriptName, lineNo); linkerScriptName, lineNo);
if (fileStackIndex == fileStackSize) { if (fileStackIndex == fileStackSize) {
@@ -45,7 +45,7 @@ static void pushFile(char *newFileName)
fileStackSize *= 2; fileStackSize *= 2;
fileStack = realloc(fileStack, sizeof(*fileStack) * fileStackSize); fileStack = realloc(fileStack, sizeof(*fileStack) * fileStackSize);
if (!fileStack) if (!fileStack)
err(1, "%s(%" PRIu32 "): Internal INCLUDE error", err("%s(%" PRIu32 "): Internal INCLUDE error",
linkerScriptName, lineNo); linkerScriptName, lineNo);
} }
@@ -56,7 +56,7 @@ static void pushFile(char *newFileName)
linkerScript = fopen(newFileName, "r"); linkerScript = fopen(newFileName, "r");
if (!linkerScript) if (!linkerScript)
err(1, "%s(%" PRIu32 "): Could not open \"%s\"", err("%s(%" PRIu32 "): Could not open \"%s\"",
linkerScriptName, lineNo, newFileName); linkerScriptName, lineNo, newFileName);
lineNo = 1; lineNo = 1;
linkerScriptName = newFileName; linkerScriptName = newFileName;
@@ -177,7 +177,7 @@ static int nextChar(void)
int curchar = getc(linkerScript); int curchar = getc(linkerScript);
if (curchar == EOF && ferror(linkerScript)) if (curchar == EOF && ferror(linkerScript))
err(1, "%s(%" PRIu32 "): Unexpected error in %s", err("%s(%" PRIu32 "): Unexpected error in %s",
linkerScriptName, lineNo, __func__); linkerScriptName, lineNo, __func__);
return curchar; return curchar;
} }
@@ -226,7 +226,7 @@ static struct LinkerScriptToken *nextToken(void)
do { do {
curchar = nextChar(); curchar = nextChar();
if (curchar == EOF || isNewline(curchar)) { if (curchar == EOF || isNewline(curchar)) {
errx(1, "%s(%" PRIu32 "): Unterminated string", errx("%s(%" PRIu32 "): Unterminated string",
linkerScriptName, lineNo); linkerScriptName, lineNo);
} else if (curchar == '"') { } else if (curchar == '"') {
/* Quotes force a string termination */ /* Quotes force a string termination */
@@ -235,7 +235,7 @@ static struct LinkerScriptToken *nextToken(void)
/* Backslashes are escape sequences */ /* Backslashes are escape sequences */
curchar = nextChar(); curchar = nextChar();
if (curchar == EOF || isNewline(curchar)) if (curchar == EOF || isNewline(curchar))
errx(1, "%s(%" PRIu32 "): Unterminated string", errx("%s(%" PRIu32 "): Unterminated string",
linkerScriptName, lineNo); linkerScriptName, lineNo);
else if (curchar == 'n') else if (curchar == 'n')
curchar = '\n'; curchar = '\n';
@@ -244,7 +244,7 @@ static struct LinkerScriptToken *nextToken(void)
else if (curchar == 't') else if (curchar == 't')
curchar = '\t'; curchar = '\t';
else if (curchar != '\\' && curchar != '"') else if (curchar != '\\' && curchar != '"')
errx(1, "%s(%" PRIu32 "): Illegal character escape", errx("%s(%" PRIu32 "): Illegal character escape",
linkerScriptName, lineNo); linkerScriptName, lineNo);
} }
@@ -252,7 +252,7 @@ static struct LinkerScriptToken *nextToken(void)
capacity *= 2; capacity *= 2;
token.attr.string = realloc(token.attr.string, capacity); token.attr.string = realloc(token.attr.string, capacity);
if (!token.attr.string) if (!token.attr.string)
err(1, "%s: Failed to allocate memory for string", err("%s: Failed to allocate memory for string",
__func__); __func__);
} }
token.attr.string[size++] = curchar; token.attr.string[size++] = curchar;
@@ -268,7 +268,7 @@ static struct LinkerScriptToken *nextToken(void)
capacity *= 2; capacity *= 2;
str = realloc(str, capacity); str = realloc(str, capacity);
if (!str) if (!str)
err(1, "%s: Failed to allocate memory for token", err("%s: Failed to allocate memory for token",
__func__); __func__);
} }
str[size] = toupper(curchar); str[size] = toupper(curchar);
@@ -318,7 +318,7 @@ static struct LinkerScriptToken *nextToken(void)
if (tryParseNumber(str, &token.attr.number)) if (tryParseNumber(str, &token.attr.number))
token.type = TOKEN_NUMBER; token.type = TOKEN_NUMBER;
else else
errx(1, "%s(%" PRIu32 "): Unknown token \"%s\"", errx("%s(%" PRIu32 "): Unknown token \"%s\"",
linkerScriptName, lineNo, str); linkerScriptName, lineNo, str);
} }
@@ -345,7 +345,7 @@ static void processCommand(enum LinkerScriptCommand command, uint16_t arg, uint1
} }
if (arg < *pc) if (arg < *pc)
errx(1, "%s(%" PRIu32 "): `%s` cannot be used to go backwards (currently at $%x)", errx("%s(%" PRIu32 "): `%s` cannot be used to go backwards (currently at $%x)",
linkerScriptName, lineNo, commands[command], *pc); linkerScriptName, lineNo, commands[command], *pc);
*pc = arg; *pc = arg;
} }
@@ -394,11 +394,11 @@ struct SectionPlacement *script_NextSection(void)
if (type != SECTTYPE_INVALID) { if (type != SECTTYPE_INVALID) {
if (curaddr[type][bankID] > endaddr(type) + 1) if (curaddr[type][bankID] > endaddr(type) + 1)
errx(1, "%s(%" PRIu32 "): Sections would extend past the end of %s ($%04" PRIx16 " > $%04" PRIx16 ")", errx("%s(%" PRIu32 "): Sections would extend past the end of %s ($%04" PRIx16 " > $%04" PRIx16 ")",
linkerScriptName, lineNo, typeNames[type], linkerScriptName, lineNo, typeNames[type],
curaddr[type][bankID], endaddr(type)); curaddr[type][bankID], endaddr(type));
if (curaddr[type][bankID] < startaddr[type]) if (curaddr[type][bankID] < startaddr[type])
errx(1, "%s(%" PRIu32 "): PC underflowed ($%04" PRIx16 " < $%04" PRIx16 ")", errx("%s(%" PRIu32 "): PC underflowed ($%04" PRIx16 " < $%04" PRIx16 ")",
linkerScriptName, lineNo, linkerScriptName, lineNo,
curaddr[type][bankID], startaddr[type]); curaddr[type][bankID], startaddr[type]);
} }
@@ -419,7 +419,7 @@ struct SectionPlacement *script_NextSection(void)
break; break;
case TOKEN_NUMBER: case TOKEN_NUMBER:
errx(1, "%s(%" PRIu32 "): stray number \"%" PRIu32 "\"", errx("%s(%" PRIu32 "): stray number \"%" PRIu32 "\"",
linkerScriptName, lineNo, linkerScriptName, lineNo,
token->attr.number); token->attr.number);
@@ -432,13 +432,13 @@ struct SectionPlacement *script_NextSection(void)
parserState = PARSER_LINEEND; parserState = PARSER_LINEEND;
if (type == SECTTYPE_INVALID) if (type == SECTTYPE_INVALID)
errx(1, "%s(%" PRIu32 "): Didn't specify a location before the section", errx("%s(%" PRIu32 "): Didn't specify a location before the section",
linkerScriptName, lineNo); linkerScriptName, lineNo);
section.section = section.section =
sect_GetSection(token->attr.string); sect_GetSection(token->attr.string);
if (!section.section) if (!section.section)
errx(1, "%s(%" PRIu32 "): Unknown section \"%s\"", errx("%s(%" PRIu32 "): Unknown section \"%s\"",
linkerScriptName, lineNo, linkerScriptName, lineNo,
token->attr.string); token->attr.string);
section.org = curaddr[type][bankID]; section.org = curaddr[type][bankID];
@@ -467,10 +467,10 @@ struct SectionPlacement *script_NextSection(void)
if (tokType == TOKEN_COMMAND) { if (tokType == TOKEN_COMMAND) {
if (type == SECTTYPE_INVALID) if (type == SECTTYPE_INVALID)
errx(1, "%s(%" PRIu32 "): Didn't specify a location before the command", errx("%s(%" PRIu32 "): Didn't specify a location before the command",
linkerScriptName, lineNo); linkerScriptName, lineNo);
if (!hasArg) if (!hasArg)
errx(1, "%s(%" PRIu32 "): Command specified without an argument", errx("%s(%" PRIu32 "): Command specified without an argument",
linkerScriptName, lineNo); linkerScriptName, lineNo);
processCommand(attr.command, arg, &curaddr[type][bankID]); processCommand(attr.command, arg, &curaddr[type][bankID]);
@@ -481,16 +481,16 @@ struct SectionPlacement *script_NextSection(void)
* specifying the number is optional. * specifying the number is optional.
*/ */
if (!hasArg && nbbanks(type) != 1) if (!hasArg && nbbanks(type) != 1)
errx(1, "%s(%" PRIu32 "): Didn't specify a bank number", errx("%s(%" PRIu32 "): Didn't specify a bank number",
linkerScriptName, lineNo); linkerScriptName, lineNo);
else if (!hasArg) else if (!hasArg)
arg = bankranges[type][0]; arg = bankranges[type][0];
else if (arg < bankranges[type][0]) else if (arg < bankranges[type][0])
errx(1, "%s(%" PRIu32 "): specified bank number is too low (%" PRIu32 " < %" PRIu32 ")", errx("%s(%" PRIu32 "): specified bank number is too low (%" PRIu32 " < %" PRIu32 ")",
linkerScriptName, lineNo, linkerScriptName, lineNo,
arg, bankranges[type][0]); arg, bankranges[type][0]);
else if (arg > bankranges[type][1]) else if (arg > bankranges[type][1])
errx(1, "%s(%" PRIu32 "): specified bank number is too high (%" PRIu32 " > %" PRIu32 ")", errx("%s(%" PRIu32 "): specified bank number is too high (%" PRIu32 " > %" PRIu32 ")",
linkerScriptName, lineNo, linkerScriptName, lineNo,
arg, bankranges[type][1]); arg, bankranges[type][1]);
bank = arg; bank = arg;
@@ -510,7 +510,7 @@ struct SectionPlacement *script_NextSection(void)
case PARSER_INCLUDE: case PARSER_INCLUDE:
if (token->type != TOKEN_STRING) if (token->type != TOKEN_STRING)
errx(1, "%s(%" PRIu32 "): Expected a file name after INCLUDE", errx("%s(%" PRIu32 "): Expected a file name after INCLUDE",
linkerScriptName, lineNo); linkerScriptName, lineNo);
/* Switch to that file */ /* Switch to that file */
@@ -530,7 +530,7 @@ lineend:
return NULL; return NULL;
parserState = PARSER_LINEEND; parserState = PARSER_LINEEND;
} else if (token->type != TOKEN_NEWLINE) } else if (token->type != TOKEN_NEWLINE)
errx(1, "%s(%" PRIu32 "): Unexpected %s at the end of the line", errx("%s(%" PRIu32 "): Unexpected %s at the end of the line",
linkerScriptName, lineNo, linkerScriptName, lineNo,
tokenTypes[token->type]); tokenTypes[token->type]);
break; break;

View File

@@ -14,8 +14,7 @@
#include "link/main.h" #include "link/main.h"
#include "link/section.h" #include "link/section.h"
#include "extern/err.h" #include "error.h"
#include "hashmap.h" #include "hashmap.h"
HashMap sections; HashMap sections;
@@ -44,12 +43,12 @@ static void checkSectUnionCompat(struct Section *target, struct Section *other)
if (other->isAddressFixed) { if (other->isAddressFixed) {
if (target->isAddressFixed) { if (target->isAddressFixed) {
if (target->org != other->org) if (target->org != other->org)
errx(1, "Section \"%s\" is defined with conflicting addresses $%04" errx("Section \"%s\" is defined with conflicting addresses $%04"
PRIx16 " and $%04" PRIx16, PRIx16 " and $%04" PRIx16,
other->name, target->org, other->org); other->name, target->org, other->org);
} else if (target->isAlignFixed) { } else if (target->isAlignFixed) {
if ((other->org - target->alignOfs) & target->alignMask) if ((other->org - target->alignOfs) & target->alignMask)
errx(1, "Section \"%s\" is defined with conflicting %d-byte alignment (offset %" errx("Section \"%s\" is defined with conflicting %d-byte alignment (offset %"
PRIu16 ") and address $%04" PRIx16, PRIu16 ") and address $%04" PRIx16,
other->name, target->alignMask + 1, other->name, target->alignMask + 1,
target->alignOfs, other->org); target->alignOfs, other->org);
@@ -60,14 +59,14 @@ static void checkSectUnionCompat(struct Section *target, struct Section *other)
} else if (other->isAlignFixed) { } else if (other->isAlignFixed) {
if (target->isAddressFixed) { if (target->isAddressFixed) {
if ((target->org - other->alignOfs) & other->alignMask) if ((target->org - other->alignOfs) & other->alignMask)
errx(1, "Section \"%s\" is defined with conflicting address $%04" errx("Section \"%s\" is defined with conflicting address $%04"
PRIx16 " and %d-byte alignment (offset %" PRIu16 ")", PRIx16 " and %d-byte alignment (offset %" PRIu16 ")",
other->name, target->org, other->name, target->org,
other->alignMask + 1, other->alignOfs); other->alignMask + 1, other->alignOfs);
} else if (target->isAlignFixed } else if (target->isAlignFixed
&& (other->alignMask & target->alignOfs) && (other->alignMask & target->alignOfs)
!= (target->alignMask & other->alignOfs)) { != (target->alignMask & other->alignOfs)) {
errx(1, "Section \"%s\" is defined with conflicting %d-byte alignment (offset %" errx("Section \"%s\" is defined with conflicting %d-byte alignment (offset %"
PRIu16 ") and %d-byte alignment (offset %" PRIu16 ")", PRIu16 ") and %d-byte alignment (offset %" PRIu16 ")",
other->name, target->alignMask + 1, target->alignOfs, other->name, target->alignMask + 1, target->alignOfs,
other->alignMask + 1, other->alignOfs); other->alignMask + 1, other->alignOfs);
@@ -85,13 +84,13 @@ static void checkFragmentCompat(struct Section *target, struct Section *other)
if (target->isAddressFixed) { if (target->isAddressFixed) {
if (target->org != org) if (target->org != org)
errx(1, "Section \"%s\" is defined with conflicting addresses $%04" errx("Section \"%s\" is defined with conflicting addresses $%04"
PRIx16 " and $%04" PRIx16, PRIx16 " and $%04" PRIx16,
other->name, target->org, other->org); other->name, target->org, other->org);
} else if (target->isAlignFixed) { } else if (target->isAlignFixed) {
if ((org - target->alignOfs) & target->alignMask) if ((org - target->alignOfs) & target->alignMask)
errx(1, "Section \"%s\" is defined with conflicting %d-byte alignment (offset %" errx("Section \"%s\" is defined with conflicting %d-byte alignment (offset %"
PRIu16 ") and address $%04" PRIx16, PRIu16 ") and address $%04" PRIx16,
other->name, target->alignMask + 1, other->name, target->alignMask + 1,
target->alignOfs, other->org); target->alignOfs, other->org);
@@ -107,14 +106,14 @@ static void checkFragmentCompat(struct Section *target, struct Section *other)
if (target->isAddressFixed) { if (target->isAddressFixed) {
if ((target->org - ofs) & other->alignMask) if ((target->org - ofs) & other->alignMask)
errx(1, "Section \"%s\" is defined with conflicting address $%04" errx("Section \"%s\" is defined with conflicting address $%04"
PRIx16 " and %d-byte alignment (offset %" PRIu16 ")", PRIx16 " and %d-byte alignment (offset %" PRIu16 ")",
other->name, target->org, other->name, target->org,
other->alignMask + 1, other->alignOfs); other->alignMask + 1, other->alignOfs);
} else if (target->isAlignFixed } else if (target->isAlignFixed
&& (other->alignMask & target->alignOfs) != (target->alignMask & ofs)) { && (other->alignMask & target->alignOfs) != (target->alignMask & ofs)) {
errx(1, "Section \"%s\" is defined with conflicting %d-byte alignment (offset %" errx("Section \"%s\" is defined with conflicting %d-byte alignment (offset %"
PRIu16 ") and %d-byte alignment (offset %" PRIu16 ")", PRIu16 ") and %d-byte alignment (offset %" PRIu16 ")",
other->name, target->alignMask + 1, target->alignOfs, other->name, target->alignMask + 1, target->alignOfs,
other->alignMask + 1, other->alignOfs); other->alignMask + 1, other->alignOfs);
@@ -132,7 +131,7 @@ static void mergeSections(struct Section *target, struct Section *other, enum Se
// Common checks // Common checks
if (target->type != other->type) if (target->type != other->type)
errx(1, "Section \"%s\" is defined with conflicting types %s and %s", errx("Section \"%s\" is defined with conflicting types %s and %s",
other->name, typeNames[target->type], typeNames[other->type]); other->name, typeNames[target->type], typeNames[other->type]);
if (other->isBankFixed) { if (other->isBankFixed) {
@@ -140,7 +139,7 @@ static void mergeSections(struct Section *target, struct Section *other, enum Se
target->isBankFixed = true; target->isBankFixed = true;
target->bank = other->bank; target->bank = other->bank;
} else if (target->bank != other->bank) { } else if (target->bank != other->bank) {
errx(1, "Section \"%s\" is defined with conflicting banks %" PRIu32 " and %" errx("Section \"%s\" is defined with conflicting banks %" PRIu32 " and %"
PRIu32, other->name, target->bank, other->bank); PRIu32, other->name, target->bank, other->bank);
} }
} }
@@ -161,7 +160,7 @@ static void mergeSections(struct Section *target, struct Section *other, enum Se
target->data = realloc(target->data, target->data = realloc(target->data,
sizeof(*target->data) * target->size + 1); sizeof(*target->data) * target->size + 1);
if (!target->data) if (!target->data)
errx(1, "Failed to concatenate \"%s\"'s fragments", target->name); errx("Failed to concatenate \"%s\"'s fragments", target->name);
memcpy(target->data + target->size - other->size, other->data, other->size); memcpy(target->data + target->size - other->size, other->data, other->size);
/* Adjust patches' PC offsets */ /* Adjust patches' PC offsets */
for (uint32_t patchID = 0; patchID < other->nbPatches; patchID++) for (uint32_t patchID = 0; patchID < other->nbPatches; patchID++)
@@ -184,14 +183,14 @@ void sect_AddSection(struct Section *section)
if (other) { if (other) {
if (section->modifier != other->modifier) if (section->modifier != other->modifier)
errx(1, "Section \"%s\" defined as %s and %s", section->name, errx("Section \"%s\" defined as %s and %s", section->name,
sectionModNames[section->modifier], sectionModNames[other->modifier]); sectionModNames[section->modifier], sectionModNames[other->modifier]);
else if (section->modifier == SECTION_NORMAL) else if (section->modifier == SECTION_NORMAL)
errx(1, "Section name \"%s\" is already in use", section->name); errx("Section name \"%s\" is already in use", section->name);
else else
mergeSections(other, section, section->modifier); mergeSections(other, section, section->modifier);
} else if (section->modifier == SECTION_UNION && sect_HasData(section->type)) { } else if (section->modifier == SECTION_UNION && sect_HasData(section->type)) {
errx(1, "Section \"%s\" is of type %s, which cannot be unionized", errx("Section \"%s\" is of type %s, which cannot be unionized",
section->name, typeNames[section->type]); section->name, typeNames[section->type]);
} else { } else {
/* If not, add it */ /* If not, add it */
@@ -302,5 +301,5 @@ void sect_DoSanityChecks(void)
{ {
sect_ForEach(doSanityChecks, NULL); sect_ForEach(doSanityChecks, NULL);
if (sanityChecksFailed) if (sanityChecksFailed)
errx(1, "Sanity checks failed"); errx("Sanity checks failed");
} }

View File

@@ -14,7 +14,7 @@
#include "link/symbol.h" #include "link/symbol.h"
#include "link/main.h" #include "link/main.h"
#include "extern/err.h" #include "error.h"
#include "hashmap.h" #include "hashmap.h"
HashMap symbols; HashMap symbols;