summaryrefslogtreecommitdiff
path: root/sys/ddb
diff options
context:
space:
mode:
Diffstat (limited to 'sys/ddb')
-rw-r--r--sys/ddb/db_command.c5
-rw-r--r--sys/ddb/db_struct.c277
-rw-r--r--sys/ddb/db_structinfo.c106
-rwxr-xr-xsys/ddb/parse_structinfo.pl390
4 files changed, 1 insertions, 777 deletions
diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c
index 2242dce5e6c..0cf09c4c878 100644
--- a/sys/ddb/db_command.c
+++ b/sys/ddb/db_command.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: db_command.c,v 1.76 2017/09/06 04:47:26 dlg Exp $ */
+/* $OpenBSD: db_command.c,v 1.77 2017/09/12 08:23:42 mpi Exp $ */
/* $NetBSD: db_command.c,v 1.20 1996/03/30 22:30:05 christos Exp $ */
/*
@@ -581,9 +581,6 @@ struct db_command db_show_cmds[] = {
{ "nfsnode", db_nfsnode_print_cmd, 0, NULL },
#endif
{ "object", db_object_print_cmd, 0, NULL },
-#ifdef DDB_STRUCT
- { "offset", db_struct_offset_cmd, CS_OWN, NULL },
-#endif
{ "page", db_page_print_cmd, 0, NULL },
{ "panic", db_show_panic_cmd, 0, NULL },
{ "pool", db_pool_print_cmd, 0, NULL },
diff --git a/sys/ddb/db_struct.c b/sys/ddb/db_struct.c
deleted file mode 100644
index 32ac575030d..00000000000
--- a/sys/ddb/db_struct.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/* $OpenBSD: db_struct.c,v 1.4 2015/09/01 05:26:10 jsg Exp $ */
-
-/*
- * Copyright (c) 2009 Miodrag Vallat.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * ddb routines to describe struct information
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-
-#include <machine/db_machdep.h>
-
-#include <ddb/db_lex.h>
-#include <ddb/db_output.h>
-#include <ddb/db_access.h>
-#include <ddb/db_command.h>
-#include <ddb/db_extern.h>
-#include <ddb/db_interface.h>
-#include <ddb/db_var.h>
-
-#include "db_structinfo.h"
-
-void db_struct_print_field(uint, int, db_expr_t);
-
-/*
- * Flags to pass db_struct_printf().
- */
-
-#define DBSP_STRUCT_NAME 0x01 /* prepend struct name */
-#define DBSP_VALUE 0x02 /* display field value */
-
-void
-db_struct_print_field(uint fidx, int flags, db_expr_t baseaddr)
-{
- const struct ddb_field_info *field;
- const struct ddb_struct_info *struc;
- db_expr_t value;
- uint tmp;
- size_t namelen;
- int width, basecol, curcol;
- char tmpfmt[28];
-
- field = &ddb_field_info[fidx];
- basecol = 0;
-
- if (ISSET(flags, DBSP_STRUCT_NAME)) {
- struc = &ddb_struct_info[field->sidx];
- namelen = strlen(ddb_structfield_strings + struc->name);
- db_printf("%-30s ", ddb_structfield_strings + struc->name);
- if (namelen > 30)
- basecol += namelen + 1;
- else
- basecol += 30 + 1;
- }
-
- namelen = strlen(ddb_structfield_strings + field->name);
- if (field->nitems == 1) {
- db_printf("%-30s ", ddb_structfield_strings + field->name);
- if (namelen > 30)
- basecol += namelen + 1;
- else
- basecol += 30 + 1;
- } else {
- width = 30 - 2;
- tmp = field->nitems;
- while (tmp != 0) {
- width--;
- tmp /= 10;
- }
- if (namelen >= width) {
- db_printf("%s[%hu] ",
- ddb_structfield_strings + field->name,
- field->nitems);
- basecol += namelen + (30 - width) + 1;
- } else {
- db_printf("%s[%hu]%*s ",
- ddb_structfield_strings + field->name,
- field->nitems, width - (int)namelen, "");
- /* namelen + (30-width) + (width-namelen) + 1 */
- basecol += 30 + 1;
- }
- }
-
- if (field->size == 0) {
- db_printf("bitfield");
- /* basecol irrelevant from there on */
- } else {
- snprintf(tmpfmt, sizeof tmpfmt, "%u", (u_int)field->size);
- basecol += strlen(tmpfmt) + 1;
- db_printf("%s ", tmpfmt);
- }
-
- if (ISSET(flags, DBSP_VALUE)) {
- /* only print the field value if it has a friendly size. */
- switch (field->size) {
- case 1:
- width = 4;
- break;
- case 2:
- width = 8;
- break;
- case 4:
- width = 12;
- break;
-#ifdef __LP64__
- case 8:
- width = 20;
- break;
-#endif
- default:
- width = 0;
- }
- if (width != 0) {
- baseaddr += field->offs;
- curcol = basecol;
- for (tmp = field->nitems; tmp != 0; tmp--) {
- value = db_get_value(baseaddr, field->size,
- FALSE); /* assume unsigned */
- db_format(tmpfmt, sizeof tmpfmt, (long)value,
- DB_FORMAT_N, 0, width);
- if (field->nitems > 1)
- db_printf("%s", tmpfmt);
- else
- db_printf("%20s", tmpfmt);
- baseaddr += field->size;
-
- /*
- * Try to fit array elements on as few lines
- * as possible.
- */
- if (field->nitems > 1 && tmp > 1) {
- curcol += width + 1;
- if (basecol >= db_max_width ||
- curcol + width >= db_max_width) {
- /* new line */
- db_printf("\n");
- if (basecol + width >=
- db_max_width) {
- db_printf("\t");
- curcol = 8;
- } else {
- db_printf("%*s",
- basecol, "");
- curcol = basecol;
- }
- } else
- db_printf(" ");
- }
- }
- }
- }
-
- db_printf("\n");
-}
-
-
-/*
- * show offset <value>: displays the list of struct fields which exist
- * at that particular offset from the beginning of the struct.
- */
-void
-db_struct_offset_cmd(db_expr_t addr, int have_addr, db_expr_t count,
- char *modifiers)
-{
- db_expr_t offset = 0;
- const struct ddb_field_offsets *field;
- const ddb_field_off *fidx;
- uint oidx;
- int width;
- char tmpfmt[28];
-
- /*
- * Read the offset from the debuggger input.
- * We don't want to get it from the standard parsing code, because
- * this would set `dot' to this value, which doesn't make sense.
- */
-
- if (!db_expression(&offset) || offset < 0) {
- db_printf("not a valid offset\n");
- db_flush_lex();
- return;
- }
-
- db_skip_to_eol();
-
- for (field = ddb_field_offsets, oidx = 0; oidx < NOFFS; field++, oidx++)
- if (field->offs == (size_t)offset)
- break;
-
- if (oidx == NOFFS) {
- width = 0;
- db_format(tmpfmt, sizeof tmpfmt, (long)offset,
- DB_FORMAT_N, 0, width);
- db_printf("no known structure element at offset %-*s\n",
- width, tmpfmt);
- db_flush_lex();
- return;
- }
-
- db_printf("%-30s %-30s size\n", "struct", "member");
- for (fidx = ddb_fields_by_offset + field->list; *fidx != 0; fidx++)
- db_struct_print_field(*fidx, DBSP_STRUCT_NAME, 0);
-}
-
-/*
- * show struct <struct name> [addr]: displays the data starting at addr
- * (`dot' if unspecified) as a struct of the given type.
- */
-void
-db_struct_layout_cmd(db_expr_t addr, int have_addr, db_expr_t count,
- char *modifiers)
-{
- const struct ddb_struct_info *struc;
- uint sidx, fidx;
- int t;
-
- /*
- * Read the struct name from the debugger input.
- */
-
- t = db_read_token();
- if (t != tIDENT) {
- db_printf("Bad struct name\n");
- db_flush_lex();
- return;
- }
-
- for (struc = ddb_struct_info, sidx = 0; sidx < NSTRUCT;
- struc++, sidx++)
- if (strcmp(ddb_structfield_strings + struc->name,
- db_tok_string) == 0)
- break;
-
- if (sidx == NSTRUCT) {
- db_printf("unknown struct %s\n", db_tok_string);
- db_flush_lex();
- return;
- }
-
- /*
- * Read the address, if any, from the debugger input.
- * In that case, update `dot' value.
- */
-
- if (db_expression(&addr)) {
- db_dot = (db_addr_t)addr;
- db_last_addr = db_dot;
- } else
- addr = (db_expr_t)db_dot;
-
- db_skip_to_eol();
-
- /*
- * Display the structure contents.
- */
-
- db_printf("struct %s at %p (%u bytes)\n",
- ddb_structfield_strings + struc->name, (void *)addr,
- (u_int)struc->size);
- for (fidx = struc->fmin; fidx <= struc->fmax; fidx++)
- db_struct_print_field(fidx, DBSP_VALUE, addr);
-}
diff --git a/sys/ddb/db_structinfo.c b/sys/ddb/db_structinfo.c
deleted file mode 100644
index 611e1636843..00000000000
--- a/sys/ddb/db_structinfo.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/* $OpenBSD: db_structinfo.c,v 1.16 2017/07/29 08:50:42 zhuk Exp $ */
-/* public domain */
-/*
- * This file is intended to be compiled with debug information,
- * which is then translated by parse_debug.awk into support data
- * for ddb.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-
-#include <sys/device.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/acct.h>
-#include <sys/buf.h>
-#include <sys/conf.h>
-#include <sys/disk.h>
-#include <sys/disklabel.h>
-#include <sys/dirent.h>
-#include <sys/evcount.h>
-#include <sys/event.h>
-#include <sys/eventvar.h>
-#include <sys/exec.h>
-#include <sys/extent.h>
-#include <sys/fcntl.h>
-#include <sys/file.h>
-#include <sys/filedesc.h>
-#include <sys/gpio.h>
-#include <sys/hotplug.h>
-#include <sys/ipc.h>
-#include <sys/kcore.h>
-#include <sys/kthread.h>
-#include <sys/ktrace.h>
-#include <sys/lock.h>
-#include <sys/lockf.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/memrange.h>
-#include <sys/mman.h>
-#include <sys/mount.h>
-#include <sys/msg.h>
-#include <sys/msgbuf.h>
-#include <sys/namei.h>
-#include <sys/pipe.h>
-#include <sys/pool.h>
-#include <sys/protosw.h>
-#include <sys/ptrace.h>
-#include <sys/queue.h>
-#include <sys/resource.h>
-#include <sys/resourcevar.h>
-#include <sys/rwlock.h>
-#include <sys/sched.h>
-#include <sys/select.h>
-#include <sys/selinfo.h>
-#include <sys/sem.h>
-#include <sys/sensors.h>
-#include <sys/shm.h>
-#include <sys/siginfo.h>
-#include <sys/signal.h>
-#include <sys/signalvar.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/swap.h>
-#include <sys/syscall.h>
-#include <sys/syscallargs.h>
-#include <sys/sysctl.h>
-#include <sys/syslog.h>
-#include <sys/termios.h>
-#include <sys/time.h>
-#include <sys/timeout.h>
-#include <sys/timetc.h>
-#include <sys/tprintf.h>
-#include <sys/tree.h>
-#include <sys/tty.h>
-#include <sys/ucred.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/unpcb.h>
-#include <sys/utsname.h>
-#include <sys/vmmeter.h>
-#include <sys/vnode.h>
-#include <sys/wait.h>
-
-#include <machine/cpu.h>
-#include <machine/conf.h>
-#include <machine/mutex.h>
-
-#include <uvm/uvm.h>
-
-/* XXX add filesystem includes there */
-
-#include <sys/ataio.h>
-#include <sys/audioio.h>
-#include <sys/cdio.h>
-#include <sys/chio.h>
-#include <sys/dkio.h>
-#include <sys/filio.h>
-#include <sys/mtio.h>
-#include <sys/pciio.h>
-#include <sys/radioio.h>
-#include <sys/scsiio.h>
-#include <sys/sockio.h>
-#include <sys/videoio.h>
diff --git a/sys/ddb/parse_structinfo.pl b/sys/ddb/parse_structinfo.pl
deleted file mode 100755
index 8bee04ed584..00000000000
--- a/sys/ddb/parse_structinfo.pl
+++ /dev/null
@@ -1,390 +0,0 @@
-#!/usr/bin/perl
-# $OpenBSD: parse_structinfo.pl,v 1.3 2015/04/29 06:06:38 guenther Exp $
-#
-# Copyright (c) 2009 Miodrag Vallat.
-# Copyright (c) 2013 Philip Guenther.
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-
-# This ugly script parses the output of objdump -g in order to extract
-# structure layout information, to be used by ddb.
-#
-# The output of this script is the following static data:
-# - for each struct:
-# - its name
-# - its size (individual element size if an array)
-# - the number of elements in the array (1 if not)
-# - its first and last field indexes
-# - for each field:
-# - its name
-# - its offset and size
-# - the index of the struct it is member of
-# This allows fast struct -> field information retrieval.
-#
-# To retrieve information from a field size or offset, we also output
-# the following reverse arrays:
-# - for each offset, in ascending order, a variable length list of field
-# indexes.
-# - for each size, in ascending order, a variable length list of field
-# indexes.
-#
-# The compromise here is that I want to minimize linear searches. Memory
-# use is considered secondary, hence the back `pointer' to the struct in the
-# fields array.
-
-use strict;
-use warnings;
-use integer;
-use IO::File;
-
-use constant MAX_COLUMN => 72;
-
-my $depth = 0;
-my $ignore = 0;
-
-my $cur_struct;
-
-my $max_offs = 0;
-my $max_fsize = 0;
-my $max_ssize = 0;
-
-# Variables used in generating the raw, textual output
-my $txt; # IO::File to write to
-my @id2struct; # mapping of objdump's struct ids to @structs idxes
-my @subfield; # list of subfields to dump at the end
-
-# count of how many times each literal string appears
-my %strings;
-my @strings_by_len;
-sub add_string
-{
- my $string = shift;
- if ($strings{$string}++ == 0) {
- push @{ $strings_by_len[ length $string ] }, $string;
- }
-}
-
-my @structs;
-
-my %offs_to_fields;
-my %size_to_fields;
-my @fields = ( {
- name => "",
- offs => 0,
- size => 0,
- items => 0,
- struct => 0,
- } );
-sub new_field
-{
- my($name, $offs, $size, $items, $id) = @_;
-
- $items //= 1;
- add_string($name);
- push @fields, {
- name => $name,
- offs => $offs,
- size => $size,
- items => $items,
- struct => scalar(@structs),
- };
- $max_offs = $offs if $offs > $max_offs;
- $max_fsize = $size if $size > $max_fsize;
- push @{ $offs_to_fields{$offs} }, $#fields;
- push @{ $size_to_fields{$size} }, $#fields;
- if ($txt) {
- raw($offs, $size * $items, $cur_struct->{name}, $name);
- if (defined $id) {
- push @subfield, [ $cur_struct->{name}, $name, $offs, $id ];
- }
- }
-}
-
-# Generate textual output for those who are ddb challenged.
-$txt = IO::File->new("db_structinfo.txt", "w")
- or warn "$0: unable to create db_structinfo.txt: $!";
-sub raw {
- my($offs, $size, $struct, $member) = @_;
- $txt->print(join("\t", $offs, $size, $offs+$size, $struct, $member), "\n");
-}
-$txt and $txt->print(join("\t", qw(offset size next struct member)), "\n");
-
-
-while (<>) {
- chomp; # strip record separator
- if (m!^struct (\w+) \{ /\* size (\d+) id (\d+) !) {
- $depth = 1;
- $cur_struct = {
- name => $1,
- size => $2,
- fieldmin => scalar(@fields)
- };
- $id2struct[$3] = scalar(@structs);
- next
- }
-
- if (/^};/) {
- if ($depth == 0) {
- $ignore--;
- next
- }
- $depth = 0;
- if (scalar(@fields) == $cur_struct->{fieldmin}) {
- # empty struct, ignore it
- undef $cur_struct;
- next
- }
- $cur_struct->{fieldmax} = $#fields;
- add_string( $cur_struct->{name} );
- $max_ssize = $cur_struct->{size} if $cur_struct->{size} > $max_ssize;
- push @structs, $cur_struct;
- next
- }
-
- next if /\{.*\}/; # single line enum
-
- if (/\{/) {
- # subcomponent
- if ($depth) {
- $depth++;
- } else {
- $ignore++;
- }
- next
- }
-
- if (/\}/) {
- if ($ignore) {
- $ignore--;
- next
- }
- $depth--;
- next if $depth != 1;
- # FALL THROUGH
- }
-
- if (/bitsize (\d+), bitpos (\d+)/) {
- next if $ignore;
- next if $depth != 1;
-
- # Bitfields are a PITA... From a ddb point of view, we can't really
- # access storage units smaller than a byte.
- # So we'll report all bitfields as having size 0, and the
- # rounded down byte position where they start.
- my $cursize = ($1 % 8) ? 0 : ($1 / 8);
- my $curoffs = $2 / 8;
-
- # Try and gather the field name.
- # The most common case: not a function pointer or array
- if (m!\s(\**)(\w+);\s/\* bitsize!) {
- my $pointer = $1 ne "";
- my $name = $2;
- # check for a struct id to match up
- my($id) = !$pointer && m!/\* id (\d+) \*/.*;!;
- new_field($name, $curoffs, $cursize, 1, $id);
- next
- }
-
- # How about a function pointer?
- if (m!\s\**\(\*+(\w+)\) \(/\* unknown \*/\);\s/\* bitsize!) {
- new_field($1, $curoffs, $cursize);
- next
- }
-
- # Maybe it's an array
- if (m!\s(\**)([][:\w]+);\s/\* bitsize!) {
- my $pointer = $1 ne "";
- my $name = $2;
- my $items = 1;
- while ($name =~ s/\[(\d+)\]:\w+//) {
- $items *= $1;
- }
- # check for a struct id to match up
- my($id) = !$pointer && m!/\* id (\d+) \*/.*;!;
- new_field($name, $curoffs, $cursize / $items, $items, $id);
- next
- }
-
- # skip any anonymous unions {
- next if m!\}; /\*!;
-
- # Should be nothing left
- print STDERR "unknown member type: $_\n";
- next
- }
-}
-
-# Do all the subfield processing
-# XXX Should recurse into subsub...fields?
-foreach my $sf (@subfield) {
- my($struct_name, $name, $offs, $id) = @$sf;
- my $s = $id2struct[$id];
-
- # We don't remember unions. No point in doing so
- next if !defined $s;
-
- my $struct = $structs[$s];
- foreach my $i ($struct->{fieldmin} .. $struct->{fieldmax}) {
- my $f = $fields[$i];
- raw($offs + $f->{offs}, $f->{size} * $f->{items},
- $struct_name, "$name.$f->{name}");
- }
-}
-
-# Pick a type for ddb_field_off: if the offsets and sizes are all less than
-# 65536 then we'll use u_short, otherwise u_int.
-my $f_type = "u_short";
-if ($max_offs > 65535 || $max_fsize > 65535 || $max_ssize > 65535) {
- $f_type = "u_int";
- print STDERR "Using u_int for struct/field sizes and offsets\n";
-}
-
-
-print <<EOM;
-/*
- * THIS IS A GENERATED FILE. DO NOT EDIT!
- */
-
-#include <sys/param.h>
-#include <sys/types.h>
-
-typedef $f_type ddb_field_off;
-
-struct ddb_struct_info {
- u_short name;
- ddb_field_off size;
- u_short fmin, fmax;
-};
-struct ddb_field_info {
- u_short name;
- u_short sidx;
- ddb_field_off offs;
- ddb_field_off size;
- u_short nitems;
-};
-struct ddb_field_offsets {
- ddb_field_off offs;
- u_short list;
-};
-struct ddb_field_sizes {
- ddb_field_off size;
- u_short list;
-};
-EOM
-
-my $prefix = qq(static const char ddb_structfield_strings[] =\n\t"\\0);
-my %string_to_offset = ( "" => 0 );
-my $soff = 1;
-for (my $len = $#strings_by_len; $len > 0; $len--) {
- foreach my $string (@{ $strings_by_len[$len] }) {
- next if exists $string_to_offset{$string};
- my $off = $string_to_offset{$string} = $soff;
- $soff += $len + 1; # for the NUL
- print $prefix, $string;
- $prefix = qq(\\0"\n\t");
-
- # check for suffixes that are also strings
- for (my $o = 1; $o < $len; $o++) {
- my $sstr = substr($string, $o);
- next unless exists $strings{$sstr};
- next if exists $string_to_offset{$sstr};
- $string_to_offset{$sstr} = $off + $o;
- #print STDERR "found $sstr inside $string\n";
- }
- }
-}
-print qq(";\n);
-
-sub resolve_string
-{
- my $string = shift;
- if (! exists $string_to_offset{$string}) {
- die "no mapping for $string";
- }
- return $string_to_offset{$string};
-}
-
-# Check for overflow and, if so, print some stats
-if ($soff > 65535 || @structs > 65535 || @fields > 65535) {
- print STDERR <<EOM;
-ERROR: value out of range of u_short Time to change types?
-
-max string offset: $soff
-max field offset: $max_offs
-max field size: $max_fsize
-max struct size: $max_ssize
-number of structs: ${\scalar(@structs)}
-number of fields: ${\scalar(@fields)}
-EOM
- exit 1
-}
-
-
-print "#define NSTRUCT ", scalar(@structs), "\n";
-print "static const struct ddb_struct_info ddb_struct_info[NSTRUCT] = {\n";
-
-foreach my $s (@structs) {
- my $name = resolve_string($s->{name});
- print "\t{ ",
- join(", ", $name, @{$s}{qw( size fieldmin fieldmax )}),
- " },\n";
-}
-printf "};\n\n";
-
-print "#define NFIELD ", scalar(@fields), "\n";
-print "static const struct ddb_field_info ddb_field_info[NFIELD] = {\n";
-foreach my $f (@fields) {
- my $name = resolve_string($f->{name});
- print "\t{ ",
- join(", ", $name, @{$f}{qw( struct offs size items )}),
- " },\n";
-}
-printf "};\n\n";
-
-
-# Given a mapping from values to fields that have that value, generate
-# two C arrays: one containing lists of fields with each value, in order;
-# the other indexing into that one for each value. I.e., to get the
-# fields that have a given value, find the value in the second array and
-# then iterate from where that points into the first array until you hit
-# an entry with field==0.
-sub print_reverse_mapping
-{
- my($prefix, $map, $max) = @_;
- print "static const ddb_field_off ddb_fields_by_${prefix}[] = {";
- my @heads;
- my $w = 0;
- foreach my $val (sort { $a <=> $b } keys %$map) {
- push @heads, [$val, $w];
- foreach my $field (@{ $map->{$val} }, 0) {
- print( ($w++ % 10) == 0 ? "\n\t" : " ", $field, ",");
- }
- }
- print "\n};\n\n";
- print "#define $max ", scalar(@heads), "\n";
- print "static const struct ddb_field_${prefix}s",
- " ddb_field_${prefix}s[$max] = {\n";
- foreach my $h (@heads) {
- print "\t{ $h->[0], $h->[1] },\n";
- }
- print "};\n";
-}
-
-# reverse arrays
-print_reverse_mapping("offset", \%offs_to_fields, "NOFFS");
-print "\n";
-
-# The size->field mapping isn't used by ddb currently, so don't output it
-# print_reverse_mapping("size", \%size_to_fields, "NSIZES");
-