|
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 |
}
|