target: fix unaligned return of target_get_working_area_avail()
authorTomas Vanek <vanekt@fbl.cz>
Sat, 30 Jul 2022 10:15:43 +0000 (12:15 +0200)
committerTomas Vanek <vanekt@fbl.cz>
Mon, 8 Aug 2022 20:51:52 +0000 (20:51 +0000)
The working area allocation routines use 4 byte word alignment.
In the corner case the size of the working area is not aligned,
target_alloc_working_area() of size = target_get_working_area_avail()
will fail because the size gets aligned up and does not fit to the area
which size is aligned down.

Align down the result of target_get_working_area_avail() to cope with that
corner case.

While on it use fancy ALIGN_... macros instead of bitwise and operator.

Change-Id: Ia2a1e861c401c2c78fe6323379a3776fb4f47b06
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: https://review.openocd.org/c/openocd/+/7096
Tested-by: jenkins
Reviewed-by: Erhan Kurubas <erhan.kurubas@espressif.com>
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
src/target/target.c

index 78073f68070cb37e923bfb5d794ec2eb17c04a88..553400df68297dff7eb6721092865d49c0191b19 100644 (file)
@@ -2071,7 +2071,7 @@ int target_alloc_working_area_try(struct target *target, uint32_t size, struct w
                struct working_area *new_wa = malloc(sizeof(*new_wa));
                if (new_wa) {
                        new_wa->next = NULL;
-                       new_wa->size = target->working_area_size & ~3UL; /* 4-byte align */
+                       new_wa->size = ALIGN_DOWN(target->working_area_size, 4); /* 4-byte align */
                        new_wa->address = target->working_area;
                        new_wa->backup = NULL;
                        new_wa->user = NULL;
@@ -2082,8 +2082,7 @@ int target_alloc_working_area_try(struct target *target, uint32_t size, struct w
        }
 
        /* only allocate multiples of 4 byte */
-       if (size % 4)
-               size = (size + 3) & (~3UL);
+       size = ALIGN_UP(size, 4);
 
        struct working_area *c = target->working_areas;
 
@@ -2237,7 +2236,7 @@ uint32_t target_get_working_area_avail(struct target *target)
        uint32_t max_size = 0;
 
        if (!c)
-               return target->working_area_size;
+               return ALIGN_DOWN(target->working_area_size, 4);
 
        while (c) {
                if (c->free && max_size < c->size)