~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#include        "../ld/elf.h"
20
20
#include        "../ld/macho.h"
21
21
#include        "../ld/pe.h"
 
22
#include        "../../pkg/runtime/typekind.h"
22
23
 
23
24
/*
24
25
 * Offsets and sizes of the debug_* sections in the cout file.
26
27
 
27
28
static vlong abbrevo;
28
29
static vlong abbrevsize;
 
30
static Sym*  abbrevsym;
 
31
static vlong abbrevsympos;
29
32
static vlong lineo;
30
33
static vlong linesize;
 
34
static Sym*  linesym;
 
35
static vlong linesympos;
31
36
static vlong infoo;     // also the base for DWDie->offs and reference attributes.
32
37
static vlong infosize;
 
38
static Sym*  infosym;
 
39
static vlong infosympos;
33
40
static vlong frameo;
34
41
static vlong framesize;
35
42
static vlong pubnameso;
41
48
static vlong gdbscripto;
42
49
static vlong gdbscriptsize;
43
50
 
 
51
static Sym *infosec;
 
52
static vlong inforeloco;
 
53
static vlong inforelocsize;
 
54
 
 
55
static Sym *arangessec;
 
56
static vlong arangesreloco;
 
57
static vlong arangesrelocsize;
 
58
 
 
59
static Sym *linesec;
 
60
static vlong linereloco;
 
61
static vlong linerelocsize;
 
62
 
44
63
static char  gdbscript[1024];
45
64
 
46
65
/*
149
168
        DW_ABRV_IFACETYPE,
150
169
        DW_ABRV_MAPTYPE,
151
170
        DW_ABRV_PTRTYPE,
 
171
        DW_ABRV_BARE_PTRTYPE, // only for void*, no DW_AT_type attr to please gdb 6.
152
172
        DW_ABRV_SLICETYPE,
153
173
        DW_ABRV_STRINGTYPE,
154
174
        DW_ABRV_STRUCTTYPE,
302
322
                DW_AT_type,     DW_FORM_ref_addr,
303
323
                0, 0
304
324
        },
 
325
        /* BARE_PTRTYPE */
 
326
        {
 
327
                DW_TAG_pointer_type, DW_CHILDREN_no,
 
328
                DW_AT_name,     DW_FORM_string,
 
329
                0, 0
 
330
        },
305
331
 
306
332
        /* SLICETYPE */
307
333
        {
484
510
        die->hash = mal(HASHSIZE * sizeof(DWDie*));
485
511
}
486
512
 
 
513
static DWDie*
 
514
walktypedef(DWDie *die)
 
515
{
 
516
        DWAttr *attr;
 
517
 
 
518
        // Resolve typedef if present.
 
519
        if (die->abbrev == DW_ABRV_TYPEDECL) {
 
520
                for (attr = die->attr; attr; attr = attr->link) {
 
521
                        if (attr->atr == DW_AT_type && attr->cls == DW_CLS_REFERENCE && attr->data != nil) {
 
522
                                return (DWDie*)attr->data;
 
523
                        }
 
524
                }
 
525
        }
 
526
        return die;
 
527
}
 
528
 
487
529
// Find child by AT_name using hashtable if available or linear scan
488
530
// if not.
489
531
static DWDie*
490
532
find(DWDie *die, char* name)
491
533
{
492
 
        DWDie *a, *b;
 
534
        DWDie *a, *b, *die2;
493
535
        int h;
494
536
 
 
537
top:
495
538
        if (die->hash == nil) {
496
539
                for (a = die->child; a != nil; a = a->link)
497
540
                        if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
498
541
                                return a;
499
 
                return nil;
 
542
                goto notfound;
500
543
        }
501
544
 
502
545
        h = hashstr(name);
503
546
        a = die->hash[h];
504
547
 
505
548
        if (a == nil)
506
 
                return nil;
 
549
                goto notfound;
507
550
 
508
551
 
509
552
        if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
521
564
                a = b;
522
565
                b = b->hlink;
523
566
        }
 
567
 
 
568
notfound:
 
569
        die2 = walktypedef(die);
 
570
        if(die2 != die) {
 
571
                die = die2;
 
572
                goto top;
 
573
        }
 
574
 
524
575
        return nil;
525
576
}
526
577
 
530
581
        DWDie *r;
531
582
        r = find(die, name);
532
583
        if (r == nil) {
533
 
                diag("dwarf find: %s has no %s", getattr(die, DW_AT_name)->data, name);
 
584
                diag("dwarf find: %s %p has no %s", getattr(die, DW_AT_name)->data, die, name);
534
585
                errorexit();
535
586
        }
536
587
        return r;
537
588
}
538
589
 
 
590
static void
 
591
adddwarfrel(Sym* sec, Sym* sym, vlong offsetbase, int siz, vlong addend)
 
592
{
 
593
        Reloc *r;
 
594
 
 
595
        r = addrel(sec);
 
596
        r->sym = sym;
 
597
        r->xsym = sym;
 
598
        r->off = cpos() - offsetbase;
 
599
        r->siz = siz;
 
600
        r->type = D_ADDR;
 
601
        r->add = addend;
 
602
        r->xadd = addend;
 
603
        if(iself && thechar == '6')
 
604
                addend = 0;
 
605
        switch(siz) {
 
606
        case 4:
 
607
                LPUT(addend);
 
608
                break;
 
609
        case 8:
 
610
                VPUT(addend);
 
611
                break;
 
612
        default:
 
613
                diag("bad size in adddwarfrel");
 
614
                break;
 
615
        }
 
616
}
 
617
 
