Skip to content

Commit f8cdf06

Browse files
authored
Proper handling of several source files per code section in Codeview debug information
1 parent 6ea84f9 commit f8cdf06

File tree

1 file changed

+61
-39
lines changed

1 file changed

+61
-39
lines changed

output/codeview.c

Lines changed: 61 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,6 @@ const struct dfmt df_cv8 = {
4747
/*******************************************************************************
4848
* dfmt callbacks
4949
******************************************************************************/
50-
struct sect_lines
51-
{
52-
struct SAA *lines;
53-
uint32_t num_lines;
54-
};
55-
5650
struct source_file;
5751

5852
struct source_file {
@@ -65,12 +59,11 @@ struct source_file {
6559
uint32_t filetbl_off;
6660
uint32_t sourcetbl_off;
6761

68-
struct sect_lines *sects;
69-
7062
unsigned char md5sum[MD5_HASHBYTES];
7163
};
7264

73-
struct linepair {
65+
struct line_info {
66+
struct source_file *file;
7467
uint32_t file_offset;
7568
uint32_t linenumber;
7669
};
@@ -120,6 +113,8 @@ struct cv8_state {
120113
unsigned num_files;
121114
uint32_t total_filename_len;
122115

116+
struct SAA **lines;
117+
123118
struct SAA *symbols;
124119
struct cv8_symbol *last_sym;
125120
unsigned num_syms[SYMTYPE_MAX];
@@ -149,6 +144,8 @@ static void cv8_init(void)
149144
cv8_state.num_files = 0;
150145
cv8_state.total_filename_len = 0;
151146

147+
cv8_state.lines = NULL;
148+
152149
cv8_state.symbols = saa_init(sizeof(struct cv8_symbol));
153150
cv8_state.last_sym = NULL;
154151
}
@@ -159,8 +156,8 @@ static int find_section(int32_t segto);
159156
static void cv8_linenum(const char *filename, int32_t linenumber,
160157
int32_t segto)
161158
{
162-
struct linepair *li;
163-
struct sect_lines *sl;
159+
struct line_info *li;
160+
struct source_file *file;
164161
int i;
165162

166163
i = find_section(segto);
@@ -170,16 +167,18 @@ static void cv8_linenum(const char *filename, int32_t linenumber,
170167
if ((coff_sects[i]->flags & IMAGE_SCN_MEM_EXECUTE) == 0)
171168
return;
172169

173-
sl = &register_file(filename)->sects[i];
170+
file = register_file(filename);
171+
172+
if (!cv8_state.lines)
173+
cv8_state.lines = nasm_calloc(coff_nsects, sizeof(*cv8_state.lines));
174174

175-
if (!sl->lines)
176-
sl->lines = saa_init(sizeof(struct linepair));
175+
if (!cv8_state.lines[i])
176+
cv8_state.lines[i] = saa_init(sizeof(struct line_info));
177177

178-
li = saa_wstruct(sl->lines);
178+
li = saa_wstruct(cv8_state.lines[i]);
179+
li->file = file;
179180
li->file_offset = coff_sects[i]->len;
180181
li->linenumber = linenumber;
181-
182-
sl->num_lines++;
183182
}
184183

185184
static void cv8_deflabel(char *name, int32_t segment, int64_t offset,
@@ -285,16 +284,19 @@ static void cv8_cleanup(void)
285284
build_type_table(type_sect);
286285

287286
list_for_each_safe(file, ftmp, cv8_state.source_files) {
288-
int i;
289287
nasm_free(file->fullname);
290-
for (i = 0; i < coff_nsects; i++)
291-
if (file->sects[i].lines)
292-
saa_free(file->sects[i].lines);
293-
nasm_free(file->sects);
294288
nasm_free(file);
295289
}
296290
hash_free(&cv8_state.file_hash);
297291

292+
if (cv8_state.lines) {
293+
int i;
294+
for (i = 0; i < coff_nsects; i++)
295+
if (cv8_state.lines[i])
296+
saa_free(cv8_state.lines[i]);
297+
nasm_free(cv8_state.lines);
298+
}
299+
298300
saa_rewind(cv8_state.symbols);
299301
while ((sym = saa_rstruct(cv8_state.symbols)))
300302
nasm_free(sym->name);
@@ -374,7 +376,6 @@ static struct source_file *register_file(const char *filename)
374376
file->filename = filename;
375377
file->fullname = fullpath;
376378
file->fullnamelen = strlen(fullpath);
377-
file->sects = nasm_calloc(coff_nsects, sizeof(*file->sects));
378379
*cv8_state.source_files_tail = file;
379380
cv8_state.source_files_tail = &file->next;
380381
calc_md5(fullpath, file->md5sum);
@@ -528,22 +529,31 @@ static void write_linenumber_table(struct coff_Section *const sect)
528529
size_t field_base;
529530
struct source_file *file;
530531
struct coff_Section *s;
531-
unsigned num_files = 0;
532-
unsigned total_lines = 0;
532+
struct line_info *li;
533+
unsigned num_files;
534+
unsigned num_lines;
535+
struct SAA *lines = cv8_state.lines[i];
533536

534-
list_for_each(file, cv8_state.source_files)
535-
if (file->sects[i].num_lines) {
537+
if (!lines)
538+
continue;
539+
540+
num_files = 0;
541+
num_lines = 0;
542+
file = NULL;
543+
saa_rewind(lines);
544+
while ((li = saa_rstruct(lines))) {
545+
num_lines++;
546+
if (file != li->file) {
547+
file = li->file;
536548
num_files++;
537-
total_lines += file->sects[i].num_lines;
538549
}
539-
if (!total_lines)
540-
continue;
550+
}
541551

542552
s = coff_sects[i];
543553

544554
field_length = 12;
545555
field_length += (num_files * file_field_len);
546-
field_length += (total_lines * line_field_len);
556+
field_length += (num_lines * line_field_len);
547557

548558
section_write32(sect, 0x000000F2);
549559
section_write32(sect, field_length);
@@ -560,21 +570,33 @@ static void write_linenumber_table(struct coff_Section *const sect)
560570
register_reloc(sect, i, NULL, field_base + 4,
561571
win64 ? IMAGE_REL_AMD64_SECTION : IMAGE_REL_I386_SECTION);
562572

563-
list_for_each(file, cv8_state.source_files) {
564-
struct linepair *li;
573+
saa_rewind(lines);
574+
li = saa_rstruct(lines);
575+
do {
576+
struct line_info *li2;
577+
char **rblk = lines->rblk;
578+
size_t rpos = lines->rpos;
579+
size_t rptr = lines->rptr;
580+
file = li->file;
581+
for (num_lines = 1; (li2 = saa_rstruct(lines)); num_lines++)
582+
if (li2->file != file)
583+
break;
584+
lines->rblk = rblk;
585+
lines->rpos = rpos;
586+
lines->rptr = rptr;
565587

566588
/* source mapping */
567589
section_write32(sect, file->sourcetbl_off);
568-
section_write32(sect, file->sects[i].num_lines);
569-
section_write32(sect, file_field_len + (file->sects[i].num_lines * line_field_len));
590+
section_write32(sect, num_lines);
591+
section_write32(sect, file_field_len + (num_lines * line_field_len));
570592

571593
/* the pairs */
572-
saa_rewind(file->sects[i].lines);
573-
while ((li = saa_rstruct(file->sects[i].lines))) {
594+
do {
574595
section_write32(sect, li->file_offset);
575596
section_write32(sect, li->linenumber |= 0x80000000);
576-
}
577-
}
597+
li = saa_rstruct(lines);
598+
} while (li && li->file == file);
599+
} while (li);
578600
}
579601
}
580602

0 commit comments

Comments
 (0)