~john-koepi/ubuntu/trusty/golang/default

« back to all changes in this revision

Viewing changes to src/cmd/ld/dwarf.c

  • Committer: Bazaar Package Importer
  • Author(s): Ondřej Surý
  • Date: 2011-04-20 17:36:48 UTC
  • Revision ID: james.westby@ubuntu.com-20110420173648-ifergoxyrm832trd
Tags: upstream-2011.03.07.1
Import upstream version 2011.03.07.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2010 The Go Authors. All rights reserved.
 
2
// Use of this source code is governed by a BSD-style
 
3
// license that can be found in the LICENSE file.
 
4
 
 
5
// TODO/NICETOHAVE:
 
6
//   - eliminate DW_CLS_ if not used
 
7
//   - package info in compilation units
 
8
//   - assign global variables and types to their packages
 
9
//   - (upstream) type info for C parts of runtime
 
10
//   - gdb uses c syntax, meaning clumsy quoting is needed for go identifiers. eg
 
11
//     ptype struct '[]uint8' and qualifiers need to be quoted away
 
12
//   - lexical scoping is lost, so gdb gets confused as to which 'main.i' you mean.
 
13
//   - file:line info for variables
 
14
//   - make strings a typedef so prettyprinters can see the underlying string type
 
15
//
 
16
#include        "l.h"
 
17
#include        "lib.h"
 
18
#include        "../ld/dwarf.h"
 
19
#include        "../ld/dwarf_defs.h"
 
20
#include        "../ld/elf.h"
 
21
#include        "../ld/macho.h"
 
22
#include        "../ld/pe.h"
 
23
 
 
24
/*
 
25
 * Offsets and sizes of the debug_* sections in the cout file.
 
26
 */
 
27
 
 
28
static vlong abbrevo;
 
29
static vlong abbrevsize;
 
30
static vlong lineo;
 
31
static vlong linesize;
 
32
static vlong infoo;     // also the base for DWDie->offs and reference attributes.
 
33
static vlong infosize;
 
34
static vlong frameo;
 
35
static vlong framesize;
 
36
static vlong pubnameso;
 
37
static vlong pubnamessize;
 
38
static vlong pubtypeso;
 
39
static vlong pubtypessize;
 
40
static vlong arangeso;
 
41
static vlong arangessize;
 
42
static vlong gdbscripto;
 
43
static vlong gdbscriptsize;
 
44
 
 
45
static char  gdbscript[1024];
 
46
 
 
47
/*
 
48
 *  Basic I/O
 
49
 */
 
50
 
 
51
static void
 
52
addrput(vlong addr)
 
53
{
 
54
        switch(PtrSize) {
 
55
        case 4:
 
56
                LPUT(addr);
 
57
                break;
 
58
        case 8:
 
59
                VPUT(addr);
 
60
                break;
 
61
        }
 
62
}
 
63
 
 
64
static int
 
65
uleb128enc(uvlong v, char* dst)
 
66
{
 
67
        uint8 c, len;
 
68
 
 
69
        len = 0;
 
70
        do {
 
71
                c = v & 0x7f;
 
72
                v >>= 7;
 
73
                if (v)
 
74
                        c |= 0x80;
 
75
                if (dst)
 
76
                        *dst++ = c;
 
77
                len++;
 
78
        } while (c & 0x80);
 
79
        return len;
 
80
};
 
81
 
 
82
static int
 
83
sleb128enc(vlong v, char *dst)
 
84
{
 
85
        uint8 c, s, len;
 
86
 
 
87
        len = 0;
 
88
        do {
 
89
                c = v & 0x7f;
 
90
                s = v & 0x40;
 
91
                v >>= 7;
 
92
                if ((v != -1 || !s) && (v != 0 || s))
 
93
                        c |= 0x80;
 
94
                if (dst)
 
95
                        *dst++ = c;
 
96
                len++;
 
97
        } while(c & 0x80);
 
98
        return len;
 
99
}
 
100
 
 
101
static void
 
102
uleb128put(vlong v)
 
103
{
 
104
        char buf[10];
 
105
        strnput(buf, uleb128enc(v, buf));
 
106
}
 
107
 
 
108
static void
 
109
sleb128put(vlong v)
 
110
{
 
111
        char buf[10];
 
112
        strnput(buf, sleb128enc(v, buf));
 
113
}
 
114
 
 
115
/*
 
116
 * Defining Abbrevs.  This is hardcoded, and there will be
 
117
 * only a handful of them.  The DWARF spec places no restriction on
 
118
 * the ordering of atributes in the Abbrevs and DIEs, and we will
 
119
 * always write them out in the order of declaration in the abbrev.
 
120
 * This implementation relies on tag, attr < 127, so they serialize as
 
121
 * a char.  Higher numbered user-defined tags or attributes can be used
 
122
 * for storing internal data but won't be serialized.
 
123
 */
 
124
typedef struct DWAttrForm DWAttrForm;
 
125
struct DWAttrForm {
 
126
        uint8 attr;
 
127
        uint8 form;
 
128
};
 
129
 
 
130
// Index into the abbrevs table below.
 
131
// Keep in sync with ispubname() and ispubtype() below.
 
132
// ispubtype considers >= NULLTYPE public
 
133
enum
 
134
{
 
135
        DW_ABRV_NULL,
 
136
        DW_ABRV_COMPUNIT,
 
137
        DW_ABRV_FUNCTION,
 
138
        DW_ABRV_VARIABLE,
 
139
        DW_ABRV_AUTO,
 
140
        DW_ABRV_PARAM,
 
141
        DW_ABRV_STRUCTFIELD,
 
142
        DW_ABRV_FUNCTYPEPARAM,
 
143
        DW_ABRV_DOTDOTDOT,
 
144
        DW_ABRV_ARRAYRANGE,
 
145
        DW_ABRV_NULLTYPE,
 
146
        DW_ABRV_BASETYPE,
 
147
        DW_ABRV_ARRAYTYPE,
 
148
        DW_ABRV_CHANTYPE,
 
149
        DW_ABRV_FUNCTYPE,
 
150
        DW_ABRV_IFACETYPE,
 
151
        DW_ABRV_MAPTYPE,
 
152
        DW_ABRV_PTRTYPE,
 
153
        DW_ABRV_SLICETYPE,
 
154
        DW_ABRV_STRINGTYPE,
 
155
        DW_ABRV_STRUCTTYPE,
 
156
        DW_ABRV_TYPEDECL,
 
157
        DW_NABRV
 
158
};
 
159
 
 
160
typedef struct DWAbbrev DWAbbrev;
 
161
static struct DWAbbrev {
 
162
        uint8 tag;
 
163
        uint8 children;
 
164
        DWAttrForm attr[30];
 
165
} abbrevs[DW_NABRV] = {
 
166
        /* The mandatory DW_ABRV_NULL entry. */
 
167
        { 0 },
 
168
        /* COMPUNIT */
 
169
        {
 
170
                DW_TAG_compile_unit, DW_CHILDREN_yes,
 
171
                DW_AT_name,      DW_FORM_string,
 
172
                DW_AT_language,  DW_FORM_data1,
 
173
                DW_AT_low_pc,    DW_FORM_addr,
 
174
                DW_AT_high_pc,   DW_FORM_addr,
 
175
                DW_AT_stmt_list, DW_FORM_data4,
 
176
                0, 0
 
177
        },
 
178
        /* FUNCTION */
 
179
        {
 
180
                DW_TAG_subprogram, DW_CHILDREN_yes,
 
181
                DW_AT_name,      DW_FORM_string,
 
182
                DW_AT_low_pc,    DW_FORM_addr,
 
183
                DW_AT_high_pc,   DW_FORM_addr,
 
184
                DW_AT_external,  DW_FORM_flag,
 
185
                0, 0
 
186
        },
 
187
        /* VARIABLE */
 
188
        {
 
189
                DW_TAG_variable, DW_CHILDREN_no,
 
190
                DW_AT_name,      DW_FORM_string,
 
191
                DW_AT_location,  DW_FORM_block1,
 
192
                DW_AT_type,      DW_FORM_ref_addr,
 
193
                DW_AT_external,  DW_FORM_flag,
 
194
                0, 0
 
195
        },
 
196
        /* AUTO */
 
197
        {
 
198
                DW_TAG_variable, DW_CHILDREN_no,
 
199
                DW_AT_name,      DW_FORM_string,
 
200
                DW_AT_location,  DW_FORM_block1,
 
201
                DW_AT_type,      DW_FORM_ref_addr,
 
202
                0, 0
 
203
        },
 
204
        /* PARAM */
 
205
        {
 
206
                DW_TAG_formal_parameter, DW_CHILDREN_no,
 
207
                DW_AT_name,      DW_FORM_string,
 
208
                DW_AT_location,  DW_FORM_block1,
 
209
                DW_AT_type,      DW_FORM_ref_addr,
 
210
                0, 0
 
211
        },
 
212
        /* STRUCTFIELD */
 
213
        {
 
214
                DW_TAG_member,  DW_CHILDREN_no,
 
215
                DW_AT_name,     DW_FORM_string,
 
216
                DW_AT_data_member_location, DW_FORM_block1,
 
217
                DW_AT_type,      DW_FORM_ref_addr,
 
218
                0, 0
 
219
        },
 
220
        /* FUNCTYPEPARAM */
 
221
        {
 
222
                DW_TAG_formal_parameter, DW_CHILDREN_no,
 
223
                // No name!
 
224
                DW_AT_type,      DW_FORM_ref_addr,
 
225
                0, 0
 
226
        },
 
227
 
 
228
        /* DOTDOTDOT */
 
229
        {
 
230
                DW_TAG_unspecified_parameters, DW_CHILDREN_no,
 
231
                0, 0
 
232
        },
 
233
        /* ARRAYRANGE */
 
234
        {
 
235
                DW_TAG_subrange_type, DW_CHILDREN_no,
 
236
                // No name!
 
237
                DW_AT_type,      DW_FORM_ref_addr,
 
238
                DW_AT_upper_bound, DW_FORM_data1,
 
239
                0, 0
 
240
        },
 
241
 
 
242
        // Below here are the types considered public by ispubtype
 
243
        /* NULLTYPE */
 
244
        {
 
245
                DW_TAG_unspecified_type, DW_CHILDREN_no,
 
246
                DW_AT_name,     DW_FORM_string,
 
247
                0, 0
 
248
        },
 
249
        /* BASETYPE */
 
250
        {
 
251
                DW_TAG_base_type, DW_CHILDREN_no,
 
252
                DW_AT_name,      DW_FORM_string,
 
253
                DW_AT_encoding,  DW_FORM_data1,
 
254
                DW_AT_byte_size, DW_FORM_data1,
 
255
                0, 0
 
256
        },
 
257
        /* ARRAYTYPE */
 
258
        // child is subrange with upper bound
 
259
        {
 
260
                DW_TAG_array_type, DW_CHILDREN_yes,
 
261
                DW_AT_name,     DW_FORM_string,
 
262
                DW_AT_type,     DW_FORM_ref_addr,
 
263
                DW_AT_byte_size, DW_FORM_udata,
 
264
                0, 0
 
265
        },
 
266
 
 
267
        /* CHANTYPE */
 
268
        {
 
269
                DW_TAG_typedef, DW_CHILDREN_no,
 
270
                DW_AT_name,     DW_FORM_string,
 
271
                DW_AT_type,     DW_FORM_ref_addr,
 
272
                0, 0
 
273
        },
 
274
 
 
275
        /* FUNCTYPE */
 
276
        {
 
277
                DW_TAG_subroutine_type, DW_CHILDREN_yes,
 
278
                DW_AT_name,     DW_FORM_string,
 
279
//              DW_AT_type,     DW_FORM_ref_addr,
 
280
                0, 0
 
281
        },
 
282
 
 
283
        /* IFACETYPE */
 
284
        {
 
285
                DW_TAG_typedef, DW_CHILDREN_yes,
 
286
                DW_AT_name,      DW_FORM_string,
 
287
                DW_AT_type,     DW_FORM_ref_addr,
 
288
                0, 0
 
289
        },
 
290
 
 
291
        /* MAPTYPE */
 
292
        {
 
293
                DW_TAG_typedef, DW_CHILDREN_no,
 
294
                DW_AT_name,     DW_FORM_string,
 
295
                DW_AT_type,     DW_FORM_ref_addr,
 
296
                0, 0
 
297
        },
 
298
 
 
299
        /* PTRTYPE */
 
300
        {
 
301
                DW_TAG_pointer_type, DW_CHILDREN_no,
 
302
                DW_AT_name,     DW_FORM_string,
 
303
                DW_AT_type,     DW_FORM_ref_addr,
 
304
                0, 0
 
305
        },
 
306
 
 
307
        /* SLICETYPE */
 
308
        {
 
309
                DW_TAG_structure_type, DW_CHILDREN_yes,
 
310
                DW_AT_name,     DW_FORM_string,
 
311
                DW_AT_byte_size, DW_FORM_udata,
 
312
                0, 0
 
313
        },
 
314
 
 
315
        /* STRINGTYPE */
 
316
        {
 
317
                DW_TAG_structure_type, DW_CHILDREN_yes,
 
318
                DW_AT_name,     DW_FORM_string,
 
319
                DW_AT_byte_size, DW_FORM_udata,
 
320
                0, 0
 
321
        },
 
322
 
 
323
        /* STRUCTTYPE */
 
324
        {
 
325
                DW_TAG_structure_type, DW_CHILDREN_yes,
 
326
                DW_AT_name,     DW_FORM_string,
 
327
                DW_AT_byte_size, DW_FORM_udata,
 
328
                0, 0
 
329
        },
 
330
 
 
331
        /* TYPEDECL */
 
332
        {
 
333
                DW_TAG_typedef, DW_CHILDREN_no,
 
334
                DW_AT_name,     DW_FORM_string,
 
335
                DW_AT_type,     DW_FORM_ref_addr,
 
336
                0, 0
 
337
        },
 
338
};
 
