Penguin
Annotated edit history of pstruct(1) version 1, including all changes. View license author blame.
Rev Author # Line
1 perry 1 PSTRUCT
2 !!!PSTRUCT
3 NAME
4 SYNOPSIS
5 DESCRIPTION
6 ----
7 !!NAME
8
9
10 c2ph, pstruct - Dump C structures as generated from cc -g -S stabs
11 !!SYNOPSIS
12
13
14 c2ph [[-dpnP] [[var=val] [[files ...]
15
16
17 __OPTIONS__
18
19
20 Options:
21 -w wide; short for: type_width=45 member_width=35 offset_width=8
22 -x hex; short for: offset_fmt=x offset_width=08 size_fmt=x size_width=04
23 -n do not generate perl code (default when invoked as pstruct)
24 -p generate perl code (default when invoked as c2ph)
25 -v generate perl code, with C decls as comments
26 -i do NOT recompute sizes for intrinsic datatypes
27 -a dump information on intrinsics also
28 -t trace execution
29 -d spew reams of debugging output
30 -slist give comma-separated list a structures to dump
31 !!DESCRIPTION
32
33
34 The following is the old c2ph.doc documentation by Tom
35 Christiansen
36 GMT
37
38
39 Once upon a time, I wrote a program called pstruct. It was a
40 perl program that tried to parse out C structures and
41 display their member offsets for you. This was especially
42 useful for people looking at binary dumps or poking around
43 the kernel.
44
45
46 Pstruct was not a pretty program. Neither was it
47 particularly robust. The problem, you see, was that the C
48 compiler was much better at parsing C than I could ever hope
49 to be.
50
51
52 So I got smart: I decided to be lazy and let the C compiler
53 parse the C, which would spit out debugger stabs for me to
54 read. These were much easier to parse. It's still not a
55 pretty program, but at least it's more robust.
56
57
58 Pstruct takes any .c or .h files, or preferably .s ones,
59 since that's the format it is going to massage them into
60 anyway, and spits out listings like this:
61
62
63 struct tty {
64 int tty.t_locker 000 4
65 int tty.t_mutex_index 004 4
66 struct tty * tty.t_tp_virt 008 4
67 struct clist tty.t_rawq 00c 20
68 int tty.t_rawq.c_cc 00c 4
69 int tty.t_rawq.c_cmax 010 4
70 int tty.t_rawq.c_cfx 014 4
71 int tty.t_rawq.c_clx 018 4
72 struct tty * tty.t_rawq.c_tp_cpu 01c 4
73 struct tty * tty.t_rawq.c_tp_iop 020 4
74 unsigned char * tty.t_rawq.c_buf_cpu 024 4
75 unsigned char * tty.t_rawq.c_buf_iop 028 4
76 struct clist tty.t_canq 02c 20
77 int tty.t_canq.c_cc 02c 4
78 int tty.t_canq.c_cmax 030 4
79 int tty.t_canq.c_cfx 034 4
80 int tty.t_canq.c_clx 038 4
81 struct tty * tty.t_canq.c_tp_cpu 03c 4
82 struct tty * tty.t_canq.c_tp_iop 040 4
83 unsigned char * tty.t_canq.c_buf_cpu 044 4
84 unsigned char * tty.t_canq.c_buf_iop 048 4
85 struct clist tty.t_outq 04c 20
86 int tty.t_outq.c_cc 04c 4
87 int tty.t_outq.c_cmax 050 4
88 int tty.t_outq.c_cfx 054 4
89 int tty.t_outq.c_clx 058 4
90 struct tty * tty.t_outq.c_tp_cpu 05c 4
91 struct tty * tty.t_outq.c_tp_iop 060 4
92 unsigned char * tty.t_outq.c_buf_cpu 064 4
93 unsigned char * tty.t_outq.c_buf_iop 068 4
94 (*int)() tty.t_oproc_cpu 06c 4
95 (*int)() tty.t_oproc_iop 070 4
96 (*int)() tty.t_stopproc_cpu 074 4
97 (*int)() tty.t_stopproc_iop 078 4
98 struct thread * tty.t_rsel 07c 4
99 etc.
100
101
102 Actually, this was generated by a particular set of options.
103 You can control the formatting of each column, whether you
104 prefer wide or fat, hex or decimal, leading zeroes or
105 whatever.
106
107
108 All you need to be able to use this is a C compiler than
109 generates BSD/GCC-style stabs. The __-g__ option on
110 native BSD compilers and GCC
111 should get this for you.
112
113
114 To learn more, just type a bogus option, like __-?__, and
115 a long usage message will be provided. There are a fair
116 number of possibilities.
117
118
119 If you're only a C programmer, than this is the end of the
120 message for you. You can quit right now, and if you care to,
121 save off the source and run it when you feel like it. Or
122 not.
123
124
125 But if you're a perl programmer, then for you I have
126 something much more wondrous than just a structure offset
127 printer.
128
129
130 You see, if you call pstruct by its other incybernation,
131 c2ph, you have a code generator that translates C code into
132 perl code! Well, structure and union declarations at least,
133 but that's quite a bit.
134
135
136 Prior to this point, anyone programming in perl who wanted
137 to interact with C programs, like the kernel, was forced to
138 guess the layouts of the C strutures, and then hardwire
139 these into his program. Of course, when you took your
140 wonderfully crafted program to a system where the sgtty
141 structure was laid out differently, you program broke. Which
142 is a shame.
143
144
145 We've had Larry's h2ph translator, which helped, but that
146 only works on cpp symbols, not real C, which was also very
147 much needed. What I offer you is a symbolic way of getting
148 at all the C structures. I've couched them in terms of
149 packages and functions. Consider the following
150 program:
151
152
153 #!/usr/local/bin/perl
154 require 'syscall.ph';
155 require 'sys/time.ph';
156 require 'sys/resource.ph';
157 $ru =
158 syscall(
159 @ru = unpack($t =
160 $utime = $ru[[
161 $stime = $ru[[
162 printf
163 As you see, the name of the package is the name of the structure. Regular fields are just their own names. Plus the following accessor functions are provided for your convenience:
164
165
166 struct This takes no arguments, and is merely the number of first-level
167 elements in the structure. You would use this for indexing
168 into arrays of structures, perhaps like this
169 $usec = $u[[
170 sizeof Returns the bytes in the structure, or the member if
171 you pass it an argument, such as
172
173 typedef This is the perl format definition for passing to pack and
174 unpack. If you ask for the typedef of a nothing, you get
175 the whole structure, otherwise you get that of the member
176 you ask for. Padding is taken care of, as is the magic to
177 guarantee that a union is unpacked into all its aliases.
178 Bitfields are not quite yet supported however.
179 offsetof This function is the byte offset into the array of that
180 member. You may wish to use this for indexing directly
181 into the packed structure with vec() if you're too lazy
182 to unpack it.
183 typeof Not to be confused with the typedef accessor function, this
184 one returns the C type of that field. This would allow
185 you to print out a nice structured pretty print of some
186 structure without knoning anything about it beforehand.
187 No args to this one is a noop. Someday I'll post such
188 a thing to dump out your u structure for you.
189 The way I see this being used is like basically this:
190
191
192 % h2ph
193 It's a little tricker with c2ph because you have to get the includes right. I can't know this for your system, but it's not usually too terribly difficult.
194
195
196 The code isn't pretty as I mentioned -- I never thought it
197 would be a 1000- line program when I started, or I might not
198 have begun. :-) But I would have been less cavalier in how
199 the parts of the program communicated with each other, etc.
200 It might also have helped if I didn't have to divine the
201 makeup of the stabs on the fly, and then account for micro
202 differences between my compiler and gcc.
203
204
205 Anyway, here it is. Should run on perl v4 or greater. Maybe
206 less.
207
208
209 --tom
210 ----
This page is a man page (or other imported legacy content). We are unable to automatically determine the license status of this page.