| // | |
| // Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> | |
| // | |
| // This program and the accompanying materials | |
| // are licensed and made available under the terms and conditions of the BSD License | |
| // which accompanies this distribution. The full text of the license may be found at | |
| // http://opensource.org/licenses/bsd-license.php | |
| // | |
| // THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| // | |
| define /R int compare_guid(guid1, guid2) | |
| unsigned char *guid1; | |
| unsigned char *guid2; | |
| { | |
| return strncmp(guid1, guid2, 16); | |
| } | |
| . | |
| define /R unsigned char * find_system_table(mem_start, mem_size) | |
| unsigned char *mem_start; | |
| unsigned long mem_size; | |
| { | |
| unsigned char *mem_ptr; | |
| mem_ptr = mem_start + mem_size; | |
| do | |
| { | |
| mem_ptr -= 0x400000; // 4 MB | |
| if (strncmp(mem_ptr, "IBI SYST", 8) == 0) | |
| { | |
| return *(unsigned long *)(mem_ptr + 8); // EfiSystemTableBase | |
| } | |
| } while (mem_ptr > mem_start); | |
| return 0; | |
| } | |
| . | |
| define /R unsigned char * find_debug_info_table_header(system_table) | |
| unsigned char *system_table; | |
| { | |
| unsigned long configuration_table_entries; | |
| unsigned char *configuration_table; | |
| unsigned long index; | |
| unsigned char debug_table_guid[16]; | |
| // Fill in the debug table's guid | |
| debug_table_guid[ 0] = 0x77; | |
| debug_table_guid[ 1] = 0x2E; | |
| debug_table_guid[ 2] = 0x15; | |
| debug_table_guid[ 3] = 0x49; | |
| debug_table_guid[ 4] = 0xDA; | |
| debug_table_guid[ 5] = 0x1A; | |
| debug_table_guid[ 6] = 0x64; | |
| debug_table_guid[ 7] = 0x47; | |
| debug_table_guid[ 8] = 0xB7; | |
| debug_table_guid[ 9] = 0xA2; | |
| debug_table_guid[10] = 0x7A; | |
| debug_table_guid[11] = 0xFE; | |
| debug_table_guid[12] = 0xFE; | |
| debug_table_guid[13] = 0xD9; | |
| debug_table_guid[14] = 0x5E; | |
| debug_table_guid[15] = 0x8B; | |
| configuration_table_entries = *(unsigned long *)(system_table + 64); | |
| configuration_table = *(unsigned long *)(system_table + 68); | |
| for (index = 0; index < configuration_table_entries; index++) | |
| { | |
| if (compare_guid(configuration_table, debug_table_guid) == 0) | |
| { | |
| return *(unsigned long *)(configuration_table + 16); | |
| } | |
| configuration_table += 20; | |
| } | |
| return 0; | |
| } | |
| . | |
| define /R int valid_pe_header(header) | |
| unsigned char *header; | |
| { | |
| if ((header[0x00] == 'M') && | |
| (header[0x01] == 'Z') && | |
| (header[0x80] == 'P') && | |
| (header[0x81] == 'E')) | |
| { | |
| return 1; | |
| } | |
| return 0; | |
| } | |
| . | |
| define /R unsigned long pe_headersize(header) | |
| unsigned char *header; | |
| { | |
| unsigned long *size; | |
| size = header + 0x00AC; | |
| return *size; | |
| } | |
| . | |
| define /R unsigned char *pe_filename(header) | |
| unsigned char *header; | |
| { | |
| unsigned long *debugOffset; | |
| unsigned char *stringOffset; | |
| if (valid_pe_header(header)) | |
| { | |
| debugOffset = header + 0x0128; | |
| stringOffset = header + *debugOffset + 0x002C; | |
| return stringOffset; | |
| } | |
| return 0; | |
| } | |
| . | |
| define /R int char_is_valid(c) | |
| unsigned char c; | |
| { | |
| if (c >= 32 && c < 127) | |
| return 1; | |
| return 0; | |
| } | |
| . | |
| define /R write_symbols_file(filename, mem_start, mem_size) | |
| unsigned char *filename; | |
| unsigned char *mem_start; | |
| unsigned long mem_size; | |
| { | |
| unsigned char *system_table; | |
| unsigned char *debug_info_table_header; | |
| unsigned char *debug_info_table; | |
| unsigned long debug_info_table_size; | |
| unsigned long index; | |
| unsigned char *debug_image_info; | |
| unsigned char *loaded_image_protocol; | |
| unsigned char *image_base; | |
| unsigned char *debug_filename; | |
| unsigned long header_size; | |
| int status; | |
| system_table = find_system_table(mem_start, mem_size); | |
| if (system_table == 0) | |
| { | |
| return; | |
| } | |
| status = fopen(88, filename, "w"); | |
| debug_info_table_header = find_debug_info_table_header(system_table); | |
| debug_info_table = *(unsigned long *)(debug_info_table_header + 8); | |
| debug_info_table_size = *(unsigned long *)(debug_info_table_header + 4); | |
| for (index = 0; index < (debug_info_table_size * 4); index += 4) | |
| { | |
| debug_image_info = *(unsigned long *)(debug_info_table + index); | |
| if (debug_image_info == 0) | |
| { | |
| break; | |
| } | |
| loaded_image_protocol = *(unsigned long *)(debug_image_info + 4); | |
| image_base = *(unsigned long *)(loaded_image_protocol + 32); | |
| debug_filename = pe_filename(image_base); | |
| header_size = pe_headersize(image_base); | |
| $fprintf 88, "%s 0x%08x\n", debug_filename, image_base + header_size$; | |
| } | |
| fclose(88); | |
| } | |
| . | |