339
 
 
340
static void
 
341
writeabbrev(void)
 
342
{
 
343
        int i, n;
 
344
 
 
345
        abbrevo = cpos();
 
346
        for (i = 1; i < DW_NABRV; i++) {
 
347
                // See section 7.5.3
 
348
                uleb128put(i);
 
349
                uleb128put(abbrevs[i].tag);
 
350
                cput(abbrevs[i].children);
 
351
                // 0 is not a valid attr or form, and DWAbbrev.attr is
 
352
                // 0-terminated, so we can treat it as a string
 
353
                n = strlen((char*)abbrevs[i].attr) / 2;
 
354
                strnput((char*)abbrevs[i].attr,
 
355
                        (n+1) * sizeof(DWAttrForm));
 
356
        }
 
357
        cput(0);
 
358
        abbrevsize = cpos() - abbrevo;
 
359
}
 
360
 
 
361
/*
 
362
 * Debugging Information Entries and their attributes.
 
363
 */
 
364
 
 
365
enum
 
366
{
 
367
        HASHSIZE = 107
 
368
};
 
369
 
 
370
static uint32
 
371
hashstr(char* s)
 
372
{
 
373
        uint32 h;
 
374
 
 
375
        h = 0;
 
376
        while (*s)
 
377
                h = h+h+h + *s++;
 
378
        return h % HASHSIZE;
 
379
}
 
380
 
 
381
// For DW_CLS_string and _block, value should contain the length, and
 
382
// data the data, for _reference, value is 0 and data is a DWDie* to
 
383
// the referenced instance, for all others, value is the whole thing
 
384
// and data is null.
 
385
 
 
386
typedef struct DWAttr DWAttr;
 
387
struct DWAttr {
 
388
        DWAttr *link;
 
389
        uint8 atr;  // DW_AT_
 
390
        uint8 cls;  // DW_CLS_
 
391
        vlong value;
 
392
        char *data;
 
393
};
 
394
 
 
395
typedef struct DWDie DWDie;
 
396
struct DWDie {
 
397
        int abbrev;
 
398
        DWDie *link;
 
399
        DWDie *child;
 
400
        DWAttr *attr;
 
401
        // offset into .debug_info section, i.e relative to
 
402
        // infoo. only valid after call to putdie()
 
403
        vlong offs;
 
404
        DWDie **hash;  // optional index of children by name, enabled by mkindex()
 
405
        DWDie *hlink;  // bucket chain in parent's index
 
406
};
 
407
 
 
408
/*
 
409
 * Root DIEs for compilation units, types and global variables.
 
410
 */
 
411
 
 
412
static DWDie dwroot;
 
413
static DWDie dwtypes;
 
414
static DWDie dwglobals;
 
415
 
 
416
static DWAttr*
 
417
newattr(DWDie *die, uint8 attr, int cls, vlong value, char *data)
 
418
{
 
419
        DWAttr *a;
 
420
 
 
421
        a = mal(sizeof *a);
 
422
        a->link = die->attr;
 
423
        die->attr = a;
 
424
        a->atr = attr;
 
425
        a->cls = cls;
 
426
        a->value = value;
 
427
        a->data = data;
 
428
        return a;
 
429
}
 
430
 
 
431
// Each DIE (except the root ones) has at least 1 attribute: its
 
432
// name. getattr moves the desired one to the front so
 
433
// frequently searched ones are found faster.
 
434
static DWAttr*
 
435
getattr(DWDie *die, uint8 attr)
 
436
{
 
437
        DWAttr *a, *b;
 
438
 
 
439
        if (die->attr->atr == attr)
 
440
                return die->attr;
 
441
 
 
442
        a = die->attr;
 
443
        b = a->link;
 
444
        while (b != nil) {
 
445
                if (b->atr == attr) {
 
446
                        a->link = b->link;
 
447
                        b->link = die->attr;
 
448
                        die->attr = b;
 
449
                        return b;
 
450
                }
 
451
                a = b;
 
452
                b = b->link;
 
453
        }
 
454
        return nil;
 
455
}
 
456
 
 
457
// Every DIE has at least a DW_AT_name attribute (but it will only be
 
458
// written out if it is listed in the abbrev).  If its parent is
 
459
// keeping an index, the new DIE will be inserted there.
 
460
static DWDie*
 
461
newdie(DWDie *parent, int abbrev, char *name)
 
462
{
 
463
        DWDie *die;
 
464
        int h;
 
465
 
 
466
        die = mal(sizeof *die);
 
467
        die->abbrev = abbrev;
 
468
        die->link = parent->child;
 
469
        parent->child = die;
 
470
 
 
471
        newattr(die, DW_AT_name, DW_CLS_STRING, strlen(name), name);
 
472
 
 
473
        if (parent->hash) {
 
474
                h = hashstr(name);
 
475
                die->hlink = parent->hash[h];
 
476
                parent->hash[h] = die;
 
477
        }
 
478
 
 
479
        return die;
 
480
}
 
481
 
 
482
static void
 
483
mkindex(DWDie *die)
 
484
{
 
485
        die->hash = mal(HASHSIZE * sizeof(DWDie*));
 
486
}
 
487
 
 
488
// Find child by AT_name using hashtable if available or linear scan
 
489
// if not.
 
490
static DWDie*
 
491
find(DWDie *die, char* name)
 
492
{
 
493
        DWDie *a, *b;
 
494
        int h;
 
495
 
 
496
        if (die->hash == nil) {
 
497
                for (a = die->child; a != nil; a = a->link)
 
498
                        if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
 
499
                                return a;
 
500
                return nil;
 
501
        }
 
502
 
 
503
        h = hashstr(name);
 
504
        a = die->hash[h];
 
505
 
 
506
        if (a == nil)
 
507
                return nil;
 
508
 
 
509
 
 
510
        if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
 
511
                return a;
 
512
 
 
513
        // Move found ones to head of the list.
 
514
        b = a->hlink;
 
515
        while (b != nil) {
 
516
                if (strcmp(name, getattr(b, DW_AT_name)->data) == 0) {
 
517
                        a->hlink = b->hlink;
 
518
                        b->hlink = die->hash[h];
 
519
                        die->hash[h] = b;
 
520
                        return b;
 
521
                }
 
522
                a = b;
 
523
                b = b->hlink;
 
524
        }
 
525
        return nil;
 
526
}
 
527
 
 
528
static DWDie*
 
529
find_or_diag(DWDie *die, char* name)
 
530
{
 
531
        DWDie *r;
 
532
        r = find(die, name);
 
533
        if (r == nil)
 
534
                diag("dwarf find: %s has no %s", getattr(die, DW_AT_name)->data, name);
 
535
        return r;
 
536
}
 
537
 
 
538
static DWAttr*
 
539
newrefattr(DWDie *die, uint8 attr, DWDie* ref)
 
540
{
 
541
        if (ref == nil)
 
542
                return nil;
 
543
        return newattr(die, attr, DW_CLS_REFERENCE, 0, (char*)ref);
 
544
}
 
545
 
 
546
static int fwdcount;
 
547
 
 
548
static void
 
549
putattr(int form, int cls, vlong value, char *data)
 
550
{
 
551
        switch(form) {
 
552
        case DW_FORM_addr:      // address
 
553
                addrput(value);
 
554
                break;
 
555
 
 
556
        case DW_FORM_block1:    // block
 
557
                value &= 0xff;
 
558
                cput(value);
 
559
                while(value--)
 
560
                        cput(*data++);
 
561
                break;
 
562
 
 
563
        case DW_FORM_block2:    // block
 
564
                value &= 0xffff;
 
565
                WPUT(value);
 
566
                while(value--)
 
567
                        cput(*data++);
 
568
                break;
 
569
 
 
570
        case DW_FORM_block4:    // block
 
571
                value &= 0xffffffff;
 
572
                LPUT(value);
 
573
                while(value--)
 
574
                        cput(*data++);
 
575
                break;
 
576
 
 
577
        case DW_FORM_block:     // block
 
578
                uleb128put(value);
 
579
                while(value--)
 
580
                        cput(*data++);
 
581
                break;
 
582
 
 
583
        case DW_FORM_data1:     // constant
 
584
                cput(value);
 
585
                break;
 
586
 
 
587
        case DW_FORM_data2:     // constant
 
588
                WPUT(value);
 
589
                break;
 
590
 
 
591
        case DW_FORM_data4:     // constant, {line,loclist,mac,rangelist}ptr
 
592
                LPUT(value);
 
593
                break;
 
594
 
 
595
        case DW_FORM_data8:     // constant, {line,loclist,mac,rangelist}ptr
 
596
                VPUT(value);
 
597
                break;
 
598
 
 
599
        case DW_FORM_sdata:     // constant
 
600
                sleb128put(value);
 
601
                break;
 
602
 
 
603
        case DW_FORM_udata:     // constant
 
604
                uleb128put(value);
 
605
                break;
 
606
 
 
607
        case DW_FORM_string:    // string
 
608
                strnput(data, value+1);
 
609
                break;
 
610
 
 
611
        case DW_FORM_flag:      // flag
 
612
                cput(value?1:0);
 
613
                break;
 
614
 
 
615
        case DW_FORM_ref_addr:  // reference to a DIE in the .info section
 
616
                if (data == nil) {
 
617
                        diag("null dwarf reference");
 
618
                        LPUT(0);  // invalid dwarf, gdb will complain.
 
619
                } else {
 
620
                        if (((DWDie*)data)->offs == 0)
 
621
                                fwdcount++;
 
622
                        LPUT(((DWDie*)data)->offs);
 
623
                }
 
624
                break;
 
625
 
 
626
        case DW_FORM_ref1:      // reference within the compilation unit
 
627
        case DW_FORM_ref2:      // reference
 
628
        case DW_FORM_ref4:      // reference
 
629
        case DW_FORM_ref8:      // reference
 
630
        case DW_FORM_ref_udata: // reference
 
631
 
 
632
        case DW_FORM_strp:      // string
 
633
        case DW_FORM_indirect:  // (see Section 7.5.3)
 
634
        default:
 
635
                diag("Unsupported atribute form %d / class %d", form, cls);
 
636
                errorexit();
 
637
        }
 
638
}
 
639
 
 
640
// Note that we can (and do) add arbitrary attributes to a DIE, but
 
641
// only the ones actually listed in the Abbrev will be written out.
 
642
static void
 
643
putattrs(int abbrev, DWAttr* attr)
 
644
{
 
645
        DWAttr *attrs[DW_AT_recursive + 1];
 
646
        DWAttrForm* af;
 
647
 
 
648
        memset(attrs, 0, sizeof attrs);
 
649
        for( ; attr; attr = attr->link)
 
650
                if (attr->atr < nelem(attrs))
 
651
                        attrs[attr->atr] = attr;
 
652
 
 
653
        for(af = abbrevs[abbrev].attr; af->attr; af++)
 
654
                if (attrs[af->attr])
 
655
                        putattr(af->form,
 
656
                                attrs[af->attr]->cls,
 
657
                                attrs[af->attr]->value,
 
658
                                attrs[af->attr]->data);
 
659
                else
 
660
                        putattr(af->form, 0, 0, 0);
 
661
}
 
662
 
 
663
static void putdie(DWDie* die);
 
664
 
 
665
static void
 
666
putdies(DWDie* die)
 
667
{
 
668
        for(; die; die = die->link)
 
669
                putdie(die);
 
670
}
 
671
 
 
672
static void
 
673
putdie(DWDie* die)
 
674
{
 
675
        die->offs = cpos() - infoo;
 
676
        uleb128put(die->abbrev);
 
677
        putattrs(die->abbrev, die->attr);
 
678
        if (abbrevs[die->abbrev].children) {
 
679
                putdies(die->child);
 
680
                cput(0);
 
681
        }
 
682
}
 
683
 
 
684
static void
 
685
reverselist(DWDie** list)
 
686
{
 
687
        DWDie *curr, *prev;
 
688
 
 
689
        curr = *list;
 
690
        prev = nil;
 
691
        while(curr != nil) {
 
692
                DWDie* next = curr->link;
 
693
                curr->link = prev;
 
694
                prev = curr;
 
695
                curr = next;
 
696
        }
 
697
        *list = prev;
 
698
}
 
699
 
 
700
static void
 
701
reversetree(DWDie** list)
 
702
{
 
703
         DWDie *die;
 
704
 
 
705
         reverselist(list);
 
706
         for (die = *list; die != nil; die = die->link)
 
707
                 if (abbrevs[die->abbrev].children)
 
708
                         reversetree(&die->child);
 
709
}
 
