* ========== Copyright Header Begin ==========================================
* Hypervisor Software File: mdlint.c
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* - Do no alter or remove copyright notices
* - Redistribution and use of this software in source and binary forms, with
* or without modification, are permitted provided that the following
* - Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of Sun Microsystems, Inc. or the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* You acknowledge that this software is not designed, licensed or
* intended for use in the design, construction, operation or maintenance of
* ========== Copyright Header End ============================================
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
#pragma ident "@(#)mdlint.c 1.3 07/06/07 SMI"
#define ASSERT(_s) assert(_s)
* Deliberate attempt to not borrow code and
* be able to lint the MD based on the spec.
* That way when things get broken in other
* pieces of code we dont lint them as correct anyway.
md_t
*md_init(char *fnamep
);
int process_options(int argc
, char **argv
);
void output_text(md_t
*mdp
, FILE *fp
);
void brief_sanity(md_t
*mdp
, FILE *fp
);
void output_text_data(FILE *fp
, char *propp
, uint8_t *datap
, int len
);
main(int argc
, char **argv
)
i
= process_options(argc
, argv
);
if (i
!= argc
-1) fatal("Machine description filename expected");
if (mdp
== NULL
) fatal("Unable to open MD");
fprintf(stderr
, "usage: %s [-t|--text] <mdfile>\n", namep
);
process_options(int argc
, char **argv
)
for (i
= 1; i
< argc
&& argv
[i
][0] == '-'; i
++) {
if (strcmp(argv
[i
], "-h") == 0 ||
strcmp(argv
[i
], "--help") == 0) {
if ((strcmp(argv
[i
], "-t") == 0) ||
(strcmp(argv
[i
], "--text") == 0)) {
fatal("Unrecognised option %s\n", argv
[i
]);
output_text(mdp
, stdout
);
brief_sanity(mdp
, stderr
);
output_text(md_t
*mdp
, FILE *fp
)
for (idx
= 0; !done
; idx
++) {
fprintf(fp
, "\t\t/* The end @ 0x%x */\n", idx
);
fprintf(fp
, "\t\t/* NULL */\n");
nextidx
= ntoh64(np
->d
.prop_idx
);
fprintf(fp
, "node %s node_0x%x {\t\t\t/* next "
mdp
->namep
+ stro
, idx
, nextidx
);
fprintf(fp
, "}\t\t\t\t\t/* @ 0x%x */\n", idx
);
nextidx
= ntoh64(np
->d
.prop_idx
);
fprintf(fp
, "\t%s -> node_0x%llx;\n",
mdp
->namep
+ stro
, nextidx
);
val
= ntoh64(np
->d
.prop_val
);
fprintf(fp
, "\t%s = 0x%llx;\t\t/* %lld */\n",
mdp
->namep
+ stro
, val
, val
);
offset
= ntoh32(np
->d
.prop_data
.offset
);
len
= ntoh32(np
->d
.prop_data
.len
);
fprintf(fp
, "\t%s = \"%s\";\n",
mdp
->namep
+ stro
, mdp
->datap
+ offset
);
offset
= ntoh32(np
->d
.prop_data
.offset
);
len
= ntoh32(np
->d
.prop_data
.len
);
output_text_data(fp
, mdp
->namep
+ stro
,
&(mdp
->datap
[offset
]), len
);
fatal("At index %d found unexpected node type %d"
" (0x%x : '%c') while searching for nodes",
idx
, np
->tag
, np
->tag
, np
->tag
);
* Data properties are a little special since in some cases
* we have an array of strings.
* First scan the data looking for legal string characters
* and ensuring that there are no null strings and the last
* string is correctly terminated
output_text_data(FILE *fp
, char *propp
, uint8_t *datap
, int len
)
/* array of strings check */
fprintf(fp
, "\t%s = {\n", propp
);
for (i
= 0; i
< len
; i
++) {
if (ch
!= 0 && (ch
< ' ' || ch
>= 126))
/* back-to-back nulls not allowed */
/* looks like safe to assume an array of strings */
for (i
= 0; i
< len
; i
+= step
) {
p
= ((char *)(datap
+ i
));
fprintf(fp
, "\t\t\"%s\"%s", p
, (i
+step
) == len
? "\n" : ",\n");
for (i
= 0; i
< len
-1; i
++) {
((i
&7) == 0) ? "\n\t\t" : " ", datap
[i
]);
fprintf(fp
, " 0x%02x };\n", datap
[i
]);
brief_sanity(md_t
*mdp
, FILE *fp
)
for (idx
= 0; !done
; idx
++) {
bool_t check_name
= false;
fatal("Node element @ 0x%x (%s) "
"defined within node @ 0x%x (%s)\n",
idx
, mdp
->namep
+ stro
, nodeidx
,
ntoh32(mdp
->mdep
[nodeidx
].name
));
fatal("Node end element @ 0x%x "
"defined outside a node\n", idx
);
fatal("At index %d found unexpected node type %d"
" (0x%x : '%c') while searching for nodes",
idx
, np
->tag
, np
->tag
, np
->tag
);
nlen
= strlen((char *)(mdp
->namep
+ stro
));
fatal("Element @ 0x%x (%s): "
"name length (%d) doesnt match strlen (%d)"
idx
, mdp
->datap
+ stro
, np
->namelen
, nlen
);
mdp
= (md_t
*)Xcalloc(1, md_t
);
if (stat(fnamep
, &sb
) < 0)
if ((sb
.st_mode
& S_IFMT
) != S_IFREG
||
sb
.st_size
< sizeof (md_hdr_t
)) {
mdp
->fh
= open(fnamep
, O_RDONLY
, 0);
mdp
->caddr
= mmap(NULL
, sb
.st_size
, PROT_READ
, MAP_PRIVATE
, mdp
->fh
,
if (mdp
->headerp
== MAP_FAILED
) {
/* setup internal structures */
mdp
->headerp
= (md_hdr_t
*)mdp
->caddr
;
mdp
->node_blk_size
= ntoh32(mdp
->headerp
->node_blk_sz
);
mdp
->name_blk_size
= ntoh32(mdp
->headerp
->name_blk_sz
);
mdp
->data_blk_size
= ntoh32(mdp
->headerp
->data_blk_sz
);
mdp
->mdep
= (md_element_t
*)(mdp
->caddr
+ sizeof (md_header_t
));
mdp
->namep
= (char *)(mdp
->caddr
+ sizeof (md_header_t
) +
mdp
->datap
= (uint8_t *)(mdp
->caddr
+ sizeof (md_header_t
) +
mdp
->name_blk_size
+ mdp
->node_blk_size
);
* should do a lot more sanity checking here.
if (mdp
->headerp
->transport_version
!= MD_TRANSPORT_VERSION
)
fatal("Unrecognised transport version");
* One more property we need is the count of nodes in the
* DAG, not just the number of elements.
idx
= ntoh64(np
->d
.prop_idx
);
fatal("At index %d found unexpected node type "
"%d (0x%x : '%c') while searching for nodes",
idx
, np
->tag
, np
->tag
, np
->tag
);
mdp
->element_count
= idx
+1; /* include DT_LIST_END */
ASSERT(mdp
->element_count
== (mdp
->node_blk_size
/ MD_ELEMENT_SIZE
));
munmap(mdp
->caddr
, mdp
->size
);