Skip to content

Commit 0998713

Browse files
thanmtmm1
authored andcommitted
cmd/compile: emit DWARF call_line attrs with data4 form on iOS
When targeting iOS, change the format (DWARF "form") of the call line attribute for inlined subroutine DIEs, to work around an apparent bug in /usr/bin/symbols on Darwin. [Just for posterity: there is nothing wrong with using DW_FORM_udata for the call_line attribute form; this is perfectly legal DWARF (and is in fact recommended by the standard relative to data4, which is less descriptive and often takes more space). The form switch is there just to make the Apple tools happy.] Updates golang#31459. Change-Id: Iaf362788a8c6684eea4cde8956c0661b694cecc1 Reviewed-on: https://go-review.googlesource.com/c/go/+/174538 Run-TryBot: Than McIntosh <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: David Chase <[email protected]> (cherry picked from commit b56d1ba)
1 parent 3fb8dec commit 0998713

File tree

2 files changed

+54
-7
lines changed

2 files changed

+54
-7
lines changed

src/cmd/internal/dwarf/dwarf.go

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,12 @@ func Sleb128put(ctxt Context, s Sym, v int64) {
275275
}
276276

277277
/*
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.
282284
*/
283285
type dwAttrForm struct {
284286
attr uint16
@@ -350,6 +352,45 @@ type dwAbbrev struct {
350352
attr []dwAttrForm
351353
}
352354

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+
353394
var abbrevs = [DW_NABRV]dwAbbrev{
354395
/* The mandatory DW_ABRV_NULL entry. */
355396
{0, 0, []dwAttrForm{}},
@@ -427,7 +468,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
427468
{DW_AT_low_pc, DW_FORM_addr},
428469
{DW_AT_high_pc, DW_FORM_addr},
429470
{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
431472
},
432473
},
433474

@@ -439,7 +480,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
439480
{DW_AT_abstract_origin, DW_FORM_ref_addr},
440481
{DW_AT_ranges, DW_FORM_sec_offset},
441482
{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
443484
},
444485
},
445486

@@ -798,6 +839,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
798839

799840
// GetAbbrev returns the contents of the .debug_abbrev section.
800841
func GetAbbrev() []byte {
842+
abbrevs := Abbrevs()
801843
var buf []byte
802844
for i := 1; i < DW_NABRV; i++ {
803845
// See section 7.5.3
@@ -954,6 +996,7 @@ func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, da
954996
// Note that we can (and do) add arbitrary attributes to a DIE, but
955997
// only the ones actually listed in the Abbrev will be written out.
956998
func PutAttrs(ctxt Context, s Sym, abbrev int, attr *DWAttr) {
999+
abbrevs := Abbrevs()
9571000
Outer:
9581001
for _, f := range abbrevs[abbrev].attr {
9591002
for ap := attr; ap != nil; ap = ap.Link {
@@ -969,6 +1012,7 @@ Outer:
9691012

9701013
// HasChildren reports whether 'die' uses an abbrev that supports children.
9711014
func HasChildren(die *DWDie) bool {
1015+
abbrevs := Abbrevs()
9721016
return abbrevs[die.Abbrev].children != 0
9731017
}
9741018

@@ -1205,7 +1249,8 @@ func PutInlinedFunc(ctxt Context, s *FnState, callersym Sym, callIdx int) error
12051249

12061250
// Emit call file, line attrs.
12071251
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)
12091254

12101255
// Variables associated with this inlined routine instance.
12111256
vars := ic.InlVars

src/cmd/internal/dwarf/dwarf_defs.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ const (
220220
DW_FORM_exprloc = 0x18 // exprloc
221221
DW_FORM_flag_present = 0x19 // flag
222222
DW_FORM_ref_sig8 = 0x20 // reference
223+
// Pseudo-form: expanded to data4 on IOS, udata elsewhere.
224+
DW_FORM_udata_pseudo = 0x99
223225
)
224226

225227
// Table 24 (#operands, notes)

0 commit comments

Comments
 (0)