mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 05:11:48 +00:00
scripts/dtc: Update to upstream version v1.4.7-57-gf267e674d145
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>
This commit is contained in:
parent
e8b1dee214
commit
c2e7075ca8
@ -19,6 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dtc.h"
|
#include "dtc.h"
|
||||||
|
#include "srcpos.h"
|
||||||
|
|
||||||
#ifdef TRACE_CHECKS
|
#ifdef TRACE_CHECKS
|
||||||
#define TRACE(c, ...) \
|
#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, ...)
|
const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
char *str = NULL;
|
||||||
|
struct srcpos *pos = NULL;
|
||||||
|
char *file_str;
|
||||||
|
|
||||||
if ((c->warn && (quiet < 1))
|
if (!(c->warn && (quiet < 1)) && !(c->error && (quiet < 2)))
|
||||||
|| (c->error && (quiet < 2))) {
|
return;
|
||||||
fprintf(stderr, "%s: %s (%s): ",
|
|
||||||
strcmp(dti->outname, "-") ? dti->outname : "<stdout>",
|
if (prop && prop->srcpos)
|
||||||
(c->error) ? "ERROR" : "Warning", c->name);
|
pos = prop->srcpos;
|
||||||
if (node) {
|
else if (node && node->srcpos)
|
||||||
fprintf(stderr, "%s", node->fullpath);
|
pos = node->srcpos;
|
||||||
if (prop)
|
|
||||||
fprintf(stderr, ":%s", prop->name);
|
if (pos) {
|
||||||
fputs(": ", stderr);
|
file_str = srcpos_string(pos);
|
||||||
}
|
xasprintf(&str, "%s", file_str);
|
||||||
vfprintf(stderr, fmt, ap);
|
free(file_str);
|
||||||
fprintf(stderr, "\n");
|
} else if (streq(dti->outname, "-")) {
|
||||||
|
xasprintf(&str, "<stdout>");
|
||||||
|
} else {
|
||||||
|
xasprintf(&str, "%s", dti->outname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xasprintf_append(&str, ": %s (%s): ",
|
||||||
|
(c->error) ? "ERROR" : "Warning", c->name);
|
||||||
|
|
||||||
|
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);
|
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, ...) \
|
#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;
|
for (str = prop->val.val, end = str + prop->val.len; str < end;
|
||||||
str += strnlen(str, end - str) + 1) {
|
str += strnlen(str, end - str) + 1) {
|
||||||
if (strprefixeq(str, end - str, compat))
|
if (streq(str, compat))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
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"))
|
if (node_is_compatible(node, "simple-bus"))
|
||||||
node->bus = &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)
|
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)
|
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")) {
|
if (strprefixeq(node->name, node->basenamelen, "spi")) {
|
||||||
node->bus = &spi_bus;
|
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)
|
if (node->bus != &spi_bus || !node->children)
|
||||||
return;
|
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");
|
FAIL(c, dti, node, "incorrect #address-cells for SPI bus");
|
||||||
if (node_size_cells(node) != 0)
|
if (node_size_cells(node) != 0)
|
||||||
FAIL(c, dti, node, "incorrect #size-cells for SPI bus");
|
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))
|
if (!node->parent || (node->parent->bus != &spi_bus))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (get_property(node->parent, "spi-slave"))
|
||||||
|
return;
|
||||||
|
|
||||||
prop = get_property(node, "reg");
|
prop = get_property(node, "reg");
|
||||||
if (prop)
|
if (prop)
|
||||||
cells = (cell_t *)prop->val.val;
|
cells = (cell_t *)prop->val.val;
|
||||||
|
@ -213,14 +213,14 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
|
|||||||
<*>\&{LABEL} { /* label reference */
|
<*>\&{LABEL} { /* label reference */
|
||||||
DPRINT("Ref: %s\n", yytext+1);
|
DPRINT("Ref: %s\n", yytext+1);
|
||||||
yylval.labelref = xstrdup(yytext+1);
|
yylval.labelref = xstrdup(yytext+1);
|
||||||
return DT_REF;
|
return DT_LABEL_REF;
|
||||||
}
|
}
|
||||||
|
|
||||||
<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */
|
<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */
|
||||||
yytext[yyleng-1] = '\0';
|
yytext[yyleng-1] = '\0';
|
||||||
DPRINT("Ref: %s\n", yytext+2);
|
DPRINT("Ref: %s\n", yytext+2);
|
||||||
yylval.labelref = xstrdup(yytext+2);
|
yylval.labelref = xstrdup(yytext+2);
|
||||||
return DT_REF;
|
return DT_PATH_REF;
|
||||||
}
|
}
|
||||||
|
|
||||||
<BYTESTRING>[0-9a-fA-F]{2} {
|
<BYTESTRING>[0-9a-fA-F]{2} {
|
||||||
|
@ -70,7 +70,8 @@ extern bool treesource_error;
|
|||||||
%token <byte> DT_BYTE
|
%token <byte> DT_BYTE
|
||||||
%token <data> DT_STRING
|
%token <data> DT_STRING
|
||||||
%token <labelref> DT_LABEL
|
%token <labelref> DT_LABEL
|
||||||
%token <labelref> DT_REF
|
%token <labelref> DT_LABEL_REF
|
||||||
|
%token <labelref> DT_PATH_REF
|
||||||
%token DT_INCBIN
|
%token DT_INCBIN
|
||||||
|
|
||||||
%type <data> propdata
|
%type <data> propdata
|
||||||
@ -83,6 +84,7 @@ extern bool treesource_error;
|
|||||||
%type <data> bytestring
|
%type <data> bytestring
|
||||||
%type <prop> propdef
|
%type <prop> propdef
|
||||||
%type <proplist> proplist
|
%type <proplist> proplist
|
||||||
|
%type <labelref> dt_ref
|
||||||
|
|
||||||
%type <node> devicetree
|
%type <node> devicetree
|
||||||
%type <node> nodedef
|
%type <node> nodedef
|
||||||
@ -158,6 +160,8 @@ memreserve:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
dt_ref: DT_LABEL_REF | DT_PATH_REF;
|
||||||
|
|
||||||
devicetree:
|
devicetree:
|
||||||
'/' nodedef
|
'/' nodedef
|
||||||
{
|
{
|
||||||
@ -167,7 +171,7 @@ devicetree:
|
|||||||
{
|
{
|
||||||
$$ = merge_nodes($1, $3);
|
$$ = merge_nodes($1, $3);
|
||||||
}
|
}
|
||||||
| DT_REF nodedef
|
| dt_ref nodedef
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We rely on the rule being always:
|
* We rely on the rule being always:
|
||||||
@ -176,9 +180,12 @@ devicetree:
|
|||||||
*/
|
*/
|
||||||
if (!($<flags>-1 & DTSF_PLUGIN))
|
if (!($<flags>-1 & DTSF_PLUGIN))
|
||||||
ERROR(&@2, "Label or path %s not found", $1);
|
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);
|
struct node *target = get_node_by_ref($1, $3);
|
||||||
|
|
||||||
@ -189,7 +196,7 @@ devicetree:
|
|||||||
ERROR(&@3, "Label or path %s not found", $3);
|
ERROR(&@3, "Label or path %s not found", $3);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| devicetree DT_REF nodedef
|
| devicetree DT_PATH_REF nodedef
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We rely on the rule being always:
|
* We rely on the rule being always:
|
||||||
@ -208,7 +215,26 @@ devicetree:
|
|||||||
}
|
}
|
||||||
$$ = $1;
|
$$ = $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);
|
struct node *target = get_node_by_ref($1, $3);
|
||||||
|
|
||||||
@ -220,7 +246,7 @@ devicetree:
|
|||||||
|
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| devicetree DT_OMIT_NO_REF DT_REF ';'
|
| devicetree DT_OMIT_NO_REF dt_ref ';'
|
||||||
{
|
{
|
||||||
struct node *target = get_node_by_ref($1, $3);
|
struct node *target = get_node_by_ref($1, $3);
|
||||||
|
|
||||||
@ -237,7 +263,7 @@ devicetree:
|
|||||||
nodedef:
|
nodedef:
|
||||||
'{' proplist subnodes '}' ';'
|
'{' proplist subnodes '}' ';'
|
||||||
{
|
{
|
||||||
$$ = build_node($2, $3);
|
$$ = build_node($2, $3, &@$);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -255,11 +281,11 @@ proplist:
|
|||||||
propdef:
|
propdef:
|
||||||
DT_PROPNODENAME '=' propdata ';'
|
DT_PROPNODENAME '=' propdata ';'
|
||||||
{
|
{
|
||||||
$$ = build_property($1, $3);
|
$$ = build_property($1, $3, &@$);
|
||||||
}
|
}
|
||||||
| DT_PROPNODENAME ';'
|
| DT_PROPNODENAME ';'
|
||||||
{
|
{
|
||||||
$$ = build_property($1, empty_data);
|
$$ = build_property($1, empty_data, &@$);
|
||||||
}
|
}
|
||||||
| DT_DEL_PROP DT_PROPNODENAME ';'
|
| DT_DEL_PROP DT_PROPNODENAME ';'
|
||||||
{
|
{
|
||||||
@ -285,7 +311,7 @@ propdata:
|
|||||||
{
|
{
|
||||||
$$ = data_merge($1, $3);
|
$$ = data_merge($1, $3);
|
||||||
}
|
}
|
||||||
| propdataprefix DT_REF
|
| propdataprefix dt_ref
|
||||||
{
|
{
|
||||||
$1 = data_add_marker($1, TYPE_STRING, $2);
|
$1 = data_add_marker($1, TYPE_STRING, $2);
|
||||||
$$ = data_add_marker($1, REF_PATH, $2);
|
$$ = data_add_marker($1, REF_PATH, $2);
|
||||||
@ -383,7 +409,7 @@ arrayprefix:
|
|||||||
|
|
||||||
$$.data = data_append_integer($1.data, $2, $1.bits);
|
$$.data = data_append_integer($1.data, $2, $1.bits);
|
||||||
}
|
}
|
||||||
| arrayprefix DT_REF
|
| arrayprefix dt_ref
|
||||||
{
|
{
|
||||||
uint64_t val = ~0ULL >> (64 - $1.bits);
|
uint64_t val = ~0ULL >> (64 - $1.bits);
|
||||||
|
|
||||||
@ -540,7 +566,7 @@ subnode:
|
|||||||
}
|
}
|
||||||
| DT_DEL_NODE DT_PROPNODENAME ';'
|
| DT_DEL_NODE DT_PROPNODENAME ';'
|
||||||
{
|
{
|
||||||
$$ = name_node(build_node_delete(), $2);
|
$$ = name_node(build_node_delete(&@$), $2);
|
||||||
}
|
}
|
||||||
| DT_OMIT_NO_REF subnode
|
| DT_OMIT_NO_REF subnode
|
||||||
{
|
{
|
||||||
|
@ -35,6 +35,8 @@ int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties *
|
|||||||
int generate_symbols; /* enable symbols & fixup support */
|
int generate_symbols; /* enable symbols & fixup support */
|
||||||
int generate_fixups; /* suppress generation of fixups on symbol support */
|
int generate_fixups; /* suppress generation of fixups on symbol support */
|
||||||
int auto_label_aliases; /* auto generate labels -> aliases */
|
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)
|
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. */
|
/* Usage related data. */
|
||||||
static const char usage_synopsis[] = "dtc [options] <input file>";
|
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[] = {
|
static struct option const usage_long_opts[] = {
|
||||||
{"quiet", no_argument, NULL, 'q'},
|
{"quiet", no_argument, NULL, 'q'},
|
||||||
{"in-format", a_argument, NULL, 'I'},
|
{"in-format", a_argument, NULL, 'I'},
|
||||||
@ -81,6 +83,7 @@ static struct option const usage_long_opts[] = {
|
|||||||
{"error", a_argument, NULL, 'E'},
|
{"error", a_argument, NULL, 'E'},
|
||||||
{"symbols", no_argument, NULL, '@'},
|
{"symbols", no_argument, NULL, '@'},
|
||||||
{"auto-alias", no_argument, NULL, 'A'},
|
{"auto-alias", no_argument, NULL, 'A'},
|
||||||
|
{"annotate", no_argument, NULL, 'T'},
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{"version", no_argument, NULL, 'v'},
|
{"version", no_argument, NULL, 'v'},
|
||||||
{NULL, no_argument, NULL, 0x0},
|
{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/disable errors (prefix with \"no-\")",
|
||||||
"\n\tEnable generation of symbols",
|
"\n\tEnable generation of symbols",
|
||||||
"\n\tEnable auto-alias of labels",
|
"\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 this help and exit",
|
||||||
"\n\tPrint version and exit",
|
"\n\tPrint version and exit",
|
||||||
NULL,
|
NULL,
|
||||||
@ -264,6 +268,9 @@ int main(int argc, char *argv[])
|
|||||||
case 'A':
|
case 'A':
|
||||||
auto_label_aliases = 1;
|
auto_label_aliases = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'T':
|
||||||
|
annotate++;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
usage(NULL);
|
usage(NULL);
|
||||||
@ -302,6 +309,8 @@ int main(int argc, char *argv[])
|
|||||||
outform = "dts";
|
outform = "dts";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (annotate && (!streq(inform, "dts") || !streq(outform, "dts")))
|
||||||
|
die("--annotate requires -I dts -O dts\n");
|
||||||
if (streq(inform, "dts"))
|
if (streq(inform, "dts"))
|
||||||
dti = dt_from_source(arg);
|
dti = dt_from_source(arg);
|
||||||
else if (streq(inform, "fs"))
|
else if (streq(inform, "fs"))
|
||||||
|
@ -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_symbols; /* generate symbols for nodes with labels */
|
||||||
extern int generate_fixups; /* generate fixups */
|
extern int generate_fixups; /* generate fixups */
|
||||||
extern int auto_label_aliases; /* auto generate labels -> aliases */
|
extern int auto_label_aliases; /* auto generate labels -> aliases */
|
||||||
|
extern int annotate; /* annotate .dts with input source location */
|
||||||
|
|
||||||
#define PHANDLE_LEGACY 0x1
|
#define PHANDLE_LEGACY 0x1
|
||||||
#define PHANDLE_EPAPR 0x2
|
#define PHANDLE_EPAPR 0x2
|
||||||
@ -158,6 +159,7 @@ struct property {
|
|||||||
struct property *next;
|
struct property *next;
|
||||||
|
|
||||||
struct label *labels;
|
struct label *labels;
|
||||||
|
struct srcpos *srcpos;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct node {
|
struct node {
|
||||||
@ -177,6 +179,7 @@ struct node {
|
|||||||
|
|
||||||
struct label *labels;
|
struct label *labels;
|
||||||
const struct bus_type *bus;
|
const struct bus_type *bus;
|
||||||
|
struct srcpos *srcpos;
|
||||||
|
|
||||||
bool omit_if_unused, is_referenced;
|
bool omit_if_unused, is_referenced;
|
||||||
};
|
};
|
||||||
@ -205,13 +208,15 @@ struct node {
|
|||||||
void add_label(struct label **labels, char *label);
|
void add_label(struct label **labels, char *label);
|
||||||
void delete_labels(struct label **labels);
|
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 *build_property_delete(char *name);
|
||||||
struct property *chain_property(struct property *first, struct property *list);
|
struct property *chain_property(struct property *first, struct property *list);
|
||||||
struct property *reverse_properties(struct property *first);
|
struct property *reverse_properties(struct property *first);
|
||||||
|
|
||||||
struct node *build_node(struct property *proplist, struct node *children);
|
struct node *build_node(struct property *proplist, struct node *children,
|
||||||
struct node *build_node_delete(void);
|
struct srcpos *srcpos);
|
||||||
|
struct node *build_node_delete(struct srcpos *srcpos);
|
||||||
struct node *name_node(struct node *node, char *name);
|
struct node *name_node(struct node *node, char *name);
|
||||||
struct node *omit_node_if_unused(struct node *node);
|
struct node *omit_node_if_unused(struct node *node);
|
||||||
struct node *reference_node(struct node *node);
|
struct node *reference_node(struct node *node);
|
||||||
|
@ -692,7 +692,7 @@ static struct property *flat_read_property(struct inbuf *dtbuf,
|
|||||||
|
|
||||||
val = flat_read_data(dtbuf, proplen);
|
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;
|
char *flatname;
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
|
|
||||||
node = build_node(NULL, NULL);
|
node = build_node(NULL, NULL, NULL);
|
||||||
|
|
||||||
flatname = flat_read_string(dtbuf);
|
flatname = flat_read_string(dtbuf);
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ static struct node *read_fstree(const char *dirname)
|
|||||||
if (!d)
|
if (!d)
|
||||||
die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno));
|
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) {
|
while ((de = readdir(d)) != NULL) {
|
||||||
char *tmpname;
|
char *tmpname;
|
||||||
@ -60,7 +60,8 @@ static struct node *read_fstree(const char *dirname)
|
|||||||
} else {
|
} else {
|
||||||
prop = build_property(xstrdup(de->d_name),
|
prop = build_property(xstrdup(de->d_name),
|
||||||
data_copy_file(pfile,
|
data_copy_file(pfile,
|
||||||
st.st_size));
|
st.st_size),
|
||||||
|
NULL);
|
||||||
add_property(tree, prop);
|
add_property(tree, prop);
|
||||||
fclose(pfile);
|
fclose(pfile);
|
||||||
}
|
}
|
||||||
|
@ -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 \
|
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
|
fdt_addresses.c fdt_overlay.c
|
||||||
LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
|
LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
|
||||||
|
|
||||||
|
libfdt_clean:
|
||||||
|
@$(VECHO) CLEAN "(libfdt)"
|
||||||
|
rm -f $(STD_CLEANFILES:%=$(LIBFDT_dir)/%)
|
||||||
|
@ -64,7 +64,7 @@ static int fdt_cells(const void *fdt, int nodeoffset, const char *name)
|
|||||||
|
|
||||||
c = fdt_getprop(fdt, nodeoffset, name, &len);
|
c = fdt_getprop(fdt, nodeoffset, name, &len);
|
||||||
if (!c)
|
if (!c)
|
||||||
return 2;
|
return len;
|
||||||
|
|
||||||
if (len != sizeof(*c))
|
if (len != sizeof(*c))
|
||||||
return -FDT_ERR_BADNCELLS;
|
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)
|
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)
|
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;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
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 ((uint32_t)bp[0] << 24)
|
||||||
return fdt32_to_cpu(v);
|
| ((uint32_t)bp[1] << 16)
|
||||||
|
| ((uint32_t)bp[2] << 8)
|
||||||
|
| bp[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t fdt64_ld(const fdt64_t *p)
|
static inline uint64_t fdt64_ld(const fdt64_t *p)
|
||||||
{
|
{
|
||||||
fdt64_t v;
|
const uint8_t *bp = (const uint8_t *)p;
|
||||||
|
|
||||||
memcpy(&v, p, sizeof(v));
|
return ((uint64_t)bp[0] << 56)
|
||||||
return fdt64_to_cpu(v);
|
| ((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:
|
* returns:
|
||||||
* 0 <= n < FDT_MAX_NCELLS, on success
|
* 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
|
* -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
|
||||||
* #size-cells property
|
* #size-cells property
|
||||||
* -FDT_ERR_BADMAGIC,
|
* -FDT_ERR_BADMAGIC,
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dtc.h"
|
#include "dtc.h"
|
||||||
|
#include "srcpos.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tree building functions
|
* Tree building functions
|
||||||
@ -50,7 +51,8 @@ void delete_labels(struct label **labels)
|
|||||||
label->deleted = 1;
|
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));
|
struct property *new = xmalloc(sizeof(*new));
|
||||||
|
|
||||||
@ -58,6 +60,7 @@ struct property *build_property(char *name, struct data val)
|
|||||||
|
|
||||||
new->name = name;
|
new->name = name;
|
||||||
new->val = val;
|
new->val = val;
|
||||||
|
new->srcpos = srcpos_copy(srcpos);
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
@ -97,7 +100,8 @@ struct property *reverse_properties(struct property *first)
|
|||||||
return head;
|
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 *new = xmalloc(sizeof(*new));
|
||||||
struct node *child;
|
struct node *child;
|
||||||
@ -106,6 +110,7 @@ struct node *build_node(struct property *proplist, struct node *children)
|
|||||||
|
|
||||||
new->proplist = reverse_properties(proplist);
|
new->proplist = reverse_properties(proplist);
|
||||||
new->children = children;
|
new->children = children;
|
||||||
|
new->srcpos = srcpos_copy(srcpos);
|
||||||
|
|
||||||
for_each_child(new, child) {
|
for_each_child(new, child) {
|
||||||
child->parent = new;
|
child->parent = new;
|
||||||
@ -114,13 +119,14 @@ struct node *build_node(struct property *proplist, struct node *children)
|
|||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct node *build_node_delete(void)
|
struct node *build_node_delete(struct srcpos *srcpos)
|
||||||
{
|
{
|
||||||
struct node *new = xmalloc(sizeof(*new));
|
struct node *new = xmalloc(sizeof(*new));
|
||||||
|
|
||||||
memset(new, 0, sizeof(*new));
|
memset(new, 0, sizeof(*new));
|
||||||
|
|
||||||
new->deleted = 1;
|
new->deleted = 1;
|
||||||
|
new->srcpos = srcpos_copy(srcpos);
|
||||||
|
|
||||||
return new;
|
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->val = new_prop->val;
|
||||||
old_prop->deleted = 0;
|
old_prop->deleted = 0;
|
||||||
|
free(old_prop->srcpos);
|
||||||
|
old_prop->srcpos = new_prop->srcpos;
|
||||||
free(new_prop);
|
free(new_prop);
|
||||||
new_prop = NULL;
|
new_prop = NULL;
|
||||||
break;
|
break;
|
||||||
@ -223,6 +231,8 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
|
|||||||
add_child(old_node, new_child);
|
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 contents are now merged into the old node. Free
|
||||||
* the new node. */
|
* the new node. */
|
||||||
free(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] == '/') {
|
if (ref[0] == '/') {
|
||||||
d = data_append_data(d, ref, strlen(ref) + 1);
|
d = data_append_data(d, ref, strlen(ref) + 1);
|
||||||
|
|
||||||
p = build_property("target-path", d);
|
p = build_property("target-path", d, NULL);
|
||||||
} else {
|
} else {
|
||||||
d = data_add_marker(d, REF_PHANDLE, ref);
|
d = data_add_marker(d, REF_PHANDLE, ref);
|
||||||
d = data_append_integer(d, 0xffffffff, 32);
|
d = data_append_integer(d, 0xffffffff, 32);
|
||||||
|
|
||||||
p = build_property("target", d);
|
p = build_property("target", d, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
xasprintf(&name, "fragment@%u",
|
xasprintf(&name, "fragment@%u",
|
||||||
next_orphan_fragment++);
|
next_orphan_fragment++);
|
||||||
name_node(new_node, "__overlay__");
|
name_node(new_node, "__overlay__");
|
||||||
node = build_node(p, new_node);
|
node = build_node(p, new_node, NULL);
|
||||||
name_node(node, name);
|
name_node(node, name);
|
||||||
|
|
||||||
add_child(dt, node);
|
add_child(dt, node);
|
||||||
@ -351,7 +361,7 @@ void append_to_property(struct node *node,
|
|||||||
p->val = d;
|
p->val = d;
|
||||||
} else {
|
} else {
|
||||||
d = data_append_data(empty_data, data, len);
|
d = data_append_data(empty_data, data, len);
|
||||||
p = build_property(name, d);
|
p = build_property(name, d, NULL);
|
||||||
add_property(node, p);
|
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")
|
if (!get_property(node, "linux,phandle")
|
||||||
&& (phandle_format & PHANDLE_LEGACY))
|
&& (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")
|
if (!get_property(node, "phandle")
|
||||||
&& (phandle_format & PHANDLE_EPAPR))
|
&& (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
|
/* If the node *does* have a phandle property, we must
|
||||||
* be dealing with a self-referencing phandle, which will be
|
* 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;
|
struct node *node;
|
||||||
|
|
||||||
node = build_node(NULL, NULL);
|
node = build_node(NULL, NULL, NULL);
|
||||||
name_node(node, xstrdup(name));
|
name_node(node, xstrdup(name));
|
||||||
add_child(parent, node);
|
add_child(parent, node);
|
||||||
|
|
||||||
@ -849,7 +859,8 @@ static void generate_label_tree_internal(struct dt_info *dti,
|
|||||||
/* insert it */
|
/* insert it */
|
||||||
p = build_property(l->label,
|
p = build_property(l->label,
|
||||||
data_copy_mem(node->fullpath,
|
data_copy_mem(node->fullpath,
|
||||||
strlen(node->fullpath) + 1));
|
strlen(node->fullpath) + 1),
|
||||||
|
NULL);
|
||||||
add_property(an, p);
|
add_property(an, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,9 @@ struct search_path {
|
|||||||
/* This is the list of directories that we search for source files */
|
/* This is the list of directories that we search for source files */
|
||||||
static struct search_path *search_path_head, **search_path_tail;
|
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)
|
static char *get_dirname(const char *path)
|
||||||
{
|
{
|
||||||
@ -51,11 +54,51 @@ static char *get_dirname(const char *path)
|
|||||||
|
|
||||||
FILE *depfile; /* = NULL */
|
FILE *depfile; /* = NULL */
|
||||||
struct srcfile_state *current_srcfile; /* = 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. */
|
static void set_initial_path(char *fname)
|
||||||
#define MAX_SRCFILE_DEPTH (100)
|
{
|
||||||
static int srcfile_depth; /* = 0 */
|
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.
|
* Try to open a file in a given directory.
|
||||||
@ -157,6 +200,9 @@ void srcfile_push(const char *fname)
|
|||||||
srcfile->colno = 1;
|
srcfile->colno = 1;
|
||||||
|
|
||||||
current_srcfile = srcfile;
|
current_srcfile = srcfile;
|
||||||
|
|
||||||
|
if (srcfile_depth == 1)
|
||||||
|
set_initial_path(srcfile->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool srcfile_pop(void)
|
bool srcfile_pop(void)
|
||||||
@ -197,18 +243,6 @@ void srcfile_add_search_path(const char *dirname)
|
|||||||
search_path_tail = &node->next;
|
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)
|
void srcpos_update(struct srcpos *pos, const char *text, int len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -234,13 +268,35 @@ struct srcpos *
|
|||||||
srcpos_copy(struct srcpos *pos)
|
srcpos_copy(struct srcpos *pos)
|
||||||
{
|
{
|
||||||
struct srcpos *pos_new;
|
struct srcpos *pos_new;
|
||||||
|
struct srcfile_state *srcfile_state;
|
||||||
|
|
||||||
|
if (!pos)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
pos_new = xmalloc(sizeof(struct srcpos));
|
pos_new = xmalloc(sizeof(struct srcpos));
|
||||||
|
assert(pos->next == NULL);
|
||||||
memcpy(pos_new, pos, sizeof(struct srcpos));
|
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;
|
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 *
|
char *
|
||||||
srcpos_string(struct srcpos *pos)
|
srcpos_string(struct srcpos *pos)
|
||||||
{
|
{
|
||||||
@ -266,6 +322,68 @@ srcpos_string(struct srcpos *pos)
|
|||||||
return pos_str;
|
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,
|
void srcpos_verror(struct srcpos *pos, const char *prefix,
|
||||||
const char *fmt, va_list va)
|
const char *fmt, va_list va)
|
||||||
{
|
{
|
||||||
@ -294,4 +412,9 @@ void srcpos_set_line(char *f, int l)
|
|||||||
{
|
{
|
||||||
current_srcfile->name = f;
|
current_srcfile->name = f;
|
||||||
current_srcfile->lineno = l;
|
current_srcfile->lineno = l;
|
||||||
|
|
||||||
|
if (initial_cpp) {
|
||||||
|
initial_cpp = false;
|
||||||
|
set_initial_path(f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,7 @@ struct srcpos {
|
|||||||
int last_line;
|
int last_line;
|
||||||
int last_column;
|
int last_column;
|
||||||
struct srcfile_state *file;
|
struct srcfile_state *file;
|
||||||
|
struct srcpos *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define YYLTYPE struct srcpos
|
#define YYLTYPE struct srcpos
|
||||||
@ -93,19 +94,18 @@ struct srcpos {
|
|||||||
YYRHSLOC(Rhs, 0).last_column; \
|
YYRHSLOC(Rhs, 0).last_column; \
|
||||||
(Current).file = YYRHSLOC (Rhs, 0).file; \
|
(Current).file = YYRHSLOC (Rhs, 0).file; \
|
||||||
} \
|
} \
|
||||||
|
(Current).next = NULL; \
|
||||||
} while (0)
|
} 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 void srcpos_update(struct srcpos *pos, const char *text, int len);
|
||||||
extern struct srcpos *srcpos_copy(struct srcpos *pos);
|
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(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,
|
extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix,
|
||||||
const char *fmt, va_list va);
|
const char *fmt, va_list va);
|
||||||
|
@ -64,6 +64,10 @@ static bool isstring(char c)
|
|||||||
static void write_propval_string(FILE *f, const char *s, size_t len)
|
static void write_propval_string(FILE *f, const char *s, size_t len)
|
||||||
{
|
{
|
||||||
const char *end = s + len - 1;
|
const char *end = s + len - 1;
|
||||||
|
|
||||||
|
if (!len)
|
||||||
|
return;
|
||||||
|
|
||||||
assert(*end == '\0');
|
assert(*end == '\0');
|
||||||
|
|
||||||
fprintf(f, "\"");
|
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) {
|
for (; p < end; p += width) {
|
||||||
switch (width) {
|
switch (width) {
|
||||||
case 1:
|
case 1:
|
||||||
fprintf(f, " %02"PRIx8, *(const uint8_t*)p);
|
fprintf(f, "%02"PRIx8, *(const uint8_t*)p);
|
||||||
break;
|
break;
|
||||||
case 2:
|
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;
|
break;
|
||||||
case 4:
|
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;
|
break;
|
||||||
case 8:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
if (p + width < end)
|
||||||
|
fputc(' ', f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,10 +168,10 @@ static const char *delim_start[] = {
|
|||||||
[TYPE_STRING] = "",
|
[TYPE_STRING] = "",
|
||||||
};
|
};
|
||||||
static const char *delim_end[] = {
|
static const char *delim_end[] = {
|
||||||
[TYPE_UINT8] = " ]",
|
[TYPE_UINT8] = "]",
|
||||||
[TYPE_UINT16] = " >",
|
[TYPE_UINT16] = ">",
|
||||||
[TYPE_UINT32] = " >",
|
[TYPE_UINT32] = ">",
|
||||||
[TYPE_UINT64] = " >",
|
[TYPE_UINT64] = ">",
|
||||||
[TYPE_STRING] = "",
|
[TYPE_STRING] = "",
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -208,13 +214,22 @@ static void write_propval(FILE *f, struct property *prop)
|
|||||||
struct marker *m = prop->val.markers;
|
struct marker *m = prop->val.markers;
|
||||||
struct marker dummy_marker;
|
struct marker dummy_marker;
|
||||||
enum markertype emit_type = TYPE_NONE;
|
enum markertype emit_type = TYPE_NONE;
|
||||||
|
char *srcstr;
|
||||||
|
|
||||||
if (len == 0) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, " = ");
|
fprintf(f, " =");
|
||||||
|
|
||||||
if (!next_type_marker(m)) {
|
if (!next_type_marker(m)) {
|
||||||
/* data type information missing, need to guess */
|
/* data type information missing, need to guess */
|
||||||
@ -225,33 +240,24 @@ static void write_propval(FILE *f, struct property *prop)
|
|||||||
m = &dummy_marker;
|
m = &dummy_marker;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct marker *m_label = prop->val.markers;
|
|
||||||
for_each_marker(m) {
|
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];
|
const char *p = &prop->val.val[m->offset];
|
||||||
|
|
||||||
if (!has_data_type_information(m))
|
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 (emit_type == TYPE_NONE) {
|
||||||
|
assert(chunk_len == 0);
|
||||||
continue;
|
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 (chunk_len <= 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
switch(emit_type) {
|
switch(emit_type) {
|
||||||
case TYPE_UINT16:
|
case TYPE_UINT16:
|
||||||
write_propval_int(f, p, chunk_len, 2);
|
write_propval_int(f, p, chunk_len, 2);
|
||||||
@ -268,15 +274,23 @@ static void write_propval(FILE *f, struct property *prop)
|
|||||||
default:
|
default:
|
||||||
write_propval_int(f, p, chunk_len, 1);
|
write_propval_int(f, p, chunk_len, 1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Wrap up any labels at the end of the value */
|
if (chunk_len == data_len) {
|
||||||
for_each_marker_of_type(m_label, LABEL) {
|
size_t pos = m->offset + chunk_len;
|
||||||
assert (m_label->offset == len);
|
fprintf(f, pos == len ? "%s" : "%s,",
|
||||||
fprintf(f, " %s:", m_label->ref);
|
delim_end[emit_type] ? : "");
|
||||||
|
emit_type = TYPE_NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
fprintf(f, ";");
|
||||||
fprintf(f, "%s;\n", delim_end[emit_type] ? : "");
|
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)
|
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 property *prop;
|
||||||
struct node *child;
|
struct node *child;
|
||||||
struct label *l;
|
struct label *l;
|
||||||
|
char *srcstr;
|
||||||
|
|
||||||
write_prefix(f, level);
|
write_prefix(f, level);
|
||||||
for_each_label(tree->labels, l)
|
for_each_label(tree->labels, l)
|
||||||
fprintf(f, "%s: ", l->label);
|
fprintf(f, "%s: ", l->label);
|
||||||
if (tree->name && (*tree->name))
|
if (tree->name && (*tree->name))
|
||||||
fprintf(f, "%s {\n", tree->name);
|
fprintf(f, "%s {", tree->name);
|
||||||
else
|
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) {
|
for_each_property(tree, prop) {
|
||||||
write_prefix(f, level+1);
|
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_tree_source_node(f, child, level+1);
|
||||||
}
|
}
|
||||||
write_prefix(f, level);
|
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)
|
void dt_to_source(FILE *f, struct dt_info *dti)
|
||||||
{
|
{
|
||||||
struct reserve_info *re;
|
struct reserve_info *re;
|
||||||
|
@ -46,36 +46,54 @@ char *xstrdup(const char *s)
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* based in part from (3) vsnprintf */
|
int xavsprintf_append(char **strp, const char *fmt, va_list ap)
|
||||||
int xasprintf(char **strp, const char *fmt, ...)
|
|
||||||
{
|
{
|
||||||
int n, size = 128; /* start with 128 bytes */
|
int n, size = 0; /* start with 128 bytes */
|
||||||
char *p;
|
char *p;
|
||||||
va_list ap;
|
va_list ap_copy;
|
||||||
|
|
||||||
/* initial pointer is NULL making the fist realloc to be malloc */
|
p = *strp;
|
||||||
p = NULL;
|
if (p)
|
||||||
while (1) {
|
size = strlen(p);
|
||||||
p = xrealloc(p, size);
|
|
||||||
|
|
||||||
/* Try to print in the allocated space. */
|
va_copy(ap_copy, ap);
|
||||||
va_start(ap, fmt);
|
n = vsnprintf(NULL, 0, fmt, ap_copy) + 1;
|
||||||
n = vsnprintf(p, size, fmt, ap);
|
va_end(ap_copy);
|
||||||
va_end(ap);
|
|
||||||
|
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;
|
*strp = p;
|
||||||
return strlen(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)
|
char *join_path(const char *path, const char *name)
|
||||||
{
|
{
|
||||||
int lenp = strlen(path);
|
int lenp = strlen(path);
|
||||||
|
@ -72,6 +72,8 @@ static inline void *xrealloc(void *p, size_t len)
|
|||||||
extern char *xstrdup(const char *s);
|
extern char *xstrdup(const char *s);
|
||||||
|
|
||||||
extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...);
|
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);
|
extern char *join_path(const char *path, const char *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1 +1 @@
|
|||||||
#define DTC_VERSION "DTC 1.4.7-gc86da84d"
|
#define DTC_VERSION "DTC 1.4.7-gf267e674"
|
||||||
|
Loading…
Reference in New Issue
Block a user