lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260112142009.1006236-34-herve.codina@bootlin.com>
Date: Mon, 12 Jan 2026 15:19:23 +0100
From: Herve Codina <herve.codina@...tlin.com>
To: David Gibson <david@...son.dropbear.id.au>,
	Rob Herring <robh@...nel.org>,
	Krzysztof Kozlowski <krzk@...nel.org>,
	Conor Dooley <conor+dt@...nel.org>
Cc: Ayush Singh <ayush@...gleboard.org>,
	Geert Uytterhoeven <geert@...ux-m68k.org>,
	devicetree-compiler@...r.kernel.org,
	devicetree@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	devicetree-spec@...r.kernel.org,
	Hui Pu <hui.pu@...ealthcare.com>,
	Ian Ray <ian.ray@...ealthcare.com>,
	Luca Ceresoli <luca.ceresoli@...tlin.com>,
	Thomas Petazzoni <thomas.petazzoni@...tlin.com>,
	Herve Codina <herve.codina@...tlin.com>
Subject: [RFC PATCH 33/77] dtc: Add support for /import/ dts keyword parsing

The /import/ dts keyword is the keyword used to define an imported
symbol used by an addon device-tree.

An imported symbol is not related to a specific node and it is global to
a whole addon. It can be present after the header definition (and the
possible memreserves definition) and before the devicetree nodes
definition.

If several symbols are imported, several /import/ keyword are present.

The syntax used is the following:
  /import/ name: compatible;

with:
  name: The name of the imported symbol
  compatible: a string indicating the kind of symbol is expected. This
              compatible string can be used when the addon is applied in
              order to help the symbol resolution.

For instance:
  /import/ foo: "bar, foo";

  The foo symbol is expected by the addon and should be "bar, foo"
  compatible.

  The addon uses this symbol (i.e. it references it) but it doesn't
  define the symbol itself.

  From the addon point of view, foo is an unresolved symbol and it will
  be resolved when the addon is applied.

Add support for /import/ dts keyword.

Signed-off-by: Herve Codina <herve.codina@...tlin.com>
---
 dtc-lexer.l  |  6 ++++++
 dtc-parser.y | 45 +++++++++++++++++++++++++++++++++++++++++++++
 dtc.h        |  3 +++
 livetree.c   | 13 +++++++++++++
 4 files changed, 67 insertions(+)

diff --git a/dtc-lexer.l b/dtc-lexer.l
index 90fe70e..cb616f9 100644
--- a/dtc-lexer.l
+++ b/dtc-lexer.l
@@ -155,6 +155,12 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
 			return DT_EXPORT;
 		}
 
+<*>"/import/" 	{
+			DPRINT("Keyword: /import/\n");
+			BEGIN_DEFAULT();
+			return DT_IMPORT;
+		}
+
 <*>{LABEL}:	{
 			DPRINT("Label: %s\n", yytext);
 			yylval.labelref = xstrdup(yytext);
diff --git a/dtc-parser.y b/dtc-parser.y
index 48c40e8..61ebde2 100644
--- a/dtc-parser.y
+++ b/dtc-parser.y
@@ -50,6 +50,7 @@ static bool is_ref_relative(const char *ref)
 	struct node *nodelist;
 	struct symbol *symbol;
 	struct symbol *exportlist;
+	struct symbol *importlist;
 	struct reserve_info *re;
 	uint64_t integer;
 	unsigned int flags;
@@ -65,6 +66,7 @@ static bool is_ref_relative(const char *ref)
 %token DT_DEL_NODE
 %token DT_OMIT_NO_REF
 %token DT_EXPORT
+%token DT_IMPORT
 %token <propnodename> DT_PROPNODENAME
 %token <integer> DT_LITERAL
 %token <integer> DT_CHAR_LITERAL
@@ -87,6 +89,8 @@ static bool is_ref_relative(const char *ref)
 %type <proplist> proplist
 %type <symbol> exportdef
 %type <exportlist> exportlist
+%type <symbol> importdef
+%type <exportlist> importlist
 %type <labelref> dt_ref
 
 %type <node> devicetree
@@ -118,6 +122,17 @@ sourcefile:
 			                              guess_boot_cpuid($3),
 						      NULL);
 		}
+	|  headers memreserves importlist devicetree
+		{
+			/*
+			 * importlist is created with chain_symbol() and so it
+			 * is created in reverse order. Reverse it now to have
+			 * it in correct order
+			 */
+			parser_output = build_dt_info($1, $2, $4,
+			                              $4 ? guess_boot_cpuid($4) : 0,
+			                              reverse_symbol($3));
+		}
 	;
 
 header:
@@ -171,6 +186,36 @@ memreserve:
 		}
 	;
 
+importlist:
+	  importdef
+		{
+			$$ = chain_symbol($1, NULL);
+		}
+	| importlist importdef
+		{
+			$$ = chain_symbol($2, $1);
+		}
+	| importlist memreserve
+		{
+			ERROR(&@2, "Mem reserve must precede imports");
+			YYERROR;
+		}
+	;
+
+importdef:
+	DT_IMPORT DT_LABEL DT_STRING ';'
+		{
+			struct data d = $3;
+
+			if (!(last_header_flags & DTSF_ADDON))
+				ERROR(&@2, "Import symbols supported only in addon");
+
+			$$ = build_importsym($2, d.val, &@$);
+			free($2);
+			data_free($3);
+		}
+	;
+
 dt_ref: DT_LABEL_REF | DT_PATH_REF;
 
 devicetree:
diff --git a/dtc.h b/dtc.h
index 796ed51..4ebe576 100644
--- a/dtc.h
+++ b/dtc.h
@@ -207,6 +207,7 @@ struct label {
 struct symbol {
 	bool is_local;
 	char *name;
+	char *compatible;
 	char *ref;
 	cell_t phandle;
 	char *fullpath;
@@ -287,6 +288,8 @@ struct property *reverse_properties(struct property *first);
 
 struct symbol *build_exportsym(const char *name, const char *ref, cell_t phandle,
 			       struct srcpos *srcpos);
+struct symbol *build_importsym(const char *name, const char *compatible,
+			       struct srcpos *srcpos);
 struct symbol *chain_symbol(struct symbol *first, struct symbol *list);
 struct symbol *reverse_symbol(struct symbol *list);
 void add_symbol(struct symbol **list, struct symbol *new);
diff --git a/livetree.c b/livetree.c
index 4ec9609..dac5359 100644
--- a/livetree.c
+++ b/livetree.c
@@ -51,6 +51,19 @@ struct symbol *build_exportsym(const char *name, const char *ref, cell_t phandle
 	return new;
 }
 
+struct symbol *build_importsym(const char *name, const char *compatible, struct srcpos *srcpos)
+{
+	struct symbol *new = xmalloc(sizeof(*new));
+
+	memset(new, 0, sizeof(*new));
+
+	new->name = xstrdup(name);
+	new->compatible = xstrdup(compatible);
+	new->srcpos = srcpos_copy(srcpos);
+
+	return new;
+}
+
 struct symbol *chain_symbol(struct symbol *first, struct symbol *list)
 {
 	assert(first->next == NULL);
-- 
2.52.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