539
618
static DWAttr*
540
619
newrefattr(DWDie *die, uint8 attr, DWDie* ref)
541
620
{
547
626
static int fwdcount;
548
627
 
549
628
static void
550
 
putattr(int form, int cls, vlong value, char *data)
 
629
putattr(int abbrev, int form, int cls, vlong value, char *data)
551
630
{
 
631
        vlong off;
 
632
 
552
633
        switch(form) {
553
634
        case DW_FORM_addr:      // address
 
635
                if(linkmode == LinkExternal) {
 
636
                        value -= ((Sym*)data)->value;
 
637
                        adddwarfrel(infosec, (Sym*)data, infoo, PtrSize, value);
 
638
                        break;
 
639
                }
554
640
                addrput(value);
555
641
                break;
556
642
 
557
643
        case DW_FORM_block1:    // block
 
644
                if(cls == DW_CLS_ADDRESS) {
 
645
                        cput(1+PtrSize);
 
646
                        cput(DW_OP_addr);
 
647
                        if(linkmode == LinkExternal) {
 
648
                                value -= ((Sym*)data)->value;
 
649
                                adddwarfrel(infosec, (Sym*)data, infoo, PtrSize, value);
 
650
                                break;
 
651
                        }
 
652
                        addrput(value);
 
653
                        break;
 
654
                }
558
655
                value &= 0xff;
559
656
                cput(value);
560
657
                while(value--)
590
687
                break;
591
688
 
592
689
        case DW_FORM_data4:     // constant, {line,loclist,mac,rangelist}ptr
 
690
                if(linkmode == LinkExternal && cls == DW_CLS_PTR) {
 
691
                        adddwarfrel(infosec, linesym, infoo, 4, value);
 
692
                        break;
 
693
                }
593
694
                LPUT(value);
594
695
                break;
595
696
 
614
715
                break;
615
716
 
616
717
        case DW_FORM_ref_addr:  // reference to a DIE in the .info section
 
718
                // In DWARF 2 (which is what we claim to generate),
 
719
                // the ref_addr is the same size as a normal address.
 
720
                // In DWARF 3 it is always 32 bits, unless emitting a large
 
721
                // (> 4 GB of debug info aka "64-bit") unit, which we don't implement.
617
722
                if (data == nil) {
618
 
                        diag("dwarf: null reference");
619
 
                        LPUT(0);  // invalid dwarf, gdb will complain.
 
723
                        diag("dwarf: null reference in %d", abbrev);
 
724
                        if(PtrSize == 8)
 
725
                                VPUT(0); // invalid dwarf, gdb will complain.
 
726
                        else
 
727
                                LPUT(0); // invalid dwarf, gdb will complain.
620
728
                } else {
621
 
                        if (((DWDie*)data)->offs == 0)
 
729
                        off = ((DWDie*)data)->offs;
 
730
                        if (off == 0)
622
731
                                fwdcount++;
623
 
                        LPUT(((DWDie*)data)->offs);
 
732
                        if(linkmode == LinkExternal) {
 
733
                                adddwarfrel(infosec, infosym, infoo, PtrSize, off);
 
734
                                break;
 
735
                        }
 
736
                        addrput(off);
624
737
                }
625
738
                break;
626
739
 
653
766
 
654
767
        for(af = abbrevs[abbrev].attr; af->attr; af++)
655
768
                if (attrs[af->attr])
656
 
                        putattr(af->form,
 
769
                        putattr(abbrev, af->form,
657
770
                                attrs[af->attr]->cls,
658
771
                                attrs[af->attr]->value,
659
772
                                attrs[af->attr]->data);
660
773
                else
661
 
                        putattr(af->form, 0, 0, 0);
 
774
                        putattr(abbrev, af->form, 0, 0, nil);
662
775
}
663
776
 
664
777
static void putdie(DWDie* die);
728
841
// GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a
729
842
// location expression that evals to a const.
730
843
static void
731
 
newabslocexprattr(DWDie *die, vlong addr)
732
 
{
733
 
        char block[10];
734
 
        int i;
735
 
 
736
 
        i = 0;
737
 
        block[i++] = DW_OP_constu;
738
 
        i += uleb128enc(addr, block+i);
739
 
        newattr(die, DW_AT_location, DW_CLS_BLOCK, i, mal(i));
740
 
        memmove(die->attr->data, block, i);
741
 
}
742
 
 
743
 
// Decoding the type.* symbols.  This has to be in sync with
744
 
// ../../pkg/runtime/type.go, or more specificaly, with what
745
 
// ../gc/reflect.c stuffs in these.
746
 
 
747
 
enum {
748
 
        KindBool = 1,
749
 
        KindInt,
750
 
        KindInt8,
751
 
        KindInt16,
752
 
        KindInt32,
753
 
        KindInt64,
754
 
        KindUint,
755
 
        KindUint8,
756
 
        KindUint16,
757
 
        KindUint32,
758
 
        KindUint64,
759
 
        KindUintptr,
760
 
        KindFloat32,
761
 
        KindFloat64,
762
 
        KindComplex64,
763
 
        KindComplex128,
764
 
        KindArray,
765
 
        KindChan,
766
 
        KindFunc,
767
 
        KindInterface,
768
 
        KindMap,
769
 
        KindPtr,
770
 
        KindSlice,
771
 
        KindString,
772
 
        KindStruct,
773
 
        KindUnsafePointer,
774
 
 
775
 
        KindNoPointers = 1<<7,
776
 
 
777
 
        // size of Type interface header + CommonType structure.
778
 
        CommonSize = 2*PtrSize+ 5*PtrSize + 8,
779
 
};
780
 
 
781
 
static Reloc*
782
 
decode_reloc(Sym *s, int32 off)
783
 
{
784
 
        int i;
785
 
 
786
 
        for (i = 0; i < s->nr; i++)
787
 
                if (s->r[i].off == off)
788
 
                        return s->r + i;
789
 
        return nil;
790
 
}
791
 
 
792
 
static Sym*
793
 
decode_reloc_sym(Sym *s, int32 off)
794
 
{
795
 
        Reloc *r;
796
 
 
797
 
        r = decode_reloc(s,off);
798
 
        if (r == nil)
799
 
                return nil;
800
 
        return r->sym;
801
 
}
802
 
 
803
 
static uvlong
804
 
decode_inuxi(uchar* p, int sz)
805
 
{
806
 
        uint64 v;
807
 
        uint32 l;
808
 
        uchar *cast, *inuxi;
809
 
        int i;
810
 
 
811
 
        v = l = 0;
812
 
        cast = nil;
813
 
        inuxi = nil;
814
 
        switch (sz) {
815
 
        case 2:
816
 
                cast = (uchar*)&l;
817
 
                inuxi = inuxi2;
818
 
                break;
819
 
        case 4:
820
 
                cast = (uchar*)&l;
821
 
                inuxi = inuxi4;
822
 
                break;
823
 
        case 8:
824
 
                cast = (uchar*)&v;
825
 
                inuxi = inuxi8;
826
 
                break;
827
 
        default:
828
 
                diag("dwarf: decode inuxi %d", sz);
829
 
                errorexit();
830
 
        }
831
 
        for (i = 0; i < sz; i++)
832
 
                cast[inuxi[i]] = p[i];
833
 
        if (sz == 8)
834
 
                return v;
835
 
        return l;
836
 
}
837
 
 
838
 
// Type.commonType.kind
839
 
static uint8
840
 
decodetype_kind(Sym *s)
841
 
{
842
 
        return s->p[3*PtrSize + 7] & ~KindNoPointers;   //  0x13 / 0x1f
843
 
}
844
 
 
845
 
// Type.commonType.size
846
 
static vlong
847
 
decodetype_size(Sym *s)
848
 
{
849
 
        return decode_inuxi(s->p + 2*PtrSize, PtrSize);  // 0x8 / 0x10
850
 
}
851
 
 
852
 
// Type.ArrayType.elem and Type.SliceType.Elem
853
 
static Sym*
854
 
decodetype_arrayelem(Sym *s)
855
 
{
856
 
        return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
857
 
}
858
 
 
859
 
static vlong
860
 
decodetype_arraylen(Sym *s)
861
 
{
862
 
        return decode_inuxi(s->p + CommonSize+PtrSize, PtrSize);
863
 
}
864
 
 
865
 
// Type.PtrType.elem
866
 
static Sym*
867
 
decodetype_ptrelem(Sym *s)
868
 
{
869
 
        return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
870
 
}
871
 
 
872
 
// Type.MapType.key, elem
873
 
static Sym*
874
 
decodetype_mapkey(Sym *s)
875
 
{
876
 
        return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
877
 
}
878
 
static Sym*
879
 
decodetype_mapvalue(Sym *s)
880
 
{
881
 
        return decode_reloc_sym(s, CommonSize+PtrSize); // 0x20 / 0x38
882
 
}
883
 
 
884
 
// Type.ChanType.elem
885
 
static Sym*
886
 
decodetype_chanelem(Sym *s)
887
 
{
888
 
        return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
889
 
}
890
 
 
891
 
// Type.FuncType.dotdotdot
892
 
static int
893
 
decodetype_funcdotdotdot(Sym *s)
894
 
{
895
 
        return s->p[CommonSize];
896
 
}
897
 
 
898
 
// Type.FuncType.in.len
899
 
static int
900
 
decodetype_funcincount(Sym *s)
901
 
{
902
 
        return decode_inuxi(s->p + CommonSize+2*PtrSize, 4);
903
 
}
904
 
 
905
 
static int
906
 
decodetype_funcoutcount(Sym *s)
907
 
{
908
 
        return decode_inuxi(s->p + CommonSize+3*PtrSize + 2*4, 4);
909
 
}
910
 
 
911
 
static Sym*
912
 
decodetype_funcintype(Sym *s, int i)
913
 
{
914
 
        Reloc *r;
915
 
 
916
 
        r = decode_reloc(s, CommonSize + PtrSize);
917
 
        if (r == nil)
918
 
                return nil;
919
 
        return decode_reloc_sym(r->sym, r->add + i * PtrSize);
920
 
}
921
 
 
922
 
static Sym*
923
 
decodetype_funcouttype(Sym *s, int i)
924
 
{
925
 
        Reloc *r;
926
 
 
927
 
        r = decode_reloc(s, CommonSize + 2*PtrSize + 2*4);
928
 
        if (r == nil)
929
 
                return nil;
930
 
        return decode_reloc_sym(r->sym, r->add + i * PtrSize);
931
 
}
932
 
 
933
 
// Type.StructType.fields.Slice::len
934
 
static int
935
 
decodetype_structfieldcount(Sym *s)
936
 
{
937
 
        return decode_inuxi(s->p + CommonSize + PtrSize, 4);
938
 
}
939
 
 
940
 
enum {
941
 
        StructFieldSize = 5*PtrSize
942
 
};
943
 
// Type.StructType.fields[]-> name, typ and offset.
944
 
static char*
945
 
decodetype_structfieldname(Sym *s, int i)
946
 
{
947
 
        Reloc *r;
948
 
 
949
 
        // go.string."foo"  0x28 / 0x40
950
 
        s = decode_reloc_sym(s, CommonSize + PtrSize + 2*4 + i*StructFieldSize);
951
 
        if (s == nil)                   // embedded structs have a nil name.
952
 
                return nil;
953
 
        r = decode_reloc(s, 0);         // s has a pointer to the string data at offset 0
954
 
        if (r == nil)                   // shouldn't happen.
955
 
                return nil;
956
 
        return (char*) r->sym->p + r->add;      // the c-string
957
 
}
958
 
 
959
 
static Sym*
960
 
decodetype_structfieldtype(Sym *s, int i)
961
 
{
962
 
        return decode_reloc_sym(s, CommonSize + PtrSize + 2*4 + i*StructFieldSize + 2*PtrSize);
963
 
}
964
 
 
965
 
static vlong
966
 
decodetype_structfieldoffs(Sym *s, int i)
967
 
{
968
 
        return decode_inuxi(s->p + CommonSize + PtrSize + 2*4 + i*StructFieldSize + 4*PtrSize, 4);
969
 
}
970
 
 
971
 
// InterfaceTYpe.methods.len
972
 
static vlong
973
 
decodetype_ifacemethodcount(Sym *s)
974
 
{
975
 
        return decode_inuxi(s->p + CommonSize + PtrSize, 4);
 
844
newabslocexprattr(DWDie *die, vlong addr, Sym *sym)
 
845
{
 
846
        newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, (char*)sym);
976
847
}
977
848
 
978
849
 
1000
871
        return s;
1001
872
}
1002
873
 
 
874
static void
 
875
dotypedef(DWDie *parent, char *name, DWDie *def)
 
876
{
 
877
        DWDie *die;
 
878
 
 
879
        // Only emit typedefs for real names.
 
880
        if(strncmp(name, "map[", 4) == 0)
 
881
                return;
 
882
        if(strncmp(name, "struct {", 8) == 0)
 
883
                return;
 
884
        if(strncmp(name, "chan ", 5) == 0)
 
885
                return;
 
886
        if(*name == '[' || *name == '*')
 
887
                return;
 
888
        if(def == nil)
 
889
                diag("dwarf: bad def in dotypedef");
 
890
 
 
891
        // The typedef entry must be created after the def,
 
892
        // so that future lookups will find the typedef instead
 
893
        // of the real definition. This hooks the typedef into any
 
894
        // circular definition loops, so that gdb can understand them.
 
895
        die = newdie(parent, DW_ABRV_TYPEDECL, name);
 
896
        newrefattr(die, DW_AT_type, def);
 
897
}
 
898
 
1003
899
// Define gotype, for composite ones recurse into constituents.
1004
900
static DWDie*
1005
901
defgotype(Sym *gotype)
1074
970
 
1075
971
        case KindArray:
1076
972
                die = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, name);
 
973
                dotypedef(&dwtypes, name, die);
1077
974
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
1078
975
                s = decodetype_arrayelem(gotype);
1079
976
                newrefattr(die, DW_AT_type, defgotype(s));
1091
988
 
1092
989
        case KindFunc:
1093
990
                die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name);
 
