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