1 // $Header$ 2 // 3 // Copyright (C) 2000 - 2003, by 4 // 5 // Carlo Wood, Run on IRC <carlo@alinoe.com> 6 // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt 7 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61 8 // 9 // This file may be distributed under the terms of the Q Public License 10 // version 1.0 as appearing in the file LICENSE.QPL included in the 11 // packaging of this file. 12 // 13 14 #include "sys.h" 15 #include <libcwd/debug.h> 16 #include <iostream> 17 18 #if !CW_RECURSIVE_BUILTIN_RETURN_ADDRESS 19 static void* return_address[6]; 20 #define store_call_address(i) return_address[i] = __builtin_return_address(0) 21 #define START _start 22 extern "C" int START(); 23 #endif 24 25 #ifdef CW_FRAME_ADDRESS_OFFSET frame_return_address(unsigned int frame)26static void* frame_return_address(unsigned int frame) 27 { 28 void* frame_ptr = __builtin_frame_address(0); 29 #if CW_FRAME_ADDRESS_OFFSET == 0 30 ++frame; 31 #endif 32 do 33 { 34 void** frame_ptr_ptr = reinterpret_cast<void**>(frame_ptr) + CW_FRAME_ADDRESS_OFFSET; 35 if (frame-- == 0) 36 return frame_ptr_ptr[1]; 37 frame_ptr = *frame_ptr_ptr; 38 } 39 while (frame_ptr); 40 return NULL; 41 } 42 #endif 43 libcwd_bfd_test3(void)44void libcwd_bfd_test3(void) 45 { 46 #if CWDEBUG_LOCATION 47 for (int i = 0; i <= 5; ++i) 48 { 49 void* retadr; 50 51 switch (i) 52 { 53 #if CW_RECURSIVE_BUILTIN_RETURN_ADDRESS 54 case 1: 55 retadr = __builtin_return_address(1); 56 break; 57 case 2: 58 retadr = __builtin_return_address(2); 59 break; 60 case 3: 61 retadr = __builtin_return_address(3); 62 break; 63 case 4: 64 retadr = __builtin_return_address(4); 65 break; 66 case 5: 67 retadr = __builtin_return_address(5); 68 break; 69 #else 70 case 1: 71 case 2: 72 case 3: 73 case 4: 74 retadr = return_address[i]; 75 break; 76 case 5: 77 retadr = (char*)&START + 10; // Whatever... 78 break; 79 #endif 80 default: 81 retadr = __builtin_return_address(0); 82 break; 83 } 84 85 #if CWDEBUG_LOCATION 86 libcwd::location_ct loc((char*)retadr + libcwd::builtin_return_address_offset); 87 Dout(dc::notice, "called from " << loc); 88 89 #ifdef CW_FRAME_ADDRESS_OFFSET 90 if (i < 5 && frame_return_address(i) != retadr) 91 DoutFatal(dc::fatal, "frame_return_address(" << i << ") returns " << 92 libcwd::location_ct((char*)frame_return_address(i) + builtin_return_address_offset) << "!"); 93 #endif 94 95 if (!loc.is_known() || strcmp(loc.mangled_function_name(), "__libc_start_main") == 0) 96 break; 97 #else // !CWDEBUG_LOCATION 98 #ifdef CW_FRAME_ADDRESS_OFFSET 99 if (i < 5 && frame_return_address(i) != retadr) 100 DoutFatal(dc::fatal, "frame_return_address(" << i << ") returns " << frame_return_address(i) << '!'); 101 #endif 102 #endif 103 } 104 #endif 105 } 106 libcwd_bfd_test2(void)107void libcwd_bfd_test2(void) 108 { 109 #if !CW_RECURSIVE_BUILTIN_RETURN_ADDRESS 110 store_call_address(1); 111 #endif 112 libcwd_bfd_test3(); 113 } 114 libcwd_bfd_test1(void)115void libcwd_bfd_test1(void) 116 { 117 #if !CW_RECURSIVE_BUILTIN_RETURN_ADDRESS 118 store_call_address(2); 119 #endif 120 libcwd_bfd_test2(); 121 } 122 libcwd_bfd_test(void)123void libcwd_bfd_test(void) 124 { 125 #if !CW_RECURSIVE_BUILTIN_RETURN_ADDRESS 126 store_call_address(3); 127 #endif 128 libcwd_bfd_test1(); 129 } 130 131 MAIN_FUNCTION 132 { PREFIX_CODE 133 #if !CWDEBUG_LOCATION 134 DoutFatal(dc::fatal, "Expected Failure."); 135 #endif 136 137 Debug( check_configuration() ); 138 139 // Select channels 140 ForAllDebugChannels( if (debugChannel.is_on()) debugChannel.off(); ); 141 #if !defined(__sun__) || !defined(__svr4__) 142 Debug( dc::warning.on() ); // On Solaris we fail to find the start of libdl 143 #endif 144 #if CWDEBUG_LOCATION 145 Debug( dc::bfd.on() ); 146 #endif 147 Debug( dc::notice.on() ); 148 Debug( dc::system.on() ); 149 #ifndef THREADTEST 150 // Write debug output to cout 151 Debug( libcw_do.set_ostream(&std::cout) ); 152 #endif 153 // Turn debug object on 154 Debug( libcw_do.on() ); 155 #if CWDEBUG_LOCATION 156 // Choose location format 157 Debug( location_format(show_objectfile|show_function) ); 158 #endif 159 160 // Run test 161 #if !CW_RECURSIVE_BUILTIN_RETURN_ADDRESS 162 store_call_address(4); 163 #endif 164 libcwd_bfd_test(); 165 166 Dout(dc::notice, "Program end"); 167 168 Debug( libcw_do.off() ); 169 170 EXIT(0); 171 } 172