710
 
 
711
static void
 
712
newmemberoffsetattr(DWDie *die, int32 offs)
 
713
{
 
714
        char block[10];
 
715
        int i;
 
716
 
 
717
        i = 0;
 
718
        if (offs != 0) {
 
719
                block[i++] = DW_OP_consts;
 
720
                i += sleb128enc(offs, block+i);
 
721
                block[i++] = DW_OP_plus;
 
722
        }
 
723
        newattr(die, DW_AT_data_member_location, DW_CLS_BLOCK, i, mal(i));
 
724
        memmove(die->attr->data, block, i);
 
725
}
 
726
 
 
727
// GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a
 
728
// location expression that evals to a const.
 
729
static void
 
730
newabslocexprattr(DWDie *die, vlong addr)
 
731
{
 
732
        char block[10];
 
733
        int i;
 
734
 
 
735
        i = 0;
 
736
        block[i++] = DW_OP_constu;
 
737
        i += uleb128enc(addr, block+i);
 
738
        newattr(die, DW_AT_location, DW_CLS_BLOCK, i, mal(i));
 
739
        memmove(die->attr->data, block, i);
 
740
}
 
741
 
 
742
// Decoding the type.* symbols.  This has to be in sync with
 
743
// ../../pkg/runtime/type.go, or more specificaly, with what
 
744
// ../gc/reflect.c stuffs in these.
 
745
 
 
746
enum {
 
747
        KindBool = 1,
 
748
        KindInt,
 
749
        KindInt8,
 
750
        KindInt16,
 
751
        KindInt32,
 
752
        KindInt64,
 
753
        KindUint,
 
754
        KindUint8,
 
755
        KindUint16,
 
756
        KindUint32,
 
757
        KindUint64,
 
758
        KindUintptr,
 
759
        KindFloat32,
 
760
        KindFloat64,
 
761
        KindComplex64,
 
762
        KindComplex128,
 
763
        KindArray,
 
764
        KindChan,
 
765
        KindFunc,
 
766
        KindInterface,
 
767
        KindMap,
 
768
        KindPtr,
 
769
        KindSlice,
 
770
        KindString,
 
771
        KindStruct,
 
772
        KindUnsafePointer,
 
773
 
 
774
        KindNoPointers = 1<<7,
 
775
 
 
776
        // size of Type interface header + CommonType structure.
 
777
        CommonSize = 2*PtrSize+ 4*PtrSize + 8,
 
778
};
 
779
 
 
780
static Reloc*
 
781
decode_reloc(Sym *s, int32 off)
 
782
{
 
783
        int i;
 
784
 
 
785
        for (i = 0; i < s->nr; i++)
 
786
                if (s->r[i].off == off)
 
787
                        return s->r + i;
 
788
        return nil;
 
789
}
 
790
 
 
791
static Sym*
 
792
decode_reloc_sym(Sym *s, int32 off)
 
793
{
 
794
        Reloc *r;
 
795
 
 
796
        r = decode_reloc(s,off);
 
797
        if (r == nil)
 
798
                return nil;
 
799
        return r->sym;
 
800
}
 
801
 
 
802
static uvlong
 
803
decode_inuxi(uchar* p, int sz)
 
804
{
 
805
        uint64 v;
 
806
        uint32 l;
 
807
        uchar *cast, *inuxi;
 
808
        int i;
 
809
 
 
810
        v = l = 0;
 
811
        cast = nil;
 
812
        inuxi = nil;
 
813
        switch (sz) {
 
814
        case 2:
 
815
                cast = (uchar*)&l;
 
816
                inuxi = inuxi2;
 
817
                break;
 
818
        case 4:
 
819
                cast = (uchar*)&l;
 
820
                inuxi = inuxi4;
 
821
                break;
 
822
        case 8:
 
823
                cast = (uchar*)&v;
 
824
                inuxi = inuxi8;
 
825
                break;
 
826
        default:
 
827
                diag("decode inuxi %d", sz);
 
828
                errorexit();
 
829
        }
 
830
        for (i = 0; i < sz; i++)
 
831
                cast[inuxi[i]] = p[i];
 
832
        if (sz == 8)
 
833
                return v;
 
834
        return l;
 
835
}
 
836
 
 
837
// Type.commonType.kind
 
838
static uint8
 
839
decodetype_kind(Sym *s)
 
840
{
 
841
        return s->p[3*PtrSize + 7] & ~KindNoPointers;   //  0x13 / 0x1f
 
842
}
 
843
 
 
844
// Type.commonType.size
 
845
static vlong
 
846
decodetype_size(Sym *s)
 
847
{
 
848
        return decode_inuxi(s->p + 2*PtrSize, PtrSize);  // 0x8 / 0x10
 
849
}
 
850
 
 
851
// Type.ArrayType.elem and Type.SliceType.Elem
 
852
static Sym*
 
853
decodetype_arrayelem(Sym *s)
 
854
{
 
855
        return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
 
856
}
 
857
 
 
858
static vlong
 
859
decodetype_arraylen(Sym *s)
 
860
{
 
861
        return decode_inuxi(s->p + CommonSize+PtrSize, PtrSize);
 
862
}
 
863
 
 
864
// Type.PtrType.elem
 
865
static Sym*
 
866
decodetype_ptrelem(Sym *s)
 
867
{
 
868
        return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
 
869
}
 
870
 
 
871
// Type.MapType.key, elem
 
872
static Sym*
 
873
decodetype_mapkey(Sym *s)
 
874
{
 
875
        return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
 
876
}
 
877
static Sym*
 
878
decodetype_mapvalue(Sym *s)
 
879
{
 
880
        return decode_reloc_sym(s, CommonSize+PtrSize); // 0x20 / 0x38
 
881
}
 
882
 
 
883
// Type.ChanType.elem
 
884
static Sym*
 
885
decodetype_chanelem(Sym *s)
 
886
{
 
887
        return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
 
888
}
 
889
 
 
890
// Type.FuncType.dotdotdot
 
891
static int
 
892
decodetype_funcdotdotdot(Sym *s)
 
893
{
 
894
        return s->p[CommonSize];
 
895
}
 
896
 
 
897
// Type.FuncType.in.len
 
898
static int
 
899
decodetype_funcincount(Sym *s)
 
900
{
 
901
        return decode_inuxi(s->p + CommonSize+2*PtrSize, 4);
 
902
}
 
903
 
 
904
static int
 
905
decodetype_funcoutcount(Sym *s)
 
906
{
 
907
        return decode_inuxi(s->p + CommonSize+3*PtrSize + 2*4, 4);
 
908
}
 
909
 
 
910
static Sym*
 
911
decodetype_funcintype(Sym *s, int i)
 
912
{
 
913
        Reloc *r;
 
914
 
 
915
        r = decode_reloc(s, CommonSize + PtrSize);
 
916
        if (r == nil)
 
917
                return nil;
 
918
        return decode_reloc_sym(r->sym, r->add + i * PtrSize);
 
919
}
 
920
 
 
921
static Sym*
 
922
decodetype_funcouttype(Sym *s, int i)
 
923
{
 
924
        Reloc *r;
 
925
 
 
926
        r = decode_reloc(s, CommonSize + 2*PtrSize + 2*4);
 
927
        if (r == nil)
 
928
                return nil;
 
929
        return decode_reloc_sym(r->sym, r->add + i * PtrSize);
 
930
}
 
931
 
 
932
// Type.StructType.fields.Slice::len
 
933
static int
 
934
decodetype_structfieldcount(Sym *s)
 
935
{
 
936
        return decode_inuxi(s->p + CommonSize + PtrSize, 4);
 
937
}
 
938
 
 
939
enum {
 
940
        StructFieldSize = 5*PtrSize
 
941
};
 
942
// Type.StructType.fields[]-> name, typ and offset.
 
943
static char*
 
944
decodetype_structfieldname(Sym *s, int i)
 
945
{
 
946
        // go.string."foo"  0x28 / 0x40
 
947
        s = decode_reloc_sym(s, CommonSize + PtrSize + 2*4 + i*StructFieldSize);
 
948
        if (s == nil)                   // embedded structs have a nil name.
 
949
                return nil;
 
950
        s = decode_reloc_sym(s, 0);     // string."foo"
 
951
        if (s == nil)                   // shouldn't happen.
 
952
                return nil;
 
953
        return (char*)s->p;             // the c-string
 
954
}
 
955
 
 
956
static Sym*
 
957
decodetype_structfieldtype(Sym *s, int i)
 
958
{
 
959
        return decode_reloc_sym(s, CommonSize + PtrSize + 2*4 + i*StructFieldSize + 2*PtrSize);
 
960
}
 
961
 
 
962
static vlong
 
963
decodetype_structfieldoffs(Sym *s, int i)
 
964
{
 
965
        return decode_inuxi(s->p + CommonSize + PtrSize + 2*4 + i*StructFieldSize + 4*PtrSize, 4);
 
966
}
 
967
 
 
968
// InterfaceTYpe.methods.len
 
969
static vlong
 
970
decodetype_ifacemethodcount(Sym *s)
 
971
{
 
972
        return decode_inuxi(s->p + CommonSize + PtrSize, 4);
 
973
}
 
974
 
 
975
 
 
976
// Fake attributes for slices, maps and channel
 
977
enum {
 
978
        DW_AT_internal_elem_type = 250,  // channels and slices
 
979
        DW_AT_internal_key_type = 251,   // maps
 
980
        DW_AT_internal_val_type = 252,   // maps
 
981
        DW_AT_internal_location = 253,   // params and locals
 
982
};
 
983
 
 
984
static DWDie* defptrto(DWDie *dwtype);  // below
 
985
 
 
986
// Lookup predefined types
 
987
static Sym*
 
988
lookup_or_diag(char *n)
 
989
{
 
990
        Sym *s;
 
991
 
 
992
        s = lookup(n, 0);
 
993
        if (s->size == 0) {
 
994
                diag("dwarf: missing type: %s", n);
 
995
                errorexit();
 
996
        }
 
997
        return s;
 
998
}
 
999
 
 
1000
// Define gotype, for composite ones recurse into constituents.
 
1001
static DWDie*
 
1002
defgotype(Sym *gotype)
 
1003
{
 
1004
        DWDie *die, *fld;
 
1005
        Sym *s;
 
1006
        char *name, *f;
 
1007
        uint8 kind;
 
1008
        vlong bytesize;
 
1009
        int i, nfields;
 
1010
 
 
1011
        if (gotype == nil)
 
1012
                return find_or_diag(&dwtypes, "<unspecified>");
 
1013
 
 
1014
        if (strncmp("type.", gotype->name, 5) != 0) {
 
1015
                diag("Type name doesn't start with \".type\": %s", gotype->name);
 
1016
                return find_or_diag(&dwtypes, "<unspecified>");
 
1017
        }
 
1018
        name = gotype->name + 5;  // could also decode from Type.string
 
1019
 
 
1020
        die = find(&dwtypes, name);
 
1021
        if (die != nil)
 
1022
                return die;
 
1023
 
 
1024
        if (0 && debug['v'] > 2) {
 
1025
                print("new type: %s @0x%08x [%d]", gotype->name, gotype->value, gotype->size);
 
1026
                for (i = 0; i < gotype->size; i++) {
 
1027
                        if (!(i%8)) print("\n\t%04x ", i);
 
1028
                        print("%02x ", gotype->p[i]);
 
1029
                }
 
1030
                print("\n");
 
1031
                for (i = 0; i < gotype->nr; i++) {
 
1032
                        print("\t0x%02x[%x] %d %s[%llx]\n",
 
1033
                              gotype->r[i].off,
 
1034
                              gotype->r[i].siz,
 
1035
                              gotype->r[i].type,
 
1036
                              gotype->r[i].sym->name,
 
1037
                              (vlong)gotype->r[i].add);
 
1038
                }
 
1039
        }
 
1040
 
 
1041
        kind = decodetype_kind(gotype);
 
1042
        bytesize = decodetype_size(gotype);
 
1043
 
 
1044
        switch (kind) {
 
1045
        case KindBool:
 
1046
                die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
 
1047
                newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_boolean, 0);
 
1048
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
 
1049
                break;
 
1050
 
 
1051
        case KindInt:
 
1052
        case KindInt8:
 
1053
        case KindInt16:
 
1054
        case KindInt32:
 
1055
        case KindInt64:
 
1056
                die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
 
1057
                newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_signed, 0);
 
1058
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
 
1059
                break;
 
1060
 
 
1061
        case KindUint:
 
1062
        case KindUint8:
 
1063
        case KindUint16:
 
1064
        case KindUint32:
 
1065
        case KindUint64:
 
1066
        case KindUintptr:
 
1067
                die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
 
1068
                newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_unsigned, 0);
 
1069
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
 
1070
                break;
 
1071
 
 
1072
        case KindFloat32:
 
1073
        case KindFloat64:
 
1074
                die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
 
1075
                newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_float, 0);
 
1076
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
 
1077
                break;
 
1078
 
 
1079
        case KindComplex64:
 
1080
        case KindComplex128:
 
1081
                die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
 
1082
                newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_complex_float, 0);
 
1083
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
 
1084
                break;
 
1085
 
 
1086
        case KindArray:
 
1087
                die = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, name);
 
1088
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
 
1089
                s = decodetype_arrayelem(gotype);
 
