/*
 * libfdt - Flat Device Tree manipulation
 *	Test labels within values
 * Copyright (C) 2008 David Gibson, IBM Corporation.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>

#include <dlfcn.h>

#include <fdt.h>
#include <libfdt.h>

#include "tests.h"
#include "testdata.h"

struct val_label {
	const char *labelname;
	int propoff;
};

struct val_label labels1[] = {
	{ "start1", 0 },
	{ "mid1", 2 },
	{ "end1", -1 },
};

struct val_label labels2[] = {
	{ "start2", 0 },
	{ "innerstart2", 0 },
	{ "innermid2", 4 },
	{ "innerend2", -1 },
	{ "end2", -1 },
};

struct val_label labels3[] = {
	{ "start3", 0 },
	{ "innerstart3", 0 },
	{ "innermid3", 1 },
	{ "innerend3", -1 },
	{ "end3", -1 },
};

void check_prop_labels(void *sohandle, void *fdt, const char *name,
		       const struct val_label* labels, int n)
{
	const struct fdt_property *prop;
	const char *p;
	int len;
	int i;

	prop = fdt_get_property(fdt, 0, name, &len);
	if (!prop)
		FAIL("Couldn't locate property \"%s\"", name);

	p = dlsym(sohandle, name);
	if (!p)
		FAIL("Couldn't locate label symbol \"%s\"", name);

	if (p != (const char *)prop)
		FAIL("Label \"%s\" does not point to correct property", name);

	for (i = 0; i < n; i++) {
		int off = labels[i].propoff;

		if (off == -1)
			off = len;

		p = dlsym(sohandle, labels[i].labelname);
		if (!p)
			FAIL("Couldn't locate label symbol \"%s\"", name);

		if ((p - prop->data) != off)
			FAIL("Label \"%s\" points to offset %ld instead of %d"
			     "in property \"%s\"", labels[i].labelname,
			     (long)(p - prop->data), off, name);
	}
}

int main(int argc, char *argv[])
{
	void *sohandle;
	void *fdt;
	int err;

	test_init(argc, argv);
	if (argc != 2)
		CONFIG("Usage: %s <so file>", argv[0]);

	sohandle = dlopen(argv[1], RTLD_NOW);
	if (!sohandle)
		FAIL("Couldn't dlopen() %s", argv[1]);

	fdt = dlsym(sohandle, "dt_blob_start");
	if (!fdt)
		FAIL("Couldn't locate \"dt_blob_start\" symbol in %s",
		     argv[1]);

	err = fdt_check_header(fdt);
	if (err != 0)
		FAIL("%s contains invalid tree: %s", argv[1],
		     fdt_strerror(err));


	check_prop_labels(sohandle, fdt, "prop1", labels1, ARRAY_SIZE(labels1));
	check_prop_labels(sohandle, fdt, "prop2", labels2, ARRAY_SIZE(labels2));
	check_prop_labels(sohandle, fdt, "prop3", labels3, ARRAY_SIZE(labels3));

	PASS();
}