991
                dotypedef(&dwtypes, name, die);
1094
992
                newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "void"));
1095
993
                nfields = decodetype_funcincount(gotype);
1096
994
                for (i = 0; i < nfields; i++) {
1110
1008
 
1111
1009
        case KindInterface:
1112
1010
                die = newdie(&dwtypes, DW_ABRV_IFACETYPE, name);
 
1011
                dotypedef(&dwtypes, name, die);
1113
1012
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
1114
1013
                nfields = decodetype_ifacemethodcount(gotype);
1115
1014
                if (nfields == 0)
1129
1028
 
1130
1029
        case KindPtr:
1131
1030
                die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name);
 
1031
                dotypedef(&dwtypes, name, die);
1132
1032
                s = decodetype_ptrelem(gotype);
1133
1033
                newrefattr(die, DW_AT_type, defgotype(s));
1134
1034
                break;
1135
1035
 
1136
1036
        case KindSlice:
1137
1037
                die = newdie(&dwtypes, DW_ABRV_SLICETYPE, name);
 
1038
                dotypedef(&dwtypes, name, die);
1138
1039
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
1139
1040
                s = decodetype_arrayelem(gotype);
1140
1041
                newrefattr(die, DW_AT_internal_elem_type, defgotype(s));
1147
1048
 
