/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "utils.h" #include #include #include #include #include #include #include #include #include #include #include void *xmalloc(size_t size) { void *p = malloc(size); if (p == NULL) { fprintf(stderr, "Failed to allocate memory\n"); abort(); } return p; } char *to_chars(const CHAR16 uchars[], size_t size) { char *chars = xmalloc(size / 2 + 1); const CHAR16 *from = uchars; char *to = chars; while (*from != 0) { CHAR16 uc = *from++; if (uc < CHAR_MAX) *to++ = uc; else *to++ = '?'; } // In case there was no terminating NUL. if (to != chars && to[-1] != '\0') *to = '\0'; return chars; } CHAR16 *to_uchars(const char chars[], size_t *size) { *size = (strlen(chars) + 1) * 2; CHAR16 *uchars = xmalloc(*size); const char *from = chars; CHAR16 *to = uchars; while (*from != '\0') *to++ = *from++; *to = 0; return uchars; } bool str_eq(const char lhs[], const char rhs[]) { return strcmp(lhs, rhs) == 0; } struct mem_range_t map_file(const char path[], bool rw) { struct mem_range_t range = {0}; int open_flags = rw ? O_RDWR : O_RDONLY; int mmap_flags = rw ? PROT_READ | PROT_WRITE : PROT_READ; int fd = open(path, open_flags); if (fd == -1) { fprintf(stderr, "Failed to open(): %s\n", strerror(errno)); return range; } struct stat stat_buf; if (fstat(fd, &stat_buf) != 0) { (void)close(fd); fprintf(stderr, "Failed to fstat(): %s\n", strerror(errno)); return range; } if (stat_buf.st_size == 0) { (void)close(fd); fprintf(stderr, "Can't map an empty \"%s\" file\n", path); return range; } uint8_t *mem = mmap(/*addr=*/NULL, stat_buf.st_size, mmap_flags, MAP_SHARED | MAP_POPULATE, fd, /*offset=*/0); (void)close(fd); if (mem == MAP_FAILED) { fprintf(stderr, "Failed to mmap(): %s\n", strerror(errno)); return range; } range.start = mem; range.length = stat_buf.st_size; return range; } void unmap_file(struct mem_range_t store) { if (munmap(store.start, store.length) != 0) fprintf(stderr, "Failed to munmap(): %s\n", strerror(errno)); }