1 /* $NetBSD: value-labels.c,v 1.1.1.2 2017/06/08 15:59:28 skrll Exp $ */ 2 3 /* 4 * libfdt - Flat Device Tree manipulation 5 * Test labels within values 6 * Copyright (C) 2008 David Gibson, IBM Corporation. 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public License 10 * as published by the Free Software Foundation; either version 2.1 of 11 * the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23 #include <stdlib.h> 24 #include <stdio.h> 25 #include <string.h> 26 #include <stdint.h> 27 #include <errno.h> 28 29 #include <dlfcn.h> 30 31 #include <libfdt.h> 32 33 #include "tests.h" 34 #include "testdata.h" 35 36 struct val_label { 37 const char *labelname; 38 int propoff; 39 }; 40 41 static struct val_label labels1[] = { 42 { "start1", 0 }, 43 { "mid1", 2 }, 44 { "end1", -1 }, 45 }; 46 47 static struct val_label labels2[] = { 48 { "start2", 0 }, 49 { "innerstart2", 0 }, 50 { "innermid2", 4 }, 51 { "innerend2", -1 }, 52 { "end2", -1 }, 53 }; 54 55 static struct val_label labels3[] = { 56 { "start3", 0 }, 57 { "innerstart3", 0 }, 58 { "innermid3", 1 }, 59 { "innerend3", -1 }, 60 { "end3", -1 }, 61 }; 62 63 static void check_prop_labels(void *sohandle, void *fdt, const char *name, 64 const struct val_label* labels, int n) 65 { 66 const struct fdt_property *prop; 67 const char *p; 68 int len; 69 int i; 70 71 prop = fdt_get_property(fdt, 0, name, &len); 72 if (!prop) 73 FAIL("Couldn't locate property \"%s\"", name); 74 75 p = dlsym(sohandle, name); 76 if (!p) 77 FAIL("Couldn't locate label symbol \"%s\"", name); 78 79 if (p != (const char *)prop) 80 FAIL("Label \"%s\" does not point to correct property", name); 81 82 for (i = 0; i < n; i++) { 83 int off = labels[i].propoff; 84 85 if (off == -1) 86 off = len; 87 88 p = dlsym(sohandle, labels[i].labelname); 89 if (!p) 90 FAIL("Couldn't locate label symbol \"%s\"", name); 91 92 if ((p - prop->data) != off) 93 FAIL("Label \"%s\" points to offset %ld instead of %d" 94 "in property \"%s\"", labels[i].labelname, 95 (long)(p - prop->data), off, name); 96 } 97 } 98 99 int main(int argc, char *argv[]) 100 { 101 void *sohandle; 102 void *fdt; 103 int err; 104 105 test_init(argc, argv); 106 if (argc != 2) 107 CONFIG("Usage: %s <so file>", argv[0]); 108 109 sohandle = dlopen(argv[1], RTLD_NOW); 110 if (!sohandle) 111 FAIL("Couldn't dlopen() %s", argv[1]); 112 113 fdt = dlsym(sohandle, "dt_blob_start"); 114 if (!fdt) 115 FAIL("Couldn't locate \"dt_blob_start\" symbol in %s", 116 argv[1]); 117 118 err = fdt_check_header(fdt); 119 if (err != 0) 120 FAIL("%s contains invalid tree: %s", argv[1], 121 fdt_strerror(err)); 122 123 124 check_prop_labels(sohandle, fdt, "prop1", labels1, ARRAY_SIZE(labels1)); 125 check_prop_labels(sohandle, fdt, "prop2", labels2, ARRAY_SIZE(labels2)); 126 check_prop_labels(sohandle, fdt, "prop3", labels3, ARRAY_SIZE(labels3)); 127 128 PASS(); 129 } 130