1090
                newrefattr(die, DW_AT_type, defgotype(s));
 
1091
                fld = newdie(die, DW_ABRV_ARRAYRANGE, "range");
 
1092
                newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0);
 
1093
                newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
 
1094
                break;
 
1095
 
 
1096
        case KindChan:
 
1097
                die = newdie(&dwtypes, DW_ABRV_CHANTYPE, name);
 
1098
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
 
1099
                s = decodetype_chanelem(gotype);
 
1100
                newrefattr(die, DW_AT_internal_elem_type, defgotype(s));
 
1101
                break;
 
1102
 
 
1103
        case KindFunc:
 
1104
                die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name);
 
1105
                newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "void"));
 
1106
                nfields = decodetype_funcincount(gotype);
 
1107
                for (i = 0; i < nfields; i++) {
 
1108
                        s = decodetype_funcintype(gotype, i);
 
1109
                        fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s->name+5);
 
1110
                        newrefattr(fld, DW_AT_type, defgotype(s));
 
1111
                }
 
1112
                if (decodetype_funcdotdotdot(gotype))
 
1113
                        newdie(die, DW_ABRV_DOTDOTDOT, "...");
 
1114
                nfields = decodetype_funcoutcount(gotype);
 
1115
                for (i = 0; i < nfields; i++) {
 
1116
                        s = decodetype_funcouttype(gotype, i);
 
1117
                        fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s->name+5);
 
1118
                        newrefattr(fld, DW_AT_type, defptrto(defgotype(s)));
 
1119
                }
 
1120
                die = defptrto(die);
 
1121
                break;
 
1122
 
 
1123
        case KindInterface:
 
1124
                die = newdie(&dwtypes, DW_ABRV_IFACETYPE, name);
 
1125
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
 
1126
                nfields = decodetype_ifacemethodcount(gotype);
 
1127
                if (nfields == 0)
 
1128
                        s = lookup_or_diag("type.runtime.eface");
 
1129
                else
 
1130
                        s = lookup_or_diag("type.runtime.iface");
 
1131
                newrefattr(die, DW_AT_type, defgotype(s));
 
1132
                break;
 
1133
 
 
1134
        case KindMap:
 
1135
                die = newdie(&dwtypes, DW_ABRV_MAPTYPE, name);
 
1136
                s = decodetype_mapkey(gotype);
 
1137
                newrefattr(die, DW_AT_internal_key_type, defgotype(s));
 
1138
                s = decodetype_mapvalue(gotype);
 
1139
                newrefattr(die, DW_AT_internal_val_type, defgotype(s));
 
1140
                break;
 
1141
 
 
1142
        case KindPtr:
 
1143
                die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name);
 
1144
                s = decodetype_ptrelem(gotype);
 
1145
                newrefattr(die, DW_AT_type, defgotype(s));
 
1146
                break;
 
1147
 
 
1148
        case KindSlice:
 
1149
                die = newdie(&dwtypes, DW_ABRV_SLICETYPE, name);
 
1150
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
 
1151
                s = decodetype_arrayelem(gotype);
 
1152
                newrefattr(die, DW_AT_internal_elem_type, defgotype(s));
 
1153
                break;
 
1154
 
 
1155
        case KindString:
 
1156
                die = newdie(&dwtypes, DW_ABRV_STRINGTYPE, name);
 
1157
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
 
1158
                break;
 
1159
 
 
1160
        case KindStruct:
 
1161
                die = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, name);
 
1162
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
 
1163
                nfields = decodetype_structfieldcount(gotype);
 
1164
                for (i = 0; i < nfields; i++) {
 
1165
                        f = decodetype_structfieldname(gotype, i);
 
1166
                        s = decodetype_structfieldtype(gotype, i);
 
1167
                        if (f == nil)
 
1168
                                f = s->name + 5;         // skip "type."
 
1169
                        fld = newdie(die, DW_ABRV_STRUCTFIELD, f);
 
1170
                        newrefattr(fld, DW_AT_type, defgotype(s));
 
1171
                        newmemberoffsetattr(fld, decodetype_structfieldoffs(gotype, i));
 
1172
                }
 
1173
                break;
 
1174
 
 
1175
        case KindUnsafePointer:
 
1176
                die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name);
 
1177
                newrefattr(die, DW_AT_type, find(&dwtypes, "void"));
 
1178
                break;
 
1179
 
 
1180
        default:
 
1181
                diag("definition of unknown kind %d: %s", kind, gotype->name);
 
1182
                die = newdie(&dwtypes, DW_ABRV_TYPEDECL, name);
 
1183
                newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "<unspecified>"));
 
1184
         }
 
1185
 
 
1186
        return die;
 
1187
}
 
1188
 
 
1189
// Find or construct *T given T.
 
1190
static DWDie*
 
1191
defptrto(DWDie *dwtype)
 
1192
{
 
1193
        char ptrname[1024];
 
1194
        DWDie *die;
 
1195
 
 
1196
        snprint(ptrname, sizeof ptrname, "*%s", getattr(dwtype, DW_AT_name)->data);
 
1197
        die = find(&dwtypes, ptrname);
 
1198
        if (die == nil) {
 
1199
                die = newdie(&dwtypes, DW_ABRV_PTRTYPE,
 
1200
                             strcpy(mal(strlen(ptrname)+1), ptrname));
 
1201
                newrefattr(die, DW_AT_type, dwtype);
 
1202
        }
 
1203
        return die;
 
1204
}
 
1205
 
 
1206
// Copies src's children into dst. Copies attributes by value.
 
1207
// DWAttr.data is copied as pointer only.
 
1208
static void
 
1209
copychildren(DWDie *dst, DWDie *src)
 
1210
{
 
1211
        DWDie *c;
 
1212
        DWAttr *a;
 
1213
 
 
1214
        for (src = src->child; src != nil; src = src->link) {
 
1215
                c = newdie(dst, src->abbrev, getattr(src, DW_AT_name)->data);
 
1216
                for (a = src->attr; a != nil; a = a->link)
 
1217
                        newattr(c, a->atr, a->cls, a->value, a->data);
 
1218
                copychildren(c, src);
 
1219
        }
 
1220
        reverselist(&dst->child);
 
1221
}
 
1222
 
 
1223
// Search children (assumed to have DW_TAG_member) for the one named
 
1224
// field and set it's DW_AT_type to dwtype
 
1225
static void
 
1226
substitutetype(DWDie *structdie, char *field, DWDie* dwtype)
 
1227
{
 
1228
        DWDie *child;
 
1229
        DWAttr *a;
 
1230
 
 
1231
        child = find_or_diag(structdie, field);
 
1232
        if (child == nil)
 
1233
                return;
 
1234
 
 
1235
        a = getattr(child, DW_AT_type);
 
1236
        if (a != nil)
 
1237
                a->data = (char*) dwtype;
 
1238
        else
 
1239
                newrefattr(child, DW_AT_type, dwtype);
 
1240
}
 
1241
 
 
1242
static void
 
1243
synthesizestringtypes(DWDie* die)
 
1244
{
 
1245
        DWDie *prototype;
 
1246
 
 
1247
        prototype = defgotype(lookup_or_diag("type.runtime._string"));
 
1248
        if (prototype == nil)
 
1249
                return;
 
1250
 
 
1251
        for (; die != nil; die = die->link) {
 
1252
                if (die->abbrev != DW_ABRV_STRINGTYPE)
 
1253
                        continue;
 
1254
                copychildren(die, prototype);
 
1255
        }
 
1256
}
 
1257
 
 
1258
static void
 
1259
synthesizeslicetypes(DWDie *die)
 
1260
{
 
1261
        DWDie *prototype, *elem;
 
1262
 
 
1263
        prototype = defgotype(lookup_or_diag("type.runtime.slice"));
 
1264
        if (prototype == nil)
 
1265
                return;
 
1266
 
 
1267
        for (; die != nil; die = die->link) {
 
1268
                if (die->abbrev != DW_ABRV_SLICETYPE)
 
1269
                        continue;
 
1270
                copychildren(die, prototype);
 
1271
                elem = (DWDie*) getattr(die, DW_AT_internal_elem_type)->data;
 
1272
                substitutetype(die, "array", defptrto(elem));
 
1273
        }
 
1274
}
 
1275
 
 
1276
static char*
 
1277
mkinternaltypename(char *base, char *arg1, char *arg2)
 
1278
{
 
1279
        char buf[1024];
 
1280
        char *n;
 
1281
 
 
1282
        if (arg2 == nil)
 
1283
                snprint(buf, sizeof buf, "%s<%s>", base, arg1);
 
1284
        else
 
1285
                snprint(buf, sizeof buf, "%s<%s,%s>", base, arg1, arg2);
 
1286
        n = mal(strlen(buf) + 1);
 
1287
        memmove(n, buf, strlen(buf));
 
1288
        return n;
 
1289
}
 
1290
 
 
1291
 
 
1292
// synthesizemaptypes is way too closely married to runtime/hashmap.c
 
1293
enum {
 
1294
        MaxValsize = 256 - 64
 
1295
};
 
1296
 
 
1297
static void
 
1298
synthesizemaptypes(DWDie *die)
 
1299
{
 
1300
 
 
1301
        DWDie *hash, *hash_subtable, *hash_entry,
 
1302
                *dwh, *dwhs, *dwhe, *dwhash, *keytype, *valtype, *fld;
 
1303
        int hashsize, keysize, valsize, datsize, valsize_in_hash, datavo;
 
1304
        DWAttr *a;
 
1305
 
 
1306
        hash            = defgotype(lookup_or_diag("type.runtime.hmap"));
 
1307
        hash_subtable   = defgotype(lookup_or_diag("type.runtime.hash_subtable"));
 
1308
        hash_entry      = defgotype(lookup_or_diag("type.runtime.hash_entry"));
 
1309
 
 
1310
        if (hash == nil || hash_subtable == nil || hash_entry == nil)
 
1311
                return;
 
1312
 
 
1313
        dwhash = (DWDie*)getattr(find_or_diag(hash_entry, "hash"), DW_AT_type)->data;
 
1314
        if (dwhash == nil)
 
1315
                return;
 
1316
 
 
1317
        hashsize = getattr(dwhash, DW_AT_byte_size)->value;
 
1318
 
 
1319
        for (; die != nil; die = die->link) {
 
1320
                if (die->abbrev != DW_ABRV_MAPTYPE)
 
1321
                        continue;
 
1322
 
 
1323
                keytype = (DWDie*) getattr(die, DW_AT_internal_key_type)->data;
 
1324
                valtype = (DWDie*) getattr(die, DW_AT_internal_val_type)->data;
 
1325
 
 
1326
                a = getattr(keytype, DW_AT_byte_size);
 
1327
                keysize = a ? a->value : PtrSize;  // We don't store size with Pointers
 
1328
 
 
1329
                a = getattr(valtype, DW_AT_byte_size);
 
1330
                valsize = a ? a->value : PtrSize;
 
1331
 
 
1332
                // This is what happens in hash_init and makemap_c
 
1333
                valsize_in_hash = valsize;
 
1334
                if (valsize > MaxValsize)
 
1335
                        valsize_in_hash = PtrSize;
 
1336
                datavo = keysize;
 
1337
                if (valsize_in_hash >= PtrSize)
 
1338
                        datavo = rnd(keysize, PtrSize);
 
1339
                datsize = datavo + valsize_in_hash;
 
1340
                if (datsize < PtrSize)
 
1341
                        datsize = PtrSize;
 
1342
                datsize = rnd(datsize, PtrSize);
 
1343
 
 
1344
                // Construct struct hash_entry<K,V>
 
1345
                dwhe = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
 
1346
                        mkinternaltypename("hash_entry",
 
1347
                                getattr(keytype, DW_AT_name)->data,
 
1348
                                getattr(valtype, DW_AT_name)->data));
 
1349
 
 
1350
                fld = newdie(dwhe, DW_ABRV_STRUCTFIELD, "hash");
 
1351
                newrefattr(fld, DW_AT_type, dwhash);
 
1352
                newmemberoffsetattr(fld, 0);
 
1353
 
 
1354
                fld = newdie(dwhe, DW_ABRV_STRUCTFIELD, "key");
 
1355
                newrefattr(fld, DW_AT_type, keytype);
 
1356
                newmemberoffsetattr(fld, hashsize);
 
1357
 
 
1358
                fld = newdie(dwhe, DW_ABRV_STRUCTFIELD, "val");
 
1359
                if (valsize > MaxValsize)
 
1360
                        valtype = defptrto(valtype);
 
1361
                newrefattr(fld, DW_AT_type, valtype);
 
1362
                newmemberoffsetattr(fld, hashsize + datavo);
 
1363
                newattr(dwhe, DW_AT_byte_size, DW_CLS_CONSTANT, hashsize + datsize, NULL);
 
1364
 
 
1365
                // Construct hash_subtable<hash_entry<K,V>>
 
1366
                dwhs = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
 
1367
                        mkinternaltypename("hash_subtable",
 
1368
                                getattr(keytype, DW_AT_name)->data,
 
1369
                                getattr(valtype, DW_AT_name)->data));
 
1370
                copychildren(dwhs, hash_subtable);
 
1371
                substitutetype(dwhs, "end", defptrto(dwhe));
 
