fdtdec: what is the purpose of the compat_names array

I was running strings(1) on my SPL to see if there was something obvious I could find and compile away. To my surprise, I found strings such as
altr,socfpga-dw-mshc altr,socfpga-fpga2hps-bridge altr,socfpga-fpga2sdram0-bridge altr,socfpga-fpga2sdram1-bridge
which are of course quickly tracked to the compat_names array in lib/fdtdec.c. I don't understand why that exists? It doesn't seem to scale very well that every random driver would put some compatible strings in there and use an indirection via an enum. Obviously, not every driver does that, so I must be missing something.
Take the fpga2sdram* for example. They are only used by arch/arm/mach-socfpga/reset_manager_arria10.c, and it seems that the "int compat_id" might as well be a "const char *compat" directly, with the fdtdec_next_compatible() call changed to fdt_node_offset_by_compatible().
Now, in my case [and probably also for everyone else that don't use one of those few drivers that use a "enum fdt_compat_id"] all the functions that actually refer to the compat_names[] array get garbage collected away by the linker. Unfortunately, due the .fixup section on powerpc, the same cannot be said of the compat_names[] array or the pointed-to string literals - otherwise I wouldn't have stumbled on this. A small translation unit that shows the problem/phenomenon is this:
=== foo.c === #include <common.h> static const char *const foo_strings[] = { "this won't be garbage collected", "neither will this be garbage collected", };
int foo_func(int x) { printf("the function foo_func will be gc'ed\n"); printf("so will these format strings\n"); printf("%s\n", foo_strings[x]); return 0; } === foo.c ===
Adding foo.o to the link (u-boot or SPL, doesn't matter), inspecting the .map file and/or running strings(1) or nm(1) on the binary shows that despite all public symbols provided by foo.o being gc'ed, the final binary is still bloated by the foo_strings array and the literals.
Does it make sense to try to convert the enum fdt_compat_id users to use the compatible strings directly with the fdt_* functions?
Rasmus

Hi Rasmus,
On Mon, 16 Mar 2020 at 18:10, Rasmus Villemoes rasmus.villemoes@prevas.dk wrote:
I was running strings(1) on my SPL to see if there was something obvious I could find and compile away. To my surprise, I found strings such as
altr,socfpga-dw-mshc altr,socfpga-fpga2hps-bridge altr,socfpga-fpga2sdram0-bridge altr,socfpga-fpga2sdram1-bridge
which are of course quickly tracked to the compat_names array in lib/fdtdec.c. I don't understand why that exists? It doesn't seem to scale very well that every random driver would put some compatible strings in there and use an indirection via an enum. Obviously, not every driver does that, so I must be missing something.
Did you see the comment at the top of the array? If there is something missing there, we can do an update.
Take the fpga2sdram* for example. They are only used by arch/arm/mach-socfpga/reset_manager_arria10.c, and it seems that the "int compat_id" might as well be a "const char *compat" directly, with the fdtdec_next_compatible() call changed to fdt_node_offset_by_compatible().
Now, in my case [and probably also for everyone else that don't use one of those few drivers that use a "enum fdt_compat_id"] all the functions that actually refer to the compat_names[] array get garbage collected away by the linker. Unfortunately, due the .fixup section on powerpc, the same cannot be said of the compat_names[] array or the pointed-to string literals - otherwise I wouldn't have stumbled on this. A small translation unit that shows the problem/phenomenon is this:
=== foo.c === #include <common.h> static const char *const foo_strings[] = { "this won't be garbage collected", "neither will this be garbage collected", };
int foo_func(int x) { printf("the function foo_func will be gc'ed\n"); printf("so will these format strings\n"); printf("%s\n", foo_strings[x]); return 0; } === foo.c ===
Adding foo.o to the link (u-boot or SPL, doesn't matter), inspecting the .map file and/or running strings(1) or nm(1) on the binary shows that despite all public symbols provided by foo.o being gc'ed, the final binary is still bloated by the foo_strings array and the literals.
Does it make sense to try to convert the enum fdt_compat_id users to use the compatible strings directly with the fdt_* functions?
No, we should instead convert these drivers to use driver model.
Regards, Simon
participants (2)
-
Rasmus Villemoes
-
Simon Glass