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