1 // 2 // Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> 3 // 4 // This program and the accompanying materials 5 // are licensed and made available under the terms and conditions of the BSD License 6 // which accompanies this distribution. The full text of the license may be found at 7 // http://opensource.org/licenses/bsd-license.php 8 // 9 // THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 // 12 13 define /R int compare_guid(guid1, guid2) 14 unsigned char *guid1; 15 unsigned char *guid2; 16 { 17 return strncmp(guid1, guid2, 16); 18 } 19 . 20 21 define /R unsigned char * find_system_table(mem_start, mem_size) 22 unsigned char *mem_start; 23 unsigned long mem_size; 24 { 25 unsigned char *mem_ptr; 26 27 mem_ptr = mem_start + mem_size; 28 29 do 30 { 31 mem_ptr -= 0x400000; // 4 MB 32 33 if (strncmp(mem_ptr, "IBI SYST", 8) == 0) 34 { 35 return *(unsigned long *)(mem_ptr + 8); // EfiSystemTableBase 36 } 37 38 } while (mem_ptr > mem_start); 39 40 return 0; 41 } 42 . 43 44 define /R unsigned char * find_debug_info_table_header(system_table) 45 unsigned char *system_table; 46 { 47 unsigned long configuration_table_entries; 48 unsigned char *configuration_table; 49 unsigned long index; 50 unsigned char debug_table_guid[16]; 51 52 // Fill in the debug table's guid 53 debug_table_guid[ 0] = 0x77; 54 debug_table_guid[ 1] = 0x2E; 55 debug_table_guid[ 2] = 0x15; 56 debug_table_guid[ 3] = 0x49; 57 debug_table_guid[ 4] = 0xDA; 58 debug_table_guid[ 5] = 0x1A; 59 debug_table_guid[ 6] = 0x64; 60 debug_table_guid[ 7] = 0x47; 61 debug_table_guid[ 8] = 0xB7; 62 debug_table_guid[ 9] = 0xA2; 63 debug_table_guid[10] = 0x7A; 64 debug_table_guid[11] = 0xFE; 65 debug_table_guid[12] = 0xFE; 66 debug_table_guid[13] = 0xD9; 67 debug_table_guid[14] = 0x5E; 68 debug_table_guid[15] = 0x8B; 69 70 configuration_table_entries = *(unsigned long *)(system_table + 64); 71 configuration_table = *(unsigned long *)(system_table + 68); 72 73 for (index = 0; index < configuration_table_entries; index++) 74 { 75 if (compare_guid(configuration_table, debug_table_guid) == 0) 76 { 77 return *(unsigned long *)(configuration_table + 16); 78 } 79 80 configuration_table += 20; 81 } 82 83 return 0; 84 } 85 . 86 87 define /R int valid_pe_header(header) 88 unsigned char *header; 89 { 90 if ((header[0x00] == 'M') && 91 (header[0x01] == 'Z') && 92 (header[0x80] == 'P') && 93 (header[0x81] == 'E')) 94 { 95 return 1; 96 } 97 98 return 0; 99 } 100 . 101 102 define /R unsigned long pe_headersize(header) 103 unsigned char *header; 104 { 105 unsigned long *size; 106 107 size = header + 0x00AC; 108 109 return *size; 110 } 111 . 112 113 define /R unsigned char *pe_filename(header) 114 unsigned char *header; 115 { 116 unsigned long *debugOffset; 117 unsigned char *stringOffset; 118 119 if (valid_pe_header(header)) 120 { 121 debugOffset = header + 0x0128; 122 stringOffset = header + *debugOffset + 0x002C; 123 124 return stringOffset; 125 } 126 127 return 0; 128 } 129 . 130 131 define /R int char_is_valid(c) 132 unsigned char c; 133 { 134 if (c >= 32 && c < 127) 135 return 1; 136 137 return 0; 138 } 139 . 140 141 define /R write_symbols_file(filename, mem_start, mem_size) 142 unsigned char *filename; 143 unsigned char *mem_start; 144 unsigned long mem_size; 145 { 146 unsigned char *system_table; 147 unsigned char *debug_info_table_header; 148 unsigned char *debug_info_table; 149 unsigned long debug_info_table_size; 150 unsigned long index; 151 unsigned char *debug_image_info; 152 unsigned char *loaded_image_protocol; 153 unsigned char *image_base; 154 unsigned char *debug_filename; 155 unsigned long header_size; 156 int status; 157 158 system_table = find_system_table(mem_start, mem_size); 159 if (system_table == 0) 160 { 161 return; 162 } 163 164 status = fopen(88, filename, "w"); 165 166 debug_info_table_header = find_debug_info_table_header(system_table); 167 168 debug_info_table = *(unsigned long *)(debug_info_table_header + 8); 169 debug_info_table_size = *(unsigned long *)(debug_info_table_header + 4); 170 171 for (index = 0; index < (debug_info_table_size * 4); index += 4) 172 { 173 debug_image_info = *(unsigned long *)(debug_info_table + index); 174 175 if (debug_image_info == 0) 176 { 177 break; 178 } 179 180 loaded_image_protocol = *(unsigned long *)(debug_image_info + 4); 181 182 image_base = *(unsigned long *)(loaded_image_protocol + 32); 183 184 debug_filename = pe_filename(image_base); 185 header_size = pe_headersize(image_base); 186 187 $fprintf 88, "%s 0x%08x\n", debug_filename, image_base + header_size$; 188 } 189 190 191 fclose(88); 192 } 193 . 194 195