mirror of
https://github.com/dgibson/dtc.git
synced 2026-10-09 23:53:08 -04:00
Compare commits
No commits in common. "66e1201c3775716607c28afd2bbb2b3afb08b695" and "47d7c01ba8a1241e919ab56dd01ba245b38fef8e" have entirely different histories.
66e1201c37
...
47d7c01ba8
33 changed files with 654 additions and 1343 deletions
39
.cirrus.yml
Normal file
39
.cirrus.yml
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# FreeBSD build with multiple versions
|
||||
freebsd_versions_task:
|
||||
name: FreeBSD $FREEBSD_VERSION make build
|
||||
freebsd_instance:
|
||||
image_family: $FREEBSD_IMAGE
|
||||
matrix:
|
||||
- env:
|
||||
FREEBSD_VERSION: "13.5"
|
||||
FREEBSD_IMAGE: freebsd-13-5
|
||||
- env:
|
||||
FREEBSD_VERSION: "14.3"
|
||||
FREEBSD_IMAGE: freebsd-14-3
|
||||
install_script:
|
||||
- pkg install -y git gmake flex bison python3 py312-setuptools swig libyaml pkgconf
|
||||
build_script:
|
||||
- gmake
|
||||
check_script:
|
||||
- gmake check
|
||||
|
||||
# FreeBSD meson builds with multiple versions
|
||||
freebsd_meson_versions_task:
|
||||
name: FreeBSD $FREEBSD_VERSION meson build
|
||||
freebsd_instance:
|
||||
image_family: $FREEBSD_IMAGE
|
||||
matrix:
|
||||
- env:
|
||||
FREEBSD_VERSION: "13.5"
|
||||
FREEBSD_IMAGE: freebsd-13-5
|
||||
- env:
|
||||
FREEBSD_VERSION: "14.3"
|
||||
FREEBSD_IMAGE: freebsd-14-3
|
||||
install_script:
|
||||
- pkg install -y git meson ninja flex bison python3 py312-setuptools swig libyaml pkgconf
|
||||
setup_script:
|
||||
- meson setup -D python=enabled -D yaml=enabled build
|
||||
build_script:
|
||||
- meson compile -C build
|
||||
test_script:
|
||||
- if ! meson test -C build; then cat build/meson-logs/testlog.txt; false; fi
|
||||
147
.github/workflows/build.yml
vendored
147
.github/workflows/build.yml
vendored
|
|
@ -8,8 +8,6 @@ name: Build test
|
|||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
# ensure that the workflow is only triggered once per PR, subsequent pushes to the PR will cancel
|
||||
# and restart the workflow. See https://docs.github.com/en/actions/using-jobs/using-concurrency
|
||||
|
|
@ -18,93 +16,78 @@ concurrency:
|
|||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
build-make:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ "alpine", "archlinux", "fedora", "ubuntu" ]
|
||||
build: [ "make", "meson" ]
|
||||
os: [ "alpine", "archlinux", "fedora", "ubuntu" ]
|
||||
|
||||
container:
|
||||
image: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Dependencies
|
||||
run: ./scripts/install-deps.sh
|
||||
|
||||
- name: Build (Make)
|
||||
if: matrix.build == 'make'
|
||||
run: make
|
||||
|
||||
- name: Run check (Make)
|
||||
if: matrix.build == 'make'
|
||||
run: make check
|
||||
|
||||
- name: Setup (Meson)
|
||||
if: matrix.build == 'meson'
|
||||
run: meson setup -D python=enabled -D yaml=enabled build
|
||||
|
||||
- name: Build (Meson)
|
||||
if: matrix.build == 'meson'
|
||||
run: meson compile -C build
|
||||
|
||||
- name: Run check (Meson)
|
||||
if: matrix.build == 'meson'
|
||||
run: if ! meson test -C build; then cat build/meson-logs/testlog.txt; false; fi
|
||||
|
||||
build-macos:
|
||||
runs-on: macos-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
build: [ "make", "meson" ]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
./scripts/install-deps.sh
|
||||
|
||||
- name: Build (Make)
|
||||
if: matrix.build == 'make'
|
||||
- name: Build
|
||||
run: |
|
||||
make
|
||||
|
||||
- name: Setup (Meson)
|
||||
if: matrix.build == 'meson'
|
||||
run: meson setup -D python=enabled -D yaml=enabled -D tests=false build
|
||||
- name: Run check
|
||||
run: |
|
||||
make check
|
||||
|
||||
- name: Build (Meson)
|
||||
if: matrix.build == 'meson'
|
||||
build-meson:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ "alpine", "archlinux", "fedora", "ubuntu" ]
|
||||
|
||||
container:
|
||||
image: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
./scripts/install-deps.sh
|
||||
|
||||
- name: Setup
|
||||
run: meson setup -D python=enabled -D yaml=enabled build
|
||||
|
||||
- name: Build
|
||||
run: meson compile -C build
|
||||
|
||||
- name: Run check
|
||||
run: if ! meson test -C build; then cat build/meson-logs/testlog.txt; false; fi
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { sys: mingw32, swig: false }
|
||||
- { sys: mingw64, swig: true }
|
||||
- { sys: ucrt64, swig: true }
|
||||
- { sys: clang64, swig: true }
|
||||
- { sys: mingw32 }
|
||||
- { sys: mingw64 }
|
||||
- { sys: ucrt64 }
|
||||
- { sys: clang64 }
|
||||
name: ${{ matrix.sys }}
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
|
@ -122,60 +105,10 @@ jobs:
|
|||
meson:p
|
||||
ninja:p
|
||||
libyaml:p
|
||||
${{ matrix.swig && 'swig:p python-setuptools-scm:p' || '' }}
|
||||
swig:p
|
||||
python-setuptools-scm:p
|
||||
|
||||
- name: '🚧 Build'
|
||||
run: |
|
||||
meson setup -Dtools=true -Dtests=false build
|
||||
meson compile -C build
|
||||
|
||||
build-freebsd:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: [ "13.5", "14.3" ]
|
||||
build: [ "make", "meson" ]
|
||||
|
||||
name: FreeBSD ${{ matrix.version }} ${{ matrix.build }} build
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Start VM
|
||||
uses: cross-platform-actions/action@v1
|
||||
with:
|
||||
operating_system: freebsd
|
||||
version: ${{ matrix.version }}
|
||||
shell: sh
|
||||
|
||||
- name: Install Dependencies
|
||||
shell: cpa.sh {0}
|
||||
run: sudo ./scripts/install-deps.sh
|
||||
|
||||
- name: Build (Make)
|
||||
if: matrix.build == 'make'
|
||||
shell: cpa.sh {0}
|
||||
run: gmake
|
||||
|
||||
- name: Run check (Make)
|
||||
if: matrix.build == 'make'
|
||||
shell: cpa.sh {0}
|
||||
run: gmake check
|
||||
|
||||
- name: Setup (Meson)
|
||||
if: matrix.build == 'meson'
|
||||
shell: cpa.sh {0}
|
||||
run: meson setup -D python=enabled -D yaml=enabled build
|
||||
|
||||
- name: Build (Meson)
|
||||
if: matrix.build == 'meson'
|
||||
shell: cpa.sh {0}
|
||||
run: meson compile -C build
|
||||
|
||||
- name: Run check (Meson)
|
||||
if: matrix.build == 'meson'
|
||||
shell: cpa.sh {0}
|
||||
run: if ! meson test -C build; then cat build/meson-logs/testlog.txt; false; fi
|
||||
|
|
|
|||
138
AGENTS.md
138
AGENTS.md
|
|
@ -1,138 +0,0 @@
|
|||
# AGENTS.md
|
||||
|
||||
This file provides guidance to AI coding assistants when working with
|
||||
code in this repository.
|
||||
|
||||
## Build and Test
|
||||
|
||||
The build system is Meson (the legacy Makefile still works but is
|
||||
deprecated).
|
||||
|
||||
```sh
|
||||
# Configure and build
|
||||
meson setup build
|
||||
meson compile -C build
|
||||
|
||||
# Run all tests
|
||||
meson test -C build
|
||||
|
||||
# Run a specific test suite (libfdt, dtc, fdtget, fdtput, fdtdump, fdtoverlay, pylibfdt, utilfdt, dtbs_equal)
|
||||
meson test -C build dtc
|
||||
meson test -C build libfdt
|
||||
|
||||
# Legacy make (deprecated, still functional)
|
||||
make
|
||||
make check # all tests
|
||||
make checkm # tests under valgrind
|
||||
```
|
||||
|
||||
Optional build dependencies: libyaml (>= 0.2.3) for YAML output,
|
||||
valgrind for memory checking, swig + python3-dev for pylibfdt.
|
||||
|
||||
## Architecture
|
||||
|
||||
The repo contains three main components:
|
||||
|
||||
### dtc (Device Tree Compiler)
|
||||
|
||||
Compiles device tree source (.dts) to binary (.dtb) and vice versa. The pipeline is: parse source → live tree → flatten to blob (or reverse).
|
||||
|
||||
- **Parsing**: `dtc-lexer.l` (flex) + `dtc-parser.y` (bison) produce a live tree from .dts source. `flattree.c` reads .dtb blobs. `fstree.c` reads /proc/device-tree style filesystem trees. `yamltree.c` writes YAML output.
|
||||
|
||||
- **Live tree** (`livetree.c`, `dtc.h`): In-memory representation as `struct node` / `struct property` trees with labels, phandles, and source position tracking. The `struct data` type carries property values with type markers and cross-reference markers.
|
||||
- **Checks** (`checks.c`): ~50 semantic checks registered via `WARNING()`, `ERROR()`, and `CHECK()` macros into a `check_table[]`. Each check declares prerequisite checks, forming a DAG. Checks validate DT conventions (node naming, property types, interrupt structures, etc.). Use `-W`/`-E` flags to promote/demote.
|
||||
- **Output**: `flattree.c` writes .dtb blobs and assembler output. `treesource.c` writes .dts source.
|
||||
|
||||
### libfdt (Flat Device Tree library)
|
||||
|
||||
C library for reading/writing .dtb blobs in-place, dual-licensed
|
||||
GPL-2.0-or-later OR BSD-2-Clause. Used in bootloaders, kernels, and
|
||||
hypervisors where the full compiler isn't available.
|
||||
|
||||
- `fdt_ro.c` — read-only access (property lookup, node traversal)
|
||||
- `fdt_rw.c` — read-write modification of existing blobs
|
||||
- `fdt_sw.c` — sequential-write creation of new blobs
|
||||
- `fdt_wip.c` — "write in place" operations (in-place modification)
|
||||
- `fdt_overlay.c` — device tree overlay application
|
||||
- `fdt_check.c` — blob validation (`fdt_check_full`)
|
||||
- `fdt_addresses.c` — address/size cell helpers
|
||||
- `version.lds` — exported symbol list; new public functions must be added here
|
||||
|
||||
libfdt is designed to be embeddable: `Makefile.libfdt` can be included
|
||||
by external build systems. The `FDT_ASSUME_MASK` controls safety
|
||||
vs. performance tradeoffs (see `libfdt_internal.h`).
|
||||
|
||||
### pylibfdt
|
||||
|
||||
SWIG-generated Python bindings for libfdt
|
||||
(`pylibfdt/libfdt.i`). Functions not supportable by SWIG should be
|
||||
behind `#ifndef SWIG` in `libfdt.h`.
|
||||
|
||||
## Tests
|
||||
|
||||
Tests live in `tests/`. The test runner is `tests/run_tests.sh` which
|
||||
defines test groups: `libfdt_tests`, `dtc_tests`, `fdtget_tests`,
|
||||
`fdtput_tests`, `fdtoverlay_tests`, `pylibfdt_tests`, etc.
|
||||
|
||||
Individual C test programs link against libfdt and use helpers from
|
||||
`tests/testutils.c`. Binary test trees are built from assembler macros
|
||||
in `tests/trees.S` via `tests/dumptrees.c` — if you modify
|
||||
`tests/test_tree1.dts`, you must also update `tests/trees.S`.
|
||||
|
||||
## AI Contribution Policy
|
||||
|
||||
See the "AI Coding Assistants" section in CONTRIBUTING.md. Key rules:
|
||||
|
||||
- **Do not** add `Signed-off-by` tags — only humans can certify the DCO
|
||||
- Use `Assisted-by: AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2]` for attribution in commit messages
|
||||
- The human submitter is responsible for reviewing all AI-generated code and ensuring license compliance
|
||||
- Do not add `Co-authored-by` tags.
|
||||
|
||||
## Tagging a New Release
|
||||
|
||||
Releases use the `vMAJOR.MINOR.PATCH` tag format (e.g., `v1.7.2`).
|
||||
|
||||
An AI agent can prepare the release; the human maintainer reviews,
|
||||
adds `Signed-off-by`, and signs the tag.
|
||||
|
||||
1. **Update `VERSION.txt` and commit** — run the prepare script:
|
||||
```sh
|
||||
scripts/prepare-release X.Y.Z
|
||||
```
|
||||
This updates `VERSION.txt` and creates the version bump commit
|
||||
(without `Signed-off-by`, per the AI contribution policy).
|
||||
|
||||
2. **Draft the tag message** — write it to a temporary file (e.g.,
|
||||
`tag-message.txt`) for the maintainer to review. The format is:
|
||||
```
|
||||
DTC X.Y.Z
|
||||
|
||||
Changes since vPREV include:
|
||||
* Component
|
||||
- Change description
|
||||
- ...
|
||||
```
|
||||
Group changes by component (dtc, libfdt, pylibfdt, fdtget,
|
||||
fdtoverlay, Build, General, etc.) with a bullet per notable change.
|
||||
Generate the changelog from `git log vPREV..HEAD`.
|
||||
|
||||
3. **Human review** — the maintainer reviews the commit and tag
|
||||
message, then runs the finalize script which amends the commit to
|
||||
add `Signed-off-by`, creates the signed annotated tag, pushes the
|
||||
release commit and tag to origin, and optionally uploads to
|
||||
kernel.org via kup:
|
||||
```sh
|
||||
scripts/finalize-release tag-message.txt
|
||||
```
|
||||
|
||||
Agents must **never** run `scripts/finalize-release` or
|
||||
`scripts/kup-dtc`. These perform signing, push, and upload operations
|
||||
that only a human maintainer may execute.
|
||||
|
||||
## Coding Conventions
|
||||
|
||||
- License: GPL-2.0-or-later for dtc tools; (GPL-2.0-or-later OR BSD-2-Clause) for libfdt
|
||||
- SPDX identifiers on every file
|
||||
- C style follows kernel conventions: tabs for indentation, `lower_case` names
|
||||
- Compiler warnings are errors (`-Werror`)
|
||||
- libfdt functions return negative `FDT_ERR_*` codes on failure (never errno)
|
||||
17
CLAUDE.md
17
CLAUDE.md
|
|
@ -1,17 +0,0 @@
|
|||
# CLAUDE.md
|
||||
|
||||
Read and follow AGENTS.md — it has build instructions, architecture
|
||||
notes, coding conventions, and the AI contribution policy for this
|
||||
project.
|
||||
|
||||
## Claude Code Specifics
|
||||
|
||||
When writing `Assisted-by` commit trailers, use `Claude` as the agent
|
||||
name and the model's short ID as the version. For example:
|
||||
|
||||
```
|
||||
Assisted-by: Claude:claude-opus-4-6
|
||||
```
|
||||
|
||||
Do not use `claude-code`, `Claude Code`, or other variations as the
|
||||
agent name.
|
||||
|
|
@ -77,51 +77,3 @@ from people handling and transporting the patch, but were not involved
|
|||
in its development. SoB chains should reflect the **real** route a
|
||||
patch took as it was propagated to the maintainers, with the first SoB
|
||||
entry signalling primary authorship of a single author.
|
||||
|
||||
## AI Coding Assistants
|
||||
|
||||
AI tools helping with dtc/libfdt development must follow the standard
|
||||
contribution process described in this document.
|
||||
|
||||
### Licensing and Legal Requirements
|
||||
|
||||
All contributions must comply with the project's licensing requirements:
|
||||
|
||||
* All code must be compatible with GPL-2.0-or-later
|
||||
* All libfdt code must also be compatible with BSD-2-Clause
|
||||
* Use appropriate SPDX license identifiers
|
||||
|
||||
### Signed-off-by and Developer Certificate of Origin
|
||||
|
||||
AI agents MUST NOT add Signed-off-by tags. Only humans can legally
|
||||
certify the Developer Certificate of Origin (DCO). The human submitter
|
||||
is responsible for:
|
||||
|
||||
* Reviewing all AI-generated code
|
||||
* Ensuring compliance with licensing requirements
|
||||
* Adding their own Signed-off-by tag to certify the DCO
|
||||
* Taking full responsibility for the contribution
|
||||
|
||||
### Attribution
|
||||
|
||||
When AI tools contribute to development, proper attribution helps track
|
||||
the evolving role of AI in the development process. Contributions
|
||||
should include an `Assisted-by` tag in the following format:
|
||||
|
||||
```
|
||||
Assisted-by: AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2]
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
* `AGENT_NAME` is the name of the AI tool or framework
|
||||
* `MODEL_VERSION` is the specific model version used
|
||||
* `[TOOL1] [TOOL2]` are optional specialized analysis tools used
|
||||
(e.g., coccinelle, sparse, smatch, clang-tidy)
|
||||
|
||||
Basic development tools (git, gcc, make, editors) should not be listed.
|
||||
|
||||
Example:
|
||||
```
|
||||
Assisted-by: Claude:claude-3-opus coccinelle sparse
|
||||
```
|
||||
|
|
|
|||
28
Makefile
28
Makefile
|
|
@ -153,11 +153,6 @@ include Makefile.convert-dtsv0
|
|||
include Makefile.dtc
|
||||
include Makefile.utils
|
||||
|
||||
# Flex-generated source triggers -Wsign-compare in its templates
|
||||
dtc-lexer.lex.o: CFLAGS += -Wno-sign-compare
|
||||
convert-dtsv0-lexer.lex.o: CFLAGS += -Wno-sign-compare
|
||||
|
||||
|
||||
BIN += convert-dtsv0
|
||||
BIN += dtc
|
||||
BIN += fdtdump
|
||||
|
|
@ -260,6 +255,29 @@ fdtput: $(FDTPUT_OBJS) $(LIBFDT_dep)
|
|||
|
||||
fdtoverlay: $(FDTOVERLAY_OBJS) $(LIBFDT_dep)
|
||||
|
||||
dist:
|
||||
git archive --format=tar --prefix=dtc-$(dtc_version)/ HEAD \
|
||||
> ../dtc-$(dtc_version).tar
|
||||
cat ../dtc-$(dtc_version).tar | \
|
||||
gzip -9 > ../dtc-$(dtc_version).tar.gz
|
||||
|
||||
|
||||
#
|
||||
# Release signing and uploading
|
||||
# This is for maintainer convenience, don't try this at home.
|
||||
#
|
||||
ifeq ($(MAINTAINER),y)
|
||||
GPG = gpg2
|
||||
KUP = kup
|
||||
KUPDIR = /pub/software/utils/dtc
|
||||
|
||||
kup: dist
|
||||
$(GPG) --detach-sign --armor -o ../dtc-$(dtc_version).tar.sign \
|
||||
../dtc-$(dtc_version).tar
|
||||
$(KUP) put ../dtc-$(dtc_version).tar.gz ../dtc-$(dtc_version).tar.sign \
|
||||
$(KUPDIR)/dtc-$(dtc_version).tar.gz
|
||||
endif
|
||||
|
||||
tags: FORCE
|
||||
rm -f tags
|
||||
find . \( -name tests -type d -prune \) -o \
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
1.8.1
|
||||
1.7.2
|
||||
|
|
|
|||
2
checks.c
2
checks.c
|
|
@ -1769,7 +1769,7 @@ static void check_interrupts_property(struct check *c,
|
|||
irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)));
|
||||
}
|
||||
}
|
||||
WARNING(interrupts_property, check_interrupts_property, NULL, &phandle_references);
|
||||
WARNING(interrupts_property, check_interrupts_property, &phandle_references);
|
||||
|
||||
static const struct bus_type graph_port_bus = {
|
||||
.name = "graph-port",
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@ int fdt_check_full(const void *fdt, size_t bufsize)
|
|||
const char *propname;
|
||||
bool expect_end = false;
|
||||
|
||||
if (can_assume(PERFECT))
|
||||
return 0;
|
||||
if (bufsize < FDT_V1_SIZE)
|
||||
return -FDT_ERR_TRUNCATED;
|
||||
if (bufsize < fdt_header_size(fdt))
|
||||
|
|
|
|||
|
|
@ -292,13 +292,6 @@ int fdt_setprop_placeholder_namelen(void *fdt, int nodeoffset, const char *name,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int fdt_setprop_placeholder(void *fdt, int nodeoffset,
|
||||
const char *name, int len, void **prop_data)
|
||||
{
|
||||
return fdt_setprop_placeholder_namelen(fdt, nodeoffset, name,
|
||||
strlen(name), len, prop_data);
|
||||
}
|
||||
|
||||
int fdt_setprop_namelen(void *fdt, int nodeoffset, const char *name,
|
||||
int namelen, const void *val, int len)
|
||||
{
|
||||
|
|
@ -315,13 +308,6 @@ int fdt_setprop_namelen(void *fdt, int nodeoffset, const char *name,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int fdt_setprop(void *fdt, int nodeoffset, const char *name,
|
||||
const void *val, int len)
|
||||
{
|
||||
return fdt_setprop_namelen(fdt, nodeoffset, name, strlen(name), val,
|
||||
len);
|
||||
}
|
||||
|
||||
int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
|
||||
const void *val, int len)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -330,8 +330,7 @@ int fdt_property(void *fdt, const char *name, const void *val, int len)
|
|||
ret = fdt_property_placeholder(fdt, name, len, &ptr);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (len)
|
||||
memcpy(ptr, val, len);
|
||||
memcpy(ptr, val, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1935,8 +1935,12 @@ int fdt_setprop_namelen(void *fdt, int nodeoffset, const char *name,
|
|||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_TRUNCATED, standard meanings
|
||||
*/
|
||||
int fdt_setprop(void *fdt, int nodeoffset, const char *name,
|
||||
const void *val, int len);
|
||||
static inline int fdt_setprop(void *fdt, int nodeoffset, const char *name,
|
||||
const void *val, int len)
|
||||
{
|
||||
return fdt_setprop_namelen(fdt, nodeoffset, name, strlen(name), val,
|
||||
len);
|
||||
}
|
||||
|
||||
/**
|
||||
* fdt_setprop_placeholder_namelen - allocate space for a property
|
||||
|
|
@ -1998,8 +2002,13 @@ int fdt_setprop_placeholder_namelen(void *fdt, int nodeoffset, const char *name,
|
|||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_TRUNCATED, standard meanings
|
||||
*/
|
||||
int fdt_setprop_placeholder(void *fdt, int nodeoffset,
|
||||
const char *name, int len, void **prop_data);
|
||||
static inline int fdt_setprop_placeholder(void *fdt, int nodeoffset,
|
||||
const char *name, int len,
|
||||
void **prop_data)
|
||||
{
|
||||
return fdt_setprop_placeholder_namelen(fdt, nodeoffset, name,
|
||||
strlen(name), len, prop_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* fdt_setprop_u32 - set a property to a 32-bit integer
|
||||
|
|
|
|||
|
|
@ -1234,7 +1234,7 @@ void fixup_phandles(struct dt_info *dti, const char *name)
|
|||
continue;
|
||||
|
||||
offset = strtol(soffset, NULL, 0);
|
||||
if (offset < 0 || (unsigned int)offset + 4 > p->val.len) {
|
||||
if (offset < 0 || offset + 4 > p->val.len) {
|
||||
if (quiet < 1)
|
||||
fprintf(stderr,
|
||||
"Warning: Label %s contains invalid offset for property %s in node %s\n",
|
||||
|
|
|
|||
|
|
@ -1,98 +0,0 @@
|
|||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# Finalize a release (possibly prepared with AI agent assistance)
|
||||
# Amends the version bump commit to add Signed-off-by, then creates a
|
||||
# signed annotated tag from the drafted tag message.
|
||||
|
||||
set -e
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 <tag-message-file>" >&2
|
||||
echo "" >&2
|
||||
echo "Run this from the repository root with VERSION.txt updated" >&2
|
||||
echo "and a draft tag message in given file." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
TAG_MSG_FILE="$1"
|
||||
if [ -z "$TAG_MSG_FILE" ] || [ ! -f "$TAG_MSG_FILE" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
VERSION=$(cat VERSION.txt)
|
||||
TAG="v${VERSION}"
|
||||
|
||||
if git rev-parse "$TAG" >/dev/null 2>&1; then
|
||||
echo "Error: tag $TAG already exists" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
HEAD_SUBJECT=$(git log -1 --format=%s)
|
||||
EXPECTED="Bump version to $TAG"
|
||||
if [ "$HEAD_SUBJECT" != "$EXPECTED" ]; then
|
||||
echo "Error: HEAD commit subject is:" >&2
|
||||
echo " $HEAD_SUBJECT" >&2
|
||||
echo "Expected:" >&2
|
||||
echo " $EXPECTED" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Version: $VERSION"
|
||||
echo "Tag: $TAG"
|
||||
echo ""
|
||||
echo "--- Tag message ---"
|
||||
cat "$TAG_MSG_FILE"
|
||||
echo "--- End tag message ---"
|
||||
echo ""
|
||||
|
||||
printf "Proceed? [y/N] "
|
||||
read answer
|
||||
case "$answer" in
|
||||
y|Y) ;;
|
||||
*) echo "Aborted."; exit 1 ;;
|
||||
esac
|
||||
|
||||
git commit --amend -s --no-edit
|
||||
git tag -s "$TAG" -F "$TAG_MSG_FILE"
|
||||
|
||||
echo ""
|
||||
echo "Created signed tag $TAG."
|
||||
echo "Review with: git show $TAG"
|
||||
echo ""
|
||||
|
||||
git push origin main "$TAG"
|
||||
git push github main "$TAG"
|
||||
git push gitlab main "$TAG"
|
||||
|
||||
SCRIPTDIR=$(dirname "$0")
|
||||
|
||||
printf "Upload to kernel.org via kup? [y/N] "
|
||||
read answer
|
||||
case "$answer" in
|
||||
y|Y) "$SCRIPTDIR/kup-dtc" "$VERSION" ;;
|
||||
*) echo "Skipping kup upload." ;;
|
||||
esac
|
||||
|
||||
TAG_BODY=$(git tag -l --format='%(contents:body)' "$TAG")
|
||||
|
||||
ANNOUNCE="announce-${TAG}.txt"
|
||||
cat > "$ANNOUNCE" <<MAIL
|
||||
To: devicetree-compiler@vger.kernel.org
|
||||
Subject: DTC $VERSION released
|
||||
|
||||
DTC $VERSION is now available.
|
||||
|
||||
Git tree:
|
||||
https://git.kernel.org/pub/scm/utils/dtc/dtc.git
|
||||
|
||||
Tagged release ($TAG):
|
||||
https://git.kernel.org/pub/scm/utils/dtc/dtc.git/tag/?h=$TAG
|
||||
|
||||
Tarball:
|
||||
https://kernel.org/pub/software/utils/dtc/dtc-${VERSION}.tar.gz
|
||||
|
||||
$TAG_BODY
|
||||
MAIL
|
||||
|
||||
echo "Announcement draft written to $ANNOUNCE"
|
||||
|
|
@ -1,19 +1,6 @@
|
|||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
if [ "$(uname -s)" = "Darwin" ]
|
||||
then
|
||||
brew install --quiet libyaml swig meson ninja pkg-config
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$(uname -s)" = "FreeBSD" ]
|
||||
then
|
||||
pkg install -y git gmake flex bison meson ninja \
|
||||
python3 py312-setuptools swig libyaml pkgconf
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f /etc/os-release ]
|
||||
then
|
||||
. /etc/os-release
|
||||
|
|
|
|||
|
|
@ -1,70 +0,0 @@
|
|||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# Prepare a release: update VERSION.txt and create the version bump
|
||||
# commit. This handles steps 1 and 2 of the release procedure in
|
||||
# AGENTS.md. Step 3 (drafting the tag message) requires judgement to
|
||||
# categorise and summarise changes, so is left to the caller.
|
||||
|
||||
set -e
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 <version>" >&2
|
||||
echo "" >&2
|
||||
echo " version X.Y.Z or vX.Y.Z" >&2
|
||||
echo "" >&2
|
||||
echo "Example: $0 1.8.1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
RAW="$1"
|
||||
if [ -z "$RAW" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
VERSION="${RAW#v}"
|
||||
|
||||
case "$VERSION" in
|
||||
[0-9]*.[0-9]*.[0-9]*)
|
||||
;;
|
||||
*)
|
||||
echo "Error: version '$VERSION' does not look like X.Y.Z" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
TAG="v${VERSION}"
|
||||
|
||||
if git rev-parse "$TAG" >/dev/null 2>&1; then
|
||||
echo "Error: tag $TAG already exists" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! git diff-index --quiet HEAD; then
|
||||
echo "Error: working tree is dirty; commit or stash first" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "$VERSION" > VERSION.txt
|
||||
git add VERSION.txt
|
||||
git commit -m "$(cat <<EOF
|
||||
Bump version to $TAG
|
||||
|
||||
Prepare for a new release.
|
||||
EOF
|
||||
)"
|
||||
|
||||
echo "Building with make..."
|
||||
git clean -fdx
|
||||
make check
|
||||
|
||||
echo ""
|
||||
echo "Building with meson..."
|
||||
git clean -fdx
|
||||
meson setup build
|
||||
meson test -C build
|
||||
|
||||
echo ""
|
||||
echo "All builds and tests passed."
|
||||
echo "Next: draft the tag message to tag-message.txt, then run:"
|
||||
echo " scripts/finalize-release tag-message.txt"
|
||||
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
|
|
@ -69,7 +69,6 @@ tmp.*
|
|||
/supernode_atdepth_offset
|
||||
/sw_tree1
|
||||
/sw_states
|
||||
/treegen
|
||||
/truncated_property
|
||||
/truncated_string
|
||||
/truncated_memrsv
|
||||
|
|
|
|||
|
|
@ -29,32 +29,34 @@ LIB_TESTS_L = get_mem_rsv \
|
|||
subnode_iterate \
|
||||
overlay overlay_bad_fixup \
|
||||
check_path check_header check_full \
|
||||
fs_tree1 \
|
||||
truncated_property truncated_string \
|
||||
truncated_memrsv unterminated_memrsv
|
||||
fs_tree1
|
||||
LIB_TESTS = $(LIB_TESTS_L:%=$(TESTS_PREFIX)%)
|
||||
|
||||
LIBTREE_TESTS_L = truncated_property truncated_string \
|
||||
truncated_memrsv unterminated_memrsv
|
||||
|
||||
LIBTREE_TESTS = $(LIBTREE_TESTS_L:%=$(TESTS_PREFIX)%)
|
||||
|
||||
ifneq ($(STATIC_BUILD),1)
|
||||
DL_LIB_TESTS_L = asm_tree_dump value-labels
|
||||
DL_LIB_TESTS = $(DL_LIB_TESTS_L:%=$(TESTS_PREFIX)%)
|
||||
endif
|
||||
|
||||
TESTS = $(LIB_TESTS) $(DL_LIB_TESTS)
|
||||
TESTS = $(LIB_TESTS) $(LIBTREE_TESTS) $(DL_LIB_TESTS)
|
||||
|
||||
TESTS_TREES_L = test_tree1.dtb bad_node_char.dtb bad_node_format.dtb \
|
||||
bad_prop_char.dtb ovf_size_strings.dtb truncated_property.dtb \
|
||||
truncated_string.dtb truncated_memrsv.dtb unterminated_memrsv.dtb \
|
||||
two_roots.dtb named_root.dtb
|
||||
truncated_string.dtb truncated_memrsv.dtb two_roots.dtb named_root.dtb
|
||||
TESTS_TREES = $(TESTS_TREES_L:%=$(TESTS_PREFIX)%)
|
||||
|
||||
TESTS_TARGETS = $(TESTS) $(TESTS_TREES)
|
||||
|
||||
TESTS_DEPFILES = $(TESTS:%=%.d) \
|
||||
$(addprefix $(TESTS_PREFIX),testutils.d)
|
||||
$(addprefix $(TESTS_PREFIX),testutils.d trees.d dumptrees.d)
|
||||
|
||||
TESTS_CLEANFILES_L = $(STD_CLEANFILES) \
|
||||
*.dtb *.test.dts *.test.dt.yaml *.dtsv1 tmp.* *.bak \
|
||||
treegen
|
||||
dumptrees
|
||||
TESTS_CLEANFILES = $(TESTS) $(TESTS_CLEANFILES_L:%=$(TESTS_PREFIX)%)
|
||||
TESTS_CLEANDIRS_L = fs
|
||||
TESTS_CLEANDIRS = $(TESTS_CLEANDIRS_L:%=$(TESTS_PREFIX)%)
|
||||
|
|
@ -71,9 +73,14 @@ $(DL_LIB_TESTS): %: %.o $(TESTS_PREFIX)testutils.o util.o $(LIBFDT_dep)
|
|||
@$(VECHO) LD [libdl] $@
|
||||
$(LINK.c) -o $@ $^ $(LIBDL)
|
||||
|
||||
$(TESTS_TREES): $(TESTS_PREFIX)treegen
|
||||
@$(VECHO) TREEGEN
|
||||
cd $(TESTS_PREFIX); ./treegen . >/dev/null
|
||||
$(LIBTREE_TESTS): %: $(TESTS_PREFIX)testutils.o $(TESTS_PREFIX)trees.o \
|
||||
util.o $(LIBFDT_dep)
|
||||
|
||||
$(TESTS_PREFIX)dumptrees: $(TESTS_PREFIX)trees.o
|
||||
|
||||
$(TESTS_TREES): $(TESTS_PREFIX)dumptrees
|
||||
@$(VECHO) DUMPTREES
|
||||
cd $(TESTS_PREFIX); ./dumptrees . >/dev/null
|
||||
|
||||
tests_clean:
|
||||
@$(VECHO) CLEAN "(tests)"
|
||||
|
|
|
|||
69
tests/dumptrees.c
Normal file
69
tests/dumptrees.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* dumptrees - utility for libfdt testing
|
||||
*
|
||||
* (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2006.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <libfdt.h>
|
||||
|
||||
#include "testdata.h"
|
||||
|
||||
static struct {
|
||||
void *blob;
|
||||
const char *filename;
|
||||
} trees[] = {
|
||||
#define TREE(name) { &name, #name ".dtb" }
|
||||
TREE(test_tree1),
|
||||
TREE(bad_node_char), TREE(bad_node_format), TREE(bad_prop_char),
|
||||
TREE(ovf_size_strings),
|
||||
TREE(truncated_property), TREE(truncated_string),
|
||||
TREE(truncated_memrsv),
|
||||
TREE(two_roots),
|
||||
TREE(named_root)
|
||||
};
|
||||
|
||||
#define NUM_TREES (sizeof(trees) / sizeof(trees[0]))
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Missing output directory argument\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (chdir(argv[1]) != 0) {
|
||||
perror("chdir()");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_TREES; i++) {
|
||||
void *blob = trees[i].blob;
|
||||
const char *filename = trees[i].filename;
|
||||
int size;
|
||||
int fd;
|
||||
int ret;
|
||||
|
||||
size = fdt_totalsize(blob);
|
||||
|
||||
printf("Tree \"%s\", %d bytes\n", filename, size);
|
||||
|
||||
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (fd < 0)
|
||||
perror("open()");
|
||||
|
||||
ret = write(fd, blob, size);
|
||||
if (ret != size)
|
||||
perror("write()");
|
||||
|
||||
close(fd);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
|
@ -24,11 +24,7 @@ static void start_dir(const char *name)
|
|||
{
|
||||
int rc;
|
||||
|
||||
#ifndef _WIN32
|
||||
rc = mkdir(name, 0777);
|
||||
#else
|
||||
rc = mkdir(name);
|
||||
#endif
|
||||
if (rc != 0)
|
||||
FAIL("mkdir(\"%s\"): %s", name, strerror(errno));
|
||||
|
||||
|
|
|
|||
|
|
@ -17,14 +17,6 @@
|
|||
#include "tests.h"
|
||||
#include "testdata.h"
|
||||
|
||||
/*
|
||||
* Some of these trip the -Wconstant-logical-operand warning introduced in gcc
|
||||
* 17. Disable it temporarily, we also have to disable -Wpragmas for the
|
||||
* benefit of older compiler versions that don't know about that warning.
|
||||
*/
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpragmas"
|
||||
#pragma GCC diagnostic ignored "-Wconstant-logical-operand"
|
||||
static struct test_expr {
|
||||
const char *expr;
|
||||
uint32_t result;
|
||||
|
|
@ -59,7 +51,6 @@ static struct test_expr {
|
|||
TE(11 * 257 * 1321517ULL),
|
||||
TE(123456790 - 4/2 + 17%4),
|
||||
};
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
treegen = executable('treegen', files('treegen.c'),
|
||||
build_by_default: false,
|
||||
dependencies: [util_dep])
|
||||
trees = static_library('trees', files('trees.S'),
|
||||
build_by_default: false,
|
||||
include_directories: libfdt_inc)
|
||||
|
||||
treegen_dtb = custom_target(
|
||||
'treegen_dtb',
|
||||
command: [treegen, meson.current_build_dir()],
|
||||
dumptrees = executable('dumptrees', files('dumptrees.c'),
|
||||
build_by_default: false,
|
||||
link_with: trees, dependencies: libfdt_dep)
|
||||
|
||||
dumptrees_dtb = custom_target(
|
||||
'dumptrees',
|
||||
command: [dumptrees, meson.current_build_dir()],
|
||||
output: [
|
||||
'test_tree1.dtb',
|
||||
'bad_node_char.dtb',
|
||||
|
|
@ -14,13 +18,10 @@ treegen_dtb = custom_target(
|
|||
'truncated_property.dtb',
|
||||
'truncated_string.dtb',
|
||||
'truncated_memrsv.dtb',
|
||||
'unterminated_memrsv.dtb',
|
||||
'two_roots.dtb',
|
||||
'named_root.dtb',
|
||||
]
|
||||
)
|
||||
|
||||
testutil_dep = declare_dependency(sources: ['testutils.c'])
|
||||
testutil_dep = declare_dependency(sources: ['testutils.c'], link_with: trees)
|
||||
|
||||
tests = [
|
||||
'add_subnode_with_nops',
|
||||
|
|
@ -88,11 +89,14 @@ tests = [
|
|||
'supernode_atdepth_offset',
|
||||
'sw_states',
|
||||
'sw_tree1',
|
||||
'utilfdt_test',
|
||||
]
|
||||
|
||||
tests += [
|
||||
'truncated_memrsv',
|
||||
'truncated_property',
|
||||
'truncated_string',
|
||||
'unterminated_memrsv',
|
||||
'utilfdt_test',
|
||||
]
|
||||
|
||||
test_deps = [testutil_dep, util_dep, libfdt_dep]
|
||||
|
|
@ -137,10 +141,10 @@ run_test_types = [
|
|||
'fdtget',
|
||||
'fdtput',
|
||||
'fdtdump',
|
||||
'fdtoverlay',
|
||||
'fdtoverlay'
|
||||
]
|
||||
run_test_deps = [
|
||||
dtc_tools, treegen_dtb, tests_exe,
|
||||
dtc_tools, dumptrees_dtb, tests_exe
|
||||
]
|
||||
if pylibfdt_enabled
|
||||
run_test_types += 'pylibfdt'
|
||||
|
|
|
|||
|
|
@ -13,15 +13,26 @@ sys.path.insert(0, '../pylibfdt')
|
|||
import libfdt
|
||||
from libfdt import Fdt, FdtSw, FdtException, QUIET_NOTFOUND, QUIET_ALL
|
||||
|
||||
TEST_ADDR_1H = 0xdeadbeef
|
||||
TEST_ADDR_1L = 0x00000000
|
||||
TEST_ADDR_1 = (TEST_ADDR_1H << 32) | TEST_ADDR_1L
|
||||
TEST_ADDR_1 = 0x8000000000000000
|
||||
TEST_SIZE_1 = 0x0000000000100000
|
||||
TEST_ADDR_2 = 123456789
|
||||
TEST_SIZE_2 = 0o10000
|
||||
TEST_SIZE_1H = 0x00000000
|
||||
TEST_SIZE_1L = 0x00100000
|
||||
TEST_SIZE_1 = (TEST_SIZE_1H << 32) | TEST_SIZE_1L
|
||||
TEST_ADDR_2H = 0
|
||||
TEST_ADDR_2L = 123456789
|
||||
TEST_ADDR_2 = (TEST_ADDR_2H << 32) | TEST_ADDR_2L
|
||||
TEST_SIZE_2H = 0
|
||||
TEST_SIZE_2L = 0o10000
|
||||
TEST_SIZE_2 = (TEST_SIZE_2H << 32) | TEST_SIZE_2L
|
||||
|
||||
TEST_VALUE_1 = 0xdeadbeef
|
||||
TEST_VALUE_2 = 123456789
|
||||
|
||||
TEST_VALUE64_1 = 0xdeadbeef01abcdef
|
||||
TEST_VALUE64_1H = 0xdeadbeef
|
||||
TEST_VALUE64_1L = 0x01abcdef
|
||||
TEST_VALUE64_1 = (TEST_VALUE64_1H << 32) | TEST_VALUE64_1L
|
||||
|
||||
PHANDLE_1 = 0x2000
|
||||
PHANDLE_2 = 0x2001
|
||||
|
|
|
|||
|
|
@ -492,10 +492,10 @@ libfdt_tests () {
|
|||
run_test appendprop_addrrange unit-addr-without-reg.dtb 2 1 3
|
||||
|
||||
# Tests for behaviour on various sorts of corrupted trees
|
||||
run_test truncated_property truncated_property.dtb
|
||||
run_test truncated_string truncated_string.dtb
|
||||
run_test truncated_memrsv truncated_memrsv.dtb
|
||||
run_test unterminated_memrsv unterminated_memrsv.dtb
|
||||
run_test truncated_property
|
||||
run_test truncated_string
|
||||
run_test truncated_memrsv
|
||||
run_test unterminated_memrsv
|
||||
|
||||
# Check aliases support in fdt_path_offset
|
||||
run_dtc_test -I dts -O dtb -o aliases.dtb "$SRCDIR/aliases.dts"
|
||||
|
|
|
|||
|
|
@ -1,12 +1,28 @@
|
|||
#define TEST_ADDR_1 0xdeadbeef00000000ULL
|
||||
#define TEST_SIZE_1 0x0000000000100000ULL
|
||||
#define TEST_ADDR_2 123456789ULL
|
||||
#define TEST_SIZE_2 010000ULL
|
||||
#ifdef __ASSEMBLER__
|
||||
#define ASM_CONST_LL(x) (x)
|
||||
#else
|
||||
#define ASM_CONST_LL(x) (x##ULL)
|
||||
#endif
|
||||
|
||||
#define TEST_ADDR_1H ASM_CONST_LL(0xdeadbeef)
|
||||
#define TEST_ADDR_1L ASM_CONST_LL(0x00000000)
|
||||
#define TEST_ADDR_1 ((TEST_ADDR_1H << 32) | TEST_ADDR_1L)
|
||||
#define TEST_SIZE_1H ASM_CONST_LL(0x00000000)
|
||||
#define TEST_SIZE_1L ASM_CONST_LL(0x00100000)
|
||||
#define TEST_SIZE_1 ((TEST_SIZE_1H << 32) | TEST_SIZE_1L)
|
||||
#define TEST_ADDR_2H ASM_CONST_LL(0)
|
||||
#define TEST_ADDR_2L ASM_CONST_LL(123456789)
|
||||
#define TEST_ADDR_2 ((TEST_ADDR_2H << 32) | TEST_ADDR_2L)
|
||||
#define TEST_SIZE_2H ASM_CONST_LL(0)
|
||||
#define TEST_SIZE_2L ASM_CONST_LL(010000)
|
||||
#define TEST_SIZE_2 ((TEST_SIZE_2H << 32) | TEST_SIZE_2L)
|
||||
|
||||
#define TEST_VALUE_1 0xdeadbeef
|
||||
#define TEST_VALUE_2 123456789
|
||||
|
||||
#define TEST_VALUE64_1 0xdeadbeef01abcdefULL
|
||||
#define TEST_VALUE64_1H ASM_CONST_LL(0xdeadbeef)
|
||||
#define TEST_VALUE64_1L ASM_CONST_LL(0x01abcdef)
|
||||
#define TEST_VALUE64_1 ((TEST_VALUE64_1H << 32) | TEST_VALUE64_1L)
|
||||
|
||||
#define PHANDLE_1 0x2000
|
||||
#define PHANDLE_2 0x2001
|
||||
|
|
@ -29,3 +45,17 @@
|
|||
#define TEST_MEMREGION_SIZE 0x9abcdef0
|
||||
#define TEST_MEMREGION_SIZE_HI 0x0fedcba900000000
|
||||
#define TEST_MEMREGION_SIZE_INC 0x1000
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
extern struct fdt_header test_tree1;
|
||||
extern struct fdt_header truncated_property;
|
||||
extern struct fdt_header bad_node_char;
|
||||
extern struct fdt_header bad_node_format;
|
||||
extern struct fdt_header bad_prop_char;
|
||||
extern struct fdt_header ovf_size_strings;
|
||||
extern struct fdt_header truncated_string;
|
||||
extern struct fdt_header truncated_memrsv;
|
||||
extern struct fdt_header unterminated_memrsv;
|
||||
extern struct fdt_header two_roots;
|
||||
extern struct fdt_header named_root;
|
||||
#endif /* ! __ASSEMBLER__ */
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@ void test_init(int argc, char *argv[]);
|
|||
|
||||
#define streq(s1, s2) (strcmp((s1),(s2)) == 0)
|
||||
|
||||
/* Each test case must define this function */
|
||||
void cleanup(void);
|
||||
|
||||
#define verbose_printf(...) \
|
||||
if (verbose_test) { \
|
||||
printf(__VA_ARGS__); \
|
||||
|
|
@ -36,18 +39,21 @@ void test_init(int argc, char *argv[]);
|
|||
|
||||
#define PASS() \
|
||||
do { \
|
||||
cleanup(); \
|
||||
printf("PASS\n"); \
|
||||
exit(RC_PASS); \
|
||||
} while (0)
|
||||
|
||||
#define PASS_INCONCLUSIVE() \
|
||||
do { \
|
||||
cleanup(); \
|
||||
printf("PASS (inconclusive)\n"); \
|
||||
exit(RC_PASS); \
|
||||
} while (0)
|
||||
|
||||
#define IRRELEVANT() \
|
||||
do { \
|
||||
cleanup(); \
|
||||
printf("PASS (irrelevant)\n"); \
|
||||
exit(RC_PASS); \
|
||||
} while (0)
|
||||
|
|
@ -55,18 +61,21 @@ void test_init(int argc, char *argv[]);
|
|||
/* Look out, gcc extension below... */
|
||||
#define FAIL(fmt, ...) \
|
||||
do { \
|
||||
cleanup(); \
|
||||
printf("FAIL\t" fmt "\n", ##__VA_ARGS__); \
|
||||
exit(RC_FAIL); \
|
||||
} while (0)
|
||||
|
||||
#define CONFIG(fmt, ...) \
|
||||
do { \
|
||||
cleanup(); \
|
||||
printf("Bad configuration: " fmt "\n", ##__VA_ARGS__); \
|
||||
exit(RC_CONFIG); \
|
||||
} while (0)
|
||||
|
||||
#define TEST_BUG(fmt, ...) \
|
||||
do { \
|
||||
cleanup(); \
|
||||
printf("BUG in testsuite: " fmt "\n", ##__VA_ARGS__); \
|
||||
exit(RC_BUG); \
|
||||
} while (0)
|
||||
|
|
|
|||
|
|
@ -42,21 +42,29 @@ static inline void VALGRIND_MAKE_MEM_DEFINED(void *p, size_t len)
|
|||
int verbose_test = 1;
|
||||
char *test_name;
|
||||
|
||||
static void sigint_handler(int signum)
|
||||
void __attribute__((weak)) cleanup(void)
|
||||
{
|
||||
fprintf(stderr, "%s: signal %d (pid=%d)\n", test_name,
|
||||
signum, getpid());
|
||||
}
|
||||
|
||||
static void sigint_handler(int signum, siginfo_t *si, void *uc)
|
||||
{
|
||||
cleanup();
|
||||
fprintf(stderr, "%s: %s (pid=%d)\n", test_name,
|
||||
strsignal(signum), getpid());
|
||||
exit(RC_BUG);
|
||||
}
|
||||
|
||||
void test_init(int argc, char *argv[])
|
||||
{
|
||||
int err;
|
||||
struct sigaction sa_int = {
|
||||
.sa_sigaction = sigint_handler,
|
||||
};
|
||||
|
||||
test_name = argv[0];
|
||||
|
||||
/* Use signal(), not sigaction() because it also works on the Windows /
|
||||
* mingw environments we support.
|
||||
*/
|
||||
if (signal(SIGINT, sigint_handler) == SIG_ERR)
|
||||
err = sigaction(SIGINT, &sa_int, NULL);
|
||||
if (err)
|
||||
FAIL("Can't install SIGINT handler");
|
||||
|
||||
if (getenv("QUIET_TEST"))
|
||||
|
|
|
|||
756
tests/treegen.c
756
tests/treegen.c
|
|
@ -1,756 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* treegen - generate test device tree blobs
|
||||
*
|
||||
* Build example device tree blobs for test. Note that some of the generated
|
||||
* blobs are deliberately malformed, in order to test error conditions.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <libfdt_env.h>
|
||||
#include <fdt.h>
|
||||
|
||||
#include "tests.h"
|
||||
#include "testdata.h"
|
||||
|
||||
/*
|
||||
* Buffer with write cursor. Emit helpers write at the cursor, advance it, and
|
||||
* return the offset at which data was written.
|
||||
*/
|
||||
struct buf {
|
||||
char *data;
|
||||
size_t size, cursor;
|
||||
};
|
||||
|
||||
#define CHUNKSIZE 1024
|
||||
|
||||
static struct buf buf_init(void)
|
||||
{
|
||||
struct buf b = { NULL, 0, 0 };
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/* Low-level helpers */
|
||||
|
||||
static size_t emit_bytes(struct buf *b, const void *data, int len)
|
||||
{
|
||||
size_t off = b->cursor;
|
||||
|
||||
if (!len)
|
||||
return off;
|
||||
|
||||
if (b->cursor + len > b->size) {
|
||||
size_t newsize = b->cursor + len + CHUNKSIZE;
|
||||
|
||||
b->data = xrealloc(b->data, newsize);
|
||||
memset(b->data + b->size, 0, newsize - b->size);
|
||||
b->size = newsize;
|
||||
}
|
||||
memcpy(b->data + b->cursor, data, len);
|
||||
b->cursor += len;
|
||||
return off;
|
||||
}
|
||||
|
||||
static size_t emit_u32(struct buf *b, uint32_t val)
|
||||
{
|
||||
fdt32_t beval = cpu_to_fdt32(val);
|
||||
|
||||
return emit_bytes(b, &beval, sizeof(beval));
|
||||
}
|
||||
|
||||
static size_t emit_u64(struct buf *b, uint64_t val)
|
||||
{
|
||||
fdt64_t beval = cpu_to_fdt64(val);
|
||||
|
||||
return emit_bytes(b, &beval, sizeof(beval));
|
||||
}
|
||||
|
||||
static size_t emit_string(struct buf *b, const char *str)
|
||||
{
|
||||
return emit_bytes(b, str, strlen(str) + 1);
|
||||
}
|
||||
|
||||
#define MAX_ALIGNMENT 8
|
||||
|
||||
static size_t emit_align(struct buf *b, size_t alignment)
|
||||
{
|
||||
size_t pad = ((b->cursor + alignment - 1) & ~(alignment - 1)) - b->cursor;
|
||||
static const char zeros[MAX_ALIGNMENT];
|
||||
|
||||
assert(alignment <= MAX_ALIGNMENT);
|
||||
assert(pad < alignment);
|
||||
|
||||
return emit_bytes(b, zeros, pad);
|
||||
}
|
||||
|
||||
static size_t start_block(struct buf *b)
|
||||
{
|
||||
return b->cursor;
|
||||
}
|
||||
|
||||
static void fill_prop_name(struct buf *b, size_t strs, size_t prop, size_t stroff)
|
||||
{
|
||||
struct fdt_property *fp = (struct fdt_property *)(b->data + prop);
|
||||
|
||||
fp->nameoff = cpu_to_fdt32(stroff - strs);
|
||||
}
|
||||
|
||||
/* FDT structure helpers */
|
||||
|
||||
static size_t emit_fdt_header(struct buf *b)
|
||||
{
|
||||
size_t off = emit_u32(b, FDT_MAGIC);
|
||||
|
||||
emit_u32(b, 0); /* totalsize */
|
||||
emit_u32(b, 0); /* off_dt_struct */
|
||||
emit_u32(b, 0); /* off_dt_strings */
|
||||
emit_u32(b, 0); /* off_mem_rsvmap */
|
||||
emit_u32(b, 0x11); /* version */
|
||||
emit_u32(b, 0x10); /* last_comp_version */
|
||||
emit_u32(b, 0); /* boot_cpuid_phys */
|
||||
emit_u32(b, 0); /* size_dt_strings */
|
||||
emit_u32(b, 0); /* size_dt_struct */
|
||||
return off;
|
||||
}
|
||||
|
||||
static void finish_rsvmap(struct buf *b, size_t hdr, size_t rsvmap)
|
||||
{
|
||||
struct fdt_header *fh = (struct fdt_header *)(b->data + hdr);
|
||||
|
||||
fh->off_mem_rsvmap = cpu_to_fdt32(rsvmap - hdr);
|
||||
}
|
||||
|
||||
static void finish_struct_block(struct buf *b, size_t hdr, size_t start)
|
||||
{
|
||||
struct fdt_header *fh = (struct fdt_header *)(b->data + hdr);
|
||||
|
||||
fh->off_dt_struct = cpu_to_fdt32(start - hdr);
|
||||
fh->size_dt_struct = cpu_to_fdt32(b->cursor - start);
|
||||
}
|
||||
|
||||
static void finish_strings_block(struct buf *b, size_t hdr, size_t start)
|
||||
{
|
||||
struct fdt_header *fh = (struct fdt_header *)(b->data + hdr);
|
||||
|
||||
fh->off_dt_strings = cpu_to_fdt32(start - hdr);
|
||||
fh->size_dt_strings = cpu_to_fdt32(b->cursor - start);
|
||||
}
|
||||
|
||||
static void finish_totalsize(struct buf *b, size_t hdr)
|
||||
{
|
||||
struct fdt_header *fh = (struct fdt_header *)(b->data + hdr);
|
||||
|
||||
fh->totalsize = cpu_to_fdt32(b->cursor - hdr);
|
||||
}
|
||||
|
||||
static size_t emit_rsvmap_entry(struct buf *b, uint64_t addr, uint64_t size)
|
||||
{
|
||||
size_t off = emit_u64(b, addr);
|
||||
|
||||
emit_u64(b, size);
|
||||
return off;
|
||||
}
|
||||
|
||||
static size_t emit_rsvmap_term(struct buf *b)
|
||||
{
|
||||
return emit_rsvmap_entry(b, 0, 0);
|
||||
}
|
||||
|
||||
static void emit_rsvmap_empty(struct buf *b, size_t hdr)
|
||||
{
|
||||
size_t rsvmap = start_block(b);
|
||||
|
||||
emit_rsvmap_term(b);
|
||||
finish_rsvmap(b, hdr, rsvmap);
|
||||
}
|
||||
|
||||
static size_t emit_begin_node(struct buf *b, const char *name)
|
||||
{
|
||||
size_t off = emit_u32(b, FDT_BEGIN_NODE);
|
||||
|
||||
emit_string(b, name);
|
||||
emit_align(b, FDT_TAGSIZE);
|
||||
return off;
|
||||
}
|
||||
|
||||
static size_t emit_end_node(struct buf *b)
|
||||
{
|
||||
return emit_u32(b, FDT_END_NODE);
|
||||
}
|
||||
|
||||
static size_t emit_fdt_end(struct buf *b)
|
||||
{
|
||||
return emit_u32(b, FDT_END);
|
||||
}
|
||||
|
||||
static size_t emit_prop_header(struct buf *b, int nameoff, int len)
|
||||
{
|
||||
size_t off = emit_u32(b, FDT_PROP);
|
||||
|
||||
emit_u32(b, len);
|
||||
emit_u32(b, nameoff);
|
||||
return off;
|
||||
}
|
||||
|
||||
static size_t emit_prop_nil(struct buf *b, int nameoff)
|
||||
{
|
||||
return emit_prop_header(b, nameoff, 0);
|
||||
}
|
||||
|
||||
static size_t emit_prop_u32(struct buf *b, int nameoff, uint32_t val)
|
||||
{
|
||||
size_t off = emit_prop_header(b, nameoff, 4);
|
||||
|
||||
emit_u32(b, val);
|
||||
return off;
|
||||
}
|
||||
|
||||
static size_t emit_prop_u64(struct buf *b, int nameoff, uint64_t val)
|
||||
{
|
||||
size_t off = emit_prop_header(b, nameoff, 8);
|
||||
|
||||
emit_u64(b, val);
|
||||
return off;
|
||||
}
|
||||
|
||||
static size_t emit_prop_str(struct buf *b, int nameoff, const char *str)
|
||||
{
|
||||
int len = strlen(str) + 1;
|
||||
size_t off = emit_prop_header(b, nameoff, len);
|
||||
|
||||
emit_bytes(b, str, len);
|
||||
emit_align(b, FDT_TAGSIZE);
|
||||
return off;
|
||||
}
|
||||
|
||||
#define emit_prop_strings(b, nameoff, ...) \
|
||||
emit_prop_strings_(b, nameoff, __VA_ARGS__, NULL)
|
||||
|
||||
static size_t emit_prop_strings_(struct buf *b, int nameoff, ...)
|
||||
{
|
||||
size_t off = emit_prop_header(b, nameoff, 0);
|
||||
size_t start = b->cursor;
|
||||
va_list ap;
|
||||
const char *s;
|
||||
|
||||
va_start(ap, nameoff);
|
||||
while ((s = va_arg(ap, const char *)) != NULL)
|
||||
emit_string(b, s);
|
||||
va_end(ap);
|
||||
|
||||
((struct fdt_property *)(b->data + off))->len =
|
||||
cpu_to_fdt32(b->cursor - start);
|
||||
emit_align(b, FDT_TAGSIZE);
|
||||
return off;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tree generators
|
||||
*
|
||||
* Each function builds a complete DTB in a buffer.
|
||||
*/
|
||||
|
||||
static struct buf make_test_tree1(void)
|
||||
{
|
||||
struct buf b = buf_init();
|
||||
size_t hdr;
|
||||
size_t p_compatible, p_prop_int, p_prop_int64, p_prop_str,
|
||||
p_address_cells, p_size_cells;
|
||||
size_t p_s1_compatible, p_s1_reg, p_s1_prop_int;
|
||||
size_t p_s1ss_compatible, p_s1ss_placeholder, p_s1ss_prop_int;
|
||||
size_t p_s2_reg, p_s2_linux_phandle, p_s2_prop_int,
|
||||
p_s2_address_cells, p_s2_size_cells;
|
||||
size_t p_s2ss0_reg, p_s2ss0_phandle, p_s2ss0_compatible,
|
||||
p_s2ss0_prop_int;
|
||||
|
||||
hdr = emit_fdt_header(&b);
|
||||
emit_align(&b, 8);
|
||||
|
||||
{
|
||||
size_t rsvmap = start_block(&b);
|
||||
|
||||
emit_rsvmap_entry(&b, TEST_ADDR_1, TEST_SIZE_1);
|
||||
emit_rsvmap_entry(&b, TEST_ADDR_2, TEST_SIZE_2);
|
||||
emit_rsvmap_term(&b);
|
||||
finish_rsvmap(&b, hdr, rsvmap);
|
||||
}
|
||||
|
||||
{
|
||||
size_t ss = start_block(&b);
|
||||
|
||||
emit_begin_node(&b, "");
|
||||
p_compatible = emit_prop_str(&b, 0, "test_tree1");
|
||||
p_prop_int = emit_prop_u32(&b, 0, TEST_VALUE_1);
|
||||
p_prop_int64 = emit_prop_u64(&b, 0, TEST_VALUE64_1);
|
||||
p_prop_str = emit_prop_str(&b, 0, TEST_STRING_1);
|
||||
p_address_cells = emit_prop_u32(&b, 0, 1);
|
||||
p_size_cells = emit_prop_u32(&b, 0, 0);
|
||||
|
||||
emit_begin_node(&b, "subnode@1");
|
||||
p_s1_compatible = emit_prop_str(&b, 0, "subnode1");
|
||||
p_s1_reg = emit_prop_u32(&b, 0, 1);
|
||||
p_s1_prop_int = emit_prop_u32(&b, 0, TEST_VALUE_1);
|
||||
|
||||
emit_begin_node(&b, "subsubnode");
|
||||
p_s1ss_compatible = emit_prop_strings(&b, 0,
|
||||
"subsubnode1", "subsubnode");
|
||||
p_s1ss_placeholder = emit_prop_strings(&b, 0,
|
||||
"this is a placeholder string",
|
||||
"string2");
|
||||
p_s1ss_prop_int = emit_prop_u32(&b, 0, TEST_VALUE_1);
|
||||
emit_end_node(&b);
|
||||
|
||||
emit_begin_node(&b, "ss1");
|
||||
emit_end_node(&b);
|
||||
|
||||
emit_end_node(&b);
|
||||
|
||||
emit_begin_node(&b, "subnode@2");
|
||||
p_s2_reg = emit_prop_u32(&b, 0, 2);
|
||||
p_s2_linux_phandle = emit_prop_u32(&b, 0, PHANDLE_1);
|
||||
p_s2_prop_int = emit_prop_u32(&b, 0, TEST_VALUE_2);
|
||||
p_s2_address_cells = emit_prop_u32(&b, 0, 1);
|
||||
p_s2_size_cells = emit_prop_u32(&b, 0, 0);
|
||||
|
||||
emit_begin_node(&b, "subsubnode@0");
|
||||
p_s2ss0_reg = emit_prop_u32(&b, 0, 0);
|
||||
p_s2ss0_phandle = emit_prop_u32(&b, 0, PHANDLE_2);
|
||||
p_s2ss0_compatible = emit_prop_strings(&b, 0,
|
||||
"subsubnode2", "subsubnode");
|
||||
p_s2ss0_prop_int = emit_prop_u32(&b, 0, TEST_VALUE_2);
|
||||
emit_end_node(&b);
|
||||
|
||||
emit_begin_node(&b, "ss2");
|
||||
emit_end_node(&b);
|
||||
|
||||
emit_end_node(&b);
|
||||
|
||||
emit_end_node(&b);
|
||||
emit_fdt_end(&b);
|
||||
finish_struct_block(&b, hdr, ss);
|
||||
}
|
||||
|
||||
{
|
||||
size_t strs = start_block(&b);
|
||||
size_t s;
|
||||
|
||||
s = emit_string(&b, "compatible");
|
||||
fill_prop_name(&b, strs, p_compatible, s);
|
||||
fill_prop_name(&b, strs, p_s1_compatible, s);
|
||||
fill_prop_name(&b, strs, p_s1ss_compatible, s);
|
||||
fill_prop_name(&b, strs, p_s2ss0_compatible, s);
|
||||
|
||||
s = emit_string(&b, "prop-int");
|
||||
fill_prop_name(&b, strs, p_prop_int, s);
|
||||
fill_prop_name(&b, strs, p_s1_prop_int, s);
|
||||
fill_prop_name(&b, strs, p_s1ss_prop_int, s);
|
||||
fill_prop_name(&b, strs, p_s2_prop_int, s);
|
||||
fill_prop_name(&b, strs, p_s2ss0_prop_int, s);
|
||||
|
||||
fill_prop_name(&b, strs, p_prop_int64,
|
||||
emit_string(&b, "prop-int64"));
|
||||
|
||||
fill_prop_name(&b, strs, p_prop_str,
|
||||
emit_string(&b, "prop-str"));
|
||||
|
||||
fill_prop_name(&b, strs, p_s2_linux_phandle,
|
||||
emit_string(&b, "linux,phandle"));
|
||||
|
||||
fill_prop_name(&b, strs, p_s2ss0_phandle,
|
||||
emit_string(&b, "phandle"));
|
||||
|
||||
s = emit_string(&b, "reg");
|
||||
fill_prop_name(&b, strs, p_s1_reg, s);
|
||||
fill_prop_name(&b, strs, p_s2_reg, s);
|
||||
fill_prop_name(&b, strs, p_s2ss0_reg, s);
|
||||
|
||||
fill_prop_name(&b, strs, p_s1ss_placeholder,
|
||||
emit_string(&b, "placeholder"));
|
||||
|
||||
s = emit_string(&b, "#address-cells");
|
||||
fill_prop_name(&b, strs, p_address_cells, s);
|
||||
fill_prop_name(&b, strs, p_s2_address_cells, s);
|
||||
|
||||
s = emit_string(&b, "#size-cells");
|
||||
fill_prop_name(&b, strs, p_size_cells, s);
|
||||
fill_prop_name(&b, strs, p_s2_size_cells, s);
|
||||
|
||||
finish_strings_block(&b, hdr, strs);
|
||||
}
|
||||
|
||||
finish_totalsize(&b, hdr);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static struct buf make_truncated_property(void)
|
||||
{
|
||||
struct buf b = buf_init();
|
||||
size_t hdr;
|
||||
size_t p;
|
||||
|
||||
hdr = emit_fdt_header(&b);
|
||||
emit_align(&b, 8);
|
||||
|
||||
emit_rsvmap_empty(&b, hdr);
|
||||
|
||||
{
|
||||
size_t ss = start_block(&b);
|
||||
|
||||
emit_begin_node(&b, "");
|
||||
p = emit_prop_header(&b, 0, 4);
|
||||
finish_struct_block(&b, hdr, ss);
|
||||
}
|
||||
|
||||
{
|
||||
size_t strs = start_block(&b);
|
||||
|
||||
emit_string(&b, "truncated");
|
||||
fill_prop_name(&b, strs, p, strs);
|
||||
finish_strings_block(&b, hdr, strs);
|
||||
}
|
||||
|
||||
finish_totalsize(&b, hdr);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static struct buf make_bad_node_char(void)
|
||||
{
|
||||
struct buf b = buf_init();
|
||||
size_t hdr;
|
||||
|
||||
hdr = emit_fdt_header(&b);
|
||||
emit_align(&b, 8);
|
||||
|
||||
emit_rsvmap_empty(&b, hdr);
|
||||
|
||||
{
|
||||
size_t ss = start_block(&b);
|
||||
|
||||
emit_begin_node(&b, "");
|
||||
emit_begin_node(&b, "sub$node");
|
||||
emit_end_node(&b);
|
||||
emit_end_node(&b);
|
||||
emit_fdt_end(&b);
|
||||
finish_struct_block(&b, hdr, ss);
|
||||
}
|
||||
|
||||
finish_strings_block(&b, hdr, start_block(&b));
|
||||
|
||||
finish_totalsize(&b, hdr);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static struct buf make_bad_node_format(void)
|
||||
{
|
||||
struct buf b = buf_init();
|
||||
size_t hdr;
|
||||
|
||||
hdr = emit_fdt_header(&b);
|
||||
emit_align(&b, 8);
|
||||
|
||||
emit_rsvmap_empty(&b, hdr);
|
||||
|
||||
{
|
||||
size_t ss = start_block(&b);
|
||||
|
||||
emit_begin_node(&b, "");
|
||||
emit_begin_node(&b, "subnode@1@2");
|
||||
emit_end_node(&b);
|
||||
emit_end_node(&b);
|
||||
emit_fdt_end(&b);
|
||||
finish_struct_block(&b, hdr, ss);
|
||||
}
|
||||
|
||||
finish_strings_block(&b, hdr, start_block(&b));
|
||||
|
||||
finish_totalsize(&b, hdr);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static struct buf make_bad_prop_char(void)
|
||||
{
|
||||
struct buf b = buf_init();
|
||||
size_t hdr;
|
||||
size_t p;
|
||||
|
||||
hdr = emit_fdt_header(&b);
|
||||
emit_align(&b, 8);
|
||||
|
||||
emit_rsvmap_empty(&b, hdr);
|
||||
|
||||
{
|
||||
size_t ss = start_block(&b);
|
||||
|
||||
emit_begin_node(&b, "");
|
||||
p = emit_prop_u32(&b, 0, TEST_VALUE_1);
|
||||
emit_end_node(&b);
|
||||
emit_fdt_end(&b);
|
||||
finish_struct_block(&b, hdr, ss);
|
||||
}
|
||||
|
||||
{
|
||||
size_t strs = start_block(&b);
|
||||
|
||||
fill_prop_name(&b, strs, p,
|
||||
emit_string(&b, "prop$erty"));
|
||||
finish_strings_block(&b, hdr, strs);
|
||||
}
|
||||
|
||||
finish_totalsize(&b, hdr);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static struct buf make_ovf_size_strings(void)
|
||||
{
|
||||
struct buf b = buf_init();
|
||||
size_t hdr;
|
||||
|
||||
hdr = emit_fdt_header(&b);
|
||||
emit_align(&b, 8);
|
||||
|
||||
emit_rsvmap_empty(&b, hdr);
|
||||
|
||||
{
|
||||
size_t ss = start_block(&b);
|
||||
|
||||
emit_begin_node(&b, "");
|
||||
emit_prop_u32(&b, 0x10000000, 0);
|
||||
emit_end_node(&b);
|
||||
emit_fdt_end(&b);
|
||||
finish_struct_block(&b, hdr, ss);
|
||||
}
|
||||
|
||||
{
|
||||
size_t strs = start_block(&b);
|
||||
|
||||
emit_string(&b, "x");
|
||||
finish_strings_block(&b, hdr, strs);
|
||||
}
|
||||
|
||||
((struct fdt_header *)(b.data + hdr))->size_dt_strings =
|
||||
cpu_to_fdt32(0xffffffff);
|
||||
|
||||
finish_totalsize(&b, hdr);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static struct buf make_truncated_string(void)
|
||||
{
|
||||
struct buf b = buf_init();
|
||||
size_t hdr;
|
||||
size_t p_good, p_bad;
|
||||
|
||||
hdr = emit_fdt_header(&b);
|
||||
emit_align(&b, 8);
|
||||
|
||||
emit_rsvmap_empty(&b, hdr);
|
||||
|
||||
{
|
||||
size_t ss = start_block(&b);
|
||||
|
||||
emit_begin_node(&b, "");
|
||||
p_good = emit_prop_nil(&b, 0);
|
||||
p_bad = emit_prop_nil(&b, 0);
|
||||
emit_end_node(&b);
|
||||
emit_fdt_end(&b);
|
||||
finish_struct_block(&b, hdr, ss);
|
||||
}
|
||||
|
||||
{
|
||||
size_t strs = start_block(&b);
|
||||
|
||||
fill_prop_name(&b, strs, p_good, emit_string(&b, "good"));
|
||||
fill_prop_name(&b, strs, p_bad, emit_bytes(&b, "bad", 3));
|
||||
finish_strings_block(&b, hdr, strs);
|
||||
}
|
||||
|
||||
finish_totalsize(&b, hdr);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static struct buf make_truncated_memrsv(void)
|
||||
{
|
||||
struct buf b = buf_init();
|
||||
size_t hdr;
|
||||
|
||||
hdr = emit_fdt_header(&b);
|
||||
|
||||
{
|
||||
size_t ss = start_block(&b);
|
||||
|
||||
emit_begin_node(&b, "");
|
||||
emit_end_node(&b);
|
||||
emit_fdt_end(&b);
|
||||
finish_struct_block(&b, hdr, ss);
|
||||
}
|
||||
|
||||
finish_strings_block(&b, hdr, start_block(&b));
|
||||
|
||||
{
|
||||
size_t rsvmap;
|
||||
|
||||
emit_align(&b, 8);
|
||||
rsvmap = start_block(&b);
|
||||
emit_rsvmap_entry(&b, TEST_ADDR_1, TEST_SIZE_1);
|
||||
finish_rsvmap(&b, hdr, rsvmap);
|
||||
}
|
||||
|
||||
finish_totalsize(&b, hdr);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static struct buf make_unterminated_memrsv(void)
|
||||
{
|
||||
struct buf b = buf_init();
|
||||
size_t hdr;
|
||||
|
||||
hdr = emit_fdt_header(&b);
|
||||
|
||||
{
|
||||
size_t rsvmap;
|
||||
|
||||
emit_align(&b, 8);
|
||||
rsvmap = start_block(&b);
|
||||
emit_rsvmap_entry(&b, TEST_ADDR_1, TEST_SIZE_1);
|
||||
finish_rsvmap(&b, hdr, rsvmap);
|
||||
}
|
||||
|
||||
{
|
||||
size_t ss = start_block(&b);
|
||||
|
||||
emit_begin_node(&b, "");
|
||||
emit_end_node(&b);
|
||||
emit_fdt_end(&b);
|
||||
finish_struct_block(&b, hdr, ss);
|
||||
}
|
||||
|
||||
finish_strings_block(&b, hdr, start_block(&b));
|
||||
|
||||
finish_totalsize(&b, hdr);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static struct buf make_two_roots(void)
|
||||
{
|
||||
struct buf b = buf_init();
|
||||
size_t hdr;
|
||||
|
||||
hdr = emit_fdt_header(&b);
|
||||
emit_align(&b, 8);
|
||||
|
||||
emit_rsvmap_empty(&b, hdr);
|
||||
|
||||
{
|
||||
size_t ss = start_block(&b);
|
||||
|
||||
emit_begin_node(&b, "");
|
||||
emit_end_node(&b);
|
||||
emit_begin_node(&b, "");
|
||||
emit_end_node(&b);
|
||||
emit_fdt_end(&b);
|
||||
finish_struct_block(&b, hdr, ss);
|
||||
}
|
||||
|
||||
finish_strings_block(&b, hdr, start_block(&b));
|
||||
|
||||
finish_totalsize(&b, hdr);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static struct buf make_named_root(void)
|
||||
{
|
||||
struct buf b = buf_init();
|
||||
size_t hdr;
|
||||
|
||||
hdr = emit_fdt_header(&b);
|
||||
emit_align(&b, 8);
|
||||
|
||||
emit_rsvmap_empty(&b, hdr);
|
||||
|
||||
{
|
||||
size_t ss = start_block(&b);
|
||||
|
||||
emit_begin_node(&b, "fake");
|
||||
emit_end_node(&b);
|
||||
emit_fdt_end(&b);
|
||||
finish_struct_block(&b, hdr, ss);
|
||||
}
|
||||
|
||||
finish_strings_block(&b, hdr, start_block(&b));
|
||||
|
||||
finish_totalsize(&b, hdr);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/* Tree table and main */
|
||||
|
||||
static struct {
|
||||
struct buf (*generator)(void);
|
||||
const char *filename;
|
||||
} trees[] = {
|
||||
#define TREE(name) { make_##name, #name ".dtb" }
|
||||
TREE(test_tree1),
|
||||
TREE(bad_node_char), TREE(bad_node_format), TREE(bad_prop_char),
|
||||
TREE(ovf_size_strings),
|
||||
TREE(truncated_property), TREE(truncated_string),
|
||||
TREE(truncated_memrsv),
|
||||
TREE(unterminated_memrsv),
|
||||
TREE(two_roots),
|
||||
TREE(named_root),
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s <output-dir>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (chdir(argv[1]) != 0) {
|
||||
perror("chdir()");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(trees); i++) {
|
||||
struct buf b = trees[i].generator();
|
||||
const char *filename = trees[i].filename;
|
||||
int fd;
|
||||
ssize_t ret;
|
||||
|
||||
printf("Tree \"%s\", %zu bytes\n", filename, b.cursor);
|
||||
|
||||
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (fd < 0)
|
||||
perror("open()");
|
||||
|
||||
ret = write(fd, b.data, b.cursor);
|
||||
if (ret < 0 || (size_t)ret != b.cursor)
|
||||
perror("write()");
|
||||
|
||||
close(fd);
|
||||
free(b.data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
343
tests/trees.S
Normal file
343
tests/trees.S
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
#include <fdt.h>
|
||||
#include "testdata.h"
|
||||
|
||||
.macro fdtlong val
|
||||
.byte ((\val) >> 24) & 0xff
|
||||
.byte ((\val) >> 16) & 0xff
|
||||
.byte ((\val) >> 8) & 0xff
|
||||
.byte (\val) & 0xff
|
||||
.endm
|
||||
|
||||
.macro treehdr tree
|
||||
.balign 8
|
||||
.globl \tree
|
||||
\tree :
|
||||
fdtlong FDT_MAGIC
|
||||
fdtlong (\tree\()_end - \tree)
|
||||
fdtlong (\tree\()_struct - \tree)
|
||||
fdtlong (\tree\()_strings - \tree)
|
||||
fdtlong (\tree\()_rsvmap - \tree)
|
||||
fdtlong 0x11
|
||||
fdtlong 0x10
|
||||
fdtlong 0
|
||||
fdtlong (\tree\()_strings_end - \tree\()_strings)
|
||||
fdtlong (\tree\()_struct_end - \tree\()_struct)
|
||||
.endm
|
||||
|
||||
.macro rsvmape addrh, addrl, lenh, lenl
|
||||
fdtlong \addrh
|
||||
fdtlong \addrl
|
||||
fdtlong \lenh
|
||||
fdtlong \lenl
|
||||
.endm
|
||||
|
||||
.macro empty_rsvmap tree
|
||||
.balign 8
|
||||
\tree\()_rsvmap:
|
||||
rsvmape 0, 0, 0, 0
|
||||
\tree\()_rsvmap_end:
|
||||
.endm
|
||||
|
||||
.macro prophdr tree, name, len
|
||||
fdtlong FDT_PROP
|
||||
fdtlong \len
|
||||
fdtlong (\tree\()_\name - \tree\()_strings)
|
||||
.endm
|
||||
|
||||
.macro propnil tree, name
|
||||
prophdr \tree, \name, 0
|
||||
.endm
|
||||
|
||||
.macro propu32 tree, name, val
|
||||
prophdr \tree, \name, 4
|
||||
fdtlong \val
|
||||
.endm
|
||||
|
||||
.macro propu64 tree, name, valh, vall
|
||||
prophdr \tree, \name, 8
|
||||
fdtlong \valh
|
||||
fdtlong \vall
|
||||
.endm
|
||||
|
||||
.macro propstr tree, name, str:vararg
|
||||
prophdr \tree, \name, (55f - 54f)
|
||||
54:
|
||||
.asciz \str
|
||||
55:
|
||||
.balign 4
|
||||
.endm
|
||||
|
||||
.macro beginn name:vararg
|
||||
fdtlong FDT_BEGIN_NODE
|
||||
.asciz \name
|
||||
.balign 4
|
||||
.endm
|
||||
|
||||
.macro endn
|
||||
fdtlong FDT_END_NODE
|
||||
.endm
|
||||
|
||||
.macro string tree, name, str:vararg
|
||||
\tree\()_\name :
|
||||
.asciz \str
|
||||
.endm
|
||||
|
||||
|
||||
.data
|
||||
|
||||
treehdr test_tree1
|
||||
|
||||
.balign 8
|
||||
test_tree1_rsvmap:
|
||||
rsvmape TEST_ADDR_1H, TEST_ADDR_1L, TEST_SIZE_1H, TEST_SIZE_1L
|
||||
rsvmape TEST_ADDR_2H, TEST_ADDR_2L, TEST_SIZE_2H, TEST_SIZE_2L
|
||||
rsvmape 0, 0, 0, 0
|
||||
test_tree1_rsvmap_end:
|
||||
|
||||
test_tree1_struct:
|
||||
beginn ""
|
||||
propstr test_tree1, compatible, "test_tree1"
|
||||
propu32 test_tree1, prop_int, TEST_VALUE_1
|
||||
propu64 test_tree1, prop_int64, TEST_VALUE64_1H, TEST_VALUE64_1L
|
||||
propstr test_tree1, prop_str, TEST_STRING_1
|
||||
propu32 test_tree1, address_cells, 1
|
||||
propu32 test_tree1, size_cells, 0
|
||||
|
||||
beginn "subnode@1"
|
||||
propstr test_tree1, compatible, "subnode1"
|
||||
propu32 test_tree1, reg, 1
|
||||
propu32 test_tree1, prop_int, TEST_VALUE_1
|
||||
|
||||
beginn "subsubnode"
|
||||
propstr test_tree1, compatible, "subsubnode1\0subsubnode"
|
||||
propstr test_tree1, placeholder, "this is a placeholder string\0string2"
|
||||
propu32 test_tree1, prop_int, TEST_VALUE_1
|
||||
endn
|
||||
|
||||
beginn "ss1"
|
||||
endn
|
||||
|
||||
endn
|
||||
|
||||
beginn "subnode@2"
|
||||
propu32 test_tree1, reg, 2
|
||||
propu32 test_tree1, linux_phandle, PHANDLE_1
|
||||
propu32 test_tree1, prop_int, TEST_VALUE_2
|
||||
propu32 test_tree1, address_cells, 1
|
||||
propu32 test_tree1, size_cells, 0
|
||||
|
||||
beginn "subsubnode@0"
|
||||
propu32 test_tree1, reg, 0
|
||||
propu32 test_tree1, phandle, PHANDLE_2
|
||||
propstr test_tree1, compatible, "subsubnode2\0subsubnode"
|
||||
propu32 test_tree1, prop_int, TEST_VALUE_2
|
||||
endn
|
||||
|
||||
beginn "ss2"
|
||||
endn
|
||||
|
||||
endn
|
||||
|
||||
endn
|
||||
fdtlong FDT_END
|
||||
test_tree1_struct_end:
|
||||
|
||||
test_tree1_strings:
|
||||
string test_tree1, compatible, "compatible"
|
||||
string test_tree1, prop_int, "prop-int"
|
||||
string test_tree1, prop_int64, "prop-int64"
|
||||
string test_tree1, prop_str, "prop-str"
|
||||
string test_tree1, linux_phandle, "linux,phandle"
|
||||
string test_tree1, phandle, "phandle"
|
||||
string test_tree1, reg, "reg"
|
||||
string test_tree1, placeholder, "placeholder"
|
||||
string test_tree1, address_cells, "#address-cells"
|
||||
string test_tree1, size_cells, "#size-cells"
|
||||
test_tree1_strings_end:
|
||||
test_tree1_end:
|
||||
|
||||
|
||||
treehdr truncated_property
|
||||
empty_rsvmap truncated_property
|
||||
|
||||
truncated_property_struct:
|
||||
beginn ""
|
||||
prophdr truncated_property, prop_truncated, 4
|
||||
/* Oops, no actual property data here */
|
||||
truncated_property_struct_end:
|
||||
|
||||
truncated_property_strings:
|
||||
string truncated_property, prop_truncated, "truncated"
|
||||
truncated_property_strings_end:
|
||||
|
||||
truncated_property_end:
|
||||
|
||||
|
||||
treehdr bad_node_char
|
||||
empty_rsvmap bad_node_char
|
||||
|
||||
bad_node_char_struct:
|
||||
beginn ""
|
||||
beginn "sub$node"
|
||||
endn
|
||||
endn
|
||||
fdtlong FDT_END
|
||||
bad_node_char_struct_end:
|
||||
|
||||
bad_node_char_strings:
|
||||
bad_node_char_strings_end:
|
||||
bad_node_char_end:
|
||||
|
||||
|
||||
treehdr bad_node_format
|
||||
empty_rsvmap bad_node_format
|
||||
|
||||
bad_node_format_struct:
|
||||
beginn ""
|
||||
beginn "subnode@1@2"
|
||||
endn
|
||||
endn
|
||||
fdtlong FDT_END
|
||||
bad_node_format_struct_end:
|
||||
|
||||
bad_node_format_strings:
|
||||
bad_node_format_strings_end:
|
||||
bad_node_format_end:
|
||||
|
||||
|
||||
treehdr bad_prop_char
|
||||
empty_rsvmap bad_prop_char
|
||||
|
||||
bad_prop_char_struct:
|
||||
beginn ""
|
||||
propu32 bad_prop_char, prop, TEST_VALUE_1
|
||||
endn
|
||||
fdtlong FDT_END
|
||||
bad_prop_char_struct_end:
|
||||
|
||||
bad_prop_char_strings:
|
||||
string bad_prop_char, prop, "prop$erty"
|
||||
bad_prop_char_strings_end:
|
||||
bad_prop_char_end:
|
||||
|
||||
|
||||
/* overflow_size_strings */
|
||||
.balign 8
|
||||
.globl ovf_size_strings
|
||||
ovf_size_strings:
|
||||
fdtlong FDT_MAGIC
|
||||
fdtlong (ovf_size_strings_end - ovf_size_strings)
|
||||
fdtlong (ovf_size_strings_struct - ovf_size_strings)
|
||||
fdtlong (ovf_size_strings_strings - ovf_size_strings)
|
||||
fdtlong (ovf_size_strings_rsvmap - ovf_size_strings)
|
||||
fdtlong 0x11
|
||||
fdtlong 0x10
|
||||
fdtlong 0
|
||||
fdtlong 0xffffffff
|
||||
fdtlong (ovf_size_strings_struct_end - ovf_size_strings_struct)
|
||||
empty_rsvmap ovf_size_strings
|
||||
|
||||
ovf_size_strings_struct:
|
||||
beginn ""
|
||||
propu32 ovf_size_strings, bad_string, 0
|
||||
endn
|
||||
fdtlong FDT_END
|
||||
ovf_size_strings_struct_end:
|
||||
|
||||
ovf_size_strings_strings:
|
||||
string ovf_size_strings, x, "x"
|
||||
ovf_size_strings_bad_string = ovf_size_strings_strings + 0x10000000
|
||||
ovf_size_strings_strings_end:
|
||||
ovf_size_strings_end:
|
||||
|
||||
|
||||
/* truncated_string */
|
||||
treehdr truncated_string
|
||||
empty_rsvmap truncated_string
|
||||
|
||||
truncated_string_struct:
|
||||
beginn ""
|
||||
propnil truncated_string, good_string
|
||||
propnil truncated_string, bad_string
|
||||
endn
|
||||
fdtlong FDT_END
|
||||
truncated_string_struct_end:
|
||||
|
||||
truncated_string_strings:
|
||||
string truncated_string, good_string, "good"
|
||||
truncated_string_bad_string:
|
||||
.ascii "bad"
|
||||
/* NOTE: terminating \0 deliberately missing */
|
||||
truncated_string_strings_end:
|
||||
truncated_string_end:
|
||||
|
||||
|
||||
/* truncated_memrsv */
|
||||
treehdr truncated_memrsv
|
||||
|
||||
truncated_memrsv_struct:
|
||||
beginn ""
|
||||
endn
|
||||
fdtlong FDT_END
|
||||
truncated_memrsv_struct_end:
|
||||
|
||||
truncated_memrsv_strings:
|
||||
truncated_memrsv_strings_end:
|
||||
|
||||
.balign 8
|
||||
truncated_memrsv_rsvmap:
|
||||
rsvmape TEST_ADDR_1H, TEST_ADDR_1L, TEST_SIZE_1H, TEST_SIZE_1L
|
||||
truncated_memrsv_rsvmap_end:
|
||||
|
||||
truncated_memrsv_end:
|
||||
|
||||
/* unterminated_memrsv */
|
||||
treehdr unterminated_memrsv
|
||||
|
||||
unterminated_memrsv_rsvmap:
|
||||
rsvmape TEST_ADDR_1H, TEST_ADDR_1L, TEST_SIZE_1H, TEST_SIZE_1L
|
||||
unterminated_memrsv_rsvmap_end:
|
||||
|
||||
unterminated_memrsv_struct:
|
||||
beginn ""
|
||||
endn
|
||||
fdtlong FDT_END
|
||||
unterminated_memrsv_struct_end:
|
||||
|
||||
unterminated_memrsv_strings:
|
||||
unterminated_memrsv_strings_end:
|
||||
|
||||
unterminated_memrsv_end:
|
||||
|
||||
/* two root nodes */
|
||||
treehdr two_roots
|
||||
empty_rsvmap two_roots
|
||||
|
||||
two_roots_struct:
|
||||
beginn ""
|
||||
endn
|
||||
beginn ""
|
||||
endn
|
||||
fdtlong FDT_END
|
||||
two_roots_struct_end:
|
||||
|
||||
two_roots_strings:
|
||||
two_roots_strings_end:
|
||||
|
||||
two_roots_end:
|
||||
|
||||
|
||||
/* root node with a non-empty name */
|
||||
treehdr named_root
|
||||
empty_rsvmap named_root
|
||||
|
||||
named_root_struct:
|
||||
beginn "fake"
|
||||
endn
|
||||
fdtlong FDT_END
|
||||
named_root_struct_end:
|
||||
|
||||
named_root_strings:
|
||||
named_root_strings_end:
|
||||
|
||||
named_root_end:
|
||||
|
|
@ -19,13 +19,12 @@
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
void *fdt;
|
||||
void *fdt = &truncated_memrsv;
|
||||
void *buf;
|
||||
int err;
|
||||
uint64_t addr, size;
|
||||
|
||||
test_init(argc, argv);
|
||||
fdt = load_blob_arg(argc, argv);
|
||||
|
||||
err = fdt_check_header(fdt);
|
||||
if (err != 0)
|
||||
|
|
|
|||
|
|
@ -13,15 +13,17 @@
|
|||
#include <libfdt.h>
|
||||
|
||||
#include "tests.h"
|
||||
#include "testdata.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
void *fdt;
|
||||
void *fdt = &truncated_property;
|
||||
const void *prop;
|
||||
int len;
|
||||
|
||||
test_init(argc, argv);
|
||||
fdt = load_blob_arg(argc, argv);
|
||||
|
||||
vg_prepare_blob(fdt, fdt_totalsize(fdt));
|
||||
|
||||
prop = fdt_getprop(fdt, 0, "truncated", &len);
|
||||
if (prop)
|
||||
|
|
|
|||
|
|
@ -13,16 +13,18 @@
|
|||
#include <libfdt.h>
|
||||
|
||||
#include "tests.h"
|
||||
#include "testdata.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
void *fdt;
|
||||
void *fdt = &truncated_string;
|
||||
const struct fdt_property *good, *bad;
|
||||
int off, len;
|
||||
const char *name;
|
||||
|
||||
test_init(argc, argv);
|
||||
fdt = load_blob_arg(argc, argv);
|
||||
|
||||
vg_prepare_blob(fdt, fdt_totalsize(fdt));
|
||||
|
||||
off = fdt_first_property_offset(fdt, 0);
|
||||
good = fdt_get_property_by_offset(fdt, off, NULL);
|
||||
|
|
|
|||
|
|
@ -22,13 +22,12 @@
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
void *fdt;
|
||||
void *fdt = &unterminated_memrsv;
|
||||
void *buf;
|
||||
int err;
|
||||
uint64_t addr, size;
|
||||
|
||||
test_init(argc, argv);
|
||||
fdt = load_blob_arg(argc, argv);
|
||||
|
||||
err = fdt_check_header(fdt);
|
||||
if (err != 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue