xref: /haiku/src/tests/system/libroot/posix/brk_test.c (revision c302a243e15e640fae0f689e32cdf0c18749afee)
1*dbf060a3SSimon South /*
2*dbf060a3SSimon South  * Copyright 2015 Simon South, ssouth@simonsouth.com
3*dbf060a3SSimon South  * All rights reserved. Distributed under the terms of the MIT License.
4*dbf060a3SSimon South  */
5*dbf060a3SSimon South 
6*dbf060a3SSimon South 
7*dbf060a3SSimon South #include <errno.h>
8*dbf060a3SSimon South #include <stdint.h>
9*dbf060a3SSimon South #include <stdio.h>
10*dbf060a3SSimon South #include <string.h>
11*dbf060a3SSimon South #include <unistd.h>
12*dbf060a3SSimon South 
13*dbf060a3SSimon South #include <image.h>
14*dbf060a3SSimon South #include <OS.h>
15*dbf060a3SSimon South 
16*dbf060a3SSimon South 
17*dbf060a3SSimon South struct sbrk_test {
18*dbf060a3SSimon South 	char *name;
19*dbf060a3SSimon South 	char *sbrk_arg_text;
20*dbf060a3SSimon South 	intptr_t sbrk_arg;
21*dbf060a3SSimon South };
22*dbf060a3SSimon South 
23*dbf060a3SSimon South 
24*dbf060a3SSimon South static void
output_area_info(void * base_address)25*dbf060a3SSimon South output_area_info(void *base_address)
26*dbf060a3SSimon South {
27*dbf060a3SSimon South 	uint8_t *next_area_address;
28*dbf060a3SSimon South 	area_id next_area;
29*dbf060a3SSimon South 	area_info next_area_info;
30*dbf060a3SSimon South 
31*dbf060a3SSimon South 	next_area = area_for(base_address);
32*dbf060a3SSimon South 	while (next_area != B_ERROR) {
33*dbf060a3SSimon South 		if (get_area_info(next_area, &next_area_info) == B_OK) {
34*dbf060a3SSimon South 			next_area_address = (uint8_t *)(next_area_info.address)
35*dbf060a3SSimon South 				+ next_area_info.size;
36*dbf060a3SSimon South 
37*dbf060a3SSimon South 			printf("Area ID 0x%x: Addr: %p - %p  Size: 0x%04zx  %s\n",
38*dbf060a3SSimon South 				next_area_info.area, next_area_info.address,
39*dbf060a3SSimon South 				next_area_address - 1, next_area_info.size,
40*dbf060a3SSimon South 				next_area_info.name);
41*dbf060a3SSimon South 
42*dbf060a3SSimon South 			next_area = area_for(next_area_address);
43*dbf060a3SSimon South 		} else {
44*dbf060a3SSimon South 			fprintf(stderr, "PROBLEM: Couldn't get area info");
45*dbf060a3SSimon South 		}
46*dbf060a3SSimon South 	}
47*dbf060a3SSimon South }
48*dbf060a3SSimon South 
49*dbf060a3SSimon South 
50*dbf060a3SSimon South static void
output_data_segment_info(void * address)51*dbf060a3SSimon South output_data_segment_info(void *address)
52*dbf060a3SSimon South {
53*dbf060a3SSimon South 	puts("Current data segment layout:");
54*dbf060a3SSimon South 	output_area_info(address);
55*dbf060a3SSimon South 	puts("");
56*dbf060a3SSimon South }
57*dbf060a3SSimon South 
58*dbf060a3SSimon South 
59*dbf060a3SSimon South static void
output_sbrk_result(intptr_t sbrk_arg,char * sbrk_arg_text)60*dbf060a3SSimon South output_sbrk_result(intptr_t sbrk_arg, char *sbrk_arg_text)
61*dbf060a3SSimon South {
62*dbf060a3SSimon South 	printf("\tsbrk(%s) returns %p\n", sbrk_arg_text, sbrk(sbrk_arg));
63*dbf060a3SSimon South 	if (errno != 0) {
64*dbf060a3SSimon South 		printf("\tError: %s\n", strerror(errno));
65*dbf060a3SSimon South 		errno = 0;
66*dbf060a3SSimon South 	}
67*dbf060a3SSimon South }
68*dbf060a3SSimon South 
69*dbf060a3SSimon South 
70*dbf060a3SSimon South int
main(int argc,char ** argv)71*dbf060a3SSimon South main(int argc, char **argv)
72*dbf060a3SSimon South {
73*dbf060a3SSimon South 	static const uint NUM_TESTS = 7;
74*dbf060a3SSimon South 	static struct sbrk_test sbrk_tests[] = {
75*dbf060a3SSimon South 		{ "Get current program break",                     "0",      0 },
76*dbf060a3SSimon South 
77*dbf060a3SSimon South 		{ "Expand data segment (less than one page)",  "0x7ff",  0x7ff },
78*dbf060a3SSimon South 		{ "Expand data segment (more than one page)", "0x57ff", 0x57ff },
79*dbf060a3SSimon South 		{
80*dbf060a3SSimon South 			"Expand data segment (unreasonable value)",
81*dbf060a3SSimon South 			"INTPTR_MAX",
82*dbf060a3SSimon South 			 INTPTR_MAX
83*dbf060a3SSimon South 		},
84*dbf060a3SSimon South 
85*dbf060a3SSimon South 		{ "Shrink data segment (less than one page)",  "-0x7ff",  -0x7ff },
86*dbf060a3SSimon South 		{ "Shrink data segment (more than one page)", "-0x27ff", -0x27ff },
87*dbf060a3SSimon South 		{
88*dbf060a3SSimon South 			"Shrink data segment (unreasonable value)",
89*dbf060a3SSimon South 			"INTPTR_MIN",
90*dbf060a3SSimon South 			 INTPTR_MIN
91*dbf060a3SSimon South 		}
92*dbf060a3SSimon South 	};
93*dbf060a3SSimon South 
94*dbf060a3SSimon South 	int result = -1;
95*dbf060a3SSimon South 
96*dbf060a3SSimon South 	bool app_image_found = false;
97*dbf060a3SSimon South 	image_info i_info;
98*dbf060a3SSimon South 	int32 image_cookie = 0;
99*dbf060a3SSimon South 
100*dbf060a3SSimon South 	void *data_segment_address = NULL;
101*dbf060a3SSimon South 
102*dbf060a3SSimon South 	uint test_index;
103*dbf060a3SSimon South 	struct sbrk_test *next_sbrk_test;
104*dbf060a3SSimon South 
105*dbf060a3SSimon South 	/* Find the address of our data segment */
106*dbf060a3SSimon South 	while (!app_image_found
107*dbf060a3SSimon South 		&& get_next_image_info(0, &image_cookie, &i_info) == B_OK) {
108*dbf060a3SSimon South 		if (i_info.type == B_APP_IMAGE) {
109*dbf060a3SSimon South 			app_image_found = true;
110*dbf060a3SSimon South 
111*dbf060a3SSimon South 			data_segment_address = i_info.data;
112*dbf060a3SSimon South 		}
113*dbf060a3SSimon South 	}
114*dbf060a3SSimon South 
115*dbf060a3SSimon South 	if (data_segment_address != NULL) {
116*dbf060a3SSimon South 		/* Run our tests */
117*dbf060a3SSimon South 		test_index = 0;
118*dbf060a3SSimon South 		while (test_index < NUM_TESTS) {
119*dbf060a3SSimon South 			next_sbrk_test = &sbrk_tests[test_index];
120*dbf060a3SSimon South 
121*dbf060a3SSimon South 			output_data_segment_info(data_segment_address);
122*dbf060a3SSimon South 			printf("%s:\n", next_sbrk_test->name);
123*dbf060a3SSimon South 			output_sbrk_result(next_sbrk_test->sbrk_arg,
124*dbf060a3SSimon South 				next_sbrk_test->sbrk_arg_text);
125*dbf060a3SSimon South 			printf("\n");
126*dbf060a3SSimon South 
127*dbf060a3SSimon South 			test_index += 1;
128*dbf060a3SSimon South 		}
129*dbf060a3SSimon South 
130*dbf060a3SSimon South 		output_data_segment_info(data_segment_address);
131*dbf060a3SSimon South 
132*dbf060a3SSimon South 		result = 0;
133*dbf060a3SSimon South 	} else {
134*dbf060a3SSimon South 		fprintf(stderr, "PROBLEM: Couldn't locate data segment\n");
135*dbf060a3SSimon South 	}
136*dbf060a3SSimon South 
137*dbf060a3SSimon South 	return result;
138*dbf060a3SSimon South }
139