@@ -280,10 +280,12 @@ func Sleb128put(ctxt Context, s Sym, v int64) {
280
280
}
281
281
282
282
/*
283
- * Defining Abbrevs. This is hardcoded, and there will be
284
- * only a handful of them. The DWARF spec places no restriction on
285
- * the ordering of attributes in the Abbrevs and DIEs, and we will
286
- * always write them out in the order of declaration in the abbrev.
283
+ * Defining Abbrevs. This is hardcoded on a per-platform basis (that is,
284
+ * each platform will see a fixed abbrev table for all objects); the number
285
+ * of abbrev entries is fairly small (compared to C++ objects). The DWARF
286
+ * spec places no restriction on the ordering of attributes in the
287
+ * Abbrevs and DIEs, and we will always write them out in the order
288
+ * of declaration in the abbrev.
287
289
*/
288
290
type dwAttrForm struct {
289
291
attr uint16
@@ -357,6 +359,45 @@ type dwAbbrev struct {
357
359
attr []dwAttrForm
358
360
}
359
361
362
+ var abbrevsFinalized bool
363
+
364
+ // expandPseudoForm takes an input DW_FORM_xxx value and translates it
365
+ // into a platform-appropriate concrete form. Existing concrete/real
366
+ // DW_FORM values are left untouched. For the moment the only
367
+ // pseudo-form is DW_FORM_udata_pseudo, which gets expanded to
368
+ // DW_FORM_data4 on Darwin and DW_FORM_udata everywhere else. See
369
+ // issue #31459 for more context.
370
+ func expandPseudoForm (form uint8 ) uint8 {
371
+ // Is this a pseudo-form?
372
+ if form != DW_FORM_udata_pseudo {
373
+ return form
374
+ }
375
+ expandedForm := DW_FORM_udata
376
+ if objabi .GOOS == "darwin" {
377
+ expandedForm = DW_FORM_data4
378
+ }
379
+ return uint8 (expandedForm )
380
+ }
381
+
382
+ // Abbrevs() returns the finalized abbrev array for the platform,
383
+ // expanding any DW_FORM pseudo-ops to real values.
384
+ func Abbrevs () [DW_NABRV ]dwAbbrev {
385
+ if abbrevsFinalized {
386
+ return abbrevs
387
+ }
388
+ for i := 1 ; i < DW_NABRV ; i ++ {
389
+ for j := 0 ; j < len (abbrevs [i ].attr ); j ++ {
390
+ abbrevs [i ].attr [j ].form = expandPseudoForm (abbrevs [i ].attr [j ].form )
391
+ }
392
+ }
393
+ abbrevsFinalized = true
394
+ return abbrevs
395
+ }
396
+
397
+ // abbrevs is a raw table of abbrev entries; it needs to be post-processed
398
+ // by the Abbrevs() function above prior to being consumed, to expand
399
+ // the 'pseudo-form' entries below to real DWARF form values.
400
+
360
401
var abbrevs = [DW_NABRV ]dwAbbrev {
361
402
/* The mandatory DW_ABRV_NULL entry. */
362
403
{0 , 0 , []dwAttrForm {}},
@@ -436,7 +477,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
436
477
{DW_AT_low_pc , DW_FORM_addr },
437
478
{DW_AT_high_pc , DW_FORM_addr },
438
479
{DW_AT_call_file , DW_FORM_data4 },
439
- {DW_AT_call_line , DW_FORM_udata },
480
+ {DW_AT_call_line , DW_FORM_udata_pseudo }, // pseudo-form
440
481
},
441
482
},
442
483
@@ -448,7 +489,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
448
489
{DW_AT_abstract_origin , DW_FORM_ref_addr },
449
490
{DW_AT_ranges , DW_FORM_sec_offset },
450
491
{DW_AT_call_file , DW_FORM_data4 },
451
- {DW_AT_call_line , DW_FORM_udata },
492
+ {DW_AT_call_line , DW_FORM_udata_pseudo }, // pseudo-form
452
493
},
453
494
},
454
495
@@ -807,6 +848,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
807
848
808
849
// GetAbbrev returns the contents of the .debug_abbrev section.
809
850
func GetAbbrev () []byte {
851
+ abbrevs := Abbrevs ()
810
852
var buf []byte
811
853
for i := 1 ; i < DW_NABRV ; i ++ {
812
854
// See section 7.5.3
@@ -963,6 +1005,7 @@ func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, da
963
1005
// Note that we can (and do) add arbitrary attributes to a DIE, but
964
1006
// only the ones actually listed in the Abbrev will be written out.
965
1007
func PutAttrs (ctxt Context , s Sym , abbrev int , attr * DWAttr ) {
1008
+ abbrevs := Abbrevs ()
966
1009
Outer:
967
1010
for _ , f := range abbrevs [abbrev ].attr {
968
1011
for ap := attr ; ap != nil ; ap = ap .Link {
@@ -978,6 +1021,7 @@ Outer:
978
1021
979
1022
// HasChildren reports whether 'die' uses an abbrev that supports children.
980
1023
func HasChildren (die * DWDie ) bool {
1024
+ abbrevs := Abbrevs ()
981
1025
return abbrevs [die .Abbrev ].children != 0
982
1026
}
983
1027
@@ -1232,7 +1276,8 @@ func PutInlinedFunc(ctxt Context, s *FnState, callersym Sym, callIdx int) error
1232
1276
1233
1277
// Emit call file, line attrs.
1234
1278
ctxt .AddFileRef (s .Info , ic .CallFile )
1235
- putattr (ctxt , s .Info , abbrev , DW_FORM_udata , DW_CLS_CONSTANT , int64 (ic .CallLine ), nil )
1279
+ form := int (expandPseudoForm (DW_FORM_udata_pseudo ))
1280
+ putattr (ctxt , s .Info , abbrev , form , DW_CLS_CONSTANT , int64 (ic .CallLine ), nil )
1236
1281
1237
1282
// Variables associated with this inlined routine instance.
1238
1283
vars := ic .InlVars
0 commit comments