@@ -275,10 +275,12 @@ func Sleb128put(ctxt Context, s Sym, v int64) {
275
275
}
276
276
277
277
/*
278
- * Defining Abbrevs. This is hardcoded, and there will be
279
- * only a handful of them. The DWARF spec places no restriction on
280
- * the ordering of attributes in the Abbrevs and DIEs, and we will
281
- * always write them out in the order of declaration in the abbrev.
278
+ * Defining Abbrevs. This is hardcoded on a per-platform basis (that is,
279
+ * each platform will see a fixed abbrev table for all objects); the number
280
+ * of abbrev entries is fairly small (compared to C++ objects). The DWARF
281
+ * spec places no restriction on the ordering of attributes in the
282
+ * Abbrevs and DIEs, and we will always write them out in the order
283
+ * of declaration in the abbrev.
282
284
*/
283
285
type dwAttrForm struct {
284
286
attr uint16
@@ -350,6 +352,45 @@ type dwAbbrev struct {
350
352
attr []dwAttrForm
351
353
}
352
354
355
+ var abbrevsFinalized bool
356
+
357
+ // expandPseudoForm takes an input DW_FORM_xxx value and translates it
358
+ // into a platform-appropriate concrete form. Existing concrete/real
359
+ // DW_FORM values are left untouched. For the moment the only
360
+ // pseudo-form is DW_FORM_udata_pseudo, which gets expanded to
361
+ // DW_FORM_data4 on Darwin and DW_FORM_udata everywhere else. See
362
+ // issue #31459 for more context.
363
+ func expandPseudoForm (form uint8 ) uint8 {
364
+ // Is this a pseudo-form?
365
+ if form != DW_FORM_udata_pseudo {
366
+ return form
367
+ }
368
+ expandedForm := DW_FORM_udata
369
+ if objabi .GOOS == "darwin" {
370
+ expandedForm = DW_FORM_data4
371
+ }
372
+ return uint8 (expandedForm )
373
+ }
374
+
375
+ // Abbrevs() returns the finalized abbrev array for the platform,
376
+ // expanding any DW_FORM pseudo-ops to real values.
377
+ func Abbrevs () [DW_NABRV ]dwAbbrev {
378
+ if abbrevsFinalized {
379
+ return abbrevs
380
+ }
381
+ for i := 1 ; i < DW_NABRV ; i ++ {
382
+ for j := 0 ; j < len (abbrevs [i ].attr ); j ++ {
383
+ abbrevs [i ].attr [j ].form = expandPseudoForm (abbrevs [i ].attr [j ].form )
384
+ }
385
+ }
386
+ abbrevsFinalized = true
387
+ return abbrevs
388
+ }
389
+
390
+ // abbrevs is a raw table of abbrev entries; it needs to be post-processed
391
+ // by the Abbrevs() function above prior to being consumed, to expand
392
+ // the 'pseudo-form' entries below to real DWARF form values.
393
+
353
394
var abbrevs = [DW_NABRV ]dwAbbrev {
354
395
/* The mandatory DW_ABRV_NULL entry. */
355
396
{0 , 0 , []dwAttrForm {}},
@@ -427,7 +468,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
427
468
{DW_AT_low_pc , DW_FORM_addr },
428
469
{DW_AT_high_pc , DW_FORM_addr },
429
470
{DW_AT_call_file , DW_FORM_data4 },
430
- {DW_AT_call_line , DW_FORM_udata },
471
+ {DW_AT_call_line , DW_FORM_udata_pseudo }, // pseudo-form
431
472
},
432
473
},
433
474
@@ -439,7 +480,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
439
480
{DW_AT_abstract_origin , DW_FORM_ref_addr },
440
481
{DW_AT_ranges , DW_FORM_sec_offset },
441
482
{DW_AT_call_file , DW_FORM_data4 },
442
- {DW_AT_call_line , DW_FORM_udata },
483
+ {DW_AT_call_line , DW_FORM_udata_pseudo }, // pseudo-form
443
484
},
444
485
},
445
486
@@ -798,6 +839,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
798
839
799
840
// GetAbbrev returns the contents of the .debug_abbrev section.
800
841
func GetAbbrev () []byte {
842
+ abbrevs := Abbrevs ()
801
843
var buf []byte
802
844
for i := 1 ; i < DW_NABRV ; i ++ {
803
845
// See section 7.5.3
@@ -954,6 +996,7 @@ func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, da
954
996
// Note that we can (and do) add arbitrary attributes to a DIE, but
955
997
// only the ones actually listed in the Abbrev will be written out.
956
998
func PutAttrs (ctxt Context , s Sym , abbrev int , attr * DWAttr ) {
999
+ abbrevs := Abbrevs ()
957
1000
Outer:
958
1001
for _ , f := range abbrevs [abbrev ].attr {
959
1002
for ap := attr ; ap != nil ; ap = ap .Link {
@@ -969,6 +1012,7 @@ Outer:
969
1012
970
1013
// HasChildren reports whether 'die' uses an abbrev that supports children.
971
1014
func HasChildren (die * DWDie ) bool {
1015
+ abbrevs := Abbrevs ()
972
1016
return abbrevs [die .Abbrev ].children != 0
973
1017
}
974
1018
@@ -1205,7 +1249,8 @@ func PutInlinedFunc(ctxt Context, s *FnState, callersym Sym, callIdx int) error
1205
1249
1206
1250
// Emit call file, line attrs.
1207
1251
ctxt .AddFileRef (s .Info , ic .CallFile )
1208
- putattr (ctxt , s .Info , abbrev , DW_FORM_udata , DW_CLS_CONSTANT , int64 (ic .CallLine ), nil )
1252
+ form := int (expandPseudoForm (DW_FORM_udata_pseudo ))
1253
+ putattr (ctxt , s .Info , abbrev , form , DW_CLS_CONSTANT , int64 (ic .CallLine ), nil )
1209
1254
1210
1255
// Variables associated with this inlined routine instance.
1211
1256
vars := ic .InlVars
0 commit comments