|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
/*
|
|
|
|
* (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "dtc.h"
|
|
|
|
|
|
|
|
void data_free(struct data d)
|
|
|
|
{
|
|
|
|
struct marker *m, *nm;
|
|
|
|
|
|
|
|
m = d.markers;
|
|
|
|
while (m) {
|
|
|
|
nm = m->next;
|
|
|
|
free(m->ref);
|
|
|
|
free(m);
|
|
|
|
m = nm;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (d.val)
|
|
|
|
free(d.val);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct data data_grow_for(struct data d, unsigned int xlen)
|
|
|
|
{
|
|
|
|
struct data nd;
|
|
|
|
unsigned int newsize;
|
|
|
|
|
|
|
|
if (xlen == 0)
|
|
|
|
return d;
|
|
|
|
|
|
|
|
nd = d;
|
|
|
|
|
|
|
|
newsize = xlen;
|
|
|
|
|
|
|
|
while ((d.len + xlen) > newsize)
|
|
|
|
newsize *= 2;
|
|
|
|
|
|
|
|
nd.val = xrealloc(d.val, newsize);
|
|
|
|
|
|
|
|
return nd;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct data data_copy_mem(const char *mem, int len)
|
|
|
|
{
|
|
|
|
struct data d;
|
|
|
|
|
|
|
|
d = data_grow_for(empty_data, len);
|
|
|
|
|
|
|
|
d.len = len;
|
|
|
|
memcpy(d.val, mem, len);
|
|
|
|
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct data data_copy_escape_string(const char *s, int len)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
struct data d;
|
|
|
|
char *q;
|
|
|
|
|
|
|
|
d = data_add_marker(empty_data, TYPE_STRING, NULL);
|
|
|
|
d = data_grow_for(d, len + 1);
|
|
|
|
|
|
|
|
q = d.val;
|
|
|
|
while (i < len) {
|
|
|
|
char c = s[i++];
|
|
|
|
|
|
|
|
if (c == '\\')
|
|
|
|
c = get_escape_char(s, &i);
|
|
|
|
|
|
|
|
q[d.len++] = c;
|
|
|
|
}
|
|
|
|
|
|
|
|
q[d.len++] = '\0';
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
dtc: Add support for binary includes.
On Wed, Jun 04, 2008 at 09:26:23AM -0500, Jon Loeliger wrote:
> David Gibson wrote:
>
>> But as I said that can be dealt with in the future without breaking
>> compatibility. Objection withdrawn.
>>
>
> And on that note, I officially implore Scott to
> re-submit his binary include patch!
Scott's original patch does still have some implementation details I
didn't like. So in the interests of saving time, I've addressed some
of those, added a testcase, and and now resubmitting my revised
version of Scott's patch.
dtc: Add support for binary includes.
A property's data can be populated with a file's contents
as follows:
node {
prop = /incbin/("path/to/data");
};
A subset of a file can be included by passing start and size parameters.
For example, to include bytes 8 through 23:
node {
prop = /incbin/("path/to/data", 8, 16);
};
As with /include/, non-absolute paths are looked for in the directory
of the source file that includes them.
Implementation revised, and a testcase added by David Gibson
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Acked-by: Scott Wood <scottwood@freescale.com>
17 years ago
|
|
|
struct data data_copy_file(FILE *f, size_t maxlen)
|
|
|
|
{
|
dtc: Add support for binary includes.
On Wed, Jun 04, 2008 at 09:26:23AM -0500, Jon Loeliger wrote:
> David Gibson wrote:
>
>> But as I said that can be dealt with in the future without breaking
>> compatibility. Objection withdrawn.
>>
>
> And on that note, I officially implore Scott to
> re-submit his binary include patch!
Scott's original patch does still have some implementation details I
didn't like. So in the interests of saving time, I've addressed some
of those, added a testcase, and and now resubmitting my revised
version of Scott's patch.
dtc: Add support for binary includes.
A property's data can be populated with a file's contents
as follows:
node {
prop = /incbin/("path/to/data");
};
A subset of a file can be included by passing start and size parameters.
For example, to include bytes 8 through 23:
node {
prop = /incbin/("path/to/data", 8, 16);
};
As with /include/, non-absolute paths are looked for in the directory
of the source file that includes them.
Implementation revised, and a testcase added by David Gibson
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Acked-by: Scott Wood <scottwood@freescale.com>
17 years ago
|
|
|
struct data d = empty_data;
|
|
|
|
|
Kill bogus TYPE_BLOB marker type
Since commit 32b9c6130762 "Preserve datatype markers when emitting dts
format", we no longer try to guess the value type. Instead, we reuse
the type of the datatype markers when they are present, if the type
is either TYPE_UINT* or TYPE_STRING.
This causes 'dtc -I fs' to crash:
Starting program: /root/dtc -q -f -O dts -I fs /proc/device-tree
/dts-v1/;
/ {
Program received signal SIGSEGV, Segmentation fault.
__strlen_power8 () at ../sysdeps/powerpc/powerpc64/power8/strlen.S:47
47 ld r12,0(r4) /* Load doubleword from memory. */
(gdb) bt
#0 __strlen_power8 () at ../sysdeps/powerpc/powerpc64/power8/strlen.S:47
#1 0x00007ffff7de3d10 in __GI__IO_fputs (str=<optimized out>,
fp=<optimized out>) at iofputs.c:33
#2 0x000000001000c7a0 in write_propval (prop=0x100525e0,
f=0x7ffff7f718a0 <_IO_2_1_stdout_>) at treesource.c:245
The offending line is:
fprintf(f, "%s", delim_start[emit_type]);
where emit_type is TYPE_BLOB and:
static const char *delim_start[] = {
[TYPE_UINT8] = "[",
[TYPE_UINT16] = "/bits/ 16 <",
[TYPE_UINT32] = "<",
[TYPE_UINT64] = "/bits/ 64 <",
[TYPE_STRING] = "",
};
/* Data blobs */
enum markertype {
TYPE_NONE,
REF_PHANDLE,
REF_PATH,
LABEL,
TYPE_UINT8,
TYPE_UINT16,
TYPE_UINT32,
TYPE_UINT64,
TYPE_BLOB,
TYPE_STRING,
};
Because TYPE_BLOB < TYPE_STRING and delim_start[] is a static array,
delim_start[emit_type] is 0x0. The glibc usually prints out "(null)"
when one passes 0x0 to %s, but it seems to call fputs() internally if
the format is exactly "%s", hence the crash.
TYPE_BLOB basically means the data comes from a file and we don't know
its type. We don't care for the former, and the latter is TYPE_NONE.
So let's drop TYPE_BLOB completely and use TYPE_NONE instead when reading
the file. Then, try to guess the data type at emission time, like the
code already does for refs and labels.
Instead of adding yet another check for TYPE_NONE, an helper is introduced
to check if the data marker has type information, ie, >= TYPE_UINT8.
Fixes: 32b9c61307629ac76c6ac0bead6f926d579b3d2c
Suggested-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
6 years ago
|
|
|
d = data_add_marker(d, TYPE_NONE, NULL);
|
dtc: Add support for binary includes.
On Wed, Jun 04, 2008 at 09:26:23AM -0500, Jon Loeliger wrote:
> David Gibson wrote:
>
>> But as I said that can be dealt with in the future without breaking
>> compatibility. Objection withdrawn.
>>
>
> And on that note, I officially implore Scott to
> re-submit his binary include patch!
Scott's original patch does still have some implementation details I
didn't like. So in the interests of saving time, I've addressed some
of those, added a testcase, and and now resubmitting my revised
version of Scott's patch.
dtc: Add support for binary includes.
A property's data can be populated with a file's contents
as follows:
node {
prop = /incbin/("path/to/data");
};
A subset of a file can be included by passing start and size parameters.
For example, to include bytes 8 through 23:
node {
prop = /incbin/("path/to/data", 8, 16);
};
As with /include/, non-absolute paths are looked for in the directory
of the source file that includes them.
Implementation revised, and a testcase added by David Gibson
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Acked-by: Scott Wood <scottwood@freescale.com>
17 years ago
|
|
|
while (!feof(f) && (d.len < maxlen)) {
|
|
|
|
size_t chunksize, ret;
|
|
|
|
|
|
|
|
if (maxlen == (size_t)-1)
|
dtc: Add support for binary includes.
On Wed, Jun 04, 2008 at 09:26:23AM -0500, Jon Loeliger wrote:
> David Gibson wrote:
>
>> But as I said that can be dealt with in the future without breaking
>> compatibility. Objection withdrawn.
>>
>
> And on that note, I officially implore Scott to
> re-submit his binary include patch!
Scott's original patch does still have some implementation details I
didn't like. So in the interests of saving time, I've addressed some
of those, added a testcase, and and now resubmitting my revised
version of Scott's patch.
dtc: Add support for binary includes.
A property's data can be populated with a file's contents
as follows:
node {
prop = /incbin/("path/to/data");
};
A subset of a file can be included by passing start and size parameters.
For example, to include bytes 8 through 23:
node {
prop = /incbin/("path/to/data", 8, 16);
};
As with /include/, non-absolute paths are looked for in the directory
of the source file that includes them.
Implementation revised, and a testcase added by David Gibson
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Acked-by: Scott Wood <scottwood@freescale.com>
17 years ago
|
|
|
chunksize = 4096;
|
|
|
|
else
|
|
|
|
chunksize = maxlen - d.len;
|
|
|
|
|
|
|
|
d = data_grow_for(d, chunksize);
|
|
|
|
ret = fread(d.val + d.len, 1, chunksize, f);
|
|
|
|
|
|
|
|
if (ferror(f))
|
|
|
|
die("Error reading file into data: %s", strerror(errno));
|
|
|
|
|
|
|
|
if (d.len + ret < d.len)
|
|
|
|
die("Overflow reading file into data\n");
|
|
|
|
|
|
|
|
d.len += ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct data data_append_data(struct data d, const void *p, int len)
|
|
|
|
{
|
|
|
|
d = data_grow_for(d, len);
|
|
|
|
memcpy(d.val + d.len, p, len);
|
|
|
|
d.len += len;
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct data data_insert_at_marker(struct data d, struct marker *m,
|
|
|
|
const void *p, int len)
|
|
|
|
{
|
|
|
|
d = data_grow_for(d, len);
|
|
|
|
memmove(d.val + m->offset + len, d.val + m->offset, d.len - m->offset);
|
|
|
|
memcpy(d.val + m->offset, p, len);
|
|
|
|
d.len += len;
|
|
|
|
|
|
|
|
/* Adjust all markers after the one we're inserting at */
|
|
|
|
m = m->next;
|
|
|
|
for_each_marker(m)
|
|
|
|
m->offset += len;
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct data data_append_markers(struct data d, struct marker *m)
|
|
|
|
{
|
|
|
|
struct marker **mp = &d.markers;
|
dtc: implement labels on property data
Extend the parser grammer to allow labels before or after any
property data (string, cell list, or byte list), and any
byte or cell within the property data.
Store the labels using the same linked list structure as node
references, but using a parallel list.
When writing assembly output emit global labels as offsets from
the start of the definition of the data.
Note that the alignment for a cell list is done as part of the
opening < delimiter, not the = or , before it. To label a cell
after a string or byte list put the label inside the cell list.
For example,
prop = zero: [ aa bb ], two: < four: 1234 > eight: ;
will produce labels with offsets 0, 2, 4, and 8 bytes from
the beginning of the data for property prop.
Signed-off-by: Milton Miller <miltonm@bga.com>
18 years ago
|
|
|
|
|
|
|
/* Find the end of the markerlist */
|
|
|
|
while (*mp)
|
|
|
|
mp = &((*mp)->next);
|
|
|
|
*mp = m;
|
|
|
|
return d;
|
dtc: implement labels on property data
Extend the parser grammer to allow labels before or after any
property data (string, cell list, or byte list), and any
byte or cell within the property data.
Store the labels using the same linked list structure as node
references, but using a parallel list.
When writing assembly output emit global labels as offsets from
the start of the definition of the data.
Note that the alignment for a cell list is done as part of the
opening < delimiter, not the = or , before it. To label a cell
after a string or byte list put the label inside the cell list.
For example,
prop = zero: [ aa bb ], two: < four: 1234 > eight: ;
will produce labels with offsets 0, 2, 4, and 8 bytes from
the beginning of the data for property prop.
Signed-off-by: Milton Miller <miltonm@bga.com>
18 years ago
|
|
|
}
|
|
|
|
|
|
|
|
struct data data_merge(struct data d1, struct data d2)
|
|
|
|
{
|
|
|
|
struct data d;
|
|
|
|
struct marker *m2 = d2.markers;
|
dtc: implement labels on property data
Extend the parser grammer to allow labels before or after any
property data (string, cell list, or byte list), and any
byte or cell within the property data.
Store the labels using the same linked list structure as node
references, but using a parallel list.
When writing assembly output emit global labels as offsets from
the start of the definition of the data.
Note that the alignment for a cell list is done as part of the
opening < delimiter, not the = or , before it. To label a cell
after a string or byte list put the label inside the cell list.
For example,
prop = zero: [ aa bb ], two: < four: 1234 > eight: ;
will produce labels with offsets 0, 2, 4, and 8 bytes from
the beginning of the data for property prop.
Signed-off-by: Milton Miller <miltonm@bga.com>
18 years ago
|
|
|
|
|
|
|
d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2);
|
dtc: implement labels on property data
Extend the parser grammer to allow labels before or after any
property data (string, cell list, or byte list), and any
byte or cell within the property data.
Store the labels using the same linked list structure as node
references, but using a parallel list.
When writing assembly output emit global labels as offsets from
the start of the definition of the data.
Note that the alignment for a cell list is done as part of the
opening < delimiter, not the = or , before it. To label a cell
after a string or byte list put the label inside the cell list.
For example,
prop = zero: [ aa bb ], two: < four: 1234 > eight: ;
will produce labels with offsets 0, 2, 4, and 8 bytes from
the beginning of the data for property prop.
Signed-off-by: Milton Miller <miltonm@bga.com>
18 years ago
|
|
|
|
|
|
|
/* Adjust for the length of d1 */
|
|
|
|
for_each_marker(m2)
|
|
|
|
m2->offset += d1.len;
|
|
|
|
|
|
|
|
d2.markers = NULL; /* So data_free() doesn't clobber them */
|
|
|
|
data_free(d2);
|
|
|
|
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct data data_append_integer(struct data d, uint64_t value, int bits)
|
|
|
|
{
|
|
|
|
uint8_t value_8;
|
|
|
|
fdt16_t value_16;
|
|
|
|
fdt32_t value_32;
|
|
|
|
fdt64_t value_64;
|
|
|
|
|
|
|
|
switch (bits) {
|
|
|
|
case 8:
|
|
|
|
value_8 = value;
|
|
|
|
return data_append_data(d, &value_8, 1);
|
|
|
|
|
|
|
|
case 16:
|
|
|
|
value_16 = cpu_to_fdt16(value);
|
|
|
|
return data_append_data(d, &value_16, 2);
|
|
|
|
|
|
|
|
case 32:
|
|
|
|
value_32 = cpu_to_fdt32(value);
|
|
|
|
return data_append_data(d, &value_32, 4);
|
|
|
|
|
|
|
|
case 64:
|
|
|
|
value_64 = cpu_to_fdt64(value);
|
|
|
|
return data_append_data(d, &value_64, 8);
|
|
|
|
|
|
|
|
default:
|
|
|
|
die("Invalid literal size (%d)\n", bits);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct data data_append_re(struct data d, uint64_t address, uint64_t size)
|
|
|
|
{
|
|
|
|
struct fdt_reserve_entry re;
|
|
|
|
|
|
|
|
re.address = cpu_to_fdt64(address);
|
|
|
|
re.size = cpu_to_fdt64(size);
|
|
|
|
|
|
|
|
return data_append_data(d, &re, sizeof(re));
|
|
|
|
}
|
|
|
|
|
|
|
|
struct data data_append_cell(struct data d, cell_t word)
|
|
|
|
{
|
|
|
|
return data_append_integer(d, word, sizeof(word) * 8);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct data data_append_addr(struct data d, uint64_t addr)
|
|
|
|
{
|
|
|
|
return data_append_integer(d, addr, sizeof(addr) * 8);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct data data_append_byte(struct data d, uint8_t byte)
|
|
|
|
{
|
|
|
|
return data_append_data(d, &byte, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct data data_append_zeroes(struct data d, int len)
|
|
|
|
{
|
|
|
|
d = data_grow_for(d, len);
|
|
|
|
|
|
|
|
memset(d.val + d.len, 0, len);
|
|
|
|
d.len += len;
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct data data_append_align(struct data d, int align)
|
|
|
|
{
|
|
|
|
int newlen = ALIGN(d.len, align);
|
|
|
|
return data_append_zeroes(d, newlen - d.len);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct data data_add_marker(struct data d, enum markertype type, char *ref)
|
dtc: implement labels on property data
Extend the parser grammer to allow labels before or after any
property data (string, cell list, or byte list), and any
byte or cell within the property data.
Store the labels using the same linked list structure as node
references, but using a parallel list.
When writing assembly output emit global labels as offsets from
the start of the definition of the data.
Note that the alignment for a cell list is done as part of the
opening < delimiter, not the = or , before it. To label a cell
after a string or byte list put the label inside the cell list.
For example,
prop = zero: [ aa bb ], two: < four: 1234 > eight: ;
will produce labels with offsets 0, 2, 4, and 8 bytes from
the beginning of the data for property prop.
Signed-off-by: Milton Miller <miltonm@bga.com>
18 years ago
|
|
|
{
|
|
|
|
struct marker *m;
|
|
|
|
|
|
|
|
m = xmalloc(sizeof(*m));
|
|
|
|
m->offset = d.len;
|
|
|
|
m->type = type;
|
|
|
|
m->ref = ref;
|
|
|
|
m->next = NULL;
|
dtc: implement labels on property data
Extend the parser grammer to allow labels before or after any
property data (string, cell list, or byte list), and any
byte or cell within the property data.
Store the labels using the same linked list structure as node
references, but using a parallel list.
When writing assembly output emit global labels as offsets from
the start of the definition of the data.
Note that the alignment for a cell list is done as part of the
opening < delimiter, not the = or , before it. To label a cell
after a string or byte list put the label inside the cell list.
For example,
prop = zero: [ aa bb ], two: < four: 1234 > eight: ;
will produce labels with offsets 0, 2, 4, and 8 bytes from
the beginning of the data for property prop.
Signed-off-by: Milton Miller <miltonm@bga.com>
18 years ago
|
|
|
|
|
|
|
return data_append_markers(d, m);
|
dtc: implement labels on property data
Extend the parser grammer to allow labels before or after any
property data (string, cell list, or byte list), and any
byte or cell within the property data.
Store the labels using the same linked list structure as node
references, but using a parallel list.
When writing assembly output emit global labels as offsets from
the start of the definition of the data.
Note that the alignment for a cell list is done as part of the
opening < delimiter, not the = or , before it. To label a cell
after a string or byte list put the label inside the cell list.
For example,
prop = zero: [ aa bb ], two: < four: 1234 > eight: ;
will produce labels with offsets 0, 2, 4, and 8 bytes from
the beginning of the data for property prop.
Signed-off-by: Milton Miller <miltonm@bga.com>
18 years ago
|
|
|
}
|
|
|
|
|
|
|
|
bool data_is_one_string(struct data d)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int len = d.len;
|
|
|
|
|
|
|
|
if (len == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (i = 0; i < len-1; i++)
|
|
|
|
if (d.val[i] == '\0')
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (d.val[len-1] != '\0')
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|