1148
1049
        case KindStruct:
1149
1050
                die = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, name);
 
1051
                dotypedef(&dwtypes, name, die);
1150
1052
                newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
1151
1053
                nfields = decodetype_structfieldcount(gotype);
1152
1054
                for (i = 0; i < nfields; i++) {
1161
1063
                break;
1162
1064
 
1163
1065
        case KindUnsafePointer:
1164
 
                die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name);
1165
 
                newrefattr(die, DW_AT_type, find(&dwtypes, "void"));
 
1066
                die = newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, name);
1166
1067
                break;
1167
1068
 
1168
1069
        default:
1232
1133
{
1233
1134
        DWDie *prototype;
1234
1135
 
1235
 
        prototype = defgotype(lookup_or_diag("type.runtime._string"));
 
1136
        prototype = walktypedef(defgotype(lookup_or_diag("type.runtime._string")));
1236
1137
        if (prototype == nil)
1237
1138
                return;
1238
1139
 
1248
1149
{
1249
1150
        DWDie *prototype, *elem;
1250
1151
 
1251
 
        prototype = defgotype(lookup_or_diag("type.runtime.slice"));
 
1152
        prototype = walktypedef(defgotype(lookup_or_diag("type.runtime.slice")));
1252
1153
        if (prototype == nil)
1253
1154
                return;
1254
1155
 
1276
1177
        return n;
1277
1178
}
1278
1179
 
1279
 
 
1280
1180
// synthesizemaptypes is way too closely married to runtime/hashmap.c
1281
1181
enum {
1282
 
        MaxValsize = 256 - 64
 
1182
        MaxKeySize = 128,
 
1183
        MaxValSize = 128,
 
1184
        BucketSize = 8,
1283
1185
};
1284
1186
 
1285
1187
static void
1286
1188
synthesizemaptypes(DWDie *die)
1287
1189
{
1288
1190
 
1289
 
        DWDie *hash, *hash_subtable, *hash_entry,
1290
 
                *dwh, *dwhs, *dwhe, *dwhash, *keytype, *valtype, *fld;
1291
 
        int hashsize, keysize, valsize, datsize, valsize_in_hash, datavo;
 
1191
        DWDie *hash, *bucket, *dwh, *dwhk, *dwhv, *dwhb, *keytype, *valtype, *fld;
 
1192
        int indirect_key, indirect_val;
 
1193
        int keysize, valsize;
1292
1194
        DWAttr *a;
1293
1195
 
1294
 
        hash            = defgotype(lookup_or_diag("type.runtime.hmap"));
1295
 
        hash_subtable   = defgotype(lookup_or_diag("type.runtime.hash_subtable"));
1296
 
        hash_entry      = defgotype(lookup_or_diag("type.runtime.hash_entry"));
1297
 
 
1298
 
        if (hash == nil || hash_subtable == nil || hash_entry == nil)
1299
 
                return;
1300
 
 
1301
 
        dwhash = (DWDie*)getattr(find_or_diag(hash_entry, "hash"), DW_AT_type)->data;
1302
 
        if (dwhash == nil)
1303
 
                return;
1304
 
 
1305
 
        hashsize = getattr(dwhash, DW_AT_byte_size)->value;
 
1196
        hash            = walktypedef(defgotype(lookup_or_diag("type.runtime.hmap")));
 
1197
        bucket          = walktypedef(defgotype(lookup_or_diag("type.runtime.bucket")));
 
1198
 
 
1199
        if (hash == nil)
 
1200
                return;
1306
1201
 
1307
1202
        for (; die != nil; die = die->link) {
1308
1203
                if (die->abbrev != DW_ABRV_MAPTYPE)
1309
1204
                        continue;
1310
1205
 
1311
 
                keytype = (DWDie*) getattr(die, DW_AT_internal_key_type)->data;
1312
 
                valtype = (DWDie*) getattr(die, DW_AT_internal_val_type)->data;
 
1206
                keytype = walktypedef((DWDie*) getattr(die, DW_AT_internal_key_type)->data);
 
1207
                valtype = walktypedef((DWDie*) getattr(die, DW_AT_internal_val_type)->data);
1313
1208
 
 
1209
                // compute size info like hashmap.c does.
1314
1210
                a = getattr(keytype, DW_AT_byte_size);
1315
1211
                keysize = a ? a->value : PtrSize;  // We don't store size with Pointers
1316
 
 
1317
1212
                a = getattr(valtype, DW_AT_byte_size);
1318
1213
                valsize = a ? a->value : PtrSize;
1319
 
 
1320
 
                // This is what happens in hash_init and makemap_c
1321
 
                valsize_in_hash = valsize;
1322
 
                if (valsize > MaxValsize)
1323
 
                        valsize_in_hash = PtrSize;
1324
 
                datavo = keysize;
1325
 
                if (valsize_in_hash >= PtrSize)
1326
 
                        datavo = rnd(keysize, PtrSize);
1327
 
                datsize = datavo + valsize_in_hash;
1328
 
                if (datsize < PtrSize)
1329
 
                        datsize = PtrSize;
1330
 
                datsize = rnd(datsize, PtrSize);
1331
 
 
1332
 
                // Construct struct hash_entry<K,V>
1333
 
                dwhe = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
1334
 
                        mkinternaltypename("hash_entry",
1335
 
                                getattr(keytype, DW_AT_name)->data,
1336
 
                                getattr(valtype, DW_AT_name)->data));
1337
 
 
1338
 
                fld = newdie(dwhe, DW_ABRV_STRUCTFIELD, "hash");
1339
 
                newrefattr(fld, DW_AT_type, dwhash);
1340
 
                newmemberoffsetattr(fld, 0);
1341
 
 
1342
 
                fld = newdie(dwhe, DW_ABRV_STRUCTFIELD, "key");
1343
 
                newrefattr(fld, DW_AT_type, keytype);
1344
 
                newmemberoffsetattr(fld, hashsize);
1345
 
 
1346
 
                fld = newdie(dwhe, DW_ABRV_STRUCTFIELD, "val");
1347
 
                if (valsize > MaxValsize)
1348
 
                        valtype = defptrto(valtype);
1349
 
                newrefattr(fld, DW_AT_type, valtype);
1350
 
                newmemberoffsetattr(fld, hashsize + datavo);
1351
 
                newattr(dwhe, DW_AT_byte_size, DW_CLS_CONSTANT, hashsize + datsize, nil);
1352
 
 
1353
 
                // Construct hash_subtable<hash_entry<K,V>>
1354
 
                dwhs = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
1355
 
                        mkinternaltypename("hash_subtable",
1356
 
                                getattr(keytype, DW_AT_name)->data,
1357
 
                                getattr(valtype, DW_AT_name)->data));
1358
 
                copychildren(dwhs, hash_subtable);
1359
 
                substitutetype(dwhs, "last", defptrto(dwhe));
1360
 
                substitutetype(dwhs, "entry", dwhe);  // todo: []hash_entry with dynamic size
1361
 
                newattr(dwhs, DW_AT_byte_size, DW_CLS_CONSTANT,
1362
 
                        getattr(hash_subtable, DW_AT_byte_size)->value, nil);
 
1214
                indirect_key = 0;
 
1215
                indirect_val = 0;
 
1216
                if(keysize > MaxKeySize) {
 
1217
                        keysize = PtrSize;
 
1218
                        indirect_key = 1;
 
1219
                }
 
1220
                if(valsize > MaxValSize) {
 
1221
                        valsize = PtrSize;
 
1222
                        indirect_val = 1;
 
1223
                }
 
1224
 
 
1225
                // Construct type to represent an array of BucketSize keys
 
1226
                dwhk = newdie(&dwtypes, DW_ABRV_ARRAYTYPE,
 
1227
                              mkinternaltypename("[]key",
 
1228
                                                 getattr(keytype, DW_AT_name)->data, nil));
 
1229
                newattr(dwhk, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize * keysize, 0);
 
1230
                newrefattr(dwhk, DW_AT_type, indirect_key ? defptrto(keytype) : keytype);
 
1231
                fld = newdie(dwhk, DW_ABRV_ARRAYRANGE, "size");
 
1232
                newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, BucketSize, 0);
 
