1# This file is part of ltrace.
2# Copyright (C) 2012, 2013 Petr Machata, Red Hat Inc.
3#
4# This program is free software; you can redistribute it and/or
5# modify it under the terms of the GNU General Public License as
6# published by the Free Software Foundation; either version 2 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12# General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17# 02110-1301 USA
18
19set trivial [ltraceCompile {} [ltraceSource c {
20    int main(void) {}
21}]]
22
23ltraceMatch1 [ltraceRun -L -F [ltraceSource conf {
24    typedef aa = int;
25    typedef aaa = int;
26    typedef bbb = struct(aa);
27}] -- $trivial] "error" == 0
28
29ltraceMatch1 [ltraceRun -L -F [ltraceSource conf {
30    typedef char_blah = char;
31    void blah(char_blah);
32}] -- $trivial] "error" == 0
33
34ltraceMatch1 [ltraceRun -L -F [ltraceSource conf {
35    typedef aa = int;
36    typedef aa = int;
37}] -- $trivial] "error" != 0
38
39ltraceMatch1 [ltraceRun -L -F [ltraceSource conf {
40    typedef aa = struct;
41    typedef aa = int;
42}] -- $trivial] "error" != 0
43
44ltraceMatch1 [ltraceRun -L -F [ltraceSource conf {
45    typedef aa = struct;
46    typedef aa = struct(int);
47    typedef aa = struct(int);
48}] -- $trivial] "error" != 0
49
50ltraceMatch1 [ltraceRun -L -F [ltraceSource conf {
51    typedef aa = struct;
52    typedef aa = struct();
53    typedef aa = struct();
54}] -- $trivial] "error" != 0
55
56ltraceMatch1 [ltraceRun -L -F [ltraceSource conf {
57    typedef aa = struct(int, struct;);
58}] -- $trivial] "error" != 0
59
60set libll [ltraceCompile libll.so [ltraceSource c {
61    struct xxx;
62    void ll(struct xxx *xxx) {}
63}]]
64
65set conf [ltraceSource conf {
66    typedef xxx = struct;
67    typedef xxx = struct(int, xxx*);
68    void ll(xxx*);
69}]
70
71ltraceMatch [ltraceRun -F $conf -e ll [ltraceCompile {} $libll [ltraceSource c {
72    struct xxx {
73	int i;
74	struct xxx *next;
75    };
76
77    void ll (struct xxx *xxx);
78    int main (int argc, char *argv[])
79    {
80	struct xxx a = { 1, 0 };
81	struct xxx b = { 2, &a };
82	struct xxx c = { 3, &b };
83	struct xxx d = { 4, &c };
84	ll (&d);
85
86	struct xxx e = { 1, 0 };
87	struct xxx f = { 2, &e };
88	e.next = &f;
89	ll (&f);
90
91	struct xxx g = { 1, &g };
92	ll (&g);
93
94	return 0;
95    }
96}]]] {
97    {{->ll\({ 4, { 3, { 2, { 1, nil } } } }\) *= <void>} == 1}
98    {{->ll\({ 2, { 1, recurse\^ } }\) *= <void>} == 1}
99    {{->ll\({ 1, recurse }\) *= <void>} == 1}
100}
101
102ltraceMatch1 [ltraceRun -F $conf -e ll -A 5 \
103-- [ltraceCompile ll $libll [ltraceSource c {
104    #include <stdlib.h>
105    struct ble {
106	int i;
107	struct ble *next;
108    };
109
110    void ll (struct ble *ble);
111    int main (int argc, char *argv[])
112    {
113	struct ble *b = NULL;
114	int i;
115	for (i = 0; i < 10; ++i) {
116	    struct ble *n = malloc(sizeof(*n));
117	    n->i = i;
118	    n->next = b;
119	    b = n;
120	}
121	ll (b);
122
123	return 0;
124    }
125}]]] {->ll\({ 9, { 8, { 7, { 6, { 5, \.\.\. } } } } }\) *= <void>} == 1
126
127# Test using lens in typedef.
128
129ltraceMatch1 [ltraceLibTest {
130    typedef hexptr = hex(uint*);
131    void fun(hexptr);
132} {
133    void fun(unsigned *arg);
134} {
135    void fun(unsigned *arg) {}
136} {
137    unsigned u = 0x123;
138    fun(&u);
139}] {fun\(0x123\) *= <void>} == 1
140
141# Test support for bitvec lens.
142
143ltraceMatch [ltraceLibTest {
144    void fun(bitvec(uint));
145    void fun2(bitvec(array(char, 32)*));
146} {
147    void fun(unsigned i);
148    void fun2(unsigned char *arr);
149} {
150    void fun(unsigned i) {}
151    void fun2(unsigned char *arr) {}
152} {
153    fun(0);
154    fun(0x123);
155    fun(0xfffffffe);
156    fun(0xffffffff);
157
158    unsigned char bytes[32] = {0x00};
159    bytes[1] = 0xff;
160    bytes[31] = 0x80;
161    fun2(bytes);
162}] {
163    {{fun\(<>\) *= <void>} == 1}
164    {{fun\(<0-1,5,8>\) *= <void>} == 1}
165    {{fun\(~<0>\) *= <void>} == 1}
166    {{fun\(~<>\) *= <void>} == 1}
167    {{fun2\(<8-15,255>\) *= <void>} == 1}
168}
169
170# Test support for hex(float), hex(double).
171
172ltraceMatch [ltraceLibTest {
173    hex(float) hex_float(hex(float));
174    hex(double) hex_double(hex(double));
175} {
176    float hex_float(float f);
177    double hex_double(double d);
178} {
179    float hex_float(float f) { return f + 1; }
180    double hex_double(double d) { return d + 1; }
181} {
182    hex_float(1.5);
183    hex_double(1.5);
184}] {
185    {{hex_float\(0x1.8p\+0\) *= 0x1.4p\+1} == 1}
186    {{hex_double\(0x1.8p\+0\) *= 0x1.4p\+1} == 1}
187}
188
189# Test that "addr" is recognized.
190
191ltraceMatch1 [ltraceLibTest {
192    void fun(addr);
193} {
194    #include <stdint.h>
195    void fun(uintptr_t u);
196} {
197    void fun(uintptr_t u) {}
198} {
199    fun(0x1234);
200}] {fun\(0x1234\) *= <void>} == 1
201
202# Test that -x fun can find "fun" prototype even if "fun" is in a
203# library.
204
205ltraceMatch1 [ltraceLibTest {
206    void fun();
207} {
208    void libfun(void);
209} {
210    void fun(void) {}
211    void libfun(void) { fun(); }
212} {
213    libfun();
214} {
215    -L -x fun
216}] {fun@.*\(\)} == 1
217
218
219# Test that %p format specifier does not crash
220
221ltraceMatch1 [ltraceLibTest {
222    void print_ptr(format);
223} {
224    void print_ptr(const char *format, ...);
225} {
226    void print_ptr(const char *format, ...) { }
227} {
228    void *addr = (void *)0x42;
229    print_ptr("%p\n", addr);
230}] {print_ptr\("%p\\n", 0x42\) *= <void>} == 1
231
232
233# Test that zero(EXPR) does not leak memory (needs valgrind)
234
235ltraceMatch1 [ltraceLibTest {
236    typedef String = string(array(char, zero(256)));
237    String *get_string();
238} {
239    char *get_string();
240} {
241    char *get_string() {
242        return "FOO";
243    }
244} {
245    get_string();
246}] {get_string\(\) *= "FOO"} == 1
247
248# Test that void* NULL's are displayed as "nil" as well.
249
250ltraceMatch1 [ltraceLibTest {
251    addr somefunc();
252} {
253    void *somefunc(void);
254} {
255    void *somefunc(void) {
256        return 0;
257    }
258} {
259    somefunc();
260}] {somefunc\(\) *= nil} == 1
261
262ltraceDone
263