1 #include "types.h"
2 #include "dbi.h"
3 #include "stream_file.h"
4 #include "tpi.h"
5
6 #define PDB_ALIGN 4
7
8 ///////////////////////////////////////////////////////////////////////////////
free_dbi_stream(void * stream)9 static void free_dbi_stream(void *stream) {
10 SDbiStream *t = (SDbiStream *) stream;
11 SDBIExHeader *dbi_ex_header = 0;
12
13 RListIter *it = r_list_iterator(t->dbiexhdrs);
14 while (r_list_iter_next(it)) {
15 dbi_ex_header = (SDBIExHeader *) r_list_iter_get(it);
16 free(dbi_ex_header->modName.name);
17 free(dbi_ex_header->objName.name);
18 free(dbi_ex_header);
19 }
20 r_list_free (t->dbiexhdrs);
21 }
22
23 ///////////////////////////////////////////////////////////////////////////////
parse_dbi_header(SDBIHeader * dbi_header,R_STREAM_FILE * stream_file)24 static void parse_dbi_header(SDBIHeader *dbi_header, R_STREAM_FILE *stream_file) {
25 stream_file_read (stream_file, sizeof (ut32), (char *)&dbi_header->magic);
26 stream_file_read (stream_file, sizeof (ut32), (char *)&dbi_header->version);
27 stream_file_read (stream_file, sizeof (ut32), (char *)&dbi_header->age);
28 stream_file_read (stream_file, sizeof (ut16), (char *)&dbi_header->gssymStream);
29 stream_file_read (stream_file, sizeof (ut16), (char *)&dbi_header->vers);
30 stream_file_read (stream_file, sizeof (st16), (char *)&dbi_header->pssymStream);
31 stream_file_read (stream_file, sizeof (ut16), (char *)&dbi_header->pdbver);
32 stream_file_read (stream_file, sizeof (st16), (char *)&dbi_header->symrecStream);
33 stream_file_read (stream_file, sizeof (ut16), (char *)&dbi_header->pdbver2);
34 stream_file_read (stream_file, sizeof (ut32), (char *)&dbi_header->module_size);
35 stream_file_read (stream_file, sizeof (ut32), (char *)&dbi_header->seccon_size);
36 stream_file_read (stream_file, sizeof (ut32), (char *)&dbi_header->secmap_size);
37 stream_file_read (stream_file, sizeof (ut32), (char *)&dbi_header->filinf_size);
38 stream_file_read (stream_file, sizeof (ut32), (char *)&dbi_header->tsmap_size);
39 stream_file_read (stream_file, sizeof (ut32), (char *)&dbi_header->mfc_index);
40 stream_file_read (stream_file, sizeof (ut32), (char *)&dbi_header->dbghdr_size);
41 stream_file_read (stream_file, sizeof (ut32), (char *)&dbi_header->ecinfo_size);
42 stream_file_read (stream_file, sizeof (ut16), (char *)&dbi_header->flags);
43 stream_file_read (stream_file, 2, (char *)&dbi_header->machine);
44 stream_file_read (stream_file, sizeof (ut32), (char *)&dbi_header->resvd);
45 }
46
47 ///////////////////////////////////////////////////////////////////////////////
parse_ssymbol_range(char * data,int max_len,SSymbolRange * symbol_range)48 static int parse_ssymbol_range(char *data, int max_len, SSymbolRange *symbol_range) {
49 int read_bytes = 0;
50
51 READ2(read_bytes, max_len, symbol_range->section, data, st16);
52 READ2(read_bytes, max_len, symbol_range->padding1, data, st16);
53 READ4(read_bytes, max_len, symbol_range->offset, data, st32);
54 READ4(read_bytes, max_len, symbol_range->size, data, st32);
55 READ4(read_bytes, max_len, symbol_range->flags, data, ut32);
56 READ4(read_bytes, max_len, symbol_range->module, data, st32);
57
58 // TODO: why not need to read this padding?
59 // READ2(read_bytes, max_len, symbol_range->padding2, data, short);
60 READ4(read_bytes, max_len, symbol_range->data_crc, data, ut32);
61 READ4(read_bytes, max_len, symbol_range->reloc_crc, data, ut32);
62
63 return read_bytes;
64 }
65
66 ///////////////////////////////////////////////////////////////////////////////
parse_dbi_ex_header(char * data,int max_len,SDBIExHeader * dbi_ex_header)67 static int parse_dbi_ex_header(char *data, int max_len, SDBIExHeader *dbi_ex_header) {
68 ut32 read_bytes = 0, before_read_bytes = 0;
69
70 READ4(read_bytes, max_len, dbi_ex_header->opened, data, ut32);
71
72 before_read_bytes = read_bytes;
73 read_bytes += parse_ssymbol_range (data, max_len, &dbi_ex_header->range);
74 data += (read_bytes - before_read_bytes);
75
76 READ2(read_bytes, max_len, dbi_ex_header->flags, data, ut16);
77 READ2(read_bytes, max_len, dbi_ex_header->stream, data, st16);
78 READ4(read_bytes, max_len, dbi_ex_header->symSize, data, ut32);
79 READ4(read_bytes, max_len, dbi_ex_header->oldLineSize, data, ut32);
80 READ4(read_bytes, max_len, dbi_ex_header->lineSize, data, ut32);
81 READ2(read_bytes, max_len, dbi_ex_header->nSrcFiles, data, st16);
82 READ2(read_bytes, max_len, dbi_ex_header->padding1, data, st16);
83 READ4(read_bytes, max_len, dbi_ex_header->offsets, data, ut32);
84 READ4(read_bytes, max_len, dbi_ex_header->niSource, data, ut32);
85 READ4(read_bytes, max_len, dbi_ex_header->niCompiler, data, ut32);
86
87 before_read_bytes = read_bytes;
88 parse_sctring(&dbi_ex_header->modName, (unsigned char *)data, &read_bytes, max_len);
89 data += (read_bytes - before_read_bytes);
90
91 parse_sctring(&dbi_ex_header->objName, (unsigned char *)data, &read_bytes, max_len);
92
93 return read_bytes;
94 }
95
96 ///////////////////////////////////////////////////////////////////////////////
parse_dbg_header(SDbiDbgHeader * dbg_header,R_STREAM_FILE * stream_file)97 static void parse_dbg_header(SDbiDbgHeader *dbg_header, R_STREAM_FILE *stream_file) {
98 stream_file_read (stream_file, sizeof (short), (char *)&dbg_header->sn_fpo);
99 stream_file_read (stream_file, sizeof (short), (char *)&dbg_header->sn_exception);
100 stream_file_read (stream_file, sizeof (short), (char *)&dbg_header->sn_fixup);
101 stream_file_read (stream_file, sizeof (short), (char *)&dbg_header->sn_omap_to_src);
102 stream_file_read (stream_file, sizeof (short), (char *)&dbg_header->sn_omap_from_src);
103 stream_file_read (stream_file, sizeof (short), (char *)&dbg_header->sn_section_hdr);
104 stream_file_read (stream_file, sizeof (short), (char *)&dbg_header->sn_token_rid_map);
105 stream_file_read (stream_file, sizeof (short), (char *)&dbg_header->sn_xdata);
106 stream_file_read (stream_file, sizeof (short), (char *)&dbg_header->sn_pdata);
107 stream_file_read (stream_file, sizeof (short), (char *)&dbg_header->sn_new_fpo);
108 stream_file_read (stream_file, sizeof (short), (char *)&dbg_header->sn_section_hdr_orig);
109 }
110
111 ///////////////////////////////////////////////////////////////////////////////
init_dbi_stream(SDbiStream * dbi_stream)112 void init_dbi_stream(SDbiStream *dbi_stream) {
113 dbi_stream->free_ = free_dbi_stream;
114 }
115
116 ///////////////////////////////////////////////////////////////////////////////
parse_dbi_stream(void * parsed_pdb_stream,R_STREAM_FILE * stream_file)117 void parse_dbi_stream(void *parsed_pdb_stream, R_STREAM_FILE *stream_file) {
118 SDbiStream *dbi_stream = (SDbiStream *) parsed_pdb_stream;
119 SDBIExHeader *dbi_ex_header = 0;
120 int pos = 0;
121 char *dbiexhdr_data = 0, *p_tmp = 0;
122 int size = 0, sz = 0;
123 int i = 0;
124
125 parse_dbi_header (&dbi_stream->dbi_header, stream_file);
126 pos += sizeof (SDBIHeader) - 2; // 2 because enum in C equal to 4, but
127 // to read just 2;
128 stream_file_seek (stream_file, pos, 0);
129
130 size = dbi_stream->dbi_header.module_size;
131 dbiexhdr_data = (char *) malloc(size);
132 if (!dbiexhdr_data) {
133 return;
134 }
135 stream_file_read (stream_file, size, dbiexhdr_data);
136
137 dbi_stream->dbiexhdrs = r_list_new ();
138 p_tmp = dbiexhdr_data;
139 while (i < size) {
140 dbi_ex_header = (SDBIExHeader *) malloc (sizeof(SDBIExHeader));
141 if (!dbi_ex_header) {
142 break;
143 }
144 // TODO: rewrite for signature where can to do chech CAN_READ true?
145 sz = parse_dbi_ex_header (p_tmp, size, dbi_ex_header);
146 if ((sz % PDB_ALIGN)) {
147 sz = sz + (PDB_ALIGN - (sz % PDB_ALIGN));
148 }
149 i += sz;
150 p_tmp += sz;
151 r_list_append (dbi_stream->dbiexhdrs, dbi_ex_header);
152 }
153
154 free (dbiexhdr_data);
155
156 // "Section Contribution"
157 stream_file_seek(stream_file, dbi_stream->dbi_header.seccon_size, 1);
158 // "Section Map"
159 stream_file_seek(stream_file, dbi_stream->dbi_header.secmap_size, 1);
160 // "File Info"
161 stream_file_seek(stream_file, dbi_stream->dbi_header.filinf_size, 1);
162 // "TSM"
163 stream_file_seek(stream_file, dbi_stream->dbi_header.tsmap_size, 1);
164 // "EC"
165 stream_file_seek(stream_file, dbi_stream->dbi_header.ecinfo_size, 1);
166
167 parse_dbg_header(&dbi_stream->dbg_header, stream_file);
168 }
169