1233
                newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
 
1234
                
 
1235
                // Construct type to represent an array of BucketSize values
 
1236
                dwhv = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, 
 
1237
                              mkinternaltypename("[]val",
 
1238
                                                 getattr(valtype, DW_AT_name)->data, nil));
 
1239
                newattr(dwhv, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize * valsize, 0);
 
1240
                newrefattr(dwhv, DW_AT_type, indirect_val ? defptrto(valtype) : valtype);
 
1241
                fld = newdie(dwhv, DW_ABRV_ARRAYRANGE, "size");
 
1242
                newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, BucketSize, 0);
 
1243
                newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
 
1244
 
 
1245
                // Construct bucket<K,V>
 
1246
                dwhb = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
 
1247
                              mkinternaltypename("bucket",
 
1248
                                                 getattr(keytype, DW_AT_name)->data,
 
1249
                                                 getattr(valtype, DW_AT_name)->data));
 
1250
                copychildren(dwhb, bucket);
 
1251
                fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "keys");
 
1252
                newrefattr(fld, DW_AT_type, dwhk);
 
1253
                newmemberoffsetattr(fld, BucketSize + PtrSize);
 
1254
                fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "values");
 
1255
                newrefattr(fld, DW_AT_type, dwhv);
 
1256
                newmemberoffsetattr(fld, BucketSize + PtrSize + BucketSize * keysize);
 
1257
                newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize + PtrSize + BucketSize * keysize + BucketSize * valsize, 0);
 
1258
                substitutetype(dwhb, "overflow", defptrto(dwhb));
1363
1259
 
1364
1260
                // Construct hash<K,V>
1365
1261
                dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
1367
1263
                                getattr(keytype, DW_AT_name)->data,
1368
1264
                                getattr(valtype, DW_AT_name)->data));
1369
1265
                copychildren(dwh, hash);
1370
 
                substitutetype(dwh, "st", defptrto(dwhs));
 
1266
                substitutetype(dwh, "buckets", defptrto(dwhb));
 
1267
                substitutetype(dwh, "oldbuckets", defptrto(dwhb));
1371
1268
                newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT,
1372
1269
                        getattr(hash, DW_AT_byte_size)->value, nil);
1373
1270
 
 
1271
                // make map type a pointer to hash<K,V>
1374
1272
                newrefattr(die, DW_AT_type, defptrto(dwh));
1375
1273
        }
1376
1274
}
1383
1281
        DWAttr *a;
1384
1282
        int elemsize, sudogsize;
1385
1283
 
1386
 
        sudog = defgotype(lookup_or_diag("type.runtime.sudog"));
1387
 
        waitq = defgotype(lookup_or_diag("type.runtime.waitq"));
1388
 
        hchan = defgotype(lookup_or_diag("type.runtime.hchan"));
 
1284
        sudog = walktypedef(defgotype(lookup_or_diag("type.runtime.sudog")));
 
1285
        waitq = walktypedef(defgotype(lookup_or_diag("type.runtime.waitq")));
 
1286
        hchan = walktypedef(defgotype(lookup_or_diag("type.runtime.hchan")));
1389
1287
        if (sudog == nil || waitq == nil || hchan == nil)
1390
1288
                return;
1391
1289
 
1454
1352
        case 'D':
1455
1353
        case 'B':
1456
1354
                dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s);
1457
 
                newabslocexprattr(dv, v);
 
1355
                newabslocexprattr(dv, v, sym);
1458
1356
                if (ver == 0)
1459
1357
                        newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0);
1460
1358
                // fallthrough
1494
1392
        if (n >= ftabsize) {
1495
1393
                s = ftabsize;
1496
1394
                ftabsize = 1 + n + (n >> 2);
1497
 
                ftab = realloc(ftab, ftabsize * sizeof(ftab[0]));
 
1395
                ftab = erealloc(ftab, ftabsize * sizeof(ftab[0]));
1498
1396
                memset(ftab + s, 0, (ftabsize - s) * sizeof(ftab[0]));
1499
1397
        }
1500
1398
 
1531
1429
                return 0;
1532
1430
 
1533
1431
        r = malloc(len + 1);
 
1432
        if(r == nil) {
 
1433
                diag("out of memory");
 
1434
                errorexit();
 
1435
        }
1534
1436
        rb = r;
1535
1437
        re = rb + len + 1;
1536
1438
 
1572
1474
 
1573
1475
        if (histfilesize == histfilecap) {
1574
1476
                histfilecap = 2 * histfilecap + 2;
1575
 
                histfile = realloc(histfile, histfilecap * sizeof(char*));
 
1477
                histfile = erealloc(histfile, histfilecap * sizeof(char*));
1576
1478
        }
1577
1479
        if (histfilesize == 0)
1578
1480
                histfile[histfilesize++] = "<eof>";
1642
1544
                includestacksize += 1;
1643
1545
                includestacksize <<= 2;
1644
1546
//              print("checknesting: growing to %d\n", includestacksize);
1645
 
                includestack = realloc(includestack, includestacksize * sizeof *includestack);         
 
1547
                includestack = erealloc(includestack, includestacksize * sizeof *includestack);        
1646
1548
        }
1647
1549
}
1648
1550
 
1709
1611
                        continue;
1710
1612
                if (linehist == 0 || linehist->absline != absline) {
1711
1613
                        Linehist* lh = malloc(sizeof *lh);
 
1614
                        if(lh == nil) {
 
1615
                                diag("out of memory");
 
1616
                                errorexit();
 
1617
                        }
1712
1618
                        lh->link = linehist;
1713
1619
                        lh->absline = absline;
1714
1620
                        linehist = lh;
1807
1713
 
1808
1714
// flush previous compilation unit.
1809
1715
static void
1810
 
flushunit(DWDie *dwinfo, vlong pc, vlong unitstart, int32 header_length)
 
1716
flushunit(DWDie *dwinfo, vlong pc, Sym *pcsym, vlong unitstart, int32 header_length)
1811
1717
{
1812
1718
        vlong here;
1813
1719
 
1814
1720
        if (dwinfo != nil && pc != 0) {
1815
 
                newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, 0);
 
1721
                newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, (char*)pcsym);
1816
1722
        }
