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: <aWiQ05zlfPfcIaZk@zatzit>
Date: Thu, 15 Jan 2026 18:01:39 +1100
From: David Gibson <david@...son.dropbear.id.au>
To: Herve Codina <herve.codina@...tlin.com>
Cc: Rob Herring <robh@...nel.org>, Krzysztof Kozlowski <krzk@...nel.org>,
	Conor Dooley <conor+dt@...nel.org>,
	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>
Subject: Re: [RFC PATCH 64/77] dtc: Add support for references by path
 involving orphan nodes

On Mon, Jan 12, 2026 at 03:19:54PM +0100, Herve Codina wrote:
> Referencing a sub-node from an orphan node using a path is needed.
> 
> Indeed, using the following snippet:
> --- 8< ---
> /addon/;
> 
> &node1 {
> 	subnode {
> 		foo-phandle = <&foo_label>;
> 	};
> };
> 
> &node2 {
> 	foo_label: foo {
> 		prop = <1>;
> 	};
> };
> --- 8< ---
> 
> Even if node2 is an orphan node, foo is a local node. foo-phandle
> references the foo node using a label.

Another option would be to eliminate the idea of local references, and
require a symbol be attached to things that you want to reference by
label.


> 
> Once converted to a dtb, the label is lost. Only the phandle of the foo
> node is used in the foo-phandle property and this property is marked
> FDT_REF_LOCAL.
> 
> Converting back this dtb to a dts, the marked local phandle should be
> translated to a path to the related local node.
> 
> The issue is that this local node is not in a root device tree. We need
> to identify the orphan node the foo node belongs to.
> 
> We cannot use a path starting by '/'. This kind of path identify node in
> the root tree.
> 
> This new syntax allows to identify the orphan node in a path:
>   $<orphan_name>/<path>
> 
> This leads to a reference by path in the form &{$<orphan_name>/<path>}.
> 
> Using the previous example, those both phandles points to the same node:
>   foo-phandle1 = <&foo_label>;    /* Reference by label */
>   foo-phandle2 = <&{$node2/foo}>; /* Reference by path */
> 
> When the dtb is converted back to a dts, the marked local phandle
> involving subnode available from orphan nodes can be translated to a
> reference by path thanks to the new syntax.
> 
> Add support for this &{$<orphan_name>/<path>} syntax to reference by
> path a local node from an orphan node.
> 
> Signed-off-by: Herve Codina <herve.codina@...tlin.com>
> ---
>  dtc-lexer.l  |  7 +++++++
>  dtc-parser.y | 19 +++++++++++++++++++
>  dtc.c        | 22 ++++++++++++++++++++--
>  livetree.c   | 14 +++++++++++++-
>  treesource.c |  3 ++-
>  5 files changed, 61 insertions(+), 4 deletions(-)
> 
> diff --git a/dtc-lexer.l b/dtc-lexer.l
> index cb616f9..540bfdf 100644
> --- a/dtc-lexer.l
> +++ b/dtc-lexer.l
> @@ -239,6 +239,13 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
>  			return DT_PATH_REF;
>  		}
>  
> +<*>"&{\$"{LABEL}([/]{PATHCHAR}*)?\}  {	/* orphan path reference */
> +			yytext[yyleng-1] = '\0';
> +			DPRINT("Ref orphan path: %s\n", yytext+1);
> +			yylval.labelref = xstrdup(yytext+2);
> +			return DT_ORPHAN_PATH_REF;
> +		}
> +
>  <BYTESTRING>[0-9a-fA-F]{2} {
>  			yylval.byte = strtol(yytext, NULL, 16);
>  			DPRINT("Byte: %02x\n", (int)yylval.byte);
> diff --git a/dtc-parser.y b/dtc-parser.y
> index 7f8c294..9d619cd 100644
> --- a/dtc-parser.y
> +++ b/dtc-parser.y
> @@ -111,6 +111,7 @@ static struct node *parser_get_node_by_ref(struct node *dt, struct node *orphanl
>  %token <labelref> DT_LABEL
>  %token <labelref> DT_LABEL_REF
>  %token <labelref> DT_PATH_REF
> +%token <labelref> DT_ORPHAN_PATH_REF
>  %token DT_INCBIN
>  
>  %type <data> propdata
> @@ -589,6 +590,24 @@ arrayprefix:
>  				ERROR(&@2, "References are only allowed in "
>  					    "arrays with 32-bit elements.");
>  
> +			$$.data = data_append_integer($1.data, val, $1.bits);
> +		}
> +	| arrayprefix DT_ORPHAN_PATH_REF
> +		{
> +			uint64_t val = ~0ULL >> (64 - $1.bits);
> +
> +			if ($1.bits == 32) {
> +				if (!(last_header_flags & DTSF_ADDON))
> +					ERROR(&@2, "Orphan path reference %s supported only in addon", $2);
> +
> +				$1.data = data_add_marker($1.data,
> +							  REF_PHANDLE,
> +							  $2);
> +			} else {
> +				ERROR(&@2, "References are only allowed in "
> +					    "arrays with 32-bit elements.");
> +			}
> +
>  			$$.data = data_append_integer($1.data, val, $1.bits);
>  		}
>  	| arrayprefix DT_LABEL
> diff --git a/dtc.c b/dtc.c
> index 63725bf..72d85e4 100644
> --- a/dtc.c
> +++ b/dtc.c
> @@ -48,13 +48,31 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
>  static void dti_fill_fullpaths(struct dt_info *dti)
>  {
>  	struct node *orphan;
> +	struct node *child;
>  
>  	/* Fill fullpaths for the root node */
>  	if (dti->dt)
>  		fill_fullpaths(dti->dt, "");
>  
> -	for_each_orphan(dti->orphanlist, orphan)
> -		fill_fullpaths(orphan, "__orphan__/");
> +	/* Fill fullpaths for orphan nodes */
> +	for_each_orphan(dti->orphanlist, orphan) {
> +		if (orphan->name[0] == '\0')
> +			die("orphan node has an empty name\n");
> +
> +		/*
> +		 * An orphan node name is set with its reference.
> +		 * Its name is in the form "&xxxxxx".
> +		 * For its full path, we use "$xxxxx" to make a clear
> +		 * distinction between a reference (&xxxx) where a resolution
> +		 * could be involved vs a "simple" path where we just need to
> +		 * identified the orphan ($xxxx).
> +		 */
> +		xasprintf(&orphan->fullpath, "$%s", orphan->name + 1);
> +		orphan->basenamelen = strlen(orphan->name);
> +
> +		for_each_child(orphan, child)
> +			fill_fullpaths(child, orphan->fullpath);
> +	}
>  }
>  
>  /* Usage related data. */
> diff --git a/livetree.c b/livetree.c
> index 59b912d..263da1f 100644
> --- a/livetree.c
> +++ b/livetree.c
> @@ -804,7 +804,19 @@ static struct node *get_node_by_ref(struct node *tree, const char *ref)
>  			path = slash + 1;
>  		}
>  
> -		target = get_node_by_label(tree, label);
> +		if (label[0] == '$' && tree->name[0] == '&') {
> +			/*
> +			 * We search for an orphan and the given tree is an
> +			 * orphan. Use the given tree only if it matches the
> +			 * expected orphan.
> +			 */
> +			if (streq(label + 1, tree->name + 1))
> +				target = tree;
> +			else
> +				target = NULL;
> +		} else {
> +			target = get_node_by_label(tree, label);
> +		}
>  
>  		free(buf);
>  
> diff --git a/treesource.c b/treesource.c
> index 71dbd5f..44de0db 100644
> --- a/treesource.c
> +++ b/treesource.c
> @@ -278,7 +278,8 @@ static void write_propval(FILE *f, struct property *prop)
>  					break;
>  
>  			if (m_phandle) {
> -				if (m_phandle->ref[0] == '/')
> +				if (m_phandle->ref[0] == '/' /* Root node */ ||
> +				    m_phandle->ref[0] == '$' /* Orphan node */)
>  					fprintf(f, "&{%s}", m_phandle->ref);
>  				else
>  					fprintf(f, "&%s", m_phandle->ref);
> -- 
> 2.52.0
> 
> 

-- 
David Gibson (he or they)	| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you, not the other way
				| around.
http://www.ozlabs.org/~dgibson

Download attachment "signature.asc" of type "application/pgp-signature" (834 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