include/list.h: Add support for GCC9+

When getting the address of a structure's member that is not on
offset 0, GCC9+ assumes that the address can never be NULL. However
the code relied on the fact that it can be NULL by letting the pointer
intentionally overflow.

Manually calculate the address using uintptr_t. This allows to
gracefully terminate the list_for_each MACRO instead of crashing at the
end of the list.

Tested on qemu-system-arm:
coreboot no longer crashed in the devicetree parser and is able to boot
Linux 5.5.

Change-Id: I0d569b59a23d1269f8575fcbbe92a5a6816aa1f7
Signed-off-by: Patrick Rudolph <siro@das-labor.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/44573
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
Patrick Rudolph 2020-08-19 08:40:31 +02:00
parent e8e0418d98
commit 88991caf00
1 changed files with 4 additions and 4 deletions

View File

@ -16,10 +16,10 @@ void list_insert_after(struct list_node *node, struct list_node *after);
// Insert list_node node before list_node before in a doubly linked list. // Insert list_node node before list_node before in a doubly linked list.
void list_insert_before(struct list_node *node, struct list_node *before); void list_insert_before(struct list_node *node, struct list_node *before);
#define list_for_each(ptr, head, member) \ #define list_for_each(ptr, head, member) \
for ((ptr) = container_of((head).next, typeof(*(ptr)), member); \ for ((ptr) = container_of((head).next, typeof(*(ptr)), member); \
&((ptr)->member); \ (uintptr_t)ptr + (uintptr_t)offsetof(typeof(*(ptr)), member); \
(ptr) = container_of((ptr)->member.next, \ (ptr) = container_of((ptr)->member.next, \
typeof(*(ptr)), member)) typeof(*(ptr)), member))
#endif /* __LIST_H__ */ #endif /* __LIST_H__ */