Consolidate lseek/lseek64/llseek implementations
[glibc.git] / elf / tst-_dl_addr_inside_object.c
blobd1e45815c8e7c0639d52e0dc771967da69b630a9
1 /* Unit test for _dl_addr_inside_object.
2 Copyright (C) 2016 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <link.h>
22 #include <elf.h>
23 #include <libc-symbols.h>
25 extern int internal_function _dl_addr_inside_object (struct link_map *l,
26 const ElfW(Addr) addr);
28 static int
29 do_test (void)
31 int ret, err = 0;
32 ElfW(Addr) addr;
33 struct link_map map;
34 ElfW(Phdr) header;
35 map.l_phdr = &header;
36 map.l_phnum = 1;
37 map.l_addr = 0x0;
38 /* Segment spans 0x2000 -> 0x4000. */
39 header.p_vaddr = 0x2000;
40 header.p_memsz = 0x2000;
41 header.p_type = PT_LOAD;
42 /* Address is above the segment e.g. > 0x4000. */
43 addr = 0x5000;
44 ret = _dl_addr_inside_object (&map, addr);
45 switch (ret)
47 case 0:
48 printf ("PASS: Above: Address is detected as outside the segment.\n");
49 break;
50 case 1:
51 printf ("FAIL: Above: Address is detected as inside the segment.\n");
52 err++;
53 break;
54 default:
55 printf ("FAIL: Above: Invalid return value.\n");
56 exit (1);
58 /* Address is inside the segment e.g. 0x2000 < addr < 0x4000. */
59 addr = 0x3000;
60 ret = _dl_addr_inside_object (&map, addr);
61 switch (ret)
63 case 0:
64 printf ("FAIL: Inside: Address is detected as outside the segment.\n");
65 err++;
66 break;
67 case 1:
68 printf ("PASS: Inside: Address is detected as inside the segment.\n");
69 break;
70 default:
71 printf ("FAIL: Inside: Invalid return value.\n");
72 exit (1);
74 /* Address is below the segment e.g. < 0x2000. */
75 addr = 0x1000;
76 ret = _dl_addr_inside_object (&map, addr);
77 switch (ret)
79 case 0:
80 printf ("PASS: Below: Address is detected as outside the segment.\n");
81 break;
82 case 1:
83 printf ("FAIL: Below: Address is detected as inside the segment.\n");
84 err++;
85 break;
86 default:
87 printf ("FAIL: Below: Invalid return value.\n");
88 exit (1);
90 /* Address is in the segment and addr == p_vaddr. */
91 addr = 0x2000;
92 ret = _dl_addr_inside_object (&map, addr);
93 switch (ret)
95 case 0:
96 printf ("FAIL: At p_vaddr: Address is detected as outside the segment.\n");
97 err++;
98 break;
99 case 1:
100 printf ("PASS: At p_vaddr: Address is detected as inside the segment.\n");
101 break;
102 default:
103 printf ("FAIL: At p_vaddr: Invalid return value.\n");
104 exit (1);
106 /* Address is in the segment and addr == p_vaddr + p_memsz - 1. */
107 addr = 0x2000 + 0x2000 - 0x1;
108 ret = _dl_addr_inside_object (&map, addr);
109 switch (ret)
111 case 0:
112 printf ("FAIL: At p_memsz-1: Address is detected as outside the segment.\n");
113 err++;
114 break;
115 case 1:
116 printf ("PASS: At p_memsz-1: Address is detected as inside the segment.\n");
117 break;
118 default:
119 printf ("FAIL: At p_memsz-1: Invalid return value.\n");
120 exit (1);
122 /* Address is outside the segment and addr == p_vaddr + p_memsz. */
123 addr = 0x2000 + 0x2000;
124 ret = _dl_addr_inside_object (&map, addr);
125 switch (ret)
127 case 0:
128 printf ("PASS: At p_memsz: Address is detected as outside the segment.\n");
129 break;
130 case 1:
131 printf ("FAIL: At p_memsz: Address is detected as inside the segment.\n");
132 err++;
133 break;
134 default:
135 printf ("FAIL: At p_memsz: Invalid return value.\n");
136 exit (1);
138 /* Address is outside the segment and p_vaddr at maximum address. */
139 addr = 0x0 - 0x2;
140 header.p_vaddr = 0x0 - 0x1;
141 header.p_memsz = 0x1;
142 ret = _dl_addr_inside_object (&map, addr);
143 switch (ret)
145 case 0:
146 printf ("PASS: At max: Address is detected as outside the segment.\n");
147 break;
148 case 1:
149 printf ("FAIL: At max: Address is detected as inside the segment.\n");
150 err++;
151 break;
152 default:
153 printf ("FAIL: At max: Invalid return value.\n");
154 exit (1);
156 /* Address is outside the segment and p_vaddr at minimum address. */
157 addr = 0x1;
158 header.p_vaddr = 0x0;
159 header.p_memsz = 0x1;
160 ret = _dl_addr_inside_object (&map, addr);
161 switch (ret)
163 case 0:
164 printf ("PASS: At min: Address is detected as outside the segment.\n");
165 break;
166 case 1:
167 printf ("FAIL: At min: Address is detected as inside the segment.\n");
168 err++;
169 break;
170 default:
171 printf ("FAIL: At min: Invalid return value.\n");
172 exit (1);
174 /* Address is always inside the segment with p_memsz at max. */
175 addr = 0x0;
176 header.p_vaddr = 0x0;
177 header.p_memsz = 0x0 - 0x1;
178 ret = _dl_addr_inside_object (&map, addr);
179 switch (ret)
181 case 0:
182 printf ("FAIL: At maxmem: Address is detected as outside the segment.\n");
183 err++;
184 break;
185 case 1:
186 printf ("PASS: At maxmem: Address is detected as inside the segment.\n");
187 break;
188 default:
189 printf ("FAIL: At maxmem: Invalid return value.\n");
190 exit (1);
192 /* Attempt to wrap addr into the segment.
193 Pick a load address in the middle of the address space.
194 Place the test address at 0x0 so it wraps to the middle again. */
195 map.l_addr = 0x0 - 0x1;
196 map.l_addr = map.l_addr / 2;
197 addr = 0;
198 /* Setup a segment covering 1/2 the address space. */
199 header.p_vaddr = 0x0;
200 header.p_memsz = 0x0 - 0x1 - map.l_addr;
201 /* No matter where you place addr everything is shifted modulo l_addr
202 and even with this underflow you're always 1 byte away from being
203 in the range. */
204 ret = _dl_addr_inside_object (&map, addr);
205 switch (ret)
207 case 0:
208 printf ("PASS: Underflow: Address is detected as outside the segment.\n");
209 break;
210 case 1:
211 printf ("FAIL: Underflow: Address is detected as inside the segment.\n");
212 err++;
213 break;
214 default:
215 printf ("FAIL: Underflow: Invalid return value.\n");
216 exit (1);
219 return err;
222 #define TEST_FUNCTION do_test ()
223 #include "../test-skeleton.c"