fdtdec: what is the purpose of the compat_names array

Rasmus Villemoes rasmus.villemoes at prevas.dk
Tue Mar 17 01:10:22 CET 2020


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


More information about the U-Boot mailing list