[PATCH 1/3] Add support for binary includes.
Scott Wood
scottwood at freescale.com
Sat Jan 5 08:10:43 EST 2008
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 <scottwood at freescale.com>
---
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 <stdio.h>
+
#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 <data> DT_STRING
%token <labelref> DT_LABEL
%token <labelref> DT_REF
+%token DT_INCBIN
%type <data> propdata
%type <data> propdataprefix
@@ -79,6 +83,7 @@ extern int treesource_error;
%type <node> subnode
%type <nodelist> subnodes
%type <labelref> label
+%type <range> 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);
+ dtc_close_file(file);
+ }
+ }
| propdata DT_LABEL
{
$$ = data_add_marker($1, LABEL, $2);
}
;
+mayberange:
+ /* empty */
+ {
+ $$.len = -1;
+ }
+ | ',' addr ',' addr
+ {
+ $$.start = $2;
+ $$.len = $4;
+
+ if ($$.len != $4) {
+ yyerrorf("Length %llu is too large",
+ (unsigned long long)$4);
+ $$.len = -1;
+ }
+ }
+ ;
+
propdataprefix:
/* empty */
{
diff --git a/dtc.h b/dtc.h
index cba9d28..509fbc9 100644
--- a/dtc.h
+++ b/dtc.h
@@ -122,6 +122,10 @@ struct data {
struct marker *markers;
};
+struct range {
+ off_t start;
+ int len;
+};
#define empty_data ((struct data){ /* all .members = 0 or NULL */ })
@@ -138,6 +142,7 @@ struct data data_grow_for(struct data d, int xlen);
struct data data_copy_mem(const char *mem, int len);
struct data data_copy_escape_string(const char *s, int len);
struct data data_copy_file(FILE *f, size_t len);
+struct data data_copy_file_all(FILE *f);
struct data data_append_data(struct data d, const void *p, int len);
struct data data_insert_at_marker(struct data d, struct marker *m,
--
1.5.3
More information about the Linuxppc-dev
mailing list