From: Rob Herring <robh@kernel.org>
To: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Frank Rowand <frowand.list@gmail.com>
Subject: [PATCH 1/3] scripts/dtc: Update to upstream version v1.4.7-57-gf267e674d145
Date: Fri, 30 Nov 2018 09:16:08 -0600 [thread overview]
Message-ID: <20181130151610.30596-1-robh@kernel.org> (raw)
This adds the following commits from upstream:
f267e674d145 checks: Fix crash with multiple source annotations
3616b9a811b6 checks: Use source position information for check failures
2bdbd07a1223 checks: Make each message output atomic
a1eff70c02cf util: Add xa{v}sprintf_append functions
82a52ce4573b libfdt: Add a test for fdt_getprop_by_offset()
607b8586b383 PEP8 / Flake8 cleanups for setup.py
f9c0a425b648 Remove broken objdir / srcdir support
5182b5e6f28c pylibfdt: Use common PREFIX variable
d45bf1f5f2a6 Refine make tests_clean target
99284c4db9cb Refine pylibfdt_clean target
a4629cfaedfb Refine libfdt_clean target
08380fc43aa2 tests: Use modern octal literals for Python
8113c00b99d3 pylibfdt: Allow switch to Python 3 via environment variable PYTHON
11738cf01f15 libfdt: Don't use memcpy to handle unaligned reads on ARM
86a288a73670 checks: Restructure check_msg to decrease indentation
5667e7ef9a9a annotations: add the annotation functionality
8e20ccf52f90 annotations: add positions
ca930e20bb54 tests: Don't lose errors from make checkm
43366bb4eeee tests: Property count valgrind errors in wrapped tests
5062516fb8cb srcpos: Remove srcpos_empty
a3143fafbf83 Revert "annotations: add positions"
403cc79f06a1 checks: Update SPI bus check for 'spi-slave'
baa1d2cf7894 annotations: add positions
ff2ad38f6a5a Merge remote-tracking branch 'origin/pr/18'
aa7254d9cb17 libfdt: return correct value if #size-cells property is not present
49903aed7783 use ptrdiff_t modifier for printing pointer differences
da2b691ccf68 treesource: Fix dts output for phandles in middle of a sequence of ints
8f8b77a0d62d tests: Wrap check_align() calls with base_run_test()
522d81d572f2 Fix dts output with a REF_PATH marker
e45198c98359 Added test cases for target references
0fcffda15e9f Merge nodes with local target label references
1e4a0928f3b3 pylibfdt: Don't have setup.py depend on where it's invoked from
ca399b14956f pylibfdt: Eliminate run_setup make function
98972f1b3e33 pylibfdt: Improved version extraction
7ba2be6cda5f pylibfdt: Don't silence setup.py when V=1
7691f9d39301 pylibfdt: Make SETUP make variable
855b9963def9 pylibfdt: Simpler CFLAGS handling
47cafbeeb977 pylibfdt: Link extension module with libfdt rather than rebuilding
dd695d6afb19 pylibfdt: Correctly set build output directory
59327523d0d8 pylibfdt: We don't need include files from the base directory
e84742aa7b93 checks: fix simple-bus compatible matching
8c59a97ce096 Fix missing labels when emitting dts format
d448f9a5fd94 Revert dts output formatting changes of spaces around brackets
Signed-off-by: Rob Herring <robh@kernel.org>
---
scripts/dtc/checks.c | 73 +++++++++++---
scripts/dtc/dtc-lexer.l | 4 +-
scripts/dtc/dtc-parser.y | 52 +++++++---
scripts/dtc/dtc.c | 11 ++-
scripts/dtc/dtc.h | 11 ++-
scripts/dtc/flattree.c | 4 +-
scripts/dtc/fstree.c | 5 +-
scripts/dtc/libfdt/Makefile.libfdt | 4 +
scripts/dtc/libfdt/fdt_addresses.c | 16 ++-
scripts/dtc/libfdt/libfdt.h | 24 +++--
scripts/dtc/livetree.c | 33 ++++---
scripts/dtc/srcpos.c | 153 ++++++++++++++++++++++++++---
scripts/dtc/srcpos.h | 14 +--
scripts/dtc/treesource.c | 115 ++++++++++++++--------
scripts/dtc/util.c | 60 +++++++----
scripts/dtc/util.h | 2 +
scripts/dtc/version_gen.h | 2 +-
17 files changed, 436 insertions(+), 147 deletions(-)
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index 9c9b0c328af6..4834e44b37b2 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -19,6 +19,7 @@
*/
#include "dtc.h"
+#include "srcpos.h"
#ifdef TRACE_CHECKS
#define TRACE(c, ...) \
@@ -78,23 +79,56 @@ static inline void PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti,
const char *fmt, ...)
{
va_list ap;
- va_start(ap, fmt);
+ char *str = NULL;
+ struct srcpos *pos = NULL;
+ char *file_str;
+
+ if (!(c->warn && (quiet < 1)) && !(c->error && (quiet < 2)))
+ return;
+
+ if (prop && prop->srcpos)
+ pos = prop->srcpos;
+ else if (node && node->srcpos)
+ pos = node->srcpos;
+
+ if (pos) {
+ file_str = srcpos_string(pos);
+ xasprintf(&str, "%s", file_str);
+ free(file_str);
+ } else if (streq(dti->outname, "-")) {
+ xasprintf(&str, "<stdout>");
+ } else {
+ xasprintf(&str, "%s", dti->outname);
+ }
- if ((c->warn && (quiet < 1))
- || (c->error && (quiet < 2))) {
- fprintf(stderr, "%s: %s (%s): ",
- strcmp(dti->outname, "-") ? dti->outname : "<stdout>",
+ xasprintf_append(&str, ": %s (%s): ",
(c->error) ? "ERROR" : "Warning", c->name);
- if (node) {
- fprintf(stderr, "%s", node->fullpath);
- if (prop)
- fprintf(stderr, ":%s", prop->name);
- fputs(": ", stderr);
- }
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
+
+ if (node) {
+ if (prop)
+ xasprintf_append(&str, "%s:%s: ", node->fullpath, prop->name);
+ else
+ xasprintf_append(&str, "%s: ", node->fullpath);
}
+
+ va_start(ap, fmt);
+ xavsprintf_append(&str, fmt, ap);
va_end(ap);
+
+ xasprintf_append(&str, "\n");
+
+ if (!prop && pos) {
+ pos = node->srcpos;
+ while (pos->next) {
+ pos = pos->next;
+
+ file_str = srcpos_string(pos);
+ xasprintf_append(&str, " also defined at %s\n", file_str);
+ free(file_str);
+ }
+ }
+
+ fputs(str, stderr);
}
#define FAIL(c, dti, node, ...) \
@@ -910,7 +944,7 @@ static bool node_is_compatible(struct node *node, const char *compat)
for (str = prop->val.val, end = str + prop->val.len; str < end;
str += strnlen(str, end - str) + 1) {
- if (strprefixeq(str, end - str, compat))
+ if (streq(str, compat))
return true;
}
return false;
@@ -921,7 +955,8 @@ static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct
if (node_is_compatible(node, "simple-bus"))
node->bus = &simple_bus;
}
-WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells);
+WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL,
+ &addr_size_cells, &compatible_is_string_list);
static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node)
{
@@ -1035,6 +1070,7 @@ static const struct bus_type spi_bus = {
static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct node *node)
{
+ int spi_addr_cells = 1;
if (strprefixeq(node->name, node->basenamelen, "spi")) {
node->bus = &spi_bus;
@@ -1063,7 +1099,9 @@ static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct no
if (node->bus != &spi_bus || !node->children)
return;
- if (node_addr_cells(node) != 1)
+ if (get_property(node, "spi-slave"))
+ spi_addr_cells = 0;
+ if (node_addr_cells(node) != spi_addr_cells)
FAIL(c, dti, node, "incorrect #address-cells for SPI bus");
if (node_size_cells(node) != 0)
FAIL(c, dti, node, "incorrect #size-cells for SPI bus");
@@ -1082,6 +1120,9 @@ static void check_spi_bus_reg(struct check *c, struct dt_info *dti, struct node
if (!node->parent || (node->parent->bus != &spi_bus))
return;
+ if (get_property(node->parent, "spi-slave"))
+ return;
+
prop = get_property(node, "reg");
if (prop)
cells = (cell_t *)prop->val.val;
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
index 615b7ec6588f..06c040902444 100644
--- a/scripts/dtc/dtc-lexer.l
+++ b/scripts/dtc/dtc-lexer.l
@@ -213,14 +213,14 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
<*>\&{LABEL} { /* label reference */
DPRINT("Ref: %s\n", yytext+1);
yylval.labelref = xstrdup(yytext+1);
- return DT_REF;
+ return DT_LABEL_REF;
}
<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */
yytext[yyleng-1] = '\0';
DPRINT("Ref: %s\n", yytext+2);
yylval.labelref = xstrdup(yytext+2);
- return DT_REF;
+ return DT_PATH_REF;
}
<BYTESTRING>[0-9a-fA-F]{2} {
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index dd70ebf386f4..2ec981e86111 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -70,7 +70,8 @@ extern bool treesource_error;
%token <byte> DT_BYTE
%token <data> DT_STRING
%token <labelref> DT_LABEL
-%token <labelref> DT_REF
+%token <labelref> DT_LABEL_REF
+%token <labelref> DT_PATH_REF
%token DT_INCBIN
%type <data> propdata
@@ -83,6 +84,7 @@ extern bool treesource_error;
%type <data> bytestring
%type <prop> propdef
%type <proplist> proplist
+%type <labelref> dt_ref
%type <node> devicetree
%type <node> nodedef
@@ -158,6 +160,8 @@ memreserve:
}
;
+dt_ref: DT_LABEL_REF | DT_PATH_REF;
+
devicetree:
'/' nodedef
{
@@ -167,7 +171,7 @@ devicetree:
{
$$ = merge_nodes($1, $3);
}
- | DT_REF nodedef
+ | dt_ref nodedef
{
/*
* We rely on the rule being always:
@@ -176,9 +180,12 @@ devicetree:
*/
if (!($<flags>-1 & DTSF_PLUGIN))
ERROR(&@2, "Label or path %s not found", $1);
- $$ = add_orphan_node(name_node(build_node(NULL, NULL), ""), $2, $1);
+ $$ = add_orphan_node(
+ name_node(build_node(NULL, NULL, NULL),
+ ""),
+ $2, $1);
}
- | devicetree DT_LABEL DT_REF nodedef
+ | devicetree DT_LABEL dt_ref nodedef
{
struct node *target = get_node_by_ref($1, $3);
@@ -189,7 +196,7 @@ devicetree:
ERROR(&@3, "Label or path %s not found", $3);
$$ = $1;
}
- | devicetree DT_REF nodedef
+ | devicetree DT_PATH_REF nodedef
{
/*
* We rely on the rule being always:
@@ -208,7 +215,26 @@ devicetree:
}
$$ = $1;
}
- | devicetree DT_DEL_NODE DT_REF ';'
+ | devicetree DT_LABEL_REF nodedef
+ {
+ struct node *target = get_node_by_ref($1, $2);
+
+ if (target) {
+ merge_nodes(target, $3);
+ } else {
+ /*
+ * We rely on the rule being always:
+ * versioninfo plugindecl memreserves devicetree
+ * so $-1 is what we want (plugindecl)
+ */
+ if ($<flags>-1 & DTSF_PLUGIN)
+ add_orphan_node($1, $3, $2);
+ else
+ ERROR(&@2, "Label or path %s not found", $2);
+ }
+ $$ = $1;
+ }
+ | devicetree DT_DEL_NODE dt_ref ';'
{
struct node *target = get_node_by_ref($1, $3);
@@ -220,7 +246,7 @@ devicetree:
$$ = $1;
}
- | devicetree DT_OMIT_NO_REF DT_REF ';'
+ | devicetree DT_OMIT_NO_REF dt_ref ';'
{
struct node *target = get_node_by_ref($1, $3);
@@ -237,7 +263,7 @@ devicetree:
nodedef:
'{' proplist subnodes '}' ';'
{
- $$ = build_node($2, $3);
+ $$ = build_node($2, $3, &@$);
}
;
@@ -255,11 +281,11 @@ proplist:
propdef:
DT_PROPNODENAME '=' propdata ';'
{
- $$ = build_property($1, $3);
+ $$ = build_property($1, $3, &@$);
}
| DT_PROPNODENAME ';'
{
- $$ = build_property($1, empty_data);
+ $$ = build_property($1, empty_data, &@$);
}
| DT_DEL_PROP DT_PROPNODENAME ';'
{
@@ -285,7 +311,7 @@ propdata:
{
$$ = data_merge($1, $3);
}
- | propdataprefix DT_REF
+ | propdataprefix dt_ref
{
$1 = data_add_marker($1, TYPE_STRING, $2);
$$ = data_add_marker($1, REF_PATH, $2);
@@ -383,7 +409,7 @@ arrayprefix:
$$.data = data_append_integer($1.data, $2, $1.bits);
}
- | arrayprefix DT_REF
+ | arrayprefix dt_ref
{
uint64_t val = ~0ULL >> (64 - $1.bits);
@@ -540,7 +566,7 @@ subnode:
}
| DT_DEL_NODE DT_PROPNODENAME ';'
{
- $$ = name_node(build_node_delete(), $2);
+ $$ = name_node(build_node_delete(&@$), $2);
}
| DT_OMIT_NO_REF subnode
{
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index 64134aadb997..695e1f789fc7 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -35,6 +35,8 @@ int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties *
int generate_symbols; /* enable symbols & fixup support */
int generate_fixups; /* suppress generation of fixups on symbol support */
int auto_label_aliases; /* auto generate labels -> aliases */
+int annotate; /* Level of annotation: 1 for input source location
+ >1 for full input source location. */
static int is_power_of_2(int x)
{
@@ -60,7 +62,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
/* Usage related data. */
static const char usage_synopsis[] = "dtc [options] <input file>";
-static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv";
+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@AThv";
static struct option const usage_long_opts[] = {
{"quiet", no_argument, NULL, 'q'},
{"in-format", a_argument, NULL, 'I'},
@@ -81,6 +83,7 @@ static struct option const usage_long_opts[] = {
{"error", a_argument, NULL, 'E'},
{"symbols", no_argument, NULL, '@'},
{"auto-alias", no_argument, NULL, 'A'},
+ {"annotate", no_argument, NULL, 'T'},
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'},
{NULL, no_argument, NULL, 0x0},
@@ -117,6 +120,7 @@ static const char * const usage_opts_help[] = {
"\n\tEnable/disable errors (prefix with \"no-\")",
"\n\tEnable generation of symbols",
"\n\tEnable auto-alias of labels",
+ "\n\tAnnotate output .dts with input source file and line (-T -T for more details)",
"\n\tPrint this help and exit",
"\n\tPrint version and exit",
NULL,
@@ -264,6 +268,9 @@ int main(int argc, char *argv[])
case 'A':
auto_label_aliases = 1;
break;
+ case 'T':
+ annotate++;
+ break;
case 'h':
usage(NULL);
@@ -302,6 +309,8 @@ int main(int argc, char *argv[])
outform = "dts";
}
}
+ if (annotate && (!streq(inform, "dts") || !streq(outform, "dts")))
+ die("--annotate requires -I dts -O dts\n");
if (streq(inform, "dts"))
dti = dt_from_source(arg);
else if (streq(inform, "fs"))
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index cbe541525c2c..789e0b1bc057 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -58,6 +58,7 @@ extern int phandle_format; /* Use linux,phandle or phandle properties */
extern int generate_symbols; /* generate symbols for nodes with labels */
extern int generate_fixups; /* generate fixups */
extern int auto_label_aliases; /* auto generate labels -> aliases */
+extern int annotate; /* annotate .dts with input source location */
#define PHANDLE_LEGACY 0x1
#define PHANDLE_EPAPR 0x2
@@ -158,6 +159,7 @@ struct property {
struct property *next;
struct label *labels;
+ struct srcpos *srcpos;
};
struct node {
@@ -177,6 +179,7 @@ struct node {
struct label *labels;
const struct bus_type *bus;
+ struct srcpos *srcpos;
bool omit_if_unused, is_referenced;
};
@@ -205,13 +208,15 @@ struct node {
void add_label(struct label **labels, char *label);
void delete_labels(struct label **labels);
-struct property *build_property(char *name, struct data val);
+struct property *build_property(char *name, struct data val,
+ struct srcpos *srcpos);
struct property *build_property_delete(char *name);
struct property *chain_property(struct property *first, struct property *list);
struct property *reverse_properties(struct property *first);
-struct node *build_node(struct property *proplist, struct node *children);
-struct node *build_node_delete(void);
+struct node *build_node(struct property *proplist, struct node *children,
+ struct srcpos *srcpos);
+struct node *build_node_delete(struct srcpos *srcpos);
struct node *name_node(struct node *node, char *name);
struct node *omit_node_if_unused(struct node *node);
struct node *reference_node(struct node *node);
diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c
index 851ea87dbc0f..acf04c30669f 100644
--- a/scripts/dtc/flattree.c
+++ b/scripts/dtc/flattree.c
@@ -692,7 +692,7 @@ static struct property *flat_read_property(struct inbuf *dtbuf,
val = flat_read_data(dtbuf, proplen);
- return build_property(name, val);
+ return build_property(name, val, NULL);
}
@@ -750,7 +750,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
char *flatname;
uint32_t val;
- node = build_node(NULL, NULL);
+ node = build_node(NULL, NULL, NULL);
flatname = flat_read_string(dtbuf);
diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c
index ae7d06c3c492..1e7eeba47ff6 100644
--- a/scripts/dtc/fstree.c
+++ b/scripts/dtc/fstree.c
@@ -34,7 +34,7 @@ static struct node *read_fstree(const char *dirname)
if (!d)
die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno));
- tree = build_node(NULL, NULL);
+ tree = build_node(NULL, NULL, NULL);
while ((de = readdir(d)) != NULL) {
char *tmpname;
@@ -60,7 +60,8 @@ static struct node *read_fstree(const char *dirname)
} else {
prop = build_property(xstrdup(de->d_name),
data_copy_file(pfile,
- st.st_size));
+ st.st_size),
+ NULL);
add_property(tree, prop);
fclose(pfile);
}
diff --git a/scripts/dtc/libfdt/Makefile.libfdt b/scripts/dtc/libfdt/Makefile.libfdt
index 098b3f36e668..3af3656df801 100644
--- a/scripts/dtc/libfdt/Makefile.libfdt
+++ b/scripts/dtc/libfdt/Makefile.libfdt
@@ -9,3 +9,7 @@ LIBFDT_VERSION = version.lds
LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \
fdt_addresses.c fdt_overlay.c
LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
+
+libfdt_clean:
+ @$(VECHO) CLEAN "(libfdt)"
+ rm -f $(STD_CLEANFILES:%=$(LIBFDT_dir)/%)
diff --git a/scripts/dtc/libfdt/fdt_addresses.c b/scripts/dtc/libfdt/fdt_addresses.c
index 49537b578d03..f13a87dfa068 100644
--- a/scripts/dtc/libfdt/fdt_addresses.c
+++ b/scripts/dtc/libfdt/fdt_addresses.c
@@ -64,7 +64,7 @@ static int fdt_cells(const void *fdt, int nodeoffset, const char *name)
c = fdt_getprop(fdt, nodeoffset, name, &len);
if (!c)
- return 2;
+ return len;
if (len != sizeof(*c))
return -FDT_ERR_BADNCELLS;
@@ -78,10 +78,20 @@ static int fdt_cells(const void *fdt, int nodeoffset, const char *name)
int fdt_address_cells(const void *fdt, int nodeoffset)
{
- return fdt_cells(fdt, nodeoffset, "#address-cells");
+ int val;
+
+ val = fdt_cells(fdt, nodeoffset, "#address-cells");
+ if (val == -FDT_ERR_NOTFOUND)
+ return 2;
+ return val;
}
int fdt_size_cells(const void *fdt, int nodeoffset)
{
- return fdt_cells(fdt, nodeoffset, "#size-cells");
+ int val;
+
+ val = fdt_cells(fdt, nodeoffset, "#size-cells");
+ if (val == -FDT_ERR_NOTFOUND)
+ return 1;
+ return val;
}
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
index 2bd151dd355f..627da2e079c9 100644
--- a/scripts/dtc/libfdt/libfdt.h
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -163,18 +163,26 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
static inline uint32_t fdt32_ld(const fdt32_t *p)
{
- fdt32_t v;
+ const uint8_t *bp = (const uint8_t *)p;
- memcpy(&v, p, sizeof(v));
- return fdt32_to_cpu(v);
+ return ((uint32_t)bp[0] << 24)
+ | ((uint32_t)bp[1] << 16)
+ | ((uint32_t)bp[2] << 8)
+ | bp[3];
}
static inline uint64_t fdt64_ld(const fdt64_t *p)
{
- fdt64_t v;
-
- memcpy(&v, p, sizeof(v));
- return fdt64_to_cpu(v);
+ const uint8_t *bp = (const uint8_t *)p;
+
+ return ((uint64_t)bp[0] << 56)
+ | ((uint64_t)bp[1] << 48)
+ | ((uint64_t)bp[2] << 40)
+ | ((uint64_t)bp[3] << 32)
+ | ((uint64_t)bp[4] << 24)
+ | ((uint64_t)bp[5] << 16)
+ | ((uint64_t)bp[6] << 8)
+ | bp[7];
}
/**********************************************************************/
@@ -1145,7 +1153,7 @@ int fdt_address_cells(const void *fdt, int nodeoffset);
*
* returns:
* 0 <= n < FDT_MAX_NCELLS, on success
- * 2, if the node has no #size-cells property
+ * 1, if the node has no #size-cells property
* -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
* #size-cells property
* -FDT_ERR_BADMAGIC,
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index 4ff0679e0062..7a2e6446a17b 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -19,6 +19,7 @@
*/
#include "dtc.h"
+#include "srcpos.h"
/*
* Tree building functions
@@ -50,7 +51,8 @@ void delete_labels(struct label **labels)
label->deleted = 1;
}
-struct property *build_property(char *name, struct data val)
+struct property *build_property(char *name, struct data val,
+ struct srcpos *srcpos)
{
struct property *new = xmalloc(sizeof(*new));
@@ -58,6 +60,7 @@ struct property *build_property(char *name, struct data val)
new->name = name;
new->val = val;
+ new->srcpos = srcpos_copy(srcpos);
return new;
}
@@ -97,7 +100,8 @@ struct property *reverse_properties(struct property *first)
return head;
}
-struct node *build_node(struct property *proplist, struct node *children)
+struct node *build_node(struct property *proplist, struct node *children,
+ struct srcpos *srcpos)
{
struct node *new = xmalloc(sizeof(*new));
struct node *child;
@@ -106,6 +110,7 @@ struct node *build_node(struct property *proplist, struct node *children)
new->proplist = reverse_properties(proplist);
new->children = children;
+ new->srcpos = srcpos_copy(srcpos);
for_each_child(new, child) {
child->parent = new;
@@ -114,13 +119,14 @@ struct node *build_node(struct property *proplist, struct node *children)
return new;
}
-struct node *build_node_delete(void)
+struct node *build_node_delete(struct srcpos *srcpos)
{
struct node *new = xmalloc(sizeof(*new));
memset(new, 0, sizeof(*new));
new->deleted = 1;
+ new->srcpos = srcpos_copy(srcpos);
return new;
}
@@ -183,6 +189,8 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
old_prop->val = new_prop->val;
old_prop->deleted = 0;
+ free(old_prop->srcpos);
+ old_prop->srcpos = new_prop->srcpos;
free(new_prop);
new_prop = NULL;
break;
@@ -223,6 +231,8 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
add_child(old_node, new_child);
}
+ old_node->srcpos = srcpos_extend(old_node->srcpos, new_node->srcpos);
+
/* The new node contents are now merged into the old node. Free
* the new node. */
free(new_node);
@@ -241,18 +251,18 @@ struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref)
if (ref[0] == '/') {
d = data_append_data(d, ref, strlen(ref) + 1);
- p = build_property("target-path", d);
+ p = build_property("target-path", d, NULL);
} else {
d = data_add_marker(d, REF_PHANDLE, ref);
d = data_append_integer(d, 0xffffffff, 32);
- p = build_property("target", d);
+ p = build_property("target", d, NULL);
}
xasprintf(&name, "fragment@%u",
next_orphan_fragment++);
name_node(new_node, "__overlay__");
- node = build_node(p, new_node);
+ node = build_node(p, new_node, NULL);
name_node(node, name);
add_child(dt, node);
@@ -351,7 +361,7 @@ void append_to_property(struct node *node,
p->val = d;
} else {
d = data_append_data(empty_data, data, len);
- p = build_property(name, d);
+ p = build_property(name, d, NULL);
add_property(node, p);
}
}
@@ -609,11 +619,11 @@ cell_t get_node_phandle(struct node *root, struct node *node)
if (!get_property(node, "linux,phandle")
&& (phandle_format & PHANDLE_LEGACY))
- add_property(node, build_property("linux,phandle", d));
+ add_property(node, build_property("linux,phandle", d, NULL));
if (!get_property(node, "phandle")
&& (phandle_format & PHANDLE_EPAPR))
- add_property(node, build_property("phandle", d));
+ add_property(node, build_property("phandle", d, NULL));
/* If the node *does* have a phandle property, we must
* be dealing with a self-referencing phandle, which will be
@@ -787,7 +797,7 @@ static struct node *build_and_name_child_node(struct node *parent, char *name)
{
struct node *node;
- node = build_node(NULL, NULL);
+ node = build_node(NULL, NULL, NULL);
name_node(node, xstrdup(name));
add_child(parent, node);
@@ -849,7 +859,8 @@ static void generate_label_tree_internal(struct dt_info *dti,
/* insert it */
p = build_property(l->label,
data_copy_mem(node->fullpath,
- strlen(node->fullpath) + 1));
+ strlen(node->fullpath) + 1),
+ NULL);
add_property(an, p);
}
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c
index cb6ed0e3e5e4..41f83700ee91 100644
--- a/scripts/dtc/srcpos.c
+++ b/scripts/dtc/srcpos.c
@@ -33,6 +33,9 @@ struct search_path {
/* This is the list of directories that we search for source files */
static struct search_path *search_path_head, **search_path_tail;
+/* Detect infinite include recursion. */
+#define MAX_SRCFILE_DEPTH (100)
+static int srcfile_depth; /* = 0 */
static char *get_dirname(const char *path)
{
@@ -51,11 +54,51 @@ static char *get_dirname(const char *path)
FILE *depfile; /* = NULL */
struct srcfile_state *current_srcfile; /* = NULL */
+static char *initial_path; /* = NULL */
+static int initial_pathlen; /* = 0 */
+static bool initial_cpp = true;
-/* Detect infinite include recursion. */
-#define MAX_SRCFILE_DEPTH (100)
-static int srcfile_depth; /* = 0 */
+static void set_initial_path(char *fname)
+{
+ int i, len = strlen(fname);
+ xasprintf(&initial_path, "%s", fname);
+ initial_pathlen = 0;
+ for (i = 0; i != len; i++)
+ if (initial_path[i] == '/')
+ initial_pathlen++;
+}
+
+static char *shorten_to_initial_path(char *fname)
+{
+ char *p1, *p2, *prevslash1 = NULL;
+ int slashes = 0;
+
+ for (p1 = fname, p2 = initial_path; *p1 && *p2; p1++, p2++) {
+ if (*p1 != *p2)
+ break;
+ if (*p1 == '/') {
+ prevslash1 = p1;
+ slashes++;
+ }
+ }
+ p1 = prevslash1 + 1;
+ if (prevslash1) {
+ int diff = initial_pathlen - slashes, i, j;
+ int restlen = strlen(fname) - (p1 - fname);
+ char *res;
+
+ res = xmalloc((3 * diff) + restlen + 1);
+ for (i = 0, j = 0; i != diff; i++) {
+ res[j++] = '.';
+ res[j++] = '.';
+ res[j++] = '/';
+ }
+ strcpy(res + j, p1);
+ return res;
+ }
+ return NULL;
+}
/**
* Try to open a file in a given directory.
@@ -157,6 +200,9 @@ void srcfile_push(const char *fname)
srcfile->colno = 1;
current_srcfile = srcfile;
+
+ if (srcfile_depth == 1)
+ set_initial_path(srcfile->name);
}
bool srcfile_pop(void)
@@ -197,18 +243,6 @@ void srcfile_add_search_path(const char *dirname)
search_path_tail = &node->next;
}
-/*
- * The empty source position.
- */
-
-struct srcpos srcpos_empty = {
- .first_line = 0,
- .first_column = 0,
- .last_line = 0,
- .last_column = 0,
- .file = NULL,
-};
-
void srcpos_update(struct srcpos *pos, const char *text, int len)
{
int i;
@@ -234,13 +268,35 @@ struct srcpos *
srcpos_copy(struct srcpos *pos)
{
struct srcpos *pos_new;
+ struct srcfile_state *srcfile_state;
+
+ if (!pos)
+ return NULL;
pos_new = xmalloc(sizeof(struct srcpos));
+ assert(pos->next == NULL);
memcpy(pos_new, pos, sizeof(struct srcpos));
+ /* allocate without free */
+ srcfile_state = xmalloc(sizeof(struct srcfile_state));
+ memcpy(srcfile_state, pos->file, sizeof(struct srcfile_state));
+ pos_new->file = srcfile_state;
+
return pos_new;
}
+struct srcpos *srcpos_extend(struct srcpos *pos, struct srcpos *newtail)
+{
+ struct srcpos *p;
+
+ if (!pos)
+ return newtail;
+
+ for (p = pos; p->next != NULL; p = p->next);
+ p->next = newtail;
+ return pos;
+}
+
char *
srcpos_string(struct srcpos *pos)
{
@@ -266,6 +322,68 @@ srcpos_string(struct srcpos *pos)
return pos_str;
}
+static char *
+srcpos_string_comment(struct srcpos *pos, bool first_line, int level)
+{
+ char *pos_str, *fname, *first, *rest;
+ bool fresh_fname = false;
+
+ if (!pos) {
+ if (level > 1) {
+ xasprintf(&pos_str, "<no-file>:<no-line>");
+ return pos_str;
+ } else {
+ return NULL;
+ }
+ }
+
+ if (!pos->file)
+ fname = "<no-file>";
+ else if (!pos->file->name)
+ fname = "<no-filename>";
+ else if (level > 1)
+ fname = pos->file->name;
+ else {
+ fname = shorten_to_initial_path(pos->file->name);
+ if (fname)
+ fresh_fname = true;
+ else
+ fname = pos->file->name;
+ }
+
+ if (level > 1)
+ xasprintf(&first, "%s:%d:%d-%d:%d", fname,
+ pos->first_line, pos->first_column,
+ pos->last_line, pos->last_column);
+ else
+ xasprintf(&first, "%s:%d", fname,
+ first_line ? pos->first_line : pos->last_line);
+
+ if (fresh_fname)
+ free(fname);
+
+ if (pos->next != NULL) {
+ rest = srcpos_string_comment(pos->next, first_line, level);
+ xasprintf(&pos_str, "%s, %s", first, rest);
+ free(first);
+ free(rest);
+ } else {
+ pos_str = first;
+ }
+
+ return pos_str;
+}
+
+char *srcpos_string_first(struct srcpos *pos, int level)
+{
+ return srcpos_string_comment(pos, true, level);
+}
+
+char *srcpos_string_last(struct srcpos *pos, int level)
+{
+ return srcpos_string_comment(pos, false, level);
+}
+
void srcpos_verror(struct srcpos *pos, const char *prefix,
const char *fmt, va_list va)
{
@@ -294,4 +412,9 @@ void srcpos_set_line(char *f, int l)
{
current_srcfile->name = f;
current_srcfile->lineno = l;
+
+ if (initial_cpp) {
+ initial_cpp = false;
+ set_initial_path(f);
+ }
}
diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h
index 9ded12a3830a..6326a952c40e 100644
--- a/scripts/dtc/srcpos.h
+++ b/scripts/dtc/srcpos.h
@@ -74,6 +74,7 @@ struct srcpos {
int last_line;
int last_column;
struct srcfile_state *file;
+ struct srcpos *next;
};
#define YYLTYPE struct srcpos
@@ -93,19 +94,18 @@ struct srcpos {
YYRHSLOC(Rhs, 0).last_column; \
(Current).file = YYRHSLOC (Rhs, 0).file; \
} \
+ (Current).next = NULL; \
} while (0)
-/*
- * Fictional source position used for IR nodes that are
- * created without otherwise knowing a true source position.
- * For example,constant definitions from the command line.
- */
-extern struct srcpos srcpos_empty;
-
extern void srcpos_update(struct srcpos *pos, const char *text, int len);
extern struct srcpos *srcpos_copy(struct srcpos *pos);
+extern struct srcpos *srcpos_extend(struct srcpos *new_srcpos,
+ struct srcpos *old_srcpos);
extern char *srcpos_string(struct srcpos *pos);
+extern char *srcpos_string_first(struct srcpos *pos, int level);
+extern char *srcpos_string_last(struct srcpos *pos, int level);
+
extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix,
const char *fmt, va_list va);
diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c
index f2874f1d1465..1af36628b75f 100644
--- a/scripts/dtc/treesource.c
+++ b/scripts/dtc/treesource.c
@@ -64,6 +64,10 @@ static bool isstring(char c)
static void write_propval_string(FILE *f, const char *s, size_t len)
{
const char *end = s + len - 1;
+
+ if (!len)
+ return;
+
assert(*end == '\0');
fprintf(f, "\"");
@@ -118,18 +122,20 @@ static void write_propval_int(FILE *f, const char *p, size_t len, size_t width)
for (; p < end; p += width) {
switch (width) {
case 1:
- fprintf(f, " %02"PRIx8, *(const uint8_t*)p);
+ fprintf(f, "%02"PRIx8, *(const uint8_t*)p);
break;
case 2:
- fprintf(f, " 0x%02"PRIx16, fdt16_to_cpu(*(const fdt16_t*)p));
+ fprintf(f, "0x%02"PRIx16, fdt16_to_cpu(*(const fdt16_t*)p));
break;
case 4:
- fprintf(f, " 0x%02"PRIx32, fdt32_to_cpu(*(const fdt32_t*)p));
+ fprintf(f, "0x%02"PRIx32, fdt32_to_cpu(*(const fdt32_t*)p));
break;
case 8:
- fprintf(f, " 0x%02"PRIx64, fdt64_to_cpu(*(const fdt64_t*)p));
+ fprintf(f, "0x%02"PRIx64, fdt64_to_cpu(*(const fdt64_t*)p));
break;
}
+ if (p + width < end)
+ fputc(' ', f);
}
}
@@ -162,10 +168,10 @@ static const char *delim_start[] = {
[TYPE_STRING] = "",
};
static const char *delim_end[] = {
- [TYPE_UINT8] = " ]",
- [TYPE_UINT16] = " >",
- [TYPE_UINT32] = " >",
- [TYPE_UINT64] = " >",
+ [TYPE_UINT8] = "]",
+ [TYPE_UINT16] = ">",
+ [TYPE_UINT32] = ">",
+ [TYPE_UINT64] = ">",
[TYPE_STRING] = "",
};
@@ -208,13 +214,22 @@ static void write_propval(FILE *f, struct property *prop)
struct marker *m = prop->val.markers;
struct marker dummy_marker;
enum markertype emit_type = TYPE_NONE;
+ char *srcstr;
if (len == 0) {
- fprintf(f, ";\n");
+ fprintf(f, ";");
+ if (annotate) {
+ srcstr = srcpos_string_first(prop->srcpos, annotate);
+ if (srcstr) {
+ fprintf(f, " /* %s */", srcstr);
+ free(srcstr);
+ }
+ }
+ fprintf(f, "\n");
return;
}
- fprintf(f, " = ");
+ fprintf(f, " =");
if (!next_type_marker(m)) {
/* data type information missing, need to guess */
@@ -225,32 +240,23 @@ static void write_propval(FILE *f, struct property *prop)
m = &dummy_marker;
}
- struct marker *m_label = prop->val.markers;
for_each_marker(m) {
- size_t chunk_len;
+ size_t chunk_len = (m->next ? m->next->offset : len) - m->offset;
+ size_t data_len = type_marker_length(m) ? : len - m->offset;
const char *p = &prop->val.val[m->offset];
- if (!has_data_type_information(m))
- continue;
-
- chunk_len = type_marker_length(m);
- if (!chunk_len)
- chunk_len = len - m->offset;
-
- if (emit_type != TYPE_NONE)
- fprintf(f, "%s, ", delim_end[emit_type]);
- emit_type = m->type;
-
- for_each_marker_of_type(m_label, LABEL) {
- if (m_label->offset > m->offset)
- break;
- fprintf(f, "%s: ", m_label->ref);
- }
-
- fprintf(f, "%s", delim_start[emit_type]);
+ if (has_data_type_information(m)) {
+ emit_type = m->type;
+ fprintf(f, " %s", delim_start[emit_type]);
+ } else if (m->type == LABEL)
+ fprintf(f, " %s:", m->ref);
+ else if (m->offset)
+ fputc(' ', f);
- if (chunk_len <= 0)
+ if (emit_type == TYPE_NONE) {
+ assert(chunk_len == 0);
continue;
+ }
switch(emit_type) {
case TYPE_UINT16:
@@ -268,15 +274,23 @@ static void write_propval(FILE *f, struct property *prop)
default:
write_propval_int(f, p, chunk_len, 1);
}
- }
- /* Wrap up any labels at the end of the value */
- for_each_marker_of_type(m_label, LABEL) {
- assert (m_label->offset == len);
- fprintf(f, " %s:", m_label->ref);
+ if (chunk_len == data_len) {
+ size_t pos = m->offset + chunk_len;
+ fprintf(f, pos == len ? "%s" : "%s,",
+ delim_end[emit_type] ? : "");
+ emit_type = TYPE_NONE;
+ }
}
-
- fprintf(f, "%s;\n", delim_end[emit_type] ? : "");
+ fprintf(f, ";");
+ if (annotate) {
+ srcstr = srcpos_string_first(prop->srcpos, annotate);
+ if (srcstr) {
+ fprintf(f, " /* %s */", srcstr);
+ free(srcstr);
+ }
+ }
+ fprintf(f, "\n");
}
static void write_tree_source_node(FILE *f, struct node *tree, int level)
@@ -284,14 +298,24 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
struct property *prop;
struct node *child;
struct label *l;
+ char *srcstr;
write_prefix(f, level);
for_each_label(tree->labels, l)
fprintf(f, "%s: ", l->label);
if (tree->name && (*tree->name))
- fprintf(f, "%s {\n", tree->name);
+ fprintf(f, "%s {", tree->name);
else
- fprintf(f, "/ {\n");
+ fprintf(f, "/ {");
+
+ if (annotate) {
+ srcstr = srcpos_string_first(tree->srcpos, annotate);
+ if (srcstr) {
+ fprintf(f, " /* %s */", srcstr);
+ free(srcstr);
+ }
+ }
+ fprintf(f, "\n");
for_each_property(tree, prop) {
write_prefix(f, level+1);
@@ -305,10 +329,17 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
write_tree_source_node(f, child, level+1);
}
write_prefix(f, level);
- fprintf(f, "};\n");
+ fprintf(f, "};");
+ if (annotate) {
+ srcstr = srcpos_string_last(tree->srcpos, annotate);
+ if (srcstr) {
+ fprintf(f, " /* %s */", srcstr);
+ free(srcstr);
+ }
+ }
+ fprintf(f, "\n");
}
-
void dt_to_source(FILE *f, struct dt_info *dti)
{
struct reserve_info *re;
diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c
index a69b7a13463d..9c6fb5f286ae 100644
--- a/scripts/dtc/util.c
+++ b/scripts/dtc/util.c
@@ -46,36 +46,54 @@ char *xstrdup(const char *s)
return d;
}
-/* based in part from (3) vsnprintf */
-int xasprintf(char **strp, const char *fmt, ...)
+int xavsprintf_append(char **strp, const char *fmt, va_list ap)
{
- int n, size = 128; /* start with 128 bytes */
+ int n, size = 0; /* start with 128 bytes */
char *p;
- va_list ap;
+ va_list ap_copy;
- /* initial pointer is NULL making the fist realloc to be malloc */
- p = NULL;
- while (1) {
- p = xrealloc(p, size);
+ p = *strp;
+ if (p)
+ size = strlen(p);
- /* Try to print in the allocated space. */
- va_start(ap, fmt);
- n = vsnprintf(p, size, fmt, ap);
- va_end(ap);
+ va_copy(ap_copy, ap);
+ n = vsnprintf(NULL, 0, fmt, ap_copy) + 1;
+ va_end(ap_copy);
+
+ p = xrealloc(p, size + n);
+
+ n = vsnprintf(p + size, n, fmt, ap);
- /* If that worked, return the string. */
- if (n > -1 && n < size)
- break;
- /* Else try again with more space. */
- if (n > -1) /* glibc 2.1 */
- size = n + 1; /* precisely what is needed */
- else /* glibc 2.0 */
- size *= 2; /* twice the old size */
- }
*strp = p;
return strlen(p);
}
+int xasprintf_append(char **strp, const char *fmt, ...)
+{
+ int n;
+ va_list ap;
+
+ va_start(ap, fmt);
+ n = xavsprintf_append(strp, fmt, ap);
+ va_end(ap);
+
+ return n;
+}
+
+int xasprintf(char **strp, const char *fmt, ...)
+{
+ int n;
+ va_list ap;
+
+ *strp = NULL;
+
+ va_start(ap, fmt);
+ n = xavsprintf_append(strp, fmt, ap);
+ va_end(ap);
+
+ return n;
+}
+
char *join_path(const char *path, const char *name)
{
int lenp = strlen(path);
diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h
index f6cea8274174..7658781a6200 100644
--- a/scripts/dtc/util.h
+++ b/scripts/dtc/util.h
@@ -72,6 +72,8 @@ static inline void *xrealloc(void *p, size_t len)
extern char *xstrdup(const char *s);
extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...);
+extern int PRINTF(2, 3) xasprintf_append(char **strp, const char *fmt, ...);
+extern int xavsprintf_append(char **strp, const char *fmt, va_list ap);
extern char *join_path(const char *path, const char *name);
/**
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
index 6d23fd095f16..75f383c0b9d3 100644
--- a/scripts/dtc/version_gen.h
+++ b/scripts/dtc/version_gen.h
@@ -1 +1 @@
-#define DTC_VERSION "DTC 1.4.7-gc86da84d"
+#define DTC_VERSION "DTC 1.4.7-gf267e674"
--
2.19.1
next reply other threads:[~2018-11-30 15:16 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-30 15:16 Rob Herring [this message]
2018-11-30 15:16 ` [PATCH 2/3] kbuild: disable dtc simple_bus_reg warnings by default Rob Herring
2018-11-30 15:16 ` [PATCH 3/3] kbuild: Enable dtc graph_port warning " Rob Herring
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181130151610.30596-1-robh@kernel.org \
--to=robh@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=frowand.list@gmail.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.