1817
1723
 
1818
1724
        if (unitstart >= 0) {
1823
1729
                here = cpos();
1824
1730
                cseek(unitstart);
1825
1731
                LPUT(here - unitstart - sizeof(int32));  // unit_length
1826
 
                WPUT(3);  // dwarf version
 
1732
                WPUT(2);  // dwarf version
1827
1733
                LPUT(header_length); // header length starting here
1828
1734
                cseek(here);
1829
1735
        }
1833
1739
writelines(void)
1834
1740
{
1835
1741
        Prog *q;
1836
 
        Sym *s;
 
1742
        Sym *s, *epcs;
1837
1743
        Auto *a;
1838
1744
        vlong unitstart, headerend, offs;
1839
1745
        vlong pc, epc, lc, llc, lline;
1844
1750
        DWDie *varhash[HASHSIZE];
1845
1751
        char *n, *nn;
1846
1752
 
 
1753
        if(linesec == S)
 
1754
                linesec = lookup(".dwarfline", 0);
 
1755
        linesec->nr = 0;
 
1756
 
1847
1757
        unitstart = -1;
1848
1758
        headerend = -1;
1849
1759
        pc = 0;
1850
1760
        epc = 0;
 
1761
        epcs = S;
1851
1762
        lc = 1;
1852
1763
        llc = 1;
1853
1764
        currfile = -1;
1863
1774
                // we're entering a new compilation unit
1864
1775
 
1865
1776
                if (inithist(s->autom)) {
1866
 
                        flushunit(dwinfo, epc, unitstart, headerend - unitstart - 10);
 
1777
                        flushunit(dwinfo, epc, epcs, unitstart, headerend - unitstart - 10);
1867
1778
                        unitstart = cpos();
1868
1779
 
1869
1780
                        if(debug['v'] > 1) {
1877
1788
                        lang = guesslang(histfile[1]);
1878
1789
                        finddebugruntimepath();
1879
1790
 
1880
 
                        dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, strdup(histfile[1]));
 
1791
                        dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, estrdup(histfile[1]));
1881
1792
                        newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT,lang, 0);
1882
1793
                        newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart - lineo, 0);
1883
 
                        newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s->text->pc, 0);
 
1794
                        newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s->text->pc, (char*)s);
1884
1795
 
1885
1796
                        // Write .debug_line Line Number Program Header (sec 6.2.4)
1886
1797
                        // Fields marked with (*) must be changed for 64-bit dwarf
1887
1798
                        LPUT(0);   // unit_length (*), will be filled in by flushunit.
1888
 
                        WPUT(3);   // dwarf version (appendix F)
 
1799
                        WPUT(2);   // dwarf version (appendix F)
1889
1800
                        LPUT(0);   // header_length (*), filled in by flushunit.
1890
1801
                        // cpos == unitstart + 4 + 2 + 4
1891
1802
                        cput(1);   // minimum_instruction_length
1909
1820
 
1910
1821
                        pc = s->text->pc;
1911
1822
                        epc = pc;
 
1823
                        epcs = s;
1912
1824
                        currfile = 1;
1913
1825
                        lc = 1;
1914
1826
                        llc = 1;
1916
1828
                        cput(0);  // start extended opcode
1917
1829
                        uleb128put(1 + PtrSize);
1918
1830
                        cput(DW_LNE_set_address);
1919
 
                        addrput(pc);
 
1831
 
 
1832
                        if(linkmode == LinkExternal)
 
1833
                                adddwarfrel(linesec, s, lineo, PtrSize, 0);
 
1834
                        else
 
1835
                                addrput(pc);
1920
1836
                }
1921
1837
                if(s->text == nil)
1922
1838
                        continue;
1927
1843
                }
1928
1844
 
1929
1845
                dwfunc = newdie(dwinfo, DW_ABRV_FUNCTION, s->name);
1930
 
                newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s->value, 0);
 
1846
                newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s->value, (char*)s);
1931
1847
                epc = s->value + s->size;
1932
 
                newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, 0);
 
1848
                newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, (char*)s);
1933
1849
                if (s->version == 0)
1934
1850
                        newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0);
1935
1851
 
2011
1927
                dwfunc->hash = nil;
2012
1928
        }
2013
1929
 
2014
 
        flushunit(dwinfo, epc, unitstart, headerend - unitstart - 10);
 
1930
        flushunit(dwinfo, epc, epcs, unitstart, headerend - unitstart - 10);
2015
1931
        linesize = cpos() - lineo;
2016
1932
}
2017
1933
 
2135
2051
        vlong unitstart, here;
2136
2052
 
2137
2053
        fwdcount = 0;
 
2054
        if (infosec == S)
 
2055
                infosec = lookup(".dwarfinfo", 0);
 
2056
        infosec->nr = 0;
 
2057
 
 
2058
        if(arangessec == S)
 
2059
                arangessec = lookup(".dwarfaranges", 0);
 
2060
        arangessec->nr = 0;
2138
2061
 