1372
                substitutetype(dwhs, "entry", dwhe);  // todo: []hash_entry with dynamic size
 
1373
                newattr(dwhs, DW_AT_byte_size, DW_CLS_CONSTANT,
 
1374
                        getattr(hash_subtable, DW_AT_byte_size)->value, NULL);
 
1375
 
 
1376
                // Construct hash<K,V>
 
1377
                dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
 
1378
                        mkinternaltypename("hash",
 
1379
                                getattr(keytype, DW_AT_name)->data,
 
1380
                                getattr(valtype, DW_AT_name)->data));
 
1381
                copychildren(dwh, hash);
 
1382
                substitutetype(dwh, "st", defptrto(dwhs));
 
1383
                newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT,
 
1384
                        getattr(hash, DW_AT_byte_size)->value, NULL);
 
1385
 
 
1386
                newrefattr(die, DW_AT_type, defptrto(dwh));
 
1387
        }
 
1388
}
 
1389
 
 
1390
static void
 
1391
synthesizechantypes(DWDie *die)
 
1392
{
 
1393
        DWDie *sudog, *waitq, *link, *hchan,
 
1394
                *dws, *dww, *dwl, *dwh, *elemtype;
 
1395
        DWAttr *a;
 
1396
        int elemsize, linksize, sudogsize;
 
1397
 
 
1398
        sudog = defgotype(lookup_or_diag("type.runtime.sudog"));
 
1399
        waitq = defgotype(lookup_or_diag("type.runtime.waitq"));
 
1400
        link  = defgotype(lookup_or_diag("type.runtime.link"));
 
1401
        hchan = defgotype(lookup_or_diag("type.runtime.hchan"));
 
1402
        if (sudog == nil || waitq == nil || link == nil || hchan == nil)
 
1403
                return;
 
1404
 
 
1405
        sudogsize = getattr(sudog, DW_AT_byte_size)->value;
 
1406
        linksize = getattr(link, DW_AT_byte_size)->value;
 
1407
 
 
1408
        for (; die != nil; die = die->link) {
 
1409
                if (die->abbrev != DW_ABRV_CHANTYPE)
 
1410
                        continue;
 
1411
                elemtype = (DWDie*) getattr(die, DW_AT_internal_elem_type)->data;
 
1412
                a = getattr(elemtype, DW_AT_byte_size);
 
1413
                elemsize = a ? a->value : PtrSize;
 
1414
 
 
1415
                // sudog<T>
 
1416
                dws = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
 
1417
                        mkinternaltypename("sudog",
 
1418
                                getattr(elemtype, DW_AT_name)->data, NULL));
 
1419
                copychildren(dws, sudog);
 
1420
                substitutetype(dws, "elem", elemtype);
 
1421
                newattr(dws, DW_AT_byte_size, DW_CLS_CONSTANT,
 
1422
                        sudogsize + (elemsize > 8 ? elemsize - 8 : 0), NULL);
 
1423
 
 
1424
                // waitq<T>
 
1425
                dww = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
 
1426
                        mkinternaltypename("waitq", getattr(elemtype, DW_AT_name)->data, NULL));
 
1427
                copychildren(dww, waitq);
 
1428
                substitutetype(dww, "first", defptrto(dws));
 
1429
                substitutetype(dww, "last",  defptrto(dws));
 
1430
                newattr(dww, DW_AT_byte_size, DW_CLS_CONSTANT,
 
1431
                        getattr(waitq, DW_AT_byte_size)->value, NULL);
 
1432
 
 
1433
                // link<T>
 
1434
                dwl = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
 
1435
                        mkinternaltypename("link", getattr(elemtype, DW_AT_name)->data, NULL));
 
1436
                copychildren(dwl, link);
 
1437
                substitutetype(dwl, "link", defptrto(dwl));
 
1438
                substitutetype(dwl, "elem", elemtype);
 
1439
                newattr(dwl, DW_AT_byte_size, DW_CLS_CONSTANT,
 
1440
                        linksize + (elemsize > 8 ? elemsize - 8 : 0), NULL);
 
1441
 
 
1442
                // hchan<T>
 
1443
                dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
 
1444
                        mkinternaltypename("hchan", getattr(elemtype, DW_AT_name)->data, NULL));
 
1445
                copychildren(dwh, hchan);
 
1446
                substitutetype(dwh, "senddataq", defptrto(dwl));
 
1447
                substitutetype(dwh, "recvdataq", defptrto(dwl));
 
1448
                substitutetype(dwh, "recvq", dww);
 
1449
                substitutetype(dwh, "sendq", dww);
 
1450
                substitutetype(dwh, "free", dws);
 
1451
                newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT,
 
1452
                        getattr(hchan, DW_AT_byte_size)->value, NULL);
 
1453
 
 
1454
                newrefattr(die, DW_AT_type, defptrto(dwh));
 
1455
        }
 
1456
}
 
1457
 
 
1458
// For use with pass.c::genasmsym
 
1459
static void
 
1460
defdwsymb(Sym* sym, char *s, int t, vlong v, vlong size, int ver, Sym *gotype)
 
1461
{
 
1462
        DWDie *dv, *dt;
 
1463
 
 
1464
        if (strncmp(s, "go.string.", 10) == 0)
 
1465
                return;
 
1466
        if (strncmp(s, "string.", 7) == 0)
 
1467
                return;
 
1468
        if (strncmp(s, "type._.", 7) == 0)
 
1469
                return;
 
1470
 
 
1471
        if (strncmp(s, "type.", 5) == 0) {
 
1472
                defgotype(sym);
 
1473
                return;
 
1474
        }
 
1475
 
 
1476
        dv = nil;
 
1477
 
 
1478
        switch (t) {
 
1479
        default:
 
1480
                return;
 
1481
        case 'd':
 
1482
        case 'b':
 
1483
        case 'D':
 
1484
        case 'B':
 
1485
                dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s);
 
1486
                newabslocexprattr(dv, v);
 
1487
                if (ver == 0)
 
1488
                        newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0);
 
1489
                // fallthrough
 
1490
        case 'a':
 
1491
        case 'p':
 
1492
                dt = defgotype(gotype);
 
1493
        }
 
1494
 
 
1495
        if (dv != nil)
 
1496
                newrefattr(dv, DW_AT_type, dt);
 
1497
}
 
1498
 
 
1499
// TODO(lvd) For now, just append them all to the first compilation
 
1500
// unit (that should be main), in the future distribute them to the
 
1501
// appropriate compilation units.
 
1502
static void
 
1503
movetomodule(DWDie *parent)
 
1504
{
 
1505
        DWDie *die;
 
1506
 
 
1507
        for (die = dwroot.child->child; die->link != nil; die = die->link) /* nix */;
 
1508
        die->link = parent->child;
 
1509
}
 
1510
 
 
1511
/*
 
1512
 * Filename fragments for the line history stack.
 
1513
 */
 
1514
 
 
1515
static char **ftab;
 
1516
static int ftabsize;
 
1517
 
 
1518
void
 
1519
dwarfaddfrag(int n, char *frag)
 
1520
{
 
1521
        int s;
 
1522
 
 
1523
        if (n >= ftabsize) {
 
1524
                s = ftabsize;
 
1525
                ftabsize = 1 + n + (n >> 2);
 
1526
                ftab = realloc(ftab, ftabsize * sizeof(ftab[0]));
 
1527
                memset(ftab + s, 0, (ftabsize - s) * sizeof(ftab[0]));
 
1528
        }
 
1529
 
 
1530
        if (*frag == '<')
 
1531
                frag++;
 
1532
        ftab[n] = frag;
 
1533
}
 
1534
 
 
1535
// Returns a malloc'ed string, piecewise copied from the ftab.
 
1536
static char *
 
1537
decodez(char *s)
 
1538
{
 
1539
        int len, o;
 
1540
        char *ss, *f;
 
1541
        char *r, *rb, *re;
 
1542
 
 
1543
        len = 0;
 
1544
        ss = s + 1;     // first is 0
 
1545
        while((o = ((uint8)ss[0] << 8) | (uint8)ss[1]) != 0) {
 
1546
                if (o < 0 || o >= ftabsize) {
 
1547
                        diag("corrupt z entry");
 
1548
                        return 0;
 
1549
                }
 
1550
                f = ftab[o];
 
1551
                if (f == nil) {
 
1552
                        diag("corrupt z entry");
 
1553
                        return 0;
 
1554
                }
 
1555
                len += strlen(f) + 1;   // for the '/'
 
1556
                ss += 2;
 
1557
        }
 
1558
 
 
1559
        if (len == 0)
 
1560
                return 0;
 
1561
 
 
1562
        r = malloc(len + 1);
 
1563
        rb = r;
 
1564
        re = rb + len + 1;
 
1565
 
 
1566
        s++;
 
1567
        while((o = ((uint8)s[0] << 8) | (uint8)s[1]) != 0) {
 
1568
                f = ftab[o];
 
1569
                if (rb == r || rb[-1] == '/')
 
1570
                        rb = seprint(rb, re, "%s", f);
 
1571
                else
 
1572
                        rb = seprint(rb, re, "/%s", f);
 
1573
                s += 2;
 
1574
        }
 
1575
        return r;
 
1576
}
 
1577
 
 
1578
/*
 
1579
 * The line history itself
 
1580
 */
 
1581
 
 
1582
static char **histfile;    // [0] holds "<eof>", DW_LNS_set_file arguments must be > 0.
 
1583
static int  histfilesize;
 
1584
static int  histfilecap;
 
1585
 
 
1586
static void
 
1587
clearhistfile(void)
 
1588
{
 
1589
        int i;
 
1590
 
 
1591
        // [0] holds "<eof>"
 
1592
        for (i = 1; i < histfilesize; i++)
 
1593
                free(histfile[i]);
 
1594
        histfilesize = 0;
 
1595
}
 
1596
 
 
1597
static int
 
1598
addhistfile(char *zentry)
 
1599
{
 
1600
        char *fname;
 
1601
 
 
1602
        if (histfilesize == histfilecap) {
 
1603
                histfilecap = 2 * histfilecap + 2;
 
1604
                histfile = realloc(histfile, histfilecap * sizeof(char*));
 
1605
        }
 
1606
        if (histfilesize == 0)
 
1607
                histfile[histfilesize++] = "<eof>";
 
1608
 
 
1609
        fname = decodez(zentry);
 
1610
        if (fname == 0)
 
1611
                return -1;
 
1612
        // Don't fill with duplicates (check only top one).
 
1613
        if (strcmp(fname, histfile[histfilesize-1]) == 0) {
 
1614
                free(fname);
 
1615
                return histfilesize - 1;
 
1616
        }
 
1617
        histfile[histfilesize++] = fname;
 
1618
        return histfilesize - 1;
 
1619
}
 
1620
 
 
1621
// if the histfile stack contains ..../runtime/runtime_defs.go
 
1622
// use that to set gdbscript
 
1623
static void
 
1624
finddebugruntimepath()
 
1625
{
 
1626
        int i, l;
 
1627
        char *c;
 
1628
 
 
1629
        for (i = 1; i < histfilesize; i++) {
 
1630
                if ((c = strstr(histfile[i], "runtime/runtime_defs.go")) != nil) {
 
1631
                        l = c - histfile[i];
 
1632
                        memmove(gdbscript, histfile[i], l);
 
1633
                        memmove(gdbscript + l, "runtime/runtime-gdb.py", strlen("runtime/runtime-gdb.py") + 1);
 
1634
                        break;
 
1635
                }
 
1636
        }
 
1637
}
 
1638
 
 
1639
// Go's runtime C sources are sane, and Go sources nest only 1 level,
 
1640
// so 16 should be plenty.
 
1641
static struct {
 
1642
        int file;
 
1643
        vlong line;
 
1644
} includestack[16];
 
1645
static int includetop;
 
1646
static vlong absline;
 
1647
 
 
1648
typedef struct Linehist Linehist;
 
1649
struct Linehist {
 
1650
        Linehist *link;
 
1651
        vlong absline;
 
1652
        vlong line;
 
1653
        int file;
 
1654
};
 
1655
 
 
1656
static Linehist *linehist;
 
1657
 
 
1658
static void
 
1659
checknesting(void)
 
1660
{
 
1661
        int i;
 
1662
 
 
1663
        if (includetop < 0) {
 
1664
                diag("corrupt z stack");
 
1665
                errorexit();
 
1666
        }
 
1667
        if (includetop >= nelem(includestack)) {
 
1668
                diag("nesting too deep");
 
1669
                for (i = 0; i < nelem(includestack); i++)
 
1670
                        diag("\t%s", histfile[includestack[i].file]);
 
1671
                errorexit();
 
1672
        }
 
1673
}
 
1674
 
 
1675
/*
 
1676
 * Return false if the a->link chain contains no history, otherwise
 
1677
 * returns true and finds z and Z entries in the Auto list (of a
 
1678
 * Prog), and resets the history stack
 
1679
 */
 
1680
static int
 
1681
inithist(Auto *a)
 
