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 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 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 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 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