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
13define /R int compare_guid(guid1, guid2)
14    unsigned char *guid1;
15    unsigned char *guid2;
16{
17    return strncmp(guid1, guid2, 16);
18}
19.
20
21define /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
44define /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
87define /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
102define /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
113define /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
131define /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
141define /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