1682
{
 
1683
        Linehist *lh;
 
1684
 
 
1685
        for (; a; a = a->link)
 
1686
                if (a->type == D_FILE)
 
1687
                        break;
 
1688
        if (a==nil)
 
1689
                return 0;
 
1690
 
 
1691
        // We have a new history.  They are guaranteed to come completely
 
1692
        // at the beginning of the compilation unit.
 
1693
        if (a->aoffset != 1) {
 
1694
                diag("stray 'z' with offset %d", a->aoffset);
 
1695
                return 0;
 
1696
        }
 
1697
 
 
1698
        // Clear the history.
 
1699
        clearhistfile();
 
1700
        includetop = 0;
 
1701
        includestack[includetop].file = 0;
 
1702
        includestack[includetop].line = -1;
 
1703
        absline = 0;
 
1704
        while (linehist != nil) {
 
1705
                lh = linehist->link;
 
1706
                free(linehist);
 
1707
                linehist = lh;
 
1708
        }
 
1709
 
 
1710
        // Construct the new one.
 
1711
        for (; a; a = a->link) {
 
1712
                if (a->type == D_FILE) {  // 'z'
 
1713
                        int f = addhistfile(a->asym->name);
 
1714
                        if (f < 0) {       // pop file
 
1715
                                includetop--;
 
1716
                                checknesting();
 
1717
                        } else if(f != includestack[includetop].file) { // pushed a new file
 
1718
                                includestack[includetop].line += a->aoffset - absline;
 
1719
                                includetop++;
 
1720
                                checknesting();
 
1721
                                includestack[includetop].file = f;
 
1722
                                includestack[includetop].line = 1;
 
1723
                        }
 
1724
                        absline = a->aoffset;
 
1725
                } else if (a->type == D_FILE1) {  // 'Z'
 
1726
                        // We could just fixup the current
 
1727
                        // linehist->line, but there doesn't appear to
 
1728
                        // be a guarantee that every 'Z' is preceded
 
1729
                        // by it's own 'z', so do the safe thing and
 
1730
                        // update the stack and push a new Linehist
 
1731
                        // entry
 
1732
                        includestack[includetop].line =  a->aoffset;
 
1733
                } else
 
1734
                        continue;
 
1735
                if (linehist == 0 || linehist->absline != absline) {
 
1736
                        Linehist* lh = malloc(sizeof *lh);
 
1737
                        lh->link = linehist;
 
1738
                        lh->absline = absline;
 
1739
                        linehist = lh;
 
1740
                }
 
1741
                linehist->file = includestack[includetop].file;
 
1742
                linehist->line = includestack[includetop].line;
 
1743
        }
 
1744
        return 1;
 
1745
}
 
1746
 
 
1747
static Linehist *
 
1748
searchhist(vlong absline)
 
1749
{
 
1750
        Linehist *lh;
 
1751
 
 
1752
        for (lh = linehist; lh; lh = lh->link)
 
1753
                if (lh->absline <= absline)
 
1754
                        break;
 
1755
        return lh;
 
1756
}
 
1757
 
 
1758
static int
 
1759
guesslang(char *s)
 
1760
{
 
1761
        if(strlen(s) >= 3 && strcmp(s+strlen(s)-3, ".go") == 0)
 
1762
                return DW_LANG_Go;
 
1763
 
 
1764
        return DW_LANG_C;
 
1765
}
 
1766
 
 
1767
/*
 
1768
 * Generate short opcodes when possible, long ones when neccesary.
 
1769
 * See section 6.2.5
 
1770
 */
 
1771
 
 
1772
enum {
 
1773
        LINE_BASE = -1,
 
1774
        LINE_RANGE = 4,
 
1775
        OPCODE_BASE = 5
 
1776
};
 
1777
 
 
1778
static void
 
1779
putpclcdelta(vlong delta_pc, vlong delta_lc)
 
1780
{
 
1781
        if (LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE) {
 
1782
                vlong opcode = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc);
 
1783
                if (OPCODE_BASE <= opcode && opcode < 256) {
 
1784
                        cput(opcode);
 
1785
                        return;
 
1786
                }
 
1787
        }
 
1788
 
 
1789
        if (delta_pc) {
 
1790
                cput(DW_LNS_advance_pc);
 
1791
                sleb128put(delta_pc);
 
1792
        }
 
1793
 
 
1794
        cput(DW_LNS_advance_line);
 
1795
        sleb128put(delta_lc);
 
1796
        cput(DW_LNS_copy);
 
1797
}
 
1798
 
 
1799
static void
 
1800
newcfaoffsetattr(DWDie *die, int32 offs)
 
1801
{
 
1802
        char block[10];
 
1803
        int i;
 
1804
 
 
1805
        i = 0;
 
1806
 
 
1807
        block[i++] = DW_OP_call_frame_cfa;
 
1808
        if (offs != 0) {
 
1809
                block[i++] = DW_OP_consts;
 
1810
                i += sleb128enc(offs, block+i);
 
1811
                block[i++] = DW_OP_plus;
 
1812
        }
 
1813
        newattr(die, DW_AT_location, DW_CLS_BLOCK, i, mal(i));
 
1814
        memmove(die->attr->data, block, i);
 
1815
}
 
1816
 
 
1817
static char*
 
1818
mkvarname(char* name, int da)
 
1819
{
 
1820
        char buf[1024];
 
1821
        char *n;
 
1822
 
 
1823
        snprint(buf, sizeof buf, "%s#%d", name, da);
 
1824
        n = mal(strlen(buf) + 1);
 
1825
        memmove(n, buf, strlen(buf));
 
1826
        return n;
 
1827
}
 
1828
 
 
1829
/*
 
1830
 * Walk prog table, emit line program and build DIE tree.
 
1831
 */
 
1832
 
 
1833
// flush previous compilation unit.
 
1834
static void
 
1835
flushunit(DWDie *dwinfo, vlong pc, vlong unitstart)
 
1836
{
 
1837
        vlong here;
 
1838
 
 
1839
        if (dwinfo != nil && pc != 0) {
 
1840
                newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, 0);
 
1841
        }
 
1842
 
 
1843
        if (unitstart >= 0) {
 
1844
                cput(0);  // start extended opcode
 
1845
                uleb128put(1);
 
1846
                cput(DW_LNE_end_sequence);
 
1847
                cflush();
 
1848
 
 
1849
                here = cpos();
 
1850
                seek(cout, unitstart, 0);
 
1851
                LPUT(here - unitstart - sizeof(int32));
 
1852
                cflush();
 
1853
                seek(cout, here, 0);
 
1854
        }
 
1855
}
 
1856
 
 
1857
static void
 
1858
writelines(void)
 
1859
{
 
1860
        Prog *q;
 
1861
        Sym *s;
 
1862
        Auto *a;
 
1863
        vlong unitstart, offs;
 
1864
        vlong pc, epc, lc, llc, lline;
 
1865
        int currfile;
 
1866
        int i, lang, da, dt;
 
1867
        Linehist *lh;
 
1868
        DWDie *dwinfo, *dwfunc, *dwvar, **dws;
 
1869
        DWDie *varhash[HASHSIZE];
 
1870
        char *n, *nn;
 
1871
 
 
1872
        unitstart = -1;
 
1873
        epc = pc = 0;
 
1874
        lc = 1;
 
1875
        llc = 1;
 
1876
        currfile = -1;
 
1877
        lineo = cpos();
 
1878
        dwinfo = nil;
 
1879
 
 
1880
        for(cursym = textp; cursym != nil; cursym = cursym->next) {
 
1881
                s = cursym;
 
1882
                if(s->text == P)
 
1883
                        continue;
 
1884
 
 
1885
                // Look for history stack.  If we find one,
 
1886
                // we're entering a new compilation unit
 
1887
 
 
1888
                if (inithist(s->autom)) {
 
1889
                        flushunit(dwinfo, epc, unitstart);
 
1890
                        unitstart = cpos();
 
1891
 
 
1892
                        if(debug['v'] > 1) {
 
1893
                                print("dwarf writelines found %s\n", histfile[1]);
 
1894
                                Linehist* lh;
 
1895
                                for (lh = linehist; lh; lh = lh->link)
 
1896
                                        print("\t%8lld: [%4lld]%s\n",
 
1897
                                              lh->absline, lh->line, histfile[lh->file]);
 
1898
                        }
 
1899
 
 
1900
                        lang = guesslang(histfile[1]);
 
1901
                        finddebugruntimepath();
 
1902
 
 
1903
                        dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, strdup(histfile[1]));
 
1904
                        newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT,lang, 0);
 
1905
                        newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart - lineo, 0);
 
1906
                        newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s->text->pc, 0);
 
1907
 
 
1908
                        // Write .debug_line Line Number Program Header (sec 6.2.4)
 
1909
                        // Fields marked with (*) must be changed for 64-bit dwarf
 
1910
                        LPUT(0);   // unit_length (*), will be filled in later.
 
1911
                        WPUT(3);   // dwarf version (appendix F)
 
1912
                        LPUT(11);  // header_length (*), starting here.
 
1913
 
 
1914
                        cput(1);   // minimum_instruction_length
 
1915
                        cput(1);   // default_is_stmt
 
1916
                        cput(LINE_BASE);     // line_base
 
1917
                        cput(LINE_RANGE);    // line_range
 
1918
                        cput(OPCODE_BASE);   // opcode_base (we only use 1..4)
 
1919
                        cput(0);   // standard_opcode_lengths[1]
 
1920
                        cput(1);   // standard_opcode_lengths[2]
 
1921
                        cput(1);   // standard_opcode_lengths[3]
 
1922
                        cput(1);   // standard_opcode_lengths[4]
 
1923
                        cput(0);   // include_directories  (empty)
 
1924
                        cput(0);   // file_names (empty) (emitted by DW_LNE's below)
 
1925
                        // header_length ends here.
 
1926
 
 
1927
                        for (i=1; i < histfilesize; i++) {
 
1928
                                cput(0);  // start extended opcode
 
1929
                                uleb128put(1 + strlen(histfile[i]) + 4);
 
1930
                                cput(DW_LNE_define_file);
 
1931
                                strnput(histfile[i], strlen(histfile[i]) + 4);
 
1932
                                // 4 zeros: the string termination + 3 fields.
 
1933
                        }
 
1934
 
 
1935
                        epc = pc = s->text->pc;
 
1936
                        currfile = 1;
 
1937
                        lc = 1;
 
1938
                        llc = 1;
 
1939
 
 
1940
                        cput(0);  // start extended opcode
 
1941
                        uleb128put(1 + PtrSize);
 
1942
                        cput(DW_LNE_set_address);
 
1943
                        addrput(pc);
 
1944
                }
 
1945
                if(s->text == nil)
 
1946
                        continue;
 
1947
 
 
1948
                if (unitstart < 0) {
 
1949
                        diag("reachable code before seeing any history: %P", s->text);
 
1950
                        continue;
 
1951
                }
 
1952
 
 
1953
                dwfunc = newdie(dwinfo, DW_ABRV_FUNCTION, s->name);
 
1954
                newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s->value, 0);
 
1955
                epc = s->value + s->size;
 
1956
                newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, 0);
 
1957
                if (s->version == 0)
 
1958
                        newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0);
 
1959
 
 
1960
                if(s->text->link == nil)
 
1961
                        continue;
 
1962
 
 
1963
                for(q = s->text; q != P; q = q->link) {
 
1964
                        lh = searchhist(q->line);
 
1965
                        if (lh == nil) {
 
1966
                                diag("corrupt history or bad absolute line: %P", q);
 
1967
                                continue;
 
1968
                        }
 
1969
 
 
1970
                        if (lh->file < 1) {  // 0 is the past-EOF entry.
 
1971
                                // diag("instruction with line number past EOF in %s: %P", histfile[1], q);
 
1972
                                continue;
 
1973
                        }
 
1974
 
 
1975
                        lline = lh->line + q->line - lh->absline;
 
1976
                        if (debug['v'] > 1)
 
1977
                                print("%6llux %s[%lld] %P\n", (vlong)q->pc, histfile[lh->file], lline, q);
 
1978
 
 
1979
                        if (q->line == lc)
 
1980
                                continue;
 
1981
                        if (currfile != lh->file) {
 
1982
                                currfile = lh->file;
 
1983
                                cput(DW_LNS_set_file);
 
1984
                                uleb128put(currfile);
 
1985
                        }
 
1986
                        putpclcdelta(q->pc - pc, lline - llc);
 
1987
                        pc  = q->pc;
 
1988
                        lc  = q->line;
 
1989
                        llc = lline;
 
1990
                }
 
1991
 
 
1992
                da = 0;
 
1993
                dwfunc->hash = varhash;  // enable indexing of children by name
 
1994
                memset(varhash, 0, sizeof varhash);
 
1995
                for(a = s->autom; a; a = a->link) {
 
1996
                        switch (a->type) {
 
1997
                        case D_AUTO:
 
1998
                                dt = DW_ABRV_AUTO;
 
1999
                                offs = a->aoffset - PtrSize;
 
2000
                                break;
 
2001
                        case D_PARAM:
 
2002
                                dt = DW_ABRV_PARAM;
 
2003
                                offs = a->aoffset;
 
2004
                                break;
 
2005
                        default:
 
2006
                                continue;
 
2007
                        }
 
2008
                        if (strstr(a->asym->name, ".autotmp_"))
 
2009
                                continue;
 
2010
                        if (find(dwfunc, a->asym->name) != nil)
 
2011
                                n = mkvarname(a->asym->name, da);
 
2012
                        else
 
2013
                                n = a->asym->name;
 
2014
                        // Drop the package prefix from locals and arguments.
 
2015
                        nn = strrchr(n, '.');
 
2016
                        if (nn)
 
2017
                                n = nn + 1;
 
2018
 
 
2019
                        dwvar = newdie(dwfunc, dt, n);
 
2020
                        newcfaoffsetattr(dwvar, offs);
 
2021
                        newrefattr(dwvar, DW_AT_type, defgotype(a->gotype));
 
2022
 
 
2023
                        // push dwvar down dwfunc->child to preserve order
 
2024
                        newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, NULL);
 
