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