Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / util / einfo.c
1 /*
2  * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19
20 #include <stddef.h>
21 #include <stdint.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/mman.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <getopt.h>
32
33 #define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
34
35 /** Command-line options */
36 struct options {
37 };
38
39 /** Error usage information */
40 struct einfo {
41         /** Size of error information record */
42         uint32_t size;
43         /** Error number */
44         uint32_t error;
45         /** Offset to error description (NUL-terminated) */
46         uint32_t desc;
47         /** Offset to file name (NUL-terminated) */
48         uint32_t file;
49         /** Line number */
50         uint32_t line;
51 } __attribute__ (( packed ));
52
53 /**
54  * Process einfo file
55  *
56  * @v infile            Filename
57  * @v opts              Command-line options
58  */
59 static void einfo ( const char *infile,
60                     struct options *opts __attribute__ (( unused )) ) {
61         int fd;
62         struct stat stat;
63         size_t len;
64         void *start;
65         struct einfo *einfo;
66
67         /* Open einfo file */
68         if ( ( fd = open ( infile, O_RDONLY ) ) < 0 ) {
69                 eprintf ( "Cannot open \"%s\": %s\n",
70                           infile, strerror ( errno ) );
71                 exit ( 1 );
72         }
73
74         /* Get file size */
75         if ( fstat ( fd, &stat ) < 0 ) {
76                 eprintf ( "Cannot stat \"%s\": %s\n",
77                           infile, strerror ( errno ) );
78                 exit ( 1 );
79         }
80         len = stat.st_size;
81
82         if ( len ) {
83
84                 /* Map file */
85                 if ( ( start = mmap ( NULL, len, PROT_READ, MAP_SHARED,
86                                       fd, 0 ) ) == MAP_FAILED ) {
87                         eprintf ( "Cannot mmap \"%s\": %s\n",
88                                   infile, strerror ( errno ) );
89                         exit ( 1 );
90                 }
91
92                 /* Iterate over einfo records */
93                 for ( einfo = start ; ( ( void * ) einfo ) < ( start + len ) ;
94                       einfo = ( ( ( void * ) einfo ) + einfo->size ) ) {
95                         printf ( "%08x\t%s\t%d\t%s\n", einfo->error,
96                                  ( ( ( char * ) einfo ) + einfo->file ),
97                                  einfo->line,
98                                  ( ( ( char * ) einfo ) + einfo->desc ) );
99                 }
100
101                 /* Unmap file */
102                 munmap ( start, len );
103         }
104
105         /* Close file */
106         close ( fd );
107 }
108
109 /**
110  * Print help
111  *
112  * @v program_name      Program name
113  */
114 static void print_help ( const char *program_name ) {
115         eprintf ( "Syntax: %s file1.einfo [file2.einfo...]\n",
116                   program_name );
117 }
118
119 /**
120  * Parse command-line options
121  *
122  * @v argc              Argument count
123  * @v argv              Argument list
124  * @v opts              Options structure to populate
125  */
126 static int parse_options ( const int argc, char **argv,
127                            struct options *opts __attribute__ (( unused )) ) {
128         int c;
129
130         while (1) {
131                 int option_index = 0;
132                 static struct option long_options[] = {
133                         { "help", 0, NULL, 'h' },
134                         { 0, 0, 0, 0 }
135                 };
136
137                 if ( ( c = getopt_long ( argc, argv, "s:h",
138                                          long_options,
139                                          &option_index ) ) == -1 ) {
140                         break;
141                 }
142
143                 switch ( c ) {
144                 case 'h':
145                         print_help ( argv[0] );
146                         exit ( 0 );
147                 case '?':
148                 default:
149                         exit ( 2 );
150                 }
151         }
152         return optind;
153 }
154
155 int main ( int argc, char **argv ) {
156         struct options opts = {
157         };
158         int infile_index;
159         const char *infile;
160
161         /* Parse command-line arguments */
162         infile_index = parse_options ( argc, argv, &opts );
163         if ( argc <= infile_index ) {
164                 print_help ( argv[0] );
165                 exit ( 2 );
166         }
167
168         /* Process each einfo file */
169         for ( ; infile_index < argc ; infile_index++ ) {
170                 infile = argv[infile_index];
171                 einfo ( infile, &opts );
172         }
173
174         return 0;
175 }