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.
Signed-off-by: Scott Wood <[EMAIL PROTECTED]>
---
Makefile |2 +-
data.c | 37 -
dtc-lexer.l |7 +++
dtc-parser.y | 49 +
dtc.h|5 +
5 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index 6e07862..578d8c1 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ LOCAL_VERSION =
CONFIG_LOCALVERSION =
CPPFLAGS = -I libfdt
-CFLAGS = -Wall -g -Os
+CFLAGS = -Wall -g -Os -D_FILE_OFFSET_BITS=64
BISON = bison
LEX = flex
diff --git a/data.c b/data.c
index a94718c..f9464bf 100644
--- a/data.c
+++ b/data.c
@@ -19,6 +19,7 @@
*/
#include "dtc.h"
+#include "srcpos.h"
void data_free(struct data d)
{
@@ -189,7 +190,41 @@ struct data data_copy_file(FILE *f, size_t len)
d = data_grow_for(empty_data, len);
d.len = len;
- fread(d.val, len, 1, f);
+ if (fread(d.val, len, 1, f) != 1) {
+ yyerrorf("Couldn't read %zu bytes from file: %s",
+len, feof(f) ? "end-of-file" : strerror(errno));
+ return empty_data;
+ }
+
+ return d;
+}
+
+struct data data_copy_file_all(FILE *f)
+{
+ char buf[4096];
+ struct data d = empty_data;
+
+ while (1) {
+ size_t ret = fread(buf, 1, sizeof(buf), f);
+ if (ret == 0) {
+ if (!feof(f))
+ yyerrorf("Error reading file: %s",
strerror(errno));
+
+ break;
+ }
+
+ assert(ret <= sizeof(buf));
+
+ d = data_grow_for(d, ret);
+ memcpy(d.val + d.len, buf, ret);
+
+ if (d.len + ret < d.len) {
+ yyerror("Binary include too large");
+ break;
+ }
+
+ d.len += ret;
+ }
return d;
}
diff --git a/dtc-lexer.l b/dtc-lexer.l
index bfb996e..7670aca 100644
--- a/dtc-lexer.l
+++ b/dtc-lexer.l
@@ -190,6 +190,13 @@ static int dts_version; /* = 0 */
return DT_PROPNODENAME;
}
+"/incbin/" {
+ yylloc.file = srcpos_file;
+ yylloc.first_line = yylineno;
+ DPRINT("Binary Include\n");
+ return DT_INCBIN;
+ }
+
<*>[[:space:]]+/* eat whitespace */
<*>"/*"([^*]|\*+[^*/])*\*+"/" {
diff --git a/dtc-parser.y b/dtc-parser.y
index da7f6f5..f50f2f0 100644
--- a/dtc-parser.y
+++ b/dtc-parser.y
@@ -21,6 +21,8 @@
%locations
%{
+#include
+
#include "dtc.h"
#include "srcpos.h"
@@ -47,6 +49,7 @@ extern int treesource_error;
struct node *node;
struct node *nodelist;
struct reserve_info *re;
+ struct range range;
}
%token DT_V1
@@ -59,6 +62,7 @@ extern int treesource_error;
%token DT_STRING
%token DT_LABEL
%token DT_REF
+%token DT_INCBIN
%type propdata
%type propdataprefix
@@ -79,6 +83,7 @@ extern int treesource_error;
%type subnode
%type subnodes
%type label
+%type mayberange
%%
@@ -197,12 +202,56 @@ propdata:
{
$$ = data_add_marker($1, REF_PATH, $2);
}
+ | propdataprefix DT_INCBIN '(' DT_STRING mayberange ')'
+ {
+ struct search_path path = { srcpos_file->dir, NULL,
NULL };
+ struct dtc_file *file = dtc_open_file($4.val, &path);
+
+ if (!file) {
+ yyerrorf("Cannot open file \"%s\": %s",
+$4.val, strerror(errno));
+ } else {
+ struct data d = empty_data;
+
+ if ($5.len >= 0) {
+ if (fseek(file->file, $5.start,
SEEK_SET) == 0)
+ d = data_copy_file(file->file,
$5.len);
+ else
+ yyerrorf("Couldn't seek to
offset %llu in \"%s\": %s",
+(unsigned long
long)$5.start,
+$4.val,
strerror(errno));
+ } else {
+ d = data_copy_file_all(file->file);
+ }
+
+ $$ = data_merge($1, d);
+