areas.c (2415B)
1// This is free and unencumbered software released into the public domain. 2// For more information, please refer to <https://unlicense.org> 3// bbbbbr 2020 4 5#include <stdio.h> 6#include <string.h> 7#include <stdlib.h> 8// #include <unistd.h> 9#include <stdbool.h> 10#include <stdint.h> 11 12#include "areas.h" 13 14#define AREA_GROW_SIZE 500 15 16area_item * arealist; 17uint32_t arealist_size; 18uint32_t arealist_count; 19 20 21uint32_t min(uint32_t a, uint32_t b) { 22 return (a < b) ? a : b; 23} 24 25uint32_t max(uint32_t a, uint32_t b) { 26 return (a > b) ? a : b; 27} 28 29 30// Returns size of overlap between two address ranges, 31// if zero then no overlap 32static uint32_t addrs_check_overlap(uint32_t a_start, uint32_t a_end, uint32_t b_start, uint32_t b_end) { 33 34 uint32_t size_used; 35 36 // Check whether the address range *doesn't* overlap 37 if ((b_start > a_end) || (b_end < a_start)) { 38 size_used = 0; // no overlap, size = 0 39 } else { 40 size_used = min(b_end, a_end) - max(b_start, a_start) + 1; // Calculate minimum overlap 41 42 printf("WARNING: Multiple write of %5d bytes at 0x%x -> 0x%x (%x -> %x, %x -> %x)\n", 43 size_used, max(b_start, a_start), min(b_end, a_end), 44 a_start, a_end, b_start, b_end); 45 } 46 return size_used; 47} 48 49 50void arealist_additem(area_item * p_area) { 51 52 arealist_count++; 53 // Grow array if needed 54 if (arealist_count == arealist_size) { 55 arealist_size += AREA_GROW_SIZE; 56 arealist = (area_item *)realloc(arealist, arealist_size * sizeof(area_item)); 57 } 58 59 arealist[arealist_count-1] = *p_area; 60} 61 62 63void areas_init(void) { 64 arealist_count = 0; 65 arealist_size = AREA_GROW_SIZE; 66 arealist = (area_item *)malloc(arealist_size * sizeof(area_item)); 67} 68 69 70void areas_cleanup(void) { 71 if (arealist) 72 free (arealist); 73} 74 75 76int areas_add(area_item * p_area) { 77 78 uint32_t c; 79 uint32_t size_used; 80 int ret = true; // default to success 81 82 // Check for overlap with existing areas 83 for (c = 0; c < arealist_count; c++) { 84 85 size_used = addrs_check_overlap(arealist[c].start, arealist[c].end, 86 p_area->start, p_area->end); 87 // Signal failure on any overlap 88 // (Keep looping to display all warnings though) 89 if (size_used > 0) 90 ret = false; 91 } 92 93 // Now add the area 94 arealist_additem(p_area); 95 96 return ret; 97}