2025
                        dwfunc->child = dwvar->link;  // take dwvar out from the top of the list
 
2026
                        for (dws = &dwfunc->child; *dws != nil; dws = &(*dws)->link)
 
2027
                                if (offs > getattr(*dws, DW_AT_internal_location)->value)
 
2028
                                        break;
 
2029
                        dwvar->link = *dws;
 
2030
                        *dws = dwvar;
 
2031
 
 
2032
                        da++;
 
2033
                }
 
2034
 
 
2035
                dwfunc->hash = nil;
 
2036
        }
 
2037
 
 
2038
        flushunit(dwinfo, epc, unitstart);
 
2039
        linesize = cpos() - lineo;
 
2040
}
 
2041
 
 
2042
/*
 
2043
 *  Emit .debug_frame
 
2044
 */
 
2045
enum
 
2046
{
 
2047
        CIERESERVE = 16,
 
2048
        DATAALIGNMENTFACTOR = -4,       // TODO -PtrSize?
 
2049
        FAKERETURNCOLUMN = 16           // TODO gdb6 doesnt like > 15?
 
2050
};
 
2051
 
 
2052
static void
 
2053
putpccfadelta(vlong deltapc, vlong cfa)
 
2054
{
 
2055
        if (deltapc < 0x40) {
 
2056
                cput(DW_CFA_advance_loc + deltapc);
 
2057
        } else if (deltapc < 0x100) {
 
2058
                cput(DW_CFA_advance_loc1);
 
2059
                cput(deltapc);
 
2060
        } else if (deltapc < 0x10000) {
 
2061
                cput(DW_CFA_advance_loc2);
 
2062
                WPUT(deltapc);
 
2063
        } else {
 
2064
                cput(DW_CFA_advance_loc4);
 
2065
                LPUT(deltapc);
 
2066
        }
 
2067
 
 
2068
        cput(DW_CFA_def_cfa_offset_sf);
 
2069
        sleb128put(cfa / DATAALIGNMENTFACTOR);
 
2070
}
 
2071
 
 
2072
static void
 
2073
writeframes(void)
 
2074
{
 
2075
        Prog *p, *q;
 
2076
        Sym *s;
 
2077
        vlong fdeo, fdesize, pad, cfa, pc;
 
2078
 
 
2079
        frameo = cpos();
 
2080
 
 
2081
        // Emit the CIE, Section 6.4.1
 
2082
        LPUT(CIERESERVE);       // initial length, must be multiple of PtrSize
 
2083
        LPUT(0xffffffff);       // cid.
 
2084
        cput(3);                // dwarf version (appendix F)
 
2085
        cput(0);                // augmentation ""
 
2086
        uleb128put(1);          // code_alignment_factor
 
2087
        sleb128put(DATAALIGNMENTFACTOR); // guess
 
2088
        uleb128put(FAKERETURNCOLUMN);   // return_address_register
 
2089
 
 
2090
        cput(DW_CFA_def_cfa);
 
2091
        uleb128put(DWARFREGSP); // register SP (**ABI-dependent, defined in l.h)
 
2092
        uleb128put(PtrSize);    // offset
 
2093
 
 
2094
        cput(DW_CFA_offset + FAKERETURNCOLUMN);  // return address
 
2095
        uleb128put(-PtrSize / DATAALIGNMENTFACTOR);  // at cfa - x*4
 
2096
 
 
2097
        // 4 is to exclude the length field.
 
2098
        pad = CIERESERVE + frameo + 4 - cpos();
 
2099
        if (pad < 0) {
 
2100
                diag("CIERESERVE too small by %lld bytes.", -pad);
 
2101
                errorexit();
 
2102
        }
 
2103
        strnput("", pad);
 
2104
 
 
2105
        for(cursym = textp; cursym != nil; cursym = cursym->next) {
 
2106
                s = cursym;
 
2107
                if(s->text == nil)
 
2108
                        continue;
 
2109
 
 
2110
                fdeo = cpos();
 
2111
                // Emit a FDE, Section 6.4.1, starting wit a placeholder.
 
2112
                LPUT(0);        // length, must be multiple of PtrSize
 
2113
                LPUT(0);        // Pointer to the CIE above, at offset 0
 
2114
                addrput(0);     // initial location
 
2115
                addrput(0);     // address range
 
2116
 
 
2117
                cfa = PtrSize;  // CFA starts at sp+PtrSize
 
2118
                p = s->text;
 
2119
                pc = p->pc;
 
2120
 
 
2121
                for(q = p; q->link != P; q = q->link) {
 
2122
                        if (q->spadj == 0)
 
2123
                                continue;
 
2124
                        cfa += q->spadj;
 
2125
                        putpccfadelta(q->link->pc - pc, cfa);
 
2126
                        pc = q->link->pc;
 
2127
                }
 
2128
 
 
2129
                fdesize = cpos() - fdeo - 4;    // exclude the length field.
 
2130
                pad = rnd(fdesize, PtrSize) - fdesize;
 
2131
                strnput("", pad);
 
2132
                fdesize += pad;
 
2133
                cflush();
 
2134
 
 
2135
                // Emit the FDE header for real, Section 6.4.1.
 
2136
                seek(cout, fdeo, 0);
 
2137
                LPUT(fdesize);
 
2138
                LPUT(0);
 
2139
                addrput(p->pc);
 
2140
                addrput(s->size);
 
2141
 
 
2142
                cflush();
 
2143
                seek(cout, fdeo + 4 + fdesize, 0);
 
2144
        }
 
2145
 
 
2146
        cflush();
 
2147
        framesize = cpos() - frameo;
 
2148
}
 
2149
 
 
2150
/*
 
2151
 *  Walk DWarfDebugInfoEntries, and emit .debug_info
 
2152
 */
 
2153
enum
 
2154
{
 
2155
        COMPUNITHEADERSIZE = 4+2+4+1
 
2156
};
 
2157
 
 
2158
static void
 
2159
writeinfo(void)
 
2160
{
 
2161
        DWDie *compunit;
 
2162
        vlong unitstart, here;
 
2163
 
 
2164
        fwdcount = 0;
 
2165
 
 
2166
        for (compunit = dwroot.child; compunit; compunit = compunit->link) {
 
2167
                unitstart = cpos();
 
2168
 
 
2169
                // Write .debug_info Compilation Unit Header (sec 7.5.1)
 
2170
                // Fields marked with (*) must be changed for 64-bit dwarf
 
2171
                // This must match COMPUNITHEADERSIZE above.
 
2172
                LPUT(0);        // unit_length (*), will be filled in later.
 
2173
                WPUT(3);        // dwarf version (appendix F)
 
2174
                LPUT(0);        // debug_abbrev_offset (*)
 
2175
                cput(PtrSize);  // address_size
 
2176
 
 
2177
                putdie(compunit);
 
2178
 
 
2179
                cflush();
 
2180
                here = cpos();
 
2181
                seek(cout, unitstart, 0);
 
2182
                LPUT(here - unitstart - 4);     // exclude the length field.
 
2183
                cflush();
 
2184
                seek(cout, here, 0);
 
2185
        }
 
2186
 
 
2187
}
 
2188
 
 
2189
/*
 
2190
 *  Emit .debug_pubnames/_types.  _info must have been written before,
 
2191
 *  because we need die->offs and infoo/infosize;
 
2192
 */
 
2193
static int
 
2194
ispubname(DWDie *die) {
 
2195
        DWAttr *a;
 
2196
 
 
2197
        switch(die->abbrev) {
 
2198
        case DW_ABRV_FUNCTION:
 
2199
        case DW_ABRV_VARIABLE:
 
2200
                a = getattr(die, DW_AT_external);
 
2201
                return a && a->value;
 
2202
        }
 
2203
        return 0;
 
2204
}
 
2205
 
 
2206
static int
 
2207
ispubtype(DWDie *die) {
 
2208
        return die->abbrev >= DW_ABRV_NULLTYPE;
 
2209
}
 
2210
 
 
2211
static vlong
 
2212
writepub(int (*ispub)(DWDie*))
 
2213
{
 
2214
        DWDie *compunit, *die;
 
2215
        DWAttr *dwa;
 
2216
        vlong unitstart, unitend, sectionstart, here;
 
2217
 
 
2218
        sectionstart = cpos();
 
2219
 
 
2220
        for (compunit = dwroot.child; compunit != nil; compunit = compunit->link) {
 
2221
                unitstart = compunit->offs - COMPUNITHEADERSIZE;
 
2222
                if (compunit->link != nil)
 
2223
                        unitend = compunit->link->offs - COMPUNITHEADERSIZE;
 
2224
                else
 
2225
                        unitend = infoo + infosize;
 
2226
 
 
2227
                // Write .debug_pubnames/types  Header (sec 6.1.1)
 
2228
                LPUT(0);                        // unit_length (*), will be filled in later.
 
2229
                WPUT(2);                        // dwarf version (appendix F)
 
2230
                LPUT(unitstart);                // debug_info_offset (of the Comp unit Header)
 
2231
                LPUT(unitend - unitstart);      // debug_info_length
 
2232
 
 
2233
                for (die = compunit->child; die != nil; die = die->link) {
 
2234
                        if (!ispub(die)) continue;
 
2235
                        LPUT(die->offs - unitstart);
 
2236
                        dwa = getattr(die, DW_AT_name);
 
2237
                        strnput(dwa->data, dwa->value + 1);
 
2238
                }
 
2239
                LPUT(0);
 
2240
 
 
2241
                cflush();
 
2242
                here = cpos();
 
2243
                seek(cout, sectionstart, 0);
 
2244
                LPUT(here - sectionstart - 4);  // exclude the length field.
 
2245
                cflush();
 
2246
                seek(cout, here, 0);
 
2247
 
 
2248
        }
 
2249
 
 
2250
        return sectionstart;
 
2251
}
 
2252
 
 
2253
/*
 
2254
 *  emit .debug_aranges.  _info must have been written before,
 
2255
 *  because we need die->offs of dw_globals.
 
2256
 */
 
2257
static vlong
 
2258
writearanges(void)
 
2259
{
 
2260
        DWDie *compunit;
 
2261
        DWAttr *b, *e;
 
2262
        int headersize;
 
2263
        vlong sectionstart;
 
2264
 
 
2265
        sectionstart = cpos();
 
2266
        headersize = rnd(4+2+4+1+1, PtrSize);  // don't count unit_length field itself
 
2267
 
 
2268
        for (compunit = dwroot.child; compunit != nil; compunit = compunit->link) {
 
2269
                b = getattr(compunit,  DW_AT_low_pc);
 
2270
                if (b == nil)
 
2271
                        continue;
 
2272
                e = getattr(compunit,  DW_AT_high_pc);
 
2273
                if (e == nil)
 
2274
                        continue;
 
2275
 
 
2276
                // Write .debug_aranges  Header + entry  (sec 6.1.2)
 
2277
                LPUT(headersize + 4*PtrSize - 4);       // unit_length (*)
 
2278
                WPUT(2);        // dwarf version (appendix F)
 
2279
                LPUT(compunit->offs - COMPUNITHEADERSIZE);      // debug_info_offset
 
2280
                cput(PtrSize);  // address_size
 
2281
                cput(0);        // segment_size
 
2282
                strnput("", headersize - (4+2+4+1+1));  // align to PtrSize
 
2283
 
 
2284
                addrput(b->value);
 
2285
                addrput(e->value - b->value);
 
2286
                addrput(0);
 
2287
                addrput(0);
 
2288
        }
 
2289
        cflush();
 
2290
        return sectionstart;
 
2291
}
 
2292
 
 
2293
static vlong
 
2294
writegdbscript(void)
 
2295
{
 
2296
        vlong sectionstart;
 
2297
 
 
2298
        sectionstart = cpos();
 
2299
 
 
2300
        if (gdbscript[0]) {
 
2301
                cput(1);  // magic 1 byte?
 
2302
                strnput(gdbscript, strlen(gdbscript)+1);
 
2303
                cflush();
 
2304
        }
 
2305
        return sectionstart;
 
2306
}
 
2307
 
 
2308
static void
 
2309
align(vlong size)
 
2310
{
 
2311
        if(HEADTYPE == Hwindows) // Only Windows PE need section align.
 
2312
                strnput("", rnd(size, PEFILEALIGN) - size);
 
2313
}
 
2314
 
 
2315
/*
 
2316
 * This is the main entry point for generating dwarf.  After emitting
 
2317
 * the mandatory debug_abbrev section, it calls writelines() to set up
 
2318
 * the per-compilation unit part of the DIE tree, while simultaneously
 
2319
 * emitting the debug_line section.  When the final tree contains
 
2320
 * forward references, it will write the debug_info section in 2
 
2321
 * passes.
 
2322
 *
 
2323
 */
 
