diff options
Diffstat (limited to 'dwarfdump2/tag_tree.cc')
-rw-r--r-- | dwarfdump2/tag_tree.cc | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/dwarfdump2/tag_tree.cc b/dwarfdump2/tag_tree.cc new file mode 100644 index 0000000..93ea464 --- /dev/null +++ b/dwarfdump2/tag_tree.cc @@ -0,0 +1,282 @@ +/* + Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2009-2010 SN Systems Ltd. All rights reserved. + Portions Copyright 2009-2011 David Anderson. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + + + +$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_tree.c,v 1.8 2005/12/01 17:34:59 davea Exp $ */ +#include <dwarf.h> +#include <stdio.h> +#include <stdlib.h> /* For exit() declaration etc. */ +#include <errno.h> /* For errno declaration. */ +#include <unistd.h> /* For getopt. */ + +#include "globals.h" +#include "naming.h" +#include "common.h" +#include "tag_common.h" +using std::cout; +using std::cerr; +using std::endl; +using std::string; + +unsigned int tag_tree_combination_table[TAG_TABLE_ROW_MAXIMUM][TAG_TABLE_COLUMN_MAXIMUM]; + +bool ellipsis = false; /* So we can use dwarf_names.c */ + +/* Expected input format + +0xffffffff +value of a tag +value of a standard tag that may be a child ofthat tag +... +0xffffffff +value of a tag +value of a standard tag that may be a child ofthat tag +... +0xffffffff +... + +No commentary allowed, no symbols, just numbers. +Blank lines are allowed and are dropped. + +*/ + +static const char *usage[] = { + "Usage: tag_tree_build <options>\n", + "options:\t-t\tGenerate Tags table\n", + " -i Input-file-path\n", + " -o Output-table-path\n", + " -e (Want Extended table (common extensions))\n", + " -s (Want Standard table)\n", + "" +}; + +static std::string input_name; +static std::string output_name; +bool extended_flag = false; +bool standard_flag = false; + +static void +process_args(int argc, char *argv[]) +{ + int c = 0; + bool usage_error = false; + + while ((c = getopt(argc, argv, "i:o:es")) != EOF) { + switch (c) { + case 'i': + input_name = optarg; + break; + case 'o': + output_name = optarg; + break; + case 'e': + extended_flag = true; + break; + case 's': + standard_flag = true; + break; + default: + usage_error = true; + break; + } + } + + if (usage_error || 1 == optind || optind != argc) { + print_usage_message(argv[0],usage); + exit(FAILED); + } +} + + + +int +main(int argc, char **argv) +{ + + + print_version_details(argv[0],false); + process_args(argc,argv); + print_args(argc,argv); + + if (input_name.empty() ) { + cerr << "Input name required, not supplied." << endl; + print_usage_message(argv[0],usage); + exit(FAILED); + } + FILE *fileInp = fopen(input_name.c_str(),"r"); + if (!fileInp) { + cerr << "Invalid input filename, could not open '" << + input_name << "'" << endl; + print_usage_message(argv[0],usage); + exit(FAILED); + } + + + if (output_name.empty() ) { + cerr << "Output name required, not supplied." << endl; + print_usage_message(argv[0],usage); + exit(FAILED); + } + FILE *fileOut = fopen(output_name.c_str(),"w"); + if (!fileOut) { + cerr << "Invalid output filename, could not open: '" << + output_name << "'" << endl; + print_usage_message(argv[0],usage); + exit(FAILED); + } + if ((standard_flag && extended_flag) || (!standard_flag && !extended_flag)) { + cerr <<"Invalid table type" << endl; + cerr << "Choose -e or -s ." << endl; + print_usage_message(argv[0],usage); + exit(FAILED); + } + unsigned int table_rows = 0; + unsigned int table_columns = 0; + if(standard_flag) { + table_rows = STD_TAG_TABLE_ROWS; + table_columns = STD_TAG_TABLE_COLUMNS; + } else { + table_rows = EXT_TAG_TABLE_ROWS; + table_columns = EXT_TAG_TABLE_COLS; + } + + unsigned int num = 0; + int input_eof = read_value(&num,fileInp); /* 0xffffffff */ + if (IS_EOF == input_eof) { + bad_line_input("Empty input file"); + } + if (num != MAGIC_TOKEN_VALUE) { + bad_line_input("Expected 0xffffffff"); + } + + unsigned int current_row = 0; + while (!feof(stdin)) { + unsigned int tag = 0; + unsigned int nTagLoc = 0; + + input_eof = read_value(&tag,fileInp); + if (IS_EOF == input_eof) { + /* Reached normal eof */ + break; + } + if(standard_flag) { + if (tag >= table_rows ) { + bad_line_input("tag value exceeds standard table size"); + } + } else { + if(current_row >= table_rows) { + bad_line_input("too many extended table rows."); + } + tag_tree_combination_table[current_row][0] = tag; + } + input_eof = read_value(&num,fileInp); + if (IS_EOF == input_eof) { + bad_line_input("Not terminated correctly.."); + } + nTagLoc = 1; + while (num != 0xffffffff) { + if(standard_flag) { + unsigned idx = num / BITS_PER_WORD; + unsigned bit = num % BITS_PER_WORD; + + if (idx >= table_columns) { + cout << "Want column " << idx << ", have only " << + table_columns << endl; + bad_line_input("too many TAGs: table incomplete."); + } + tag_tree_combination_table[tag][idx] |= (1 << bit); + } else { + if(nTagLoc >= table_columns) { + cout << "Attempting to use column " << nTagLoc << + ", max is " << table_columns << endl; + bad_line_input("too many subTAGs, table incomplete."); + } + tag_tree_combination_table[current_row][nTagLoc] = num; + nTagLoc++; + } + input_eof = read_value(&num,fileInp); + if (IS_EOF == input_eof) { + bad_line_input("Not terminated correctly."); + } + } + ++current_row; /* for extended table */ + } + fprintf(fileOut,"/* Generated code, do not edit. */\n"); + fprintf(fileOut,"/* Generated on %s %s */\n",__DATE__,__TIME__); + if (standard_flag) { + fprintf(fileOut,"#define TAG_TREE_COLUMN_COUNT %d\n\n",table_columns); + fprintf(fileOut,"#define TAG_TREE_ROW_COUNT %d\n\n",table_rows); + fprintf(fileOut, + "static unsigned int tag_tree_combination_table" + "[TAG_TREE_ROW_COUNT][TAG_TREE_COLUMN_COUNT] = {\n"); + } else { + fprintf(fileOut,"#define TAG_TREE_EXT_COLUMN_COUNT %d\n\n", + table_columns); + fprintf(fileOut,"#define TAG_TREE_EXT_ROW_COUNT %d\n\n",table_rows); + fprintf(fileOut,"/* Common extensions */\n"); + fprintf(fileOut, + "static unsigned int tag_tree_combination_ext_table" + "[TAG_TREE_EXT_ROW_COUNT][TAG_TREE_EXT_COLUMN_COUNT] = {\n"); + } + + for (unsigned i = 0; i < table_rows; i++) { + bool printonerr=false; + if (standard_flag) { + fprintf(fileOut,"/* %d %-37s*/\n",i, + get_TAG_name(i,printonerr).c_str()); + } else { + fprintf(fileOut,"/* %u %-37s*/\n", + tag_tree_combination_table[i][0], + get_TAG_name( + tag_tree_combination_table[i][0],printonerr).c_str()); + } + fprintf(fileOut," { "); + for(unsigned j = 0; j < table_columns; ++j ) { + fprintf(fileOut,"0x%08x,",tag_tree_combination_table[i][j]); + } + fprintf(fileOut,"},\n"); + + } + fprintf(fileOut,"\n#define MAX_CHECKED_TAG_ID 0x%2x\n",STD_TAG_TABLE_ROWS); + fprintf(fileOut,"};\n"); + fclose(fileInp); + fclose(fileOut); + return (0); +} + +/* A fake so we can use dwarf_names.c */ +void print_error (Dwarf_Debug dbg, const string& msg,int res, Dwarf_Error err) +{ +} + |