2139
2062
        for (compunit = dwroot.child; compunit; compunit = compunit->link) {
2140
2063
                unitstart = cpos();
2143
2066
                // Fields marked with (*) must be changed for 64-bit dwarf
2144
2067
                // This must match COMPUNITHEADERSIZE above.
2145
2068
                LPUT(0);        // unit_length (*), will be filled in later.
2146
 
                WPUT(3);        // dwarf version (appendix F)
2147
 
                LPUT(0);        // debug_abbrev_offset (*)
 
2069
                WPUT(2);        // dwarf version (appendix F)
 
2070
 
 
2071
                // debug_abbrev_offset (*)
 
2072
                if(linkmode == LinkExternal)
 
2073
                        adddwarfrel(infosec, abbrevsym, infoo, 4, 0);
 
2074
                else
 
2075
                        LPUT(0);
 
2076
 
2148
2077
                cput(PtrSize);  // address_size
2149
2078
 
2150
2079
                putdie(compunit);
2162
2091
 *  because we need die->offs and infoo/infosize;
2163
2092
 */
2164
2093
static int
2165
 
ispubname(DWDie *die) {
 
2094
ispubname(DWDie *die)
 
2095
{
2166
2096
        DWAttr *a;
2167
2097
 
2168
2098
        switch(die->abbrev) {
2175
2105
}
2176
2106
 
2177
2107
static int
2178
 
ispubtype(DWDie *die) {
 
2108
ispubtype(DWDie *die)
 
2109
{
2179
2110
        return die->abbrev >= DW_ABRV_NULLTYPE;
2180
2111
}
2181
2112
 
2230
2161
        DWAttr *b, *e;
2231
2162
        int headersize;
2232
2163
        vlong sectionstart;
 
2164
        vlong value;
2233
2165
 
2234
2166
        sectionstart = cpos();
2235
2167
        headersize = rnd(4+2+4+1+1, PtrSize);  // don't count unit_length field itself
2245
2177
                // Write .debug_aranges  Header + entry  (sec 6.1.2)
2246
2178
                LPUT(headersize + 4*PtrSize - 4);       // unit_length (*)
2247
2179
                WPUT(2);        // dwarf version (appendix F)
2248
 
                LPUT(compunit->offs - COMPUNITHEADERSIZE);      // debug_info_offset
 
2180
 
 
2181
                value = compunit->offs - COMPUNITHEADERSIZE;    // debug_info_offset
 
2182
                if(linkmode == LinkExternal)
 
2183
                        adddwarfrel(arangessec, infosym, sectionstart, 4, value);
 
2184
                else
 
2185
                        LPUT(value);
 
2186
 
2249
2187
                cput(PtrSize);  // address_size
2250
2188
                cput(0);        // segment_size
2251
2189
                strnput("", headersize - (4+2+4+1+1));  // align to PtrSize
2252
2190
 
2253
 
                addrput(b->value);
 
2191
                if(linkmode == LinkExternal)
 
2192
                        adddwarfrel(arangessec, (Sym*)b->data, sectionstart, PtrSize, b->value-((Sym*)b->data)->value);
 
2193
                else
 
2194
                        addrput(b->value);
 
2195
 
2254
2196
                addrput(e->value - b->value);
2255
2197
                addrput(0);
2256
2198
                addrput(0);
2281
2223
                strnput("", rnd(size, PEFILEALIGN) - size);
2282
2224
}
2283
2225
 
 
2226
static vlong
 
2227
writedwarfreloc(Sym* s)
 
2228
{
 
2229
        int i;
 
2230
        vlong start;
 
2231
        Reloc *r;
 
2232
        
 
2233
        start = cpos();
 
2234
        for(r = s->r; r < s->r+s->nr; r++) {
 
2235
                if(iself)
 
2236
                        i = elfreloc1(r, r->off);
 
2237
                else if(HEADTYPE == Hdarwin)
 
2238
                        i = machoreloc1(r, r->off);
 
2239
                else
 
2240
                        i = -1;
 
2241
                if(i < 0)
 
2242
                        diag("unsupported obj reloc %d/%d to %s", r->type, r->siz, r->sym->name);
 
2243
        }
 
2244
        return start;
 
2245
}
 
2246
 
2284
2247
/*
2285
2248
 * This is the main entry point for generating dwarf.  After emitting
2286
2249
 * the mandatory debug_abbrev section, it calls writelines() to set up
2299
2262
        if(debug['w'])  // disable dwarf
2300
2263
                return;
2301
2264
 
 
2265
        if(linkmode == LinkExternal && !iself)
 
2266
                return;
 
2267
 
2302
2268
        // For diagnostic messages.
2303
2269
        newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, strlen("dwtypes"), "dwtypes");
2304
2270
 
2309
2275
        // Some types that must exist to define other ones.
2310
2276
        newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>");
2311
2277
        newdie(&dwtypes, DW_ABRV_NULLTYPE, "void");
2312
 
        newrefattr(newdie(&dwtypes, DW_ABRV_PTRTYPE, "unsafe.Pointer"),
2313
 
                DW_AT_type, find(&dwtypes, "void"));
 
2278
        newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer");
2314
2279
        die = newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr");  // needed for array size
2315
2280
        newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_unsigned, 0);
2316
2281
        newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, PtrSize, 0);
2317
2282
 
2318
2283
        // Needed by the prettyprinter code for interface inspection.
2319
 
        defgotype(lookup_or_diag("type.runtime.commonType"));
 
2284
        defgotype(lookup_or_diag("type.runtime.rtype"));
2320
2285
        defgotype(lookup_or_diag("type.runtime.interfaceType"));
2321
2286
        defgotype(lookup_or_diag("type.runtime.itab"));
2322
2287
 
2381
2346
        gdbscripto = writegdbscript();
2382
2347
        gdbscriptsize = cpos() - gdbscripto;
2383
2348
        align(gdbscriptsize);
 
2349
 
 
2350
        while(cpos()&7)
 
2351
                cput(0);
 
2352
        inforeloco = writedwarfreloc(infosec);
 
2353
        inforelocsize = cpos() - inforeloco;
 
2354
        align(inforelocsize);
 
2355
 
 
2356
        arangesreloco = writedwarfreloc(arangessec);
 
2357
        arangesrelocsize = cpos() - arangesreloco;
 
2358
        align(arangesrelocsize);
 
2359
 
 
2360
        linereloco = writedwarfreloc(linesec);
 
2361
        linerelocsize = cpos() - linereloco;
 
2362
        align(linerelocsize);
2384
2363
}
2385
2364
 
2386
2365
/*
2400
2379
        ElfStrDebugRanges,
2401
2380
        ElfStrDebugStr,
2402
2381
        ElfStrGDBScripts,
 
2382
        ElfStrRelDebugInfo,
 
2383
        ElfStrRelDebugAranges,
 
2384
        ElfStrRelDebugLine,
2403
2385
        NElfStrDbg
2404
2386
};
2405
2387
 
2423
2405
        elfstrdbg[ElfStrDebugRanges]   = addstring(shstrtab, ".debug_ranges");
2424
2406
        elfstrdbg[ElfStrDebugStr]      = addstring(shstrtab, ".debug_str");
2425
2407
        elfstrdbg[ElfStrGDBScripts]    = addstring(shstrtab, ".debug_gdb_scripts");
 
2408
        if(linkmode == LinkExternal) {
 
2409
                if(thechar == '6') {
 
2410
                        elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rela.debug_info");
 
2411
                        elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rela.debug_aranges");
 
2412
                        elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rela.debug_line");
 
2413
                } else {
 
2414
                        elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rel.debug_info");
 
2415
                        elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rel.debug_aranges");
 
2416
                        elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rel.debug_line");
 
2417
                }
 
2418
 
 
2419
                infosym = lookup(".debug_info", 0);
 
2420
                infosym->hide = 1;
 
2421
 
 
2422
                abbrevsym = lookup(".debug_abbrev", 0);
 
2423
                abbrevsym->hide = 1;
 
2424
 
 
2425
                linesym = lookup(".debug_line", 0);
 
2426
                linesym->hide = 1;
 
2427
        }
 
2428
}
 
2429
 
 
2430
// Add section symbols for DWARF debug info.  This is called before
 
2431
// dwarfaddelfheaders.
 
2432
void
 
2433
dwarfaddelfsectionsyms()
 
2434
{
 
2435
        if(infosym != nil) {
 
2436
                infosympos = cpos();
 
2437
                putelfsectionsym(infosym, 0);
 
2438
        }
 
2439
        if(abbrevsym != nil) {
 
2440
                abbrevsympos = cpos();
 
2441
                putelfsectionsym(abbrevsym, 0);
 
2442
        }
 
2443
        if(linesym != nil) {
 
2444
                linesympos = cpos();
 
2445
                putelfsectionsym(linesym, 0);
 
2446
        }
 
2447
}
 
2448
 
 
2449
static void
 
2450
dwarfaddelfrelocheader(int elfstr, ElfShdr *shdata, vlong off, vlong size)
 
2451
{
 
2452
        ElfShdr *sh;
 
2453
 
 
2454
        sh = newElfShdr(elfstrdbg[elfstr]);
 
2455
        if(thechar == '6') {
 
2456
                sh->type = SHT_RELA;
 
2457
        } else {
 
2458
                sh->type = SHT_REL;
 
2459
        }
 
2460
        sh->entsize = PtrSize*(2+(sh->type==SHT_RELA));
 
2461
        sh->link = elfshname(".symtab")->shnum;
 
2462
        sh->info = shdata->shnum;
 
2463
        sh->off = off;
 
2464
        sh->size = size;
 
2465
        sh->addralign = PtrSize;
 
2466
        
2426
2467
}
2427
2468
 
2428
2469
void
2429
2470
dwarfaddelfheaders(void)
2430
2471
{
2431
 
        ElfShdr *sh;
 
2472
        ElfShdr *sh, *shinfo, *sharanges, *shline;
2432
2473
 
2433
2474
        if(debug['w'])  // disable dwarf
2434
2475
                return;
2438
2479
        sh->off = abbrevo;
2439
2480
        sh->size = abbrevsize;
2440
2481
        sh->addralign = 1;
 
2482
        if(abbrevsympos > 0)
 
2483
                putelfsymshndx(abbrevsympos, sh->shnum);
2441
2484
 
2442
2485
        sh = newElfShdr(elfstrdbg[ElfStrDebugLine]);
2443
2486
        sh->type = SHT_PROGBITS;
2444
2487
        sh->off = lineo;
2445
2488
        sh->size = linesize;
2446
2489
        sh->addralign = 1;
 
2490
        if(linesympos > 0)
 
2491
                putelfsymshndx(linesympos, sh->shnum);
 
2492
        shline = sh;
2447
2493
 
2448
2494
        sh = newElfShdr(elfstrdbg[ElfStrDebugFrame]);
2449
2495
        sh->type = SHT_PROGBITS;
2456
2502
        sh->off = infoo;
2457
2503
        sh->size = infosize;
2458
2504
        sh->addralign = 1;
 
2505
        if(infosympos > 0)
 
2506
                putelfsymshndx(infosympos, sh->shnum);
 
2507
        shinfo = sh;
2459
2508
 
2460
2509
        if (pubnamessize > 0) {
2461
2510
                sh = newElfShdr(elfstrdbg[ElfStrDebugPubNames]);
2473
2522
                sh->addralign = 1;
2474
2523
        }
2475
2524
 
 
2525
        sharanges = nil;
2476
2526
        if (arangessize) {
2477
2527
                sh = newElfShdr(elfstrdbg[ElfStrDebugAranges]);
2478
2528
                sh->type = SHT_PROGBITS;
2479
2529
                sh->off = arangeso;
2480
2530
                sh->size = arangessize;
2481
2531
                sh->addralign = 1;
 
2532
                sharanges = sh;
2482
2533
        }
2483
2534
 
2484
2535
        if (gdbscriptsize) {
2488
2539
                sh->size = gdbscriptsize;
2489
2540
                sh->addralign = 1;
2490
2541
        }
 
2542
 
 
2543
        if(inforelocsize)
 
2544
                dwarfaddelfrelocheader(ElfStrRelDebugInfo, shinfo, inforeloco, inforelocsize);
 
2545
 
 
2546
        if(arangesrelocsize)
 
2547
                dwarfaddelfrelocheader(ElfStrRelDebugAranges, sharanges, arangesreloco, arangesrelocsize);
 
2548
 
 
2549
        if(linerelocsize)
 
2550
                dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize);
2491
2551
}
2492
2552
 
2493
2553
/*
2522
2582
        ms->fileoffset = fakestart;
2523
2583
        ms->filesize = abbrevo-fakestart;
2524
2584
 
2525
 
        msect = newMachoSect(ms, "__debug_abbrev");
 
2585
        msect = newMachoSect(ms, "__debug_abbrev", "__DWARF");
2526
2586
        msect->off = abbrevo;
2527
2587
        msect->size = abbrevsize;
2528
2588
        ms->filesize += msect->size;
2529
2589
 
2530
 
        msect = newMachoSect(ms, "__debug_line");
 
2590
        msect = newMachoSect(ms, "__debug_line", "__DWARF");
2531
2591
        msect->off = lineo;
2532
2592
        msect->size = linesize;
2533
2593
        ms->filesize += msect->size;
2534
2594
 
2535
 
        msect = newMachoSect(ms, "__debug_frame");
 
2595
        msect = newMachoSect(ms, "__debug_frame", "__DWARF");
2536
2596
        msect->off = frameo;
2537
2597
        msect->size = framesize;
2538
2598
        ms->filesize += msect->size;
2539
2599
 
2540
 
        msect = newMachoSect(ms, "__debug_info");
 
2600
        msect = newMachoSect(ms, "__debug_info", "__DWARF");
2541
2601
        msect->off = infoo;
2542
2602
        msect->size = infosize;
2543
2603
        ms->filesize += msect->size;
2544
2604
 
2545
2605
        if (pubnamessize > 0) {
2546
 
                msect = newMachoSect(ms, "__debug_pubnames");
 
2606
                msect = newMachoSect(ms, "__debug_pubnames", "__DWARF");
2547
2607
                msect->off = pubnameso;
2548
2608
                msect->size = pubnamessize;
2549
2609
                ms->filesize += msect->size;
2550
2610
        }
2551
2611
 
2552
2612
        if (pubtypessize > 0) {
2553
 
                msect = newMachoSect(ms, "__debug_pubtypes");
 
2613
                msect = newMachoSect(ms, "__debug_pubtypes", "__DWARF");
2554
2614
                msect->off = pubtypeso;
2555
2615
                msect->size = pubtypessize;
2556
2616
                ms->filesize += msect->size;
2557
2617
        }
2558
2618
 
2559
2619
        if (arangessize > 0) {
2560
 
                msect = newMachoSect(ms, "__debug_aranges");
 
2620
                msect = newMachoSect(ms, "__debug_aranges", "__DWARF");
2561
2621
                msect->off = arangeso;
2562
2622
                msect->size = arangessize;
2563
2623
                ms->filesize += msect->size;
2565
2625
 
2566
2626
        // TODO(lvd) fix gdb/python to load MachO (16 char section name limit)
2567
2627
        if (gdbscriptsize > 0) {
2568
 
                msect = newMachoSect(ms, "__debug_gdb_scripts");
 
2628
                msect = newMachoSect(ms, "__debug_gdb_scripts", "__DWARF");
2569
2629
                msect->off = gdbscripto;
2570
2630
                msect->size = gdbscriptsize;
2571
2631
                ms->filesize += msect->size;