Blame dwarfdump/tag_attr.c

Packit cdaae3
/*
Packit cdaae3
  Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
Packit cdaae3
  Portions Copyright (C) 2009-2012 SN Systems Ltd. All Rights Reserved.
Packit cdaae3
  Portions Copyright (C) 2009-2017 David Anderson. All Rights Reserved.
Packit cdaae3
Packit cdaae3
  This program is free software; you can redistribute it and/or modify it
Packit cdaae3
  under the terms of version 2 of the GNU General Public License as
Packit cdaae3
  published by the Free Software Foundation.
Packit cdaae3
Packit cdaae3
  This program is distributed in the hope that it would be useful, but
Packit cdaae3
  WITHOUT ANY WARRANTY; without even the implied warranty of
Packit cdaae3
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Packit cdaae3
Packit cdaae3
  Further, this software is distributed without any warranty that it is
Packit cdaae3
  free of the rightful claim of any third person regarding infringement
Packit cdaae3
  or the like.  Any license provided herein, whether implied or
Packit cdaae3
  otherwise, applies only to this software file.  Patent licenses, if
Packit cdaae3
  any, provided herein do not apply to combinations of this program with
Packit cdaae3
  other software, or any other product whatsoever.
Packit cdaae3
Packit cdaae3
  You should have received a copy of the GNU General Public License along
Packit cdaae3
  with this program; if not, write the Free Software Foundation, Inc., 51
Packit cdaae3
  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
Packit cdaae3
Packit cdaae3
*/
Packit cdaae3
Packit cdaae3
#include <dwarf.h>
Packit cdaae3
#include <stdio.h>
Packit cdaae3
#include <stdarg.h>   /* For va_start va_arg va_list */
Packit cdaae3
#include <stdlib.h>             /* For exit() declaration etc. */
Packit cdaae3
#include <errno.h>              /* For errno declaration. */
Packit cdaae3
#ifdef HAVE_UNISTD_H
Packit cdaae3
#include <unistd.h>
Packit cdaae3
#endif
Packit cdaae3
Packit cdaae3
#include "globals.h"
Packit cdaae3
#include "libdwarf.h"
Packit cdaae3
#include "common.h"
Packit cdaae3
#include "tag_common.h"
Packit cdaae3
#include "dwgetopt.h"
Packit cdaae3
Packit cdaae3
boolean ellipsis = FALSE; /* So we can use dwarf_names.c */
Packit cdaae3
Packit cdaae3
#define DW_VERSION_DATE_STR " 2018-01-29 11:08:35-08:00  "
Packit cdaae3
Packit cdaae3
/* Expected input format
Packit cdaae3
Packit cdaae3
0xffffffff
Packit cdaae3
value of a tag
Packit cdaae3
value of a standard attribute that follows that tag
Packit cdaae3
...
Packit cdaae3
0xffffffff
Packit cdaae3
value of a tag
Packit cdaae3
value of a standard attribute that follows that tag
Packit cdaae3
...
Packit cdaae3
0xffffffff
Packit cdaae3
...
Packit cdaae3
Packit cdaae3
Packit cdaae3
The generated tag_attr_combination_table
Packit cdaae3
is used and generated quite differently
Packit cdaae3
for standard than for extended tags.
Packit cdaae3
Packit cdaae3
For standard tags the generated table is indexed by
Packit cdaae3
tag number. All the columns are bit flags.
Packit cdaae3
Packit cdaae3
For extended tags the generated table is indexed (call it j) by 0 - N-1
Packit cdaae3
and  [j][0] is the tag number and the rest of the columns (1 - N-1) are
Packit cdaae3
allowed attribute numbers.
Packit cdaae3
Packit cdaae3
*/
Packit cdaae3
Packit cdaae3
unsigned int tag_attr_combination_table[ATTR_TABLE_ROW_MAXIMUM][ATTR_TABLE_COLUMN_MAXIMUM];
Packit cdaae3
Packit cdaae3
#ifdef HAVE_USAGE_TAG_ATTR
Packit cdaae3
/* Working array for a specific tag and will contain its valid attributes */
Packit cdaae3
static Dwarf_Half tag_attr_vector[DW_AT_last] = {0};
Packit cdaae3
static Dwarf_Half tag_parents[DW_TAG_last] = {0};
Packit cdaae3
static Dwarf_Half tag_children[DW_TAG_last] = {0};
Packit cdaae3
static Dwarf_Small tag_attr_legal[DW_TAG_last] = {0};
Packit cdaae3
#endif /* HAVE_USAGE_TAG_ATTR */
Packit cdaae3
Packit cdaae3
static const char *usage[] = {
Packit cdaae3
  "Usage: tag_attr_build <options>",
Packit cdaae3
  "    -i input-table-path",
Packit cdaae3
  "    -o output-table-path",
Packit cdaae3
  "    -s (Generate standard attribute table)",
Packit cdaae3
  "    -e (Generate extended attribute table (common extensions))",
Packit cdaae3
  ""
Packit cdaae3
};
Packit cdaae3
Packit cdaae3
const char *program_name = 0;
Packit cdaae3
char *input_name = 0;
Packit cdaae3
char *output_name = 0;
Packit cdaae3
int standard_flag = FALSE;
Packit cdaae3
int extended_flag = FALSE;
Packit cdaae3
Packit cdaae3
/* process arguments */
Packit cdaae3
static void
Packit cdaae3
process_args(int argc, char *argv[])
Packit cdaae3
{
Packit cdaae3
    int c = 0;
Packit cdaae3
    boolean usage_error = FALSE;
Packit cdaae3
Packit cdaae3
    program_name = argv[0];
Packit cdaae3
Packit cdaae3
    while ((c = dwgetopt(argc, argv, "i:o:se")) != EOF) {
Packit cdaae3
        switch (c) {
Packit cdaae3
        case 'i':
Packit cdaae3
            input_name = dwoptarg;
Packit cdaae3
            break;
Packit cdaae3
        case 'o':
Packit cdaae3
            output_name = dwoptarg;
Packit cdaae3
            break;
Packit cdaae3
        case 'e':
Packit cdaae3
            extended_flag = TRUE;
Packit cdaae3
            break;
Packit cdaae3
        case 's':
Packit cdaae3
            standard_flag = TRUE;
Packit cdaae3
            break;
Packit cdaae3
        default:
Packit cdaae3
            usage_error = TRUE;
Packit cdaae3
            break;
Packit cdaae3
        }
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (usage_error || 1 == dwoptind || dwoptind != argc) {
Packit cdaae3
        print_usage_message(argv[0],usage);
Packit cdaae3
        exit(FAILED);
Packit cdaae3
    }
Packit cdaae3
}
Packit cdaae3
/*  Two new naming routines May 2016.
Packit cdaae3
    Instead of directly calling dwarf_get_*()
Packit cdaae3
    When bad tag/attr numbers are presented we return
Packit cdaae3
    a warning string through the pointer.
Packit cdaae3
    The thought is that eventually someone will notice the error.
Packit cdaae3
    It might, of course, be better to emit an error message
Packit cdaae3
    and stop. */
Packit cdaae3
static void
Packit cdaae3
ta_get_AT_name(unsigned int attrnum,const char **nameout)
Packit cdaae3
{
Packit cdaae3
    int res = 0;
Packit cdaae3
Packit cdaae3
    res = dwarf_get_AT_name(attrnum,nameout);
Packit cdaae3
    if (res == DW_DLV_OK) {
Packit cdaae3
        return;
Packit cdaae3
    }
Packit cdaae3
    if (res == DW_DLV_NO_ENTRY) {
Packit cdaae3
        *nameout = "<no name known for the attribute>";
Packit cdaae3
        return;
Packit cdaae3
    }
Packit cdaae3
    *nameout = "<ERROR so no name known for the attribute>";
Packit cdaae3
    return;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
static void
Packit cdaae3
ta_get_TAG_name(unsigned int tag,const char **nameout)
Packit cdaae3
{
Packit cdaae3
    int res = 0;
Packit cdaae3
Packit cdaae3
    res = dwarf_get_TAG_name(tag,nameout);
Packit cdaae3
    if (res == DW_DLV_OK) {
Packit cdaae3
        return;
Packit cdaae3
    }
Packit cdaae3
    if (res == DW_DLV_NO_ENTRY) {
Packit cdaae3
        *nameout = "<no name known for the tag>";
Packit cdaae3
        return;
Packit cdaae3
    }
Packit cdaae3
    *nameout = "<ERROR so no name known for the tag>";
Packit cdaae3
    return;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
static unsigned maxrowused = 0;
Packit cdaae3
static unsigned maxcolused = 0;
Packit cdaae3
Packit cdaae3
/*  The argument sizes are declared in tag_common.h, so
Packit cdaae3
    the max usable is toprow-1 and topcol-1. */
Packit cdaae3
static void
Packit cdaae3
check_unused_combo(unsigned toprow,unsigned topcol)
Packit cdaae3
{
Packit cdaae3
    if ((toprow-1) !=  maxrowused) {
Packit cdaae3
        printf("Providing for %u rows but used 0-%u\n",
Packit cdaae3
            toprow,maxrowused);
Packit cdaae3
        printf("Giving up\n");
Packit cdaae3
        exit(1);
Packit cdaae3
    }
Packit cdaae3
    if ((topcol-1) != maxcolused) {
Packit cdaae3
        printf("Providing for %u cols but used 0-%u\n",
Packit cdaae3
            topcol,maxcolused);
Packit cdaae3
        printf("Giving up\n");
Packit cdaae3
        exit(1);
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
Packit cdaae3
static void
Packit cdaae3
validate_row_col(const char *position,
Packit cdaae3
    unsigned crow,
Packit cdaae3
    unsigned ccol,
Packit cdaae3
    unsigned maxrow,
Packit cdaae3
    unsigned maxcol)
Packit cdaae3
{
Packit cdaae3
    if (crow >= ATTR_TABLE_ROW_MAXIMUM) {
Packit cdaae3
        printf("error generating row in tag-attr array, %s "
Packit cdaae3
            "current row: %u  size of static array decl: %u\n",
Packit cdaae3
            position,crow, ATTR_TABLE_ROW_MAXIMUM);
Packit cdaae3
        exit(1);
Packit cdaae3
    }
Packit cdaae3
    if (crow >= maxrow) {
Packit cdaae3
        printf("error generating row in tag-attr array, %s "
Packit cdaae3
            "current row: %u  max allowed: %u\n",
Packit cdaae3
            position,crow,maxrow-1);
Packit cdaae3
        exit(1);
Packit cdaae3
    }
Packit cdaae3
    if (ccol >= ATTR_TABLE_COLUMN_MAXIMUM) {
Packit cdaae3
        printf("error generating column in tag-attr array, %s "
Packit cdaae3
            "current col: %u  size of static array decl: %u\n",
Packit cdaae3
            position,ccol, ATTR_TABLE_COLUMN_MAXIMUM);
Packit cdaae3
        exit(1);
Packit cdaae3
    }
Packit cdaae3
    if (ccol >= maxcol) {
Packit cdaae3
        printf("error generating column in tag-attr array, %s "
Packit cdaae3
            "current row: %u  max allowed: %u\n",
Packit cdaae3
            position,ccol,maxcol-1);
Packit cdaae3
        exit(1);
Packit cdaae3
    }
Packit cdaae3
    if (crow > maxrowused) {
Packit cdaae3
        maxrowused = crow;
Packit cdaae3
    }
Packit cdaae3
    if (ccol > maxcolused) {
Packit cdaae3
        maxcolused = ccol;
Packit cdaae3
    }
Packit cdaae3
    return;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
int
Packit cdaae3
main(int argc, char **argv)
Packit cdaae3
{
Packit cdaae3
    unsigned u = 0;
Packit cdaae3
    unsigned int num = 0;
Packit cdaae3
    int input_eof = 0;
Packit cdaae3
    unsigned table_rows = 0;
Packit cdaae3
    unsigned table_columns = 0;
Packit cdaae3
    unsigned current_row = 0;
Packit cdaae3
    FILE * fileInp = 0;
Packit cdaae3
    FILE * fileOut = 0;
Packit cdaae3
    const char *aname = 0;
Packit cdaae3
    unsigned int index = 0;
Packit cdaae3
Packit cdaae3
    print_version_details(argv[0],FALSE);
Packit cdaae3
    process_args(argc,argv);
Packit cdaae3
    print_args(argc,argv);
Packit cdaae3
Packit cdaae3
    if (!input_name ) {
Packit cdaae3
        fprintf(stderr,"Input name required, not supplied.\n");
Packit cdaae3
        print_usage_message(argv[0],usage);
Packit cdaae3
        exit(FAILED);
Packit cdaae3
    }
Packit cdaae3
    fileInp = fopen(input_name,"r");
Packit cdaae3
    if (!fileInp) {
Packit cdaae3
        fprintf(stderr,"Invalid input filename, could not open '%s'\n",
Packit cdaae3
            input_name);
Packit cdaae3
        print_usage_message(argv[0],usage);
Packit cdaae3
        exit(FAILED);
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (!output_name ) {
Packit cdaae3
        fprintf(stderr,"Output name required, not supplied.\n");
Packit cdaae3
        print_usage_message(argv[0],usage);
Packit cdaae3
        exit(FAILED);
Packit cdaae3
    }
Packit cdaae3
    fileOut = fopen(output_name,"w");
Packit cdaae3
    if (!fileOut) {
Packit cdaae3
        fprintf(stderr,"Invalid output filename, could not open: '%s'\n",
Packit cdaae3
            output_name);
Packit cdaae3
        print_usage_message(argv[0],usage);
Packit cdaae3
        exit(FAILED);
Packit cdaae3
    }
Packit cdaae3
    if ((standard_flag && extended_flag) ||
Packit cdaae3
        (!standard_flag && !extended_flag)) {
Packit cdaae3
        fprintf(stderr,"Invalid table type\n");
Packit cdaae3
        fprintf(stderr,"Choose -e  or -s .\n");
Packit cdaae3
        print_usage_message(argv[0],usage);
Packit cdaae3
        exit(FAILED);
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (standard_flag) {
Packit cdaae3
        table_rows = STD_ATTR_TABLE_ROWS;
Packit cdaae3
        table_columns = STD_ATTR_TABLE_COLUMNS;
Packit cdaae3
    } else {
Packit cdaae3
        table_rows = EXT_ATTR_TABLE_ROWS;
Packit cdaae3
        table_columns = EXT_ATTR_TABLE_COLS;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    input_eof = read_value(&num,fileInp);       /* 0xffffffff */
Packit cdaae3
    if (IS_EOF == input_eof) {
Packit cdaae3
        bad_line_input("Empty input file");
Packit cdaae3
    }
Packit cdaae3
    if (num != MAGIC_TOKEN_VALUE) {
Packit cdaae3
        bad_line_input("Expected 0xffffffff");
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    /*  Generate main header, regardless of contents */
Packit cdaae3
    fprintf(fileOut,"/* Generated code, do not edit. */\n");
Packit cdaae3
    fprintf(fileOut,"/* Generated sourcedate %s */\n",DW_VERSION_DATE_STR);
Packit cdaae3
    fprintf(fileOut,"\n/* BEGIN FILE */\n\n");
Packit cdaae3
Packit cdaae3
#ifdef HAVE_USAGE_TAG_ATTR
Packit cdaae3
    /* Generate the data type to record the usage of the pairs tag-attr */
Packit cdaae3
    if (standard_flag) {
Packit cdaae3
        fprintf(fileOut,"#ifndef HAVE_USAGE_TAG_ATTR\n");
Packit cdaae3
        fprintf(fileOut,"#define HAVE_USAGE_TAG_ATTR 1\n");
Packit cdaae3
        fprintf(fileOut,"#endif /* HAVE_USAGE_TAG_ATTR */\n\n");
Packit cdaae3
        fprintf(fileOut,"#ifdef HAVE_USAGE_TAG_ATTR\n");
Packit cdaae3
        fprintf(fileOut,"#include \"dwarf.h\"\n");
Packit cdaae3
        fprintf(fileOut,"#include \"libdwarf.h\"\n\n");
Packit cdaae3
        fprintf(fileOut,"typedef struct {\n");
Packit cdaae3
        fprintf(fileOut,"    unsigned int count; /* Attribute count */\n");
Packit cdaae3
        fprintf(fileOut,"    Dwarf_Half attr;    /* Attribute value */\n");
Packit cdaae3
        fprintf(fileOut,"} Usage_Tag_Attr;\n\n");
Packit cdaae3
    }
Packit cdaae3
#endif /* HAVE_USAGE_TAG_ATTR */
Packit cdaae3
Packit cdaae3
    while (!feof(stdin)) {
Packit cdaae3
        unsigned int tag;
Packit cdaae3
        unsigned int curcol = 0;
Packit cdaae3
        unsigned int cur_attr = 0;
Packit cdaae3
        unsigned int attr;
Packit cdaae3
Packit cdaae3
        input_eof = read_value(&tag,fileInp);
Packit cdaae3
        if (IS_EOF == input_eof) {
Packit cdaae3
            /* Reached normal eof */
Packit cdaae3
            break;
Packit cdaae3
        }
Packit cdaae3
        if (standard_flag) {
Packit cdaae3
            /* In standard case, the row indexed by tag */
Packit cdaae3
            if (tag >= table_rows ) {
Packit cdaae3
                bad_line_input("tag %d exceeds standard table size",tag);
Packit cdaae3
            }
Packit cdaae3
        } else {
Packit cdaae3
            /*  In extended case, the row indexed by 0-N
Packit cdaae3
                and column zero has the tag number. */
Packit cdaae3
            if (current_row >= table_rows) {
Packit cdaae3
                bad_line_input("too many extended table rows. Have %u max %u",
Packit cdaae3
                    current_row,table_rows);
Packit cdaae3
            }
Packit cdaae3
            validate_row_col("Reading tag",current_row,0,
Packit cdaae3
                table_rows,table_columns);
Packit cdaae3
            tag_attr_combination_table[current_row][0] = tag;
Packit cdaae3
        }
Packit cdaae3
Packit cdaae3
        input_eof = read_value(&num,fileInp);
Packit cdaae3
        if (IS_EOF == input_eof) {
Packit cdaae3
            bad_line_input("Not terminated correctly..");
Packit cdaae3
        }
Packit cdaae3
        curcol = 1;
Packit cdaae3
        cur_attr = 1;
Packit cdaae3
Packit cdaae3
#ifdef HAVE_USAGE_TAG_ATTR
Packit cdaae3
        /* Check if we have duplicated tags */
Packit cdaae3
        if (standard_flag) {
Packit cdaae3
            if (tag_parents[tag]) {
Packit cdaae3
                bad_line_input("tag 0x%02x value already defined",tag);
Packit cdaae3
            }
Packit cdaae3
            tag_parents[tag] = tag;
Packit cdaae3
Packit cdaae3
            /* Clear out the working attribute vector */
Packit cdaae3
            memset(tag_attr_vector,0,DW_AT_last * sizeof(Dwarf_Half));
Packit cdaae3
        }
Packit cdaae3
#endif /* HAVE_USAGE_TAG_ATTR */
Packit cdaae3
Packit cdaae3
        while (num != MAGIC_TOKEN_VALUE) {
Packit cdaae3
            if (standard_flag) {
Packit cdaae3
                unsigned idx = num / BITS_PER_WORD;
Packit cdaae3
                unsigned bit = num % BITS_PER_WORD;
Packit cdaae3
Packit cdaae3
                if (idx >= table_columns) {
Packit cdaae3
                    char msg[200];
Packit cdaae3
                    snprintf(msg, sizeof(msg),
Packit cdaae3
                        "too many attributes a: table incomplete "
Packit cdaae3
                        "index %d cols %d.",idx,table_columns);
Packit cdaae3
                    bad_line_input(msg);
Packit cdaae3
                }
Packit cdaae3
                validate_row_col("Setting attr bit",tag,idx,
Packit cdaae3
                    table_rows,table_columns);
Packit cdaae3
                tag_attr_combination_table[tag][idx] |= (((unsigned)1) << bit);
Packit cdaae3
            } else {
Packit cdaae3
                if (curcol >= table_columns) {
Packit cdaae3
                    char msg[200];
Packit cdaae3
                    snprintf(msg, sizeof(msg),
Packit cdaae3
                        "too many attributes b: table incomplete "
Packit cdaae3
                        "index %d cols %d.",curcol,table_columns);
Packit cdaae3
                    bad_line_input(msg);
Packit cdaae3
                }
Packit cdaae3
                validate_row_col("Setting attr col",current_row,curcol,
Packit cdaae3
                    table_rows,table_columns);
Packit cdaae3
                tag_attr_combination_table[current_row][curcol] = num;
Packit cdaae3
                curcol++;
Packit cdaae3
Packit cdaae3
            }
Packit cdaae3
Packit cdaae3
#ifdef HAVE_USAGE_TAG_ATTR
Packit cdaae3
            /* Record the usage only for standard tables */
Packit cdaae3
            if (standard_flag) {
Packit cdaae3
                /* Add attribute to current tag */
Packit cdaae3
                if (cur_attr >= DW_AT_last) {
Packit cdaae3
                    char msg[200];
Packit cdaae3
                    snprintf(msg, sizeof(msg),
Packit cdaae3
                        "too many attributes c: table incomplete "
Packit cdaae3
                        "index %d cols %d.",cur_attr,DW_AT_last);
Packit cdaae3
                    bad_line_input(msg);
Packit cdaae3
                }
Packit cdaae3
                /* Check for duplicated entries */
Packit cdaae3
                if (tag_attr_vector[cur_attr]) {
Packit cdaae3
                    bad_line_input("duplicated attributes: table incomplete.");
Packit cdaae3
                }
Packit cdaae3
                tag_attr_vector[cur_attr] = num;
Packit cdaae3
                cur_attr++;
Packit cdaae3
            }
Packit cdaae3
#endif /* HAVE_USAGE_TAG_ATTR */
Packit cdaae3
Packit cdaae3
            input_eof = read_value(&num,fileInp);
Packit cdaae3
            if (IS_EOF == input_eof) {
Packit cdaae3
                bad_line_input("Not terminated correctly.");
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
Packit cdaae3
#ifdef HAVE_USAGE_TAG_ATTR
Packit cdaae3
        /* Generate the tag-attributes vector for current tag */
Packit cdaae3
        if (standard_flag) {
Packit cdaae3
            if (tag >= DW_TAG_last) {
Packit cdaae3
                bad_line_input("tag 0x%02x exceeds standard table size",tag);
Packit cdaae3
            }
Packit cdaae3
            if (tag_children[tag]) {
Packit cdaae3
                bad_line_input("tag 0x%02x already defined",tag);
Packit cdaae3
            }
Packit cdaae3
            tag_children[tag] = tag;
Packit cdaae3
            /* Generate reference vector */
Packit cdaae3
            aname = 0;
Packit cdaae3
            ta_get_TAG_name(tag,&aname);
Packit cdaae3
            fprintf(fileOut,"/* 0x%02x - %s */\n",tag,aname);
Packit cdaae3
            fprintf(fileOut,
Packit cdaae3
                "static Usage_Tag_Attr tag_attr_%02x[] = {\n",tag);
Packit cdaae3
            for (index = 1; index < cur_attr; ++index) {
Packit cdaae3
                attr = tag_attr_vector[index];
Packit cdaae3
                ta_get_AT_name(attr,&aname);
Packit cdaae3
                fprintf(fileOut,"    {/* 0x%02x */  0, %s},\n",attr,aname);
Packit cdaae3
            }
Packit cdaae3
            fprintf(fileOut,"    {/* %4s */  0, 0}\n};\n\n"," ");
Packit cdaae3
            /* Record allowed number of attributes */
Packit cdaae3
            tag_attr_legal[tag] = cur_attr - 1;
Packit cdaae3
        }
Packit cdaae3
#endif /* HAVE_USAGE_TAG_ATTR */
Packit cdaae3
Packit cdaae3
        ++current_row;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
#ifdef HAVE_USAGE_TAG_ATTR
Packit cdaae3
    /* Generate the parent of the individual vectors */
Packit cdaae3
    check_unused_combo(table_rows,table_columns);
Packit cdaae3
    if (standard_flag) {
Packit cdaae3
        unsigned int tag;
Packit cdaae3
        unsigned int legal;
Packit cdaae3
Packit cdaae3
        fprintf(fileOut,
Packit cdaae3
            "static Usage_Tag_Attr *usage_tag_attr[] = {\n");
Packit cdaae3
        for (index = 0; index < DW_TAG_last; ++index) {
Packit cdaae3
            tag = tag_children[index];
Packit cdaae3
            if (tag) {
Packit cdaae3
                aname = 0;
Packit cdaae3
                ta_get_TAG_name(tag,&aname);
Packit cdaae3
                fprintf(fileOut,
Packit cdaae3
                    "    tag_attr_%02x, /* 0x%02x - %s */\n",tag,tag,aname);
Packit cdaae3
            } else {
Packit cdaae3
                fprintf(fileOut,"    0,\n");
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
        fprintf(fileOut,"    0\n};\n\n");
Packit cdaae3
Packit cdaae3
        /* Generate table with allowed number of attributes */
Packit cdaae3
        fprintf(fileOut,"typedef struct {\n");
Packit cdaae3
        fprintf(fileOut,"    Dwarf_Small legal; /* Legal attributes */\n");
Packit cdaae3
        fprintf(fileOut,"    Dwarf_Small found; /* Found attributes */\n");
Packit cdaae3
        fprintf(fileOut,"} Rate_Tag_Attr;\n\n");
Packit cdaae3
        fprintf(fileOut,
Packit cdaae3
            "static Rate_Tag_Attr rate_tag_attr[] = {\n");
Packit cdaae3
        for (tag = 0; tag < DW_TAG_last; ++tag) {
Packit cdaae3
            if (tag_children[tag]) {
Packit cdaae3
                legal = tag_attr_legal[tag];
Packit cdaae3
                aname = 0;
Packit cdaae3
                ta_get_TAG_name(tag,&aname);
Packit cdaae3
                fprintf(fileOut,
Packit cdaae3
                    "    {%2d, 0, /* 0x%02x - %s */},\n",legal,tag,aname);
Packit cdaae3
            } else {
Packit cdaae3
                fprintf(fileOut,"    {0, 0},\n");
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
        fprintf(fileOut,"    {0, 0}\n};\n\n");
Packit cdaae3
        fprintf(fileOut,"#endif /* HAVE_USAGE_TAG_ATTR */\n\n");
Packit cdaae3
    }
Packit cdaae3
#endif /* HAVE_USAGE_TAG_ATTR */
Packit cdaae3
Packit cdaae3
    if (standard_flag) {
Packit cdaae3
        fprintf(fileOut,"#define ATTR_TREE_ROW_COUNT %d\n\n",table_rows);
Packit cdaae3
        fprintf(fileOut,"#define ATTR_TREE_COLUMN_COUNT %d\n\n",table_columns);
Packit cdaae3
        fprintf(fileOut,
Packit cdaae3
            "static unsigned int tag_attr_combination_table"
Packit cdaae3
            "[ATTR_TREE_ROW_COUNT][ATTR_TREE_COLUMN_COUNT] = {\n");
Packit cdaae3
    }
Packit cdaae3
    else {
Packit cdaae3
        fprintf(fileOut,"/* Common extensions */\n");
Packit cdaae3
        fprintf(fileOut,"#define ATTR_TREE_EXT_ROW_COUNT %d\n\n",table_rows);
Packit cdaae3
        fprintf(fileOut,"#define ATTR_TREE_EXT_COLUMN_COUNT %d\n\n",
Packit cdaae3
            table_columns);
Packit cdaae3
        fprintf(fileOut,
Packit cdaae3
            "static unsigned int tag_attr_combination_ext_table"
Packit cdaae3
            "[ATTR_TREE_EXT_ROW_COUNT][ATTR_TREE_EXT_COLUMN_COUNT] = {\n");
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    for (u = 0; u < table_rows; u++) {
Packit cdaae3
        unsigned j = 0;
Packit cdaae3
        const char *name = 0;
Packit cdaae3
        if (standard_flag) {
Packit cdaae3
            ta_get_TAG_name(u,&name);
Packit cdaae3
            fprintf(fileOut,"/* 0x%02x - %-37s*/\n",u,name);
Packit cdaae3
        } else {
Packit cdaae3
            unsigned k = tag_attr_combination_table[u][0];
Packit cdaae3
            ta_get_TAG_name(k,&name);
Packit cdaae3
            fprintf(fileOut,"/* 0x%02x - %-37s*/\n",k,name);
Packit cdaae3
        }
Packit cdaae3
        fprintf(fileOut,"    { ");
Packit cdaae3
        for (j = 0; j < table_columns; ++j ) {
Packit cdaae3
            fprintf(fileOut,"0x%08x,",tag_attr_combination_table[u][j]);
Packit cdaae3
        }
Packit cdaae3
        fprintf(fileOut,"},\n");
Packit cdaae3
    }
Packit cdaae3
    fprintf(fileOut,"};\n");
Packit cdaae3
    fprintf(fileOut,"\n/* END FILE */\n");
Packit cdaae3
    fclose(fileInp);
Packit cdaae3
    fclose(fileOut);
Packit cdaae3
    return (0);
Packit cdaae3
}
Packit cdaae3
/* A fake so we can use dwarf_names.c */
Packit cdaae3
void print_error (UNUSEDARG Dwarf_Debug dbg,
Packit cdaae3
    UNUSEDARG const char * msg,
Packit cdaae3
    UNUSEDARG int res,
Packit cdaae3
    UNUSEDARG Dwarf_Error localerr)
Packit cdaae3
{
Packit cdaae3
}