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.
731
newabslocexprattr(DWDie *die, vlong addr)
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);
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.
775
KindNoPointers = 1<<7,
777
// size of Type interface header + CommonType structure.
778
CommonSize = 2*PtrSize+ 5*PtrSize + 8,
782
decode_reloc(Sym *s, int32 off)
786
for (i = 0; i < s->nr; i++)
787
if (s->r[i].off == off)
793
decode_reloc_sym(Sym *s, int32 off)
797
r = decode_reloc(s,off);
804
decode_inuxi(uchar* p, int sz)
828
diag("dwarf: decode inuxi %d", sz);
831
for (i = 0; i < sz; i++)
832
cast[inuxi[i]] = p[i];
838
// Type.commonType.kind
840
decodetype_kind(Sym *s)
842
return s->p[3*PtrSize + 7] & ~KindNoPointers; // 0x13 / 0x1f
845
// Type.commonType.size
847
decodetype_size(Sym *s)
849
return decode_inuxi(s->p + 2*PtrSize, PtrSize); // 0x8 / 0x10
852
// Type.ArrayType.elem and Type.SliceType.Elem
854
decodetype_arrayelem(Sym *s)
856
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
860
decodetype_arraylen(Sym *s)
862
return decode_inuxi(s->p + CommonSize+PtrSize, PtrSize);
867
decodetype_ptrelem(Sym *s)
869
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
872
// Type.MapType.key, elem
874
decodetype_mapkey(Sym *s)
876
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
879
decodetype_mapvalue(Sym *s)
881
return decode_reloc_sym(s, CommonSize+PtrSize); // 0x20 / 0x38
884
// Type.ChanType.elem
886
decodetype_chanelem(Sym *s)
888
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
891
// Type.FuncType.dotdotdot
893
decodetype_funcdotdotdot(Sym *s)
895
return s->p[CommonSize];
898
// Type.FuncType.in.len
900
decodetype_funcincount(Sym *s)
902
return decode_inuxi(s->p + CommonSize+2*PtrSize, 4);
906
decodetype_funcoutcount(Sym *s)
908
return decode_inuxi(s->p + CommonSize+3*PtrSize + 2*4, 4);
912
decodetype_funcintype(Sym *s, int i)
916
r = decode_reloc(s, CommonSize + PtrSize);
919
return decode_reloc_sym(r->sym, r->add + i * PtrSize);
923
decodetype_funcouttype(Sym *s, int i)
927
r = decode_reloc(s, CommonSize + 2*PtrSize + 2*4);
930
return decode_reloc_sym(r->sym, r->add + i * PtrSize);
933
// Type.StructType.fields.Slice::len
935
decodetype_structfieldcount(Sym *s)
937
return decode_inuxi(s->p + CommonSize + PtrSize, 4);
941
StructFieldSize = 5*PtrSize
943
// Type.StructType.fields[]-> name, typ and offset.
945
decodetype_structfieldname(Sym *s, int i)
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.
953
r = decode_reloc(s, 0); // s has a pointer to the string data at offset 0
954
if (r == nil) // shouldn't happen.
956
return (char*) r->sym->p + r->add; // the c-string
960
decodetype_structfieldtype(Sym *s, int i)
962
return decode_reloc_sym(s, CommonSize + PtrSize + 2*4 + i*StructFieldSize + 2*PtrSize);
966
decodetype_structfieldoffs(Sym *s, int i)
968
return decode_inuxi(s->p + CommonSize + PtrSize + 2*4 + i*StructFieldSize + 4*PtrSize, 4);
971
// InterfaceTYpe.methods.len
973
decodetype_ifacemethodcount(Sym *s)
975
return decode_inuxi(s->p + CommonSize + PtrSize, 4);
844
newabslocexprattr(DWDie *die, vlong addr, Sym *sym)
846
newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, (char*)sym);
1280
1180
// synthesizemaptypes is way too closely married to runtime/hashmap.c
1282
MaxValsize = 256 - 64
1286
1188
synthesizemaptypes(DWDie *die)
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;
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"));
1298
if (hash == nil || hash_subtable == nil || hash_entry == nil)
1301
dwhash = (DWDie*)getattr(find_or_diag(hash_entry, "hash"), DW_AT_type)->data;
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")));
1307
1202
for (; die != nil; die = die->link) {
1308
1203
if (die->abbrev != DW_ABRV_MAPTYPE)
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);
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
1317
1212
a = getattr(valtype, DW_AT_byte_size);
1318
1213
valsize = a ? a->value : PtrSize;
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;
1325
if (valsize_in_hash >= PtrSize)
1326
datavo = rnd(keysize, PtrSize);
1327
datsize = datavo + valsize_in_hash;
1328
if (datsize < PtrSize)
1330
datsize = rnd(datsize, PtrSize);
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));
1338
fld = newdie(dwhe, DW_ABRV_STRUCTFIELD, "hash");
1339
newrefattr(fld, DW_AT_type, dwhash);
1340
newmemberoffsetattr(fld, 0);
1342
fld = newdie(dwhe, DW_ABRV_STRUCTFIELD, "key");
1343
newrefattr(fld, DW_AT_type, keytype);
1344
newmemberoffsetattr(fld, hashsize);
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);
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);
1216
if(keysize > MaxKeySize) {
1220
if(valsize > MaxValSize) {
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"));
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"));
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));
1364
1260
// Construct hash<K,V>
1365
1261
dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
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");
2414
elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rel.debug_info");
2415
elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rel.debug_aranges");
2416
elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rel.debug_line");
2419
infosym = lookup(".debug_info", 0);
2422
abbrevsym = lookup(".debug_abbrev", 0);
2423
abbrevsym->hide = 1;
2425
linesym = lookup(".debug_line", 0);
2430
// Add section symbols for DWARF debug info. This is called before
2431
// dwarfaddelfheaders.
2433
dwarfaddelfsectionsyms()
2435
if(infosym != nil) {
2436
infosympos = cpos();
2437
putelfsectionsym(infosym, 0);
2439
if(abbrevsym != nil) {
2440
abbrevsympos = cpos();
2441
putelfsectionsym(abbrevsym, 0);
2443
if(linesym != nil) {
2444
linesympos = cpos();
2445
putelfsectionsym(linesym, 0);
2450
dwarfaddelfrelocheader(int elfstr, ElfShdr *shdata, vlong off, vlong size)
2454
sh = newElfShdr(elfstrdbg[elfstr]);
2455
if(thechar == '6') {
2456
sh->type = SHT_RELA;
2460
sh->entsize = PtrSize*(2+(sh->type==SHT_RELA));
2461
sh->link = elfshname(".symtab")->shnum;
2462
sh->info = shdata->shnum;
2465
sh->addralign = PtrSize;
2429
2470
dwarfaddelfheaders(void)
2472
ElfShdr *sh, *shinfo, *sharanges, *shline;
2433
2474
if(debug['w']) // disable dwarf
2522
2582
ms->fileoffset = fakestart;
2523
2583
ms->filesize = abbrevo-fakestart;
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;
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;
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;
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;
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;
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;
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;