2324
void
 
2325
dwarfemitdebugsections(void)
 
2326
{
 
2327
        vlong infoe;
 
2328
        DWDie* die;
 
2329
 
 
2330
        // For diagnostic messages.
 
2331
        newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, strlen("dwtypes"), "dwtypes");
 
2332
 
 
2333
        mkindex(&dwroot);
 
2334
        mkindex(&dwtypes);
 
2335
        mkindex(&dwglobals);
 
2336
 
 
2337
        // Some types that must exist to define other ones.
 
2338
        newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>");
 
2339
        newdie(&dwtypes, DW_ABRV_NULLTYPE, "void");
 
2340
        newrefattr(newdie(&dwtypes, DW_ABRV_PTRTYPE, "unsafe.Pointer"),
 
2341
                DW_AT_type, find(&dwtypes, "void"));
 
2342
        die = newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr");  // needed for array size
 
2343
        newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_unsigned, 0);
 
2344
        newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, PtrSize, 0);
 
2345
 
 
2346
        // Needed by the prettyprinter code for interface inspection.
 
2347
        defgotype(lookup_or_diag("type.runtime.commonType"));
 
2348
        defgotype(lookup_or_diag("type.runtime.InterfaceType"));
 
2349
        defgotype(lookup_or_diag("type.runtime.itab"));
 
2350
 
 
2351
        genasmsym(defdwsymb);
 
2352
 
 
2353
        writeabbrev();
 
2354
        align(abbrevsize);
 
2355
        writelines();
 
2356
        align(linesize);
 
2357
        writeframes();
 
2358
        align(framesize);
 
2359
 
 
2360
        synthesizestringtypes(dwtypes.child);
 
2361
        synthesizeslicetypes(dwtypes.child);
 
2362
        synthesizemaptypes(dwtypes.child);
 
2363
        synthesizechantypes(dwtypes.child);
 
2364
 
 
2365
        reversetree(&dwroot.child);
 
2366
        reversetree(&dwtypes.child);
 
2367
        reversetree(&dwglobals.child);
 
2368
 
 
2369
        movetomodule(&dwtypes);
 
2370
        movetomodule(&dwglobals);
 
2371
 
 
2372
        infoo = cpos();
 
2373
        writeinfo();
 
2374
        gdbscripto = arangeso = pubtypeso = pubnameso = infoe = cpos();
 
2375
 
 
2376
        if (fwdcount > 0) {
 
2377
                if (debug['v'])
 
2378
                        Bprint(&bso, "%5.2f dwarf pass 2.\n", cputime());
 
2379
                seek(cout, infoo, 0);
 
2380
                writeinfo();
 
2381
                if (fwdcount > 0) {
 
2382
                        diag("unresolved references after first dwarf info pass");
 
2383
                        errorexit();
 
2384
                }
 
2385
                if (infoe != cpos()) {
 
2386
                        diag("inconsistent second dwarf info pass");
 
2387
                        errorexit();
 
2388
                }
 
2389
        }
 
2390
        infosize = infoe - infoo;
 
2391
        align(infosize);
 
2392
 
 
2393
        pubnameso  = writepub(ispubname);
 
2394
        pubnamessize  = cpos() - pubnameso;
 
2395
        align(pubnamessize);
 
2396
 
 
2397
        pubtypeso  = writepub(ispubtype);
 
2398
        pubtypessize  = cpos() - pubtypeso;
 
2399
        align(pubtypessize);
 
2400
 
 
2401
        arangeso   = writearanges();
 
2402
        arangessize   = cpos() - arangeso;
 
2403
        align(arangessize);
 
2404
 
 
2405
        gdbscripto = writegdbscript();
 
2406
        gdbscriptsize = cpos() - gdbscripto;
 
2407
        align(gdbscriptsize);
 
2408
}
 
2409
 
 
2410
/*
 
2411
 *  Elf.
 
2412
 */
 
2413
enum
 
2414
{
 
2415
        ElfStrDebugAbbrev,
 
2416
        ElfStrDebugAranges,
 
2417
        ElfStrDebugFrame,
 
2418
        ElfStrDebugInfo,
 
2419
        ElfStrDebugLine,
 
2420
        ElfStrDebugLoc,
 
2421
        ElfStrDebugMacinfo,
 
2422
        ElfStrDebugPubNames,
 
2423
        ElfStrDebugPubTypes,
 
2424
        ElfStrDebugRanges,
 
2425
        ElfStrDebugStr,
 
2426
        ElfStrGDBScripts,
 
2427
        NElfStrDbg
 
2428
};
 
2429
 
 
2430
vlong elfstrdbg[NElfStrDbg];
 
2431
 
 
2432
void
 
2433
dwarfaddshstrings(Sym *shstrtab)
 
2434
{
 
2435
        elfstrdbg[ElfStrDebugAbbrev]   = addstring(shstrtab, ".debug_abbrev");
 
2436
        elfstrdbg[ElfStrDebugAranges]  = addstring(shstrtab, ".debug_aranges");
 
2437
        elfstrdbg[ElfStrDebugFrame]    = addstring(shstrtab, ".debug_frame");
 
2438
        elfstrdbg[ElfStrDebugInfo]     = addstring(shstrtab, ".debug_info");
 
2439
        elfstrdbg[ElfStrDebugLine]     = addstring(shstrtab, ".debug_line");
 
2440
        elfstrdbg[ElfStrDebugLoc]      = addstring(shstrtab, ".debug_loc");
 
2441
        elfstrdbg[ElfStrDebugMacinfo]  = addstring(shstrtab, ".debug_macinfo");
 
2442
        elfstrdbg[ElfStrDebugPubNames] = addstring(shstrtab, ".debug_pubnames");
 
2443
        elfstrdbg[ElfStrDebugPubTypes] = addstring(shstrtab, ".debug_pubtypes");
 
2444
        elfstrdbg[ElfStrDebugRanges]   = addstring(shstrtab, ".debug_ranges");
 
2445
        elfstrdbg[ElfStrDebugStr]      = addstring(shstrtab, ".debug_str");
 
2446
        elfstrdbg[ElfStrGDBScripts]    = addstring(shstrtab, ".debug_gdb_scripts");
 
2447
}
 
2448
 
 
2449
void
 
2450
dwarfaddelfheaders(void)
 
2451
{
 
2452
        ElfShdr *sh;
 
2453
 
 
2454
        sh = newElfShdr(elfstrdbg[ElfStrDebugAbbrev]);
 
2455
        sh->type = SHT_PROGBITS;
 
2456
        sh->off = abbrevo;
 
2457
        sh->size = abbrevsize;
 
2458
        sh->addralign = 1;
 
2459
 
 
2460
        sh = newElfShdr(elfstrdbg[ElfStrDebugLine]);
 
2461
        sh->type = SHT_PROGBITS;
 
2462
        sh->off = lineo;
 
2463
        sh->size = linesize;
 
2464
        sh->addralign = 1;
 
2465
 
 
2466
        sh = newElfShdr(elfstrdbg[ElfStrDebugFrame]);
 
2467
        sh->type = SHT_PROGBITS;
 
2468
        sh->off = frameo;
 
2469
        sh->size = framesize;
 
2470
        sh->addralign = 1;
 
2471
 
 
2472
        sh = newElfShdr(elfstrdbg[ElfStrDebugInfo]);
 
2473
        sh->type = SHT_PROGBITS;
 
2474
        sh->off = infoo;
 
2475
        sh->size = infosize;
 
2476
        sh->addralign = 1;
 
2477
 
 
2478
        if (pubnamessize > 0) {
 
2479
                sh = newElfShdr(elfstrdbg[ElfStrDebugPubNames]);
 
2480
                sh->type = SHT_PROGBITS;
 
2481
                sh->off = pubnameso;
 
2482
                sh->size = pubnamessize;
 
2483
                sh->addralign = 1;
 
2484
        }
 
2485
 
 
2486
        if (pubtypessize > 0) {
 
2487
                sh = newElfShdr(elfstrdbg[ElfStrDebugPubTypes]);
 
2488
                sh->type = SHT_PROGBITS;
 
2489
                sh->off = pubtypeso;
 
2490
                sh->size = pubtypessize;
 
2491
                sh->addralign = 1;
 
2492
        }
 
2493
 
 
2494
        if (arangessize) {
 
2495
                sh = newElfShdr(elfstrdbg[ElfStrDebugAranges]);
 
2496
                sh->type = SHT_PROGBITS;
 
2497
                sh->off = arangeso;
 
2498
                sh->size = arangessize;
 
2499
                sh->addralign = 1;
 
2500
        }
 
2501
 
 
2502
        if (gdbscriptsize) {
 
2503
                sh = newElfShdr(elfstrdbg[ElfStrGDBScripts]);
 
2504
                sh->type = SHT_PROGBITS;
 
2505
                sh->off = gdbscripto;
 
2506
                sh->size = gdbscriptsize;
 
2507
                sh->addralign = 1;
 
2508
        }
 
2509
}
 
2510
 
 
2511
/*
 
2512
 * Macho
 
2513
 */
 
2514
void
 
2515
dwarfaddmachoheaders(void)
 
2516
{
 
2517
        MachoSect *msect;
 
2518
        MachoSeg *ms;
 
2519
        vlong fakestart;
 
2520
        int nsect;
 
2521
 
 
2522
        // Zero vsize segments won't be loaded in memory, even so they
 
2523
        // have to be page aligned in the file.
 
2524
        fakestart = abbrevo & ~0xfff;
 
2525
 
 
2526
        nsect = 4;
 
2527
        if (pubnamessize  > 0)
 
2528
                nsect++;
 
2529
        if (pubtypessize  > 0)
 
2530
                nsect++;
 
2531
        if (arangessize   > 0)
 
2532
                nsect++;
 
2533
        if (gdbscriptsize > 0)
 
2534
                nsect++;
 
2535
 
 
2536
        ms = newMachoSeg("__DWARF", nsect);
 
2537
        ms->fileoffset = fakestart;
 
2538
        ms->filesize = abbrevo-fakestart;
 
2539
 
 
2540
        msect = newMachoSect(ms, "__debug_abbrev");
 
2541
        msect->off = abbrevo;
 
2542
        msect->size = abbrevsize;
 
2543
        ms->filesize += msect->size;
 
2544
 
 
2545
        msect = newMachoSect(ms, "__debug_line");
 
2546
        msect->off = lineo;
 
2547
        msect->size = linesize;
 
2548
        ms->filesize += msect->size;
 
2549
 
 
2550
        msect = newMachoSect(ms, "__debug_frame");
 
2551
        msect->off = frameo;
 
2552
        msect->size = framesize;
 
2553
        ms->filesize += msect->size;
 
2554
 
 
2555
        msect = newMachoSect(ms, "__debug_info");
 
2556
        msect->off = infoo;
 
2557
        msect->size = infosize;
 
2558
        ms->filesize += msect->size;
 
2559
 
 
2560
        if (pubnamessize > 0) {
 
2561
                msect = newMachoSect(ms, "__debug_pubnames");
 
2562
                msect->off = pubnameso;
 
2563
                msect->size = pubnamessize;
 
2564
                ms->filesize += msect->size;
 
2565
        }
 
2566
 
 
2567
        if (pubtypessize > 0) {
 
2568
                msect = newMachoSect(ms, "__debug_pubtypes");
 
2569
                msect->off = pubtypeso;
 
2570
                msect->size = pubtypessize;
 
2571
                ms->filesize += msect->size;
 
2572
        }
 
2573
 
 
2574
        if (arangessize > 0) {
 
2575
                msect = newMachoSect(ms, "__debug_aranges");
 
2576
                msect->off = arangeso;
 
2577
                msect->size = arangessize;
 
2578
                ms->filesize += msect->size;
 
2579
        }
 
2580
 
 
2581
        // TODO(lvd) fix gdb/python to load MachO (16 char section name limit)
 
2582
        if (gdbscriptsize > 0) {
 
2583
                msect = newMachoSect(ms, "__debug_gdb_scripts");
 
2584
                msect->off = gdbscripto;
 
2585
                msect->size = gdbscriptsize;
 
2586
                ms->filesize += msect->size;
 
2587
        }
 
2588
}
 
2589
 
 
2590
/*
 
2591
 * Windows PE
 
2592
 */
 
2593
void
 
2594
dwarfaddpeheaders(void)
 
2595
{
 
2596
        dwarfemitdebugsections();
 
2597
        newPEDWARFSection(".debug_abbrev", abbrevsize);
 
2598
        newPEDWARFSection(".debug_line", linesize);
 
2599
        newPEDWARFSection(".debug_frame", framesize);
 
2600
        newPEDWARFSection(".debug_info", infosize);
 
2601
        if (pubnamessize > 0)
 
2602
                newPEDWARFSection(".debug_pubnames", pubnamessize);
 
2603
        if (pubtypessize > 0)
 
2604
                newPEDWARFSection(".debug_pubtypes", pubtypessize);
 
2605
        if (arangessize > 0)
 
2606
                newPEDWARFSection(".debug_aranges", arangessize);
 
2607
        if (gdbscriptsize > 0)
 
2608
                newPEDWARFSection(".debug_gdb_scripts", gdbscriptsize);
 
2609
}