@@ -280,10 +280,12 @@ func Sleb128put(ctxt Context, s Sym, v int64) {
280280}
281281
282282/*
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.
287289 */
288290type dwAttrForm struct {
289291 attr uint16
@@ -357,6 +359,45 @@ type dwAbbrev struct {
357359 attr []dwAttrForm
358360}
359361
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+
360401var abbrevs = [DW_NABRV ]dwAbbrev {
361402 /* The mandatory DW_ABRV_NULL entry. */
362403 {0 , 0 , []dwAttrForm {}},
@@ -436,7 +477,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
436477 {DW_AT_low_pc , DW_FORM_addr },
437478 {DW_AT_high_pc , DW_FORM_addr },
438479 {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
440481 },
441482 },
442483
@@ -448,7 +489,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
448489 {DW_AT_abstract_origin , DW_FORM_ref_addr },
449490 {DW_AT_ranges , DW_FORM_sec_offset },
450491 {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
452493 },
453494 },
454495
@@ -807,6 +848,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
807848
808849// GetAbbrev returns the contents of the .debug_abbrev section.
809850func GetAbbrev () []byte {
851+ abbrevs := Abbrevs ()
810852 var buf []byte
811853 for i := 1 ; i < DW_NABRV ; i ++ {
812854 // See section 7.5.3
@@ -963,6 +1005,7 @@ func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, da
9631005// Note that we can (and do) add arbitrary attributes to a DIE, but
9641006// only the ones actually listed in the Abbrev will be written out.
9651007func PutAttrs (ctxt Context , s Sym , abbrev int , attr * DWAttr ) {
1008+ abbrevs := Abbrevs ()
9661009Outer:
9671010 for _ , f := range abbrevs [abbrev ].attr {
9681011 for ap := attr ; ap != nil ; ap = ap .Link {
@@ -978,6 +1021,7 @@ Outer:
9781021
9791022// HasChildren reports whether 'die' uses an abbrev that supports children.
9801023func HasChildren (die * DWDie ) bool {
1024+ abbrevs := Abbrevs ()
9811025 return abbrevs [die .Abbrev ].children != 0
9821026}
9831027
@@ -1232,7 +1276,8 @@ func PutInlinedFunc(ctxt Context, s *FnState, callersym Sym, callIdx int) error
12321276
12331277 // Emit call file, line attrs.
12341278 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 )
12361281
12371282 // Variables associated with this inlined routine instance.
12381283 vars := ic .InlVars
0 commit comments