dwarf.go 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650
  1. // Copyright 2016 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package dwarf generates DWARF debugging information.
  5. // DWARF generation is split between the compiler and the linker,
  6. // this package contains the shared code.
  7. package dwarf
  8. import (
  9. "bytes"
  10. "github.com/twitchyliquid64/golang-asm/objabi"
  11. "errors"
  12. "fmt"
  13. "os/exec"
  14. "sort"
  15. "strconv"
  16. "strings"
  17. )
  18. // InfoPrefix is the prefix for all the symbols containing DWARF info entries.
  19. const InfoPrefix = "go.info."
  20. // ConstInfoPrefix is the prefix for all symbols containing DWARF info
  21. // entries that contain constants.
  22. const ConstInfoPrefix = "go.constinfo."
  23. // CUInfoPrefix is the prefix for symbols containing information to
  24. // populate the DWARF compilation unit info entries.
  25. const CUInfoPrefix = "go.cuinfo."
  26. // Used to form the symbol name assigned to the DWARF 'abstract subprogram"
  27. // info entry for a function
  28. const AbstractFuncSuffix = "$abstract"
  29. // Controls logging/debugging for selected aspects of DWARF subprogram
  30. // generation (functions, scopes).
  31. var logDwarf bool
  32. // Sym represents a symbol.
  33. type Sym interface {
  34. Length(dwarfContext interface{}) int64
  35. }
  36. // A Var represents a local variable or a function parameter.
  37. type Var struct {
  38. Name string
  39. Abbrev int // Either DW_ABRV_AUTO[_LOCLIST] or DW_ABRV_PARAM[_LOCLIST]
  40. IsReturnValue bool
  41. IsInlFormal bool
  42. StackOffset int32
  43. // This package can't use the ssa package, so it can't mention ssa.FuncDebug,
  44. // so indirect through a closure.
  45. PutLocationList func(listSym, startPC Sym)
  46. Scope int32
  47. Type Sym
  48. DeclFile string
  49. DeclLine uint
  50. DeclCol uint
  51. InlIndex int32 // subtract 1 to form real index into InlTree
  52. ChildIndex int32 // child DIE index in abstract function
  53. IsInAbstract bool // variable exists in abstract function
  54. }
  55. // A Scope represents a lexical scope. All variables declared within a
  56. // scope will only be visible to instructions covered by the scope.
  57. // Lexical scopes are contiguous in source files but can end up being
  58. // compiled to discontiguous blocks of instructions in the executable.
  59. // The Ranges field lists all the blocks of instructions that belong
  60. // in this scope.
  61. type Scope struct {
  62. Parent int32
  63. Ranges []Range
  64. Vars []*Var
  65. }
  66. // A Range represents a half-open interval [Start, End).
  67. type Range struct {
  68. Start, End int64
  69. }
  70. // This container is used by the PutFunc* variants below when
  71. // creating the DWARF subprogram DIE(s) for a function.
  72. type FnState struct {
  73. Name string
  74. Importpath string
  75. Info Sym
  76. Filesym Sym
  77. Loc Sym
  78. Ranges Sym
  79. Absfn Sym
  80. StartPC Sym
  81. Size int64
  82. External bool
  83. Scopes []Scope
  84. InlCalls InlCalls
  85. UseBASEntries bool
  86. }
  87. func EnableLogging(doit bool) {
  88. logDwarf = doit
  89. }
  90. // UnifyRanges merges the list of ranges of c into the list of ranges of s
  91. func (s *Scope) UnifyRanges(c *Scope) {
  92. out := make([]Range, 0, len(s.Ranges)+len(c.Ranges))
  93. i, j := 0, 0
  94. for {
  95. var cur Range
  96. if i < len(s.Ranges) && j < len(c.Ranges) {
  97. if s.Ranges[i].Start < c.Ranges[j].Start {
  98. cur = s.Ranges[i]
  99. i++
  100. } else {
  101. cur = c.Ranges[j]
  102. j++
  103. }
  104. } else if i < len(s.Ranges) {
  105. cur = s.Ranges[i]
  106. i++
  107. } else if j < len(c.Ranges) {
  108. cur = c.Ranges[j]
  109. j++
  110. } else {
  111. break
  112. }
  113. if n := len(out); n > 0 && cur.Start <= out[n-1].End {
  114. out[n-1].End = cur.End
  115. } else {
  116. out = append(out, cur)
  117. }
  118. }
  119. s.Ranges = out
  120. }
  121. // AppendRange adds r to s, if r is non-empty.
  122. // If possible, it extends the last Range in s.Ranges; if not, it creates a new one.
  123. func (s *Scope) AppendRange(r Range) {
  124. if r.End <= r.Start {
  125. return
  126. }
  127. i := len(s.Ranges)
  128. if i > 0 && s.Ranges[i-1].End == r.Start {
  129. s.Ranges[i-1].End = r.End
  130. return
  131. }
  132. s.Ranges = append(s.Ranges, r)
  133. }
  134. type InlCalls struct {
  135. Calls []InlCall
  136. }
  137. type InlCall struct {
  138. // index into ctx.InlTree describing the call inlined here
  139. InlIndex int
  140. // Symbol of file containing inlined call site (really *obj.LSym).
  141. CallFile Sym
  142. // Line number of inlined call site.
  143. CallLine uint32
  144. // Dwarf abstract subroutine symbol (really *obj.LSym).
  145. AbsFunSym Sym
  146. // Indices of child inlines within Calls array above.
  147. Children []int
  148. // entries in this list are PAUTO's created by the inliner to
  149. // capture the promoted formals and locals of the inlined callee.
  150. InlVars []*Var
  151. // PC ranges for this inlined call.
  152. Ranges []Range
  153. // Root call (not a child of some other call).
  154. Root bool
  155. }
  156. // A Context specifies how to add data to a Sym.
  157. type Context interface {
  158. PtrSize() int
  159. AddInt(s Sym, size int, i int64)
  160. AddBytes(s Sym, b []byte)
  161. AddAddress(s Sym, t interface{}, ofs int64)
  162. AddCURelativeAddress(s Sym, t interface{}, ofs int64)
  163. AddSectionOffset(s Sym, size int, t interface{}, ofs int64)
  164. AddDWARFAddrSectionOffset(s Sym, t interface{}, ofs int64)
  165. CurrentOffset(s Sym) int64
  166. RecordDclReference(from Sym, to Sym, dclIdx int, inlIndex int)
  167. RecordChildDieOffsets(s Sym, vars []*Var, offsets []int32)
  168. AddString(s Sym, v string)
  169. AddFileRef(s Sym, f interface{})
  170. Logf(format string, args ...interface{})
  171. }
  172. // AppendUleb128 appends v to b using DWARF's unsigned LEB128 encoding.
  173. func AppendUleb128(b []byte, v uint64) []byte {
  174. for {
  175. c := uint8(v & 0x7f)
  176. v >>= 7
  177. if v != 0 {
  178. c |= 0x80
  179. }
  180. b = append(b, c)
  181. if c&0x80 == 0 {
  182. break
  183. }
  184. }
  185. return b
  186. }
  187. // AppendSleb128 appends v to b using DWARF's signed LEB128 encoding.
  188. func AppendSleb128(b []byte, v int64) []byte {
  189. for {
  190. c := uint8(v & 0x7f)
  191. s := uint8(v & 0x40)
  192. v >>= 7
  193. if (v != -1 || s == 0) && (v != 0 || s != 0) {
  194. c |= 0x80
  195. }
  196. b = append(b, c)
  197. if c&0x80 == 0 {
  198. break
  199. }
  200. }
  201. return b
  202. }
  203. // sevenbits contains all unsigned seven bit numbers, indexed by their value.
  204. var sevenbits = [...]byte{
  205. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  206. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  207. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  208. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  209. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
  210. 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
  211. 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
  212. 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
  213. }
  214. // sevenBitU returns the unsigned LEB128 encoding of v if v is seven bits and nil otherwise.
  215. // The contents of the returned slice must not be modified.
  216. func sevenBitU(v int64) []byte {
  217. if uint64(v) < uint64(len(sevenbits)) {
  218. return sevenbits[v : v+1]
  219. }
  220. return nil
  221. }
  222. // sevenBitS returns the signed LEB128 encoding of v if v is seven bits and nil otherwise.
  223. // The contents of the returned slice must not be modified.
  224. func sevenBitS(v int64) []byte {
  225. if uint64(v) <= 63 {
  226. return sevenbits[v : v+1]
  227. }
  228. if uint64(-v) <= 64 {
  229. return sevenbits[128+v : 128+v+1]
  230. }
  231. return nil
  232. }
  233. // Uleb128put appends v to s using DWARF's unsigned LEB128 encoding.
  234. func Uleb128put(ctxt Context, s Sym, v int64) {
  235. b := sevenBitU(v)
  236. if b == nil {
  237. var encbuf [20]byte
  238. b = AppendUleb128(encbuf[:0], uint64(v))
  239. }
  240. ctxt.AddBytes(s, b)
  241. }
  242. // Sleb128put appends v to s using DWARF's signed LEB128 encoding.
  243. func Sleb128put(ctxt Context, s Sym, v int64) {
  244. b := sevenBitS(v)
  245. if b == nil {
  246. var encbuf [20]byte
  247. b = AppendSleb128(encbuf[:0], v)
  248. }
  249. ctxt.AddBytes(s, b)
  250. }
  251. /*
  252. * Defining Abbrevs. This is hardcoded on a per-platform basis (that is,
  253. * each platform will see a fixed abbrev table for all objects); the number
  254. * of abbrev entries is fairly small (compared to C++ objects). The DWARF
  255. * spec places no restriction on the ordering of attributes in the
  256. * Abbrevs and DIEs, and we will always write them out in the order
  257. * of declaration in the abbrev.
  258. */
  259. type dwAttrForm struct {
  260. attr uint16
  261. form uint8
  262. }
  263. // Go-specific type attributes.
  264. const (
  265. DW_AT_go_kind = 0x2900
  266. DW_AT_go_key = 0x2901
  267. DW_AT_go_elem = 0x2902
  268. // Attribute for DW_TAG_member of a struct type.
  269. // Nonzero value indicates the struct field is an embedded field.
  270. DW_AT_go_embedded_field = 0x2903
  271. DW_AT_go_runtime_type = 0x2904
  272. DW_AT_go_package_name = 0x2905 // Attribute for DW_TAG_compile_unit
  273. DW_AT_internal_location = 253 // params and locals; not emitted
  274. )
  275. // Index into the abbrevs table below.
  276. // Keep in sync with ispubname() and ispubtype() in ld/dwarf.go.
  277. // ispubtype considers >= NULLTYPE public
  278. const (
  279. DW_ABRV_NULL = iota
  280. DW_ABRV_COMPUNIT
  281. DW_ABRV_COMPUNIT_TEXTLESS
  282. DW_ABRV_FUNCTION
  283. DW_ABRV_FUNCTION_ABSTRACT
  284. DW_ABRV_FUNCTION_CONCRETE
  285. DW_ABRV_INLINED_SUBROUTINE
  286. DW_ABRV_INLINED_SUBROUTINE_RANGES
  287. DW_ABRV_VARIABLE
  288. DW_ABRV_INT_CONSTANT
  289. DW_ABRV_AUTO
  290. DW_ABRV_AUTO_LOCLIST
  291. DW_ABRV_AUTO_ABSTRACT
  292. DW_ABRV_AUTO_CONCRETE
  293. DW_ABRV_AUTO_CONCRETE_LOCLIST
  294. DW_ABRV_PARAM
  295. DW_ABRV_PARAM_LOCLIST
  296. DW_ABRV_PARAM_ABSTRACT
  297. DW_ABRV_PARAM_CONCRETE
  298. DW_ABRV_PARAM_CONCRETE_LOCLIST
  299. DW_ABRV_LEXICAL_BLOCK_RANGES
  300. DW_ABRV_LEXICAL_BLOCK_SIMPLE
  301. DW_ABRV_STRUCTFIELD
  302. DW_ABRV_FUNCTYPEPARAM
  303. DW_ABRV_DOTDOTDOT
  304. DW_ABRV_ARRAYRANGE
  305. DW_ABRV_NULLTYPE
  306. DW_ABRV_BASETYPE
  307. DW_ABRV_ARRAYTYPE
  308. DW_ABRV_CHANTYPE
  309. DW_ABRV_FUNCTYPE
  310. DW_ABRV_IFACETYPE
  311. DW_ABRV_MAPTYPE
  312. DW_ABRV_PTRTYPE
  313. DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6.
  314. DW_ABRV_SLICETYPE
  315. DW_ABRV_STRINGTYPE
  316. DW_ABRV_STRUCTTYPE
  317. DW_ABRV_TYPEDECL
  318. DW_NABRV
  319. )
  320. type dwAbbrev struct {
  321. tag uint8
  322. children uint8
  323. attr []dwAttrForm
  324. }
  325. var abbrevsFinalized bool
  326. // expandPseudoForm takes an input DW_FORM_xxx value and translates it
  327. // into a platform-appropriate concrete form. Existing concrete/real
  328. // DW_FORM values are left untouched. For the moment the only
  329. // pseudo-form is DW_FORM_udata_pseudo, which gets expanded to
  330. // DW_FORM_data4 on Darwin and DW_FORM_udata everywhere else. See
  331. // issue #31459 for more context.
  332. func expandPseudoForm(form uint8) uint8 {
  333. // Is this a pseudo-form?
  334. if form != DW_FORM_udata_pseudo {
  335. return form
  336. }
  337. expandedForm := DW_FORM_udata
  338. if objabi.GOOS == "darwin" {
  339. expandedForm = DW_FORM_data4
  340. }
  341. return uint8(expandedForm)
  342. }
  343. // Abbrevs() returns the finalized abbrev array for the platform,
  344. // expanding any DW_FORM pseudo-ops to real values.
  345. func Abbrevs() []dwAbbrev {
  346. if abbrevsFinalized {
  347. return abbrevs[:]
  348. }
  349. for i := 1; i < DW_NABRV; i++ {
  350. for j := 0; j < len(abbrevs[i].attr); j++ {
  351. abbrevs[i].attr[j].form = expandPseudoForm(abbrevs[i].attr[j].form)
  352. }
  353. }
  354. abbrevsFinalized = true
  355. return abbrevs[:]
  356. }
  357. // abbrevs is a raw table of abbrev entries; it needs to be post-processed
  358. // by the Abbrevs() function above prior to being consumed, to expand
  359. // the 'pseudo-form' entries below to real DWARF form values.
  360. var abbrevs = [DW_NABRV]dwAbbrev{
  361. /* The mandatory DW_ABRV_NULL entry. */
  362. {0, 0, []dwAttrForm{}},
  363. /* COMPUNIT */
  364. {
  365. DW_TAG_compile_unit,
  366. DW_CHILDREN_yes,
  367. []dwAttrForm{
  368. {DW_AT_name, DW_FORM_string},
  369. {DW_AT_language, DW_FORM_data1},
  370. {DW_AT_stmt_list, DW_FORM_sec_offset},
  371. {DW_AT_low_pc, DW_FORM_addr},
  372. {DW_AT_ranges, DW_FORM_sec_offset},
  373. {DW_AT_comp_dir, DW_FORM_string},
  374. {DW_AT_producer, DW_FORM_string},
  375. {DW_AT_go_package_name, DW_FORM_string},
  376. },
  377. },
  378. /* COMPUNIT_TEXTLESS */
  379. {
  380. DW_TAG_compile_unit,
  381. DW_CHILDREN_yes,
  382. []dwAttrForm{
  383. {DW_AT_name, DW_FORM_string},
  384. {DW_AT_language, DW_FORM_data1},
  385. {DW_AT_comp_dir, DW_FORM_string},
  386. {DW_AT_producer, DW_FORM_string},
  387. {DW_AT_go_package_name, DW_FORM_string},
  388. },
  389. },
  390. /* FUNCTION */
  391. {
  392. DW_TAG_subprogram,
  393. DW_CHILDREN_yes,
  394. []dwAttrForm{
  395. {DW_AT_name, DW_FORM_string},
  396. {DW_AT_low_pc, DW_FORM_addr},
  397. {DW_AT_high_pc, DW_FORM_addr},
  398. {DW_AT_frame_base, DW_FORM_block1},
  399. {DW_AT_decl_file, DW_FORM_data4},
  400. {DW_AT_external, DW_FORM_flag},
  401. },
  402. },
  403. /* FUNCTION_ABSTRACT */
  404. {
  405. DW_TAG_subprogram,
  406. DW_CHILDREN_yes,
  407. []dwAttrForm{
  408. {DW_AT_name, DW_FORM_string},
  409. {DW_AT_inline, DW_FORM_data1},
  410. {DW_AT_external, DW_FORM_flag},
  411. },
  412. },
  413. /* FUNCTION_CONCRETE */
  414. {
  415. DW_TAG_subprogram,
  416. DW_CHILDREN_yes,
  417. []dwAttrForm{
  418. {DW_AT_abstract_origin, DW_FORM_ref_addr},
  419. {DW_AT_low_pc, DW_FORM_addr},
  420. {DW_AT_high_pc, DW_FORM_addr},
  421. {DW_AT_frame_base, DW_FORM_block1},
  422. },
  423. },
  424. /* INLINED_SUBROUTINE */
  425. {
  426. DW_TAG_inlined_subroutine,
  427. DW_CHILDREN_yes,
  428. []dwAttrForm{
  429. {DW_AT_abstract_origin, DW_FORM_ref_addr},
  430. {DW_AT_low_pc, DW_FORM_addr},
  431. {DW_AT_high_pc, DW_FORM_addr},
  432. {DW_AT_call_file, DW_FORM_data4},
  433. {DW_AT_call_line, DW_FORM_udata_pseudo}, // pseudo-form
  434. },
  435. },
  436. /* INLINED_SUBROUTINE_RANGES */
  437. {
  438. DW_TAG_inlined_subroutine,
  439. DW_CHILDREN_yes,
  440. []dwAttrForm{
  441. {DW_AT_abstract_origin, DW_FORM_ref_addr},
  442. {DW_AT_ranges, DW_FORM_sec_offset},
  443. {DW_AT_call_file, DW_FORM_data4},
  444. {DW_AT_call_line, DW_FORM_udata_pseudo}, // pseudo-form
  445. },
  446. },
  447. /* VARIABLE */
  448. {
  449. DW_TAG_variable,
  450. DW_CHILDREN_no,
  451. []dwAttrForm{
  452. {DW_AT_name, DW_FORM_string},
  453. {DW_AT_location, DW_FORM_block1},
  454. {DW_AT_type, DW_FORM_ref_addr},
  455. {DW_AT_external, DW_FORM_flag},
  456. },
  457. },
  458. /* INT CONSTANT */
  459. {
  460. DW_TAG_constant,
  461. DW_CHILDREN_no,
  462. []dwAttrForm{
  463. {DW_AT_name, DW_FORM_string},
  464. {DW_AT_type, DW_FORM_ref_addr},
  465. {DW_AT_const_value, DW_FORM_sdata},
  466. },
  467. },
  468. /* AUTO */
  469. {
  470. DW_TAG_variable,
  471. DW_CHILDREN_no,
  472. []dwAttrForm{
  473. {DW_AT_name, DW_FORM_string},
  474. {DW_AT_decl_line, DW_FORM_udata},
  475. {DW_AT_type, DW_FORM_ref_addr},
  476. {DW_AT_location, DW_FORM_block1},
  477. },
  478. },
  479. /* AUTO_LOCLIST */
  480. {
  481. DW_TAG_variable,
  482. DW_CHILDREN_no,
  483. []dwAttrForm{
  484. {DW_AT_name, DW_FORM_string},
  485. {DW_AT_decl_line, DW_FORM_udata},
  486. {DW_AT_type, DW_FORM_ref_addr},
  487. {DW_AT_location, DW_FORM_sec_offset},
  488. },
  489. },
  490. /* AUTO_ABSTRACT */
  491. {
  492. DW_TAG_variable,
  493. DW_CHILDREN_no,
  494. []dwAttrForm{
  495. {DW_AT_name, DW_FORM_string},
  496. {DW_AT_decl_line, DW_FORM_udata},
  497. {DW_AT_type, DW_FORM_ref_addr},
  498. },
  499. },
  500. /* AUTO_CONCRETE */
  501. {
  502. DW_TAG_variable,
  503. DW_CHILDREN_no,
  504. []dwAttrForm{
  505. {DW_AT_abstract_origin, DW_FORM_ref_addr},
  506. {DW_AT_location, DW_FORM_block1},
  507. },
  508. },
  509. /* AUTO_CONCRETE_LOCLIST */
  510. {
  511. DW_TAG_variable,
  512. DW_CHILDREN_no,
  513. []dwAttrForm{
  514. {DW_AT_abstract_origin, DW_FORM_ref_addr},
  515. {DW_AT_location, DW_FORM_sec_offset},
  516. },
  517. },
  518. /* PARAM */
  519. {
  520. DW_TAG_formal_parameter,
  521. DW_CHILDREN_no,
  522. []dwAttrForm{
  523. {DW_AT_name, DW_FORM_string},
  524. {DW_AT_variable_parameter, DW_FORM_flag},
  525. {DW_AT_decl_line, DW_FORM_udata},
  526. {DW_AT_type, DW_FORM_ref_addr},
  527. {DW_AT_location, DW_FORM_block1},
  528. },
  529. },
  530. /* PARAM_LOCLIST */
  531. {
  532. DW_TAG_formal_parameter,
  533. DW_CHILDREN_no,
  534. []dwAttrForm{
  535. {DW_AT_name, DW_FORM_string},
  536. {DW_AT_variable_parameter, DW_FORM_flag},
  537. {DW_AT_decl_line, DW_FORM_udata},
  538. {DW_AT_type, DW_FORM_ref_addr},
  539. {DW_AT_location, DW_FORM_sec_offset},
  540. },
  541. },
  542. /* PARAM_ABSTRACT */
  543. {
  544. DW_TAG_formal_parameter,
  545. DW_CHILDREN_no,
  546. []dwAttrForm{
  547. {DW_AT_name, DW_FORM_string},
  548. {DW_AT_variable_parameter, DW_FORM_flag},
  549. {DW_AT_type, DW_FORM_ref_addr},
  550. },
  551. },
  552. /* PARAM_CONCRETE */
  553. {
  554. DW_TAG_formal_parameter,
  555. DW_CHILDREN_no,
  556. []dwAttrForm{
  557. {DW_AT_abstract_origin, DW_FORM_ref_addr},
  558. {DW_AT_location, DW_FORM_block1},
  559. },
  560. },
  561. /* PARAM_CONCRETE_LOCLIST */
  562. {
  563. DW_TAG_formal_parameter,
  564. DW_CHILDREN_no,
  565. []dwAttrForm{
  566. {DW_AT_abstract_origin, DW_FORM_ref_addr},
  567. {DW_AT_location, DW_FORM_sec_offset},
  568. },
  569. },
  570. /* LEXICAL_BLOCK_RANGES */
  571. {
  572. DW_TAG_lexical_block,
  573. DW_CHILDREN_yes,
  574. []dwAttrForm{
  575. {DW_AT_ranges, DW_FORM_sec_offset},
  576. },
  577. },
  578. /* LEXICAL_BLOCK_SIMPLE */
  579. {
  580. DW_TAG_lexical_block,
  581. DW_CHILDREN_yes,
  582. []dwAttrForm{
  583. {DW_AT_low_pc, DW_FORM_addr},
  584. {DW_AT_high_pc, DW_FORM_addr},
  585. },
  586. },
  587. /* STRUCTFIELD */
  588. {
  589. DW_TAG_member,
  590. DW_CHILDREN_no,
  591. []dwAttrForm{
  592. {DW_AT_name, DW_FORM_string},
  593. {DW_AT_data_member_location, DW_FORM_udata},
  594. {DW_AT_type, DW_FORM_ref_addr},
  595. {DW_AT_go_embedded_field, DW_FORM_flag},
  596. },
  597. },
  598. /* FUNCTYPEPARAM */
  599. {
  600. DW_TAG_formal_parameter,
  601. DW_CHILDREN_no,
  602. // No name!
  603. []dwAttrForm{
  604. {DW_AT_type, DW_FORM_ref_addr},
  605. },
  606. },
  607. /* DOTDOTDOT */
  608. {
  609. DW_TAG_unspecified_parameters,
  610. DW_CHILDREN_no,
  611. []dwAttrForm{},
  612. },
  613. /* ARRAYRANGE */
  614. {
  615. DW_TAG_subrange_type,
  616. DW_CHILDREN_no,
  617. // No name!
  618. []dwAttrForm{
  619. {DW_AT_type, DW_FORM_ref_addr},
  620. {DW_AT_count, DW_FORM_udata},
  621. },
  622. },
  623. // Below here are the types considered public by ispubtype
  624. /* NULLTYPE */
  625. {
  626. DW_TAG_unspecified_type,
  627. DW_CHILDREN_no,
  628. []dwAttrForm{
  629. {DW_AT_name, DW_FORM_string},
  630. },
  631. },
  632. /* BASETYPE */
  633. {
  634. DW_TAG_base_type,
  635. DW_CHILDREN_no,
  636. []dwAttrForm{
  637. {DW_AT_name, DW_FORM_string},
  638. {DW_AT_encoding, DW_FORM_data1},
  639. {DW_AT_byte_size, DW_FORM_data1},
  640. {DW_AT_go_kind, DW_FORM_data1},
  641. {DW_AT_go_runtime_type, DW_FORM_addr},
  642. },
  643. },
  644. /* ARRAYTYPE */
  645. // child is subrange with upper bound
  646. {
  647. DW_TAG_array_type,
  648. DW_CHILDREN_yes,
  649. []dwAttrForm{
  650. {DW_AT_name, DW_FORM_string},
  651. {DW_AT_type, DW_FORM_ref_addr},
  652. {DW_AT_byte_size, DW_FORM_udata},
  653. {DW_AT_go_kind, DW_FORM_data1},
  654. {DW_AT_go_runtime_type, DW_FORM_addr},
  655. },
  656. },
  657. /* CHANTYPE */
  658. {
  659. DW_TAG_typedef,
  660. DW_CHILDREN_no,
  661. []dwAttrForm{
  662. {DW_AT_name, DW_FORM_string},
  663. {DW_AT_type, DW_FORM_ref_addr},
  664. {DW_AT_go_kind, DW_FORM_data1},
  665. {DW_AT_go_runtime_type, DW_FORM_addr},
  666. {DW_AT_go_elem, DW_FORM_ref_addr},
  667. },
  668. },
  669. /* FUNCTYPE */
  670. {
  671. DW_TAG_subroutine_type,
  672. DW_CHILDREN_yes,
  673. []dwAttrForm{
  674. {DW_AT_name, DW_FORM_string},
  675. {DW_AT_byte_size, DW_FORM_udata},
  676. {DW_AT_go_kind, DW_FORM_data1},
  677. {DW_AT_go_runtime_type, DW_FORM_addr},
  678. },
  679. },
  680. /* IFACETYPE */
  681. {
  682. DW_TAG_typedef,
  683. DW_CHILDREN_yes,
  684. []dwAttrForm{
  685. {DW_AT_name, DW_FORM_string},
  686. {DW_AT_type, DW_FORM_ref_addr},
  687. {DW_AT_go_kind, DW_FORM_data1},
  688. {DW_AT_go_runtime_type, DW_FORM_addr},
  689. },
  690. },
  691. /* MAPTYPE */
  692. {
  693. DW_TAG_typedef,
  694. DW_CHILDREN_no,
  695. []dwAttrForm{
  696. {DW_AT_name, DW_FORM_string},
  697. {DW_AT_type, DW_FORM_ref_addr},
  698. {DW_AT_go_kind, DW_FORM_data1},
  699. {DW_AT_go_runtime_type, DW_FORM_addr},
  700. {DW_AT_go_key, DW_FORM_ref_addr},
  701. {DW_AT_go_elem, DW_FORM_ref_addr},
  702. },
  703. },
  704. /* PTRTYPE */
  705. {
  706. DW_TAG_pointer_type,
  707. DW_CHILDREN_no,
  708. []dwAttrForm{
  709. {DW_AT_name, DW_FORM_string},
  710. {DW_AT_type, DW_FORM_ref_addr},
  711. {DW_AT_go_kind, DW_FORM_data1},
  712. {DW_AT_go_runtime_type, DW_FORM_addr},
  713. },
  714. },
  715. /* BARE_PTRTYPE */
  716. {
  717. DW_TAG_pointer_type,
  718. DW_CHILDREN_no,
  719. []dwAttrForm{
  720. {DW_AT_name, DW_FORM_string},
  721. },
  722. },
  723. /* SLICETYPE */
  724. {
  725. DW_TAG_structure_type,
  726. DW_CHILDREN_yes,
  727. []dwAttrForm{
  728. {DW_AT_name, DW_FORM_string},
  729. {DW_AT_byte_size, DW_FORM_udata},
  730. {DW_AT_go_kind, DW_FORM_data1},
  731. {DW_AT_go_runtime_type, DW_FORM_addr},
  732. {DW_AT_go_elem, DW_FORM_ref_addr},
  733. },
  734. },
  735. /* STRINGTYPE */
  736. {
  737. DW_TAG_structure_type,
  738. DW_CHILDREN_yes,
  739. []dwAttrForm{
  740. {DW_AT_name, DW_FORM_string},
  741. {DW_AT_byte_size, DW_FORM_udata},
  742. {DW_AT_go_kind, DW_FORM_data1},
  743. {DW_AT_go_runtime_type, DW_FORM_addr},
  744. },
  745. },
  746. /* STRUCTTYPE */
  747. {
  748. DW_TAG_structure_type,
  749. DW_CHILDREN_yes,
  750. []dwAttrForm{
  751. {DW_AT_name, DW_FORM_string},
  752. {DW_AT_byte_size, DW_FORM_udata},
  753. {DW_AT_go_kind, DW_FORM_data1},
  754. {DW_AT_go_runtime_type, DW_FORM_addr},
  755. },
  756. },
  757. /* TYPEDECL */
  758. {
  759. DW_TAG_typedef,
  760. DW_CHILDREN_no,
  761. []dwAttrForm{
  762. {DW_AT_name, DW_FORM_string},
  763. {DW_AT_type, DW_FORM_ref_addr},
  764. },
  765. },
  766. }
  767. // GetAbbrev returns the contents of the .debug_abbrev section.
  768. func GetAbbrev() []byte {
  769. abbrevs := Abbrevs()
  770. var buf []byte
  771. for i := 1; i < DW_NABRV; i++ {
  772. // See section 7.5.3
  773. buf = AppendUleb128(buf, uint64(i))
  774. buf = AppendUleb128(buf, uint64(abbrevs[i].tag))
  775. buf = append(buf, abbrevs[i].children)
  776. for _, f := range abbrevs[i].attr {
  777. buf = AppendUleb128(buf, uint64(f.attr))
  778. buf = AppendUleb128(buf, uint64(f.form))
  779. }
  780. buf = append(buf, 0, 0)
  781. }
  782. return append(buf, 0)
  783. }
  784. /*
  785. * Debugging Information Entries and their attributes.
  786. */
  787. // DWAttr represents an attribute of a DWDie.
  788. //
  789. // For DW_CLS_string and _block, value should contain the length, and
  790. // data the data, for _reference, value is 0 and data is a DWDie* to
  791. // the referenced instance, for all others, value is the whole thing
  792. // and data is null.
  793. type DWAttr struct {
  794. Link *DWAttr
  795. Atr uint16 // DW_AT_
  796. Cls uint8 // DW_CLS_
  797. Value int64
  798. Data interface{}
  799. }
  800. // DWDie represents a DWARF debug info entry.
  801. type DWDie struct {
  802. Abbrev int
  803. Link *DWDie
  804. Child *DWDie
  805. Attr *DWAttr
  806. Sym Sym
  807. }
  808. func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, data interface{}) error {
  809. switch form {
  810. case DW_FORM_addr: // address
  811. // Allow nil addresses for DW_AT_go_runtime_type.
  812. if data == nil && value == 0 {
  813. ctxt.AddInt(s, ctxt.PtrSize(), 0)
  814. break
  815. }
  816. if cls == DW_CLS_GO_TYPEREF {
  817. ctxt.AddSectionOffset(s, ctxt.PtrSize(), data, value)
  818. break
  819. }
  820. ctxt.AddAddress(s, data, value)
  821. case DW_FORM_block1: // block
  822. if cls == DW_CLS_ADDRESS {
  823. ctxt.AddInt(s, 1, int64(1+ctxt.PtrSize()))
  824. ctxt.AddInt(s, 1, DW_OP_addr)
  825. ctxt.AddAddress(s, data, 0)
  826. break
  827. }
  828. value &= 0xff
  829. ctxt.AddInt(s, 1, value)
  830. p := data.([]byte)[:value]
  831. ctxt.AddBytes(s, p)
  832. case DW_FORM_block2: // block
  833. value &= 0xffff
  834. ctxt.AddInt(s, 2, value)
  835. p := data.([]byte)[:value]
  836. ctxt.AddBytes(s, p)
  837. case DW_FORM_block4: // block
  838. value &= 0xffffffff
  839. ctxt.AddInt(s, 4, value)
  840. p := data.([]byte)[:value]
  841. ctxt.AddBytes(s, p)
  842. case DW_FORM_block: // block
  843. Uleb128put(ctxt, s, value)
  844. p := data.([]byte)[:value]
  845. ctxt.AddBytes(s, p)
  846. case DW_FORM_data1: // constant
  847. ctxt.AddInt(s, 1, value)
  848. case DW_FORM_data2: // constant
  849. ctxt.AddInt(s, 2, value)
  850. case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr
  851. if cls == DW_CLS_PTR { // DW_AT_stmt_list and DW_AT_ranges
  852. ctxt.AddDWARFAddrSectionOffset(s, data, value)
  853. break
  854. }
  855. ctxt.AddInt(s, 4, value)
  856. case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr
  857. ctxt.AddInt(s, 8, value)
  858. case DW_FORM_sdata: // constant
  859. Sleb128put(ctxt, s, value)
  860. case DW_FORM_udata: // constant
  861. Uleb128put(ctxt, s, value)
  862. case DW_FORM_string: // string
  863. str := data.(string)
  864. ctxt.AddString(s, str)
  865. // TODO(ribrdb): verify padded strings are never used and remove this
  866. for i := int64(len(str)); i < value; i++ {
  867. ctxt.AddInt(s, 1, 0)
  868. }
  869. case DW_FORM_flag: // flag
  870. if value != 0 {
  871. ctxt.AddInt(s, 1, 1)
  872. } else {
  873. ctxt.AddInt(s, 1, 0)
  874. }
  875. // As of DWARF 3 the ref_addr is always 32 bits, unless emitting a large
  876. // (> 4 GB of debug info aka "64-bit") unit, which we don't implement.
  877. case DW_FORM_ref_addr: // reference to a DIE in the .info section
  878. fallthrough
  879. case DW_FORM_sec_offset: // offset into a DWARF section other than .info
  880. if data == nil {
  881. return fmt.Errorf("dwarf: null reference in %d", abbrev)
  882. }
  883. ctxt.AddDWARFAddrSectionOffset(s, data, value)
  884. case DW_FORM_ref1, // reference within the compilation unit
  885. DW_FORM_ref2, // reference
  886. DW_FORM_ref4, // reference
  887. DW_FORM_ref8, // reference
  888. DW_FORM_ref_udata, // reference
  889. DW_FORM_strp, // string
  890. DW_FORM_indirect: // (see Section 7.5.3)
  891. fallthrough
  892. default:
  893. return fmt.Errorf("dwarf: unsupported attribute form %d / class %d", form, cls)
  894. }
  895. return nil
  896. }
  897. // PutAttrs writes the attributes for a DIE to symbol 's'.
  898. //
  899. // Note that we can (and do) add arbitrary attributes to a DIE, but
  900. // only the ones actually listed in the Abbrev will be written out.
  901. func PutAttrs(ctxt Context, s Sym, abbrev int, attr *DWAttr) {
  902. abbrevs := Abbrevs()
  903. Outer:
  904. for _, f := range abbrevs[abbrev].attr {
  905. for ap := attr; ap != nil; ap = ap.Link {
  906. if ap.Atr == f.attr {
  907. putattr(ctxt, s, abbrev, int(f.form), int(ap.Cls), ap.Value, ap.Data)
  908. continue Outer
  909. }
  910. }
  911. putattr(ctxt, s, abbrev, int(f.form), 0, 0, nil)
  912. }
  913. }
  914. // HasChildren reports whether 'die' uses an abbrev that supports children.
  915. func HasChildren(die *DWDie) bool {
  916. abbrevs := Abbrevs()
  917. return abbrevs[die.Abbrev].children != 0
  918. }
  919. // PutIntConst writes a DIE for an integer constant
  920. func PutIntConst(ctxt Context, info, typ Sym, name string, val int64) {
  921. Uleb128put(ctxt, info, DW_ABRV_INT_CONSTANT)
  922. putattr(ctxt, info, DW_ABRV_INT_CONSTANT, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name)
  923. putattr(ctxt, info, DW_ABRV_INT_CONSTANT, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, typ)
  924. putattr(ctxt, info, DW_ABRV_INT_CONSTANT, DW_FORM_sdata, DW_CLS_CONSTANT, val, nil)
  925. }
  926. // PutBasedRanges writes a range table to sym. All addresses in ranges are
  927. // relative to some base address, which must be arranged by the caller
  928. // (e.g., with a DW_AT_low_pc attribute, or in a BASE-prefixed range).
  929. func PutBasedRanges(ctxt Context, sym Sym, ranges []Range) {
  930. ps := ctxt.PtrSize()
  931. // Write ranges.
  932. for _, r := range ranges {
  933. ctxt.AddInt(sym, ps, r.Start)
  934. ctxt.AddInt(sym, ps, r.End)
  935. }
  936. // Write trailer.
  937. ctxt.AddInt(sym, ps, 0)
  938. ctxt.AddInt(sym, ps, 0)
  939. }
  940. // PutRanges writes a range table to s.Ranges.
  941. // All addresses in ranges are relative to s.base.
  942. func (s *FnState) PutRanges(ctxt Context, ranges []Range) {
  943. ps := ctxt.PtrSize()
  944. sym, base := s.Ranges, s.StartPC
  945. if s.UseBASEntries {
  946. // Using a Base Address Selection Entry reduces the number of relocations, but
  947. // this is not done on macOS because it is not supported by dsymutil/dwarfdump/lldb
  948. ctxt.AddInt(sym, ps, -1)
  949. ctxt.AddAddress(sym, base, 0)
  950. PutBasedRanges(ctxt, sym, ranges)
  951. return
  952. }
  953. // Write ranges full of relocations
  954. for _, r := range ranges {
  955. ctxt.AddCURelativeAddress(sym, base, r.Start)
  956. ctxt.AddCURelativeAddress(sym, base, r.End)
  957. }
  958. // Write trailer.
  959. ctxt.AddInt(sym, ps, 0)
  960. ctxt.AddInt(sym, ps, 0)
  961. }
  962. // Return TRUE if the inlined call in the specified slot is empty,
  963. // meaning it has a zero-length range (no instructions), and all
  964. // of its children are empty.
  965. func isEmptyInlinedCall(slot int, calls *InlCalls) bool {
  966. ic := &calls.Calls[slot]
  967. if ic.InlIndex == -2 {
  968. return true
  969. }
  970. live := false
  971. for _, k := range ic.Children {
  972. if !isEmptyInlinedCall(k, calls) {
  973. live = true
  974. }
  975. }
  976. if len(ic.Ranges) > 0 {
  977. live = true
  978. }
  979. if !live {
  980. ic.InlIndex = -2
  981. }
  982. return !live
  983. }
  984. // Slot -1: return top-level inlines
  985. // Slot >= 0: return children of that slot
  986. func inlChildren(slot int, calls *InlCalls) []int {
  987. var kids []int
  988. if slot != -1 {
  989. for _, k := range calls.Calls[slot].Children {
  990. if !isEmptyInlinedCall(k, calls) {
  991. kids = append(kids, k)
  992. }
  993. }
  994. } else {
  995. for k := 0; k < len(calls.Calls); k += 1 {
  996. if calls.Calls[k].Root && !isEmptyInlinedCall(k, calls) {
  997. kids = append(kids, k)
  998. }
  999. }
  1000. }
  1001. return kids
  1002. }
  1003. func inlinedVarTable(inlcalls *InlCalls) map[*Var]bool {
  1004. vars := make(map[*Var]bool)
  1005. for _, ic := range inlcalls.Calls {
  1006. for _, v := range ic.InlVars {
  1007. vars[v] = true
  1008. }
  1009. }
  1010. return vars
  1011. }
  1012. // The s.Scopes slice contains variables were originally part of the
  1013. // function being emitted, as well as variables that were imported
  1014. // from various callee functions during the inlining process. This
  1015. // function prunes out any variables from the latter category (since
  1016. // they will be emitted as part of DWARF inlined_subroutine DIEs) and
  1017. // then generates scopes for vars in the former category.
  1018. func putPrunedScopes(ctxt Context, s *FnState, fnabbrev int) error {
  1019. if len(s.Scopes) == 0 {
  1020. return nil
  1021. }
  1022. scopes := make([]Scope, len(s.Scopes), len(s.Scopes))
  1023. pvars := inlinedVarTable(&s.InlCalls)
  1024. for k, s := range s.Scopes {
  1025. var pruned Scope = Scope{Parent: s.Parent, Ranges: s.Ranges}
  1026. for i := 0; i < len(s.Vars); i++ {
  1027. _, found := pvars[s.Vars[i]]
  1028. if !found {
  1029. pruned.Vars = append(pruned.Vars, s.Vars[i])
  1030. }
  1031. }
  1032. sort.Sort(byChildIndex(pruned.Vars))
  1033. scopes[k] = pruned
  1034. }
  1035. var encbuf [20]byte
  1036. if putscope(ctxt, s, scopes, 0, fnabbrev, encbuf[:0]) < int32(len(scopes)) {
  1037. return errors.New("multiple toplevel scopes")
  1038. }
  1039. return nil
  1040. }
  1041. // Emit DWARF attributes and child DIEs for an 'abstract' subprogram.
  1042. // The abstract subprogram DIE for a function contains its
  1043. // location-independent attributes (name, type, etc). Other instances
  1044. // of the function (any inlined copy of it, or the single out-of-line
  1045. // 'concrete' instance) will contain a pointer back to this abstract
  1046. // DIE (as a space-saving measure, so that name/type etc doesn't have
  1047. // to be repeated for each inlined copy).
  1048. func PutAbstractFunc(ctxt Context, s *FnState) error {
  1049. if logDwarf {
  1050. ctxt.Logf("PutAbstractFunc(%v)\n", s.Absfn)
  1051. }
  1052. abbrev := DW_ABRV_FUNCTION_ABSTRACT
  1053. Uleb128put(ctxt, s.Absfn, int64(abbrev))
  1054. fullname := s.Name
  1055. if strings.HasPrefix(s.Name, "\"\".") {
  1056. // Generate a fully qualified name for the function in the
  1057. // abstract case. This is so as to avoid the need for the
  1058. // linker to process the DIE with patchDWARFName(); we can't
  1059. // allow the name attribute of an abstract subprogram DIE to
  1060. // be rewritten, since it would change the offsets of the
  1061. // child DIEs (which we're relying on in order for abstract
  1062. // origin references to work).
  1063. fullname = objabi.PathToPrefix(s.Importpath) + "." + s.Name[3:]
  1064. }
  1065. putattr(ctxt, s.Absfn, abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(fullname)), fullname)
  1066. // DW_AT_inlined value
  1067. putattr(ctxt, s.Absfn, abbrev, DW_FORM_data1, DW_CLS_CONSTANT, int64(DW_INL_inlined), nil)
  1068. var ev int64
  1069. if s.External {
  1070. ev = 1
  1071. }
  1072. putattr(ctxt, s.Absfn, abbrev, DW_FORM_flag, DW_CLS_FLAG, ev, 0)
  1073. // Child variables (may be empty)
  1074. var flattened []*Var
  1075. // This slice will hold the offset in bytes for each child var DIE
  1076. // with respect to the start of the parent subprogram DIE.
  1077. var offsets []int32
  1078. // Scopes/vars
  1079. if len(s.Scopes) > 0 {
  1080. // For abstract subprogram DIEs we want to flatten out scope info:
  1081. // lexical scope DIEs contain range and/or hi/lo PC attributes,
  1082. // which we explicitly don't want for the abstract subprogram DIE.
  1083. pvars := inlinedVarTable(&s.InlCalls)
  1084. for _, scope := range s.Scopes {
  1085. for i := 0; i < len(scope.Vars); i++ {
  1086. _, found := pvars[scope.Vars[i]]
  1087. if found || !scope.Vars[i].IsInAbstract {
  1088. continue
  1089. }
  1090. flattened = append(flattened, scope.Vars[i])
  1091. }
  1092. }
  1093. if len(flattened) > 0 {
  1094. sort.Sort(byChildIndex(flattened))
  1095. if logDwarf {
  1096. ctxt.Logf("putAbstractScope(%v): vars:", s.Info)
  1097. for i, v := range flattened {
  1098. ctxt.Logf(" %d:%s", i, v.Name)
  1099. }
  1100. ctxt.Logf("\n")
  1101. }
  1102. // This slice will hold the offset in bytes for each child
  1103. // variable DIE with respect to the start of the parent
  1104. // subprogram DIE.
  1105. for _, v := range flattened {
  1106. offsets = append(offsets, int32(ctxt.CurrentOffset(s.Absfn)))
  1107. putAbstractVar(ctxt, s.Absfn, v)
  1108. }
  1109. }
  1110. }
  1111. ctxt.RecordChildDieOffsets(s.Absfn, flattened, offsets)
  1112. Uleb128put(ctxt, s.Absfn, 0)
  1113. return nil
  1114. }
  1115. // Emit DWARF attributes and child DIEs for an inlined subroutine. The
  1116. // first attribute of an inlined subroutine DIE is a reference back to
  1117. // its corresponding 'abstract' DIE (containing location-independent
  1118. // attributes such as name, type, etc). Inlined subroutine DIEs can
  1119. // have other inlined subroutine DIEs as children.
  1120. func PutInlinedFunc(ctxt Context, s *FnState, callersym Sym, callIdx int) error {
  1121. ic := s.InlCalls.Calls[callIdx]
  1122. callee := ic.AbsFunSym
  1123. abbrev := DW_ABRV_INLINED_SUBROUTINE_RANGES
  1124. if len(ic.Ranges) == 1 {
  1125. abbrev = DW_ABRV_INLINED_SUBROUTINE
  1126. }
  1127. Uleb128put(ctxt, s.Info, int64(abbrev))
  1128. if logDwarf {
  1129. ctxt.Logf("PutInlinedFunc(caller=%v,callee=%v,abbrev=%d)\n", callersym, callee, abbrev)
  1130. }
  1131. // Abstract origin.
  1132. putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, callee)
  1133. if abbrev == DW_ABRV_INLINED_SUBROUTINE_RANGES {
  1134. putattr(ctxt, s.Info, abbrev, DW_FORM_sec_offset, DW_CLS_PTR, s.Ranges.Length(ctxt), s.Ranges)
  1135. s.PutRanges(ctxt, ic.Ranges)
  1136. } else {
  1137. st := ic.Ranges[0].Start
  1138. en := ic.Ranges[0].End
  1139. putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, st, s.StartPC)
  1140. putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, en, s.StartPC)
  1141. }
  1142. // Emit call file, line attrs.
  1143. ctxt.AddFileRef(s.Info, ic.CallFile)
  1144. form := int(expandPseudoForm(DW_FORM_udata_pseudo))
  1145. putattr(ctxt, s.Info, abbrev, form, DW_CLS_CONSTANT, int64(ic.CallLine), nil)
  1146. // Variables associated with this inlined routine instance.
  1147. vars := ic.InlVars
  1148. sort.Sort(byChildIndex(vars))
  1149. inlIndex := ic.InlIndex
  1150. var encbuf [20]byte
  1151. for _, v := range vars {
  1152. if !v.IsInAbstract {
  1153. continue
  1154. }
  1155. putvar(ctxt, s, v, callee, abbrev, inlIndex, encbuf[:0])
  1156. }
  1157. // Children of this inline.
  1158. for _, sib := range inlChildren(callIdx, &s.InlCalls) {
  1159. absfn := s.InlCalls.Calls[sib].AbsFunSym
  1160. err := PutInlinedFunc(ctxt, s, absfn, sib)
  1161. if err != nil {
  1162. return err
  1163. }
  1164. }
  1165. Uleb128put(ctxt, s.Info, 0)
  1166. return nil
  1167. }
  1168. // Emit DWARF attributes and child DIEs for a 'concrete' subprogram,
  1169. // meaning the out-of-line copy of a function that was inlined at some
  1170. // point during the compilation of its containing package. The first
  1171. // attribute for a concrete DIE is a reference to the 'abstract' DIE
  1172. // for the function (which holds location-independent attributes such
  1173. // as name, type), then the remainder of the attributes are specific
  1174. // to this instance (location, frame base, etc).
  1175. func PutConcreteFunc(ctxt Context, s *FnState) error {
  1176. if logDwarf {
  1177. ctxt.Logf("PutConcreteFunc(%v)\n", s.Info)
  1178. }
  1179. abbrev := DW_ABRV_FUNCTION_CONCRETE
  1180. Uleb128put(ctxt, s.Info, int64(abbrev))
  1181. // Abstract origin.
  1182. putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, s.Absfn)
  1183. // Start/end PC.
  1184. putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, 0, s.StartPC)
  1185. putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, s.Size, s.StartPC)
  1186. // cfa / frame base
  1187. putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, 1, []byte{DW_OP_call_frame_cfa})
  1188. // Scopes
  1189. if err := putPrunedScopes(ctxt, s, abbrev); err != nil {
  1190. return err
  1191. }
  1192. // Inlined subroutines.
  1193. for _, sib := range inlChildren(-1, &s.InlCalls) {
  1194. absfn := s.InlCalls.Calls[sib].AbsFunSym
  1195. err := PutInlinedFunc(ctxt, s, absfn, sib)
  1196. if err != nil {
  1197. return err
  1198. }
  1199. }
  1200. Uleb128put(ctxt, s.Info, 0)
  1201. return nil
  1202. }
  1203. // Emit DWARF attributes and child DIEs for a subprogram. Here
  1204. // 'default' implies that the function in question was not inlined
  1205. // when its containing package was compiled (hence there is no need to
  1206. // emit an abstract version for it to use as a base for inlined
  1207. // routine records).
  1208. func PutDefaultFunc(ctxt Context, s *FnState) error {
  1209. if logDwarf {
  1210. ctxt.Logf("PutDefaultFunc(%v)\n", s.Info)
  1211. }
  1212. abbrev := DW_ABRV_FUNCTION
  1213. Uleb128put(ctxt, s.Info, int64(abbrev))
  1214. // Expand '"".' to import path.
  1215. name := s.Name
  1216. if s.Importpath != "" {
  1217. name = strings.Replace(name, "\"\".", objabi.PathToPrefix(s.Importpath)+".", -1)
  1218. }
  1219. putattr(ctxt, s.Info, DW_ABRV_FUNCTION, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name)
  1220. putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, 0, s.StartPC)
  1221. putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, s.Size, s.StartPC)
  1222. putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, 1, []byte{DW_OP_call_frame_cfa})
  1223. ctxt.AddFileRef(s.Info, s.Filesym)
  1224. var ev int64
  1225. if s.External {
  1226. ev = 1
  1227. }
  1228. putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, ev, 0)
  1229. // Scopes
  1230. if err := putPrunedScopes(ctxt, s, abbrev); err != nil {
  1231. return err
  1232. }
  1233. // Inlined subroutines.
  1234. for _, sib := range inlChildren(-1, &s.InlCalls) {
  1235. absfn := s.InlCalls.Calls[sib].AbsFunSym
  1236. err := PutInlinedFunc(ctxt, s, absfn, sib)
  1237. if err != nil {
  1238. return err
  1239. }
  1240. }
  1241. Uleb128put(ctxt, s.Info, 0)
  1242. return nil
  1243. }
  1244. func putscope(ctxt Context, s *FnState, scopes []Scope, curscope int32, fnabbrev int, encbuf []byte) int32 {
  1245. if logDwarf {
  1246. ctxt.Logf("putscope(%v,%d): vars:", s.Info, curscope)
  1247. for i, v := range scopes[curscope].Vars {
  1248. ctxt.Logf(" %d:%d:%s", i, v.ChildIndex, v.Name)
  1249. }
  1250. ctxt.Logf("\n")
  1251. }
  1252. for _, v := range scopes[curscope].Vars {
  1253. putvar(ctxt, s, v, s.Absfn, fnabbrev, -1, encbuf)
  1254. }
  1255. this := curscope
  1256. curscope++
  1257. for curscope < int32(len(scopes)) {
  1258. scope := scopes[curscope]
  1259. if scope.Parent != this {
  1260. return curscope
  1261. }
  1262. if len(scopes[curscope].Vars) == 0 {
  1263. curscope = putscope(ctxt, s, scopes, curscope, fnabbrev, encbuf)
  1264. continue
  1265. }
  1266. if len(scope.Ranges) == 1 {
  1267. Uleb128put(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_SIMPLE)
  1268. putattr(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_SIMPLE, DW_FORM_addr, DW_CLS_ADDRESS, scope.Ranges[0].Start, s.StartPC)
  1269. putattr(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_SIMPLE, DW_FORM_addr, DW_CLS_ADDRESS, scope.Ranges[0].End, s.StartPC)
  1270. } else {
  1271. Uleb128put(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_RANGES)
  1272. putattr(ctxt, s.Info, DW_ABRV_LEXICAL_BLOCK_RANGES, DW_FORM_sec_offset, DW_CLS_PTR, s.Ranges.Length(ctxt), s.Ranges)
  1273. s.PutRanges(ctxt, scope.Ranges)
  1274. }
  1275. curscope = putscope(ctxt, s, scopes, curscope, fnabbrev, encbuf)
  1276. Uleb128put(ctxt, s.Info, 0)
  1277. }
  1278. return curscope
  1279. }
  1280. // Given a default var abbrev code, select corresponding concrete code.
  1281. func concreteVarAbbrev(varAbbrev int) int {
  1282. switch varAbbrev {
  1283. case DW_ABRV_AUTO:
  1284. return DW_ABRV_AUTO_CONCRETE
  1285. case DW_ABRV_PARAM:
  1286. return DW_ABRV_PARAM_CONCRETE
  1287. case DW_ABRV_AUTO_LOCLIST:
  1288. return DW_ABRV_AUTO_CONCRETE_LOCLIST
  1289. case DW_ABRV_PARAM_LOCLIST:
  1290. return DW_ABRV_PARAM_CONCRETE_LOCLIST
  1291. default:
  1292. panic("should never happen")
  1293. }
  1294. }
  1295. // Pick the correct abbrev code for variable or parameter DIE.
  1296. func determineVarAbbrev(v *Var, fnabbrev int) (int, bool, bool) {
  1297. abbrev := v.Abbrev
  1298. // If the variable was entirely optimized out, don't emit a location list;
  1299. // convert to an inline abbreviation and emit an empty location.
  1300. missing := false
  1301. switch {
  1302. case abbrev == DW_ABRV_AUTO_LOCLIST && v.PutLocationList == nil:
  1303. missing = true
  1304. abbrev = DW_ABRV_AUTO
  1305. case abbrev == DW_ABRV_PARAM_LOCLIST && v.PutLocationList == nil:
  1306. missing = true
  1307. abbrev = DW_ABRV_PARAM
  1308. }
  1309. // Determine whether to use a concrete variable or regular variable DIE.
  1310. concrete := true
  1311. switch fnabbrev {
  1312. case DW_ABRV_FUNCTION:
  1313. concrete = false
  1314. break
  1315. case DW_ABRV_FUNCTION_CONCRETE:
  1316. // If we're emitting a concrete subprogram DIE and the variable
  1317. // in question is not part of the corresponding abstract function DIE,
  1318. // then use the default (non-concrete) abbrev for this param.
  1319. if !v.IsInAbstract {
  1320. concrete = false
  1321. }
  1322. case DW_ABRV_INLINED_SUBROUTINE, DW_ABRV_INLINED_SUBROUTINE_RANGES:
  1323. default:
  1324. panic("should never happen")
  1325. }
  1326. // Select proper abbrev based on concrete/non-concrete
  1327. if concrete {
  1328. abbrev = concreteVarAbbrev(abbrev)
  1329. }
  1330. return abbrev, missing, concrete
  1331. }
  1332. func abbrevUsesLoclist(abbrev int) bool {
  1333. switch abbrev {
  1334. case DW_ABRV_AUTO_LOCLIST, DW_ABRV_AUTO_CONCRETE_LOCLIST,
  1335. DW_ABRV_PARAM_LOCLIST, DW_ABRV_PARAM_CONCRETE_LOCLIST:
  1336. return true
  1337. default:
  1338. return false
  1339. }
  1340. }
  1341. // Emit DWARF attributes for a variable belonging to an 'abstract' subprogram.
  1342. func putAbstractVar(ctxt Context, info Sym, v *Var) {
  1343. // Remap abbrev
  1344. abbrev := v.Abbrev
  1345. switch abbrev {
  1346. case DW_ABRV_AUTO, DW_ABRV_AUTO_LOCLIST:
  1347. abbrev = DW_ABRV_AUTO_ABSTRACT
  1348. case DW_ABRV_PARAM, DW_ABRV_PARAM_LOCLIST:
  1349. abbrev = DW_ABRV_PARAM_ABSTRACT
  1350. }
  1351. Uleb128put(ctxt, info, int64(abbrev))
  1352. putattr(ctxt, info, abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(v.Name)), v.Name)
  1353. // Isreturn attribute if this is a param
  1354. if abbrev == DW_ABRV_PARAM_ABSTRACT {
  1355. var isReturn int64
  1356. if v.IsReturnValue {
  1357. isReturn = 1
  1358. }
  1359. putattr(ctxt, info, abbrev, DW_FORM_flag, DW_CLS_FLAG, isReturn, nil)
  1360. }
  1361. // Line
  1362. if abbrev != DW_ABRV_PARAM_ABSTRACT {
  1363. // See issue 23374 for more on why decl line is skipped for abs params.
  1364. putattr(ctxt, info, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(v.DeclLine), nil)
  1365. }
  1366. // Type
  1367. putattr(ctxt, info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type)
  1368. // Var has no children => no terminator
  1369. }
  1370. func putvar(ctxt Context, s *FnState, v *Var, absfn Sym, fnabbrev, inlIndex int, encbuf []byte) {
  1371. // Remap abbrev according to parent DIE abbrev
  1372. abbrev, missing, concrete := determineVarAbbrev(v, fnabbrev)
  1373. Uleb128put(ctxt, s.Info, int64(abbrev))
  1374. // Abstract origin for concrete / inlined case
  1375. if concrete {
  1376. // Here we are making a reference to a child DIE of an abstract
  1377. // function subprogram DIE. The child DIE has no LSym, so instead
  1378. // after the call to 'putattr' below we make a call to register
  1379. // the child DIE reference.
  1380. putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, absfn)
  1381. ctxt.RecordDclReference(s.Info, absfn, int(v.ChildIndex), inlIndex)
  1382. } else {
  1383. // Var name, line for abstract and default cases
  1384. n := v.Name
  1385. putattr(ctxt, s.Info, abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n)
  1386. if abbrev == DW_ABRV_PARAM || abbrev == DW_ABRV_PARAM_LOCLIST || abbrev == DW_ABRV_PARAM_ABSTRACT {
  1387. var isReturn int64
  1388. if v.IsReturnValue {
  1389. isReturn = 1
  1390. }
  1391. putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, isReturn, nil)
  1392. }
  1393. putattr(ctxt, s.Info, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(v.DeclLine), nil)
  1394. putattr(ctxt, s.Info, abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type)
  1395. }
  1396. if abbrevUsesLoclist(abbrev) {
  1397. putattr(ctxt, s.Info, abbrev, DW_FORM_sec_offset, DW_CLS_PTR, s.Loc.Length(ctxt), s.Loc)
  1398. v.PutLocationList(s.Loc, s.StartPC)
  1399. } else {
  1400. loc := encbuf[:0]
  1401. switch {
  1402. case missing:
  1403. break // no location
  1404. case v.StackOffset == 0:
  1405. loc = append(loc, DW_OP_call_frame_cfa)
  1406. default:
  1407. loc = append(loc, DW_OP_fbreg)
  1408. loc = AppendSleb128(loc, int64(v.StackOffset))
  1409. }
  1410. putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, int64(len(loc)), loc)
  1411. }
  1412. // Var has no children => no terminator
  1413. }
  1414. // VarsByOffset attaches the methods of sort.Interface to []*Var,
  1415. // sorting in increasing StackOffset.
  1416. type VarsByOffset []*Var
  1417. func (s VarsByOffset) Len() int { return len(s) }
  1418. func (s VarsByOffset) Less(i, j int) bool { return s[i].StackOffset < s[j].StackOffset }
  1419. func (s VarsByOffset) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
  1420. // byChildIndex implements sort.Interface for []*dwarf.Var by child index.
  1421. type byChildIndex []*Var
  1422. func (s byChildIndex) Len() int { return len(s) }
  1423. func (s byChildIndex) Less(i, j int) bool { return s[i].ChildIndex < s[j].ChildIndex }
  1424. func (s byChildIndex) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
  1425. // IsDWARFEnabledOnAIX returns true if DWARF is possible on the
  1426. // current extld.
  1427. // AIX ld doesn't support DWARF with -bnoobjreorder with version
  1428. // prior to 7.2.2.
  1429. func IsDWARFEnabledOnAIXLd(extld string) (bool, error) {
  1430. out, err := exec.Command(extld, "-Wl,-V").CombinedOutput()
  1431. if err != nil {
  1432. // The normal output should display ld version and
  1433. // then fails because ".main" is not defined:
  1434. // ld: 0711-317 ERROR: Undefined symbol: .main
  1435. if !bytes.Contains(out, []byte("0711-317")) {
  1436. return false, fmt.Errorf("%s -Wl,-V failed: %v\n%s", extld, err, out)
  1437. }
  1438. }
  1439. // gcc -Wl,-V output should be:
  1440. // /usr/bin/ld: LD X.X.X(date)
  1441. // ...
  1442. out = bytes.TrimPrefix(out, []byte("/usr/bin/ld: LD "))
  1443. vers := string(bytes.Split(out, []byte("("))[0])
  1444. subvers := strings.Split(vers, ".")
  1445. if len(subvers) != 3 {
  1446. return false, fmt.Errorf("cannot parse %s -Wl,-V (%s): %v\n", extld, out, err)
  1447. }
  1448. if v, err := strconv.Atoi(subvers[0]); err != nil || v < 7 {
  1449. return false, nil
  1450. } else if v > 7 {
  1451. return true, nil
  1452. }
  1453. if v, err := strconv.Atoi(subvers[1]); err != nil || v < 2 {
  1454. return false, nil
  1455. } else if v > 2 {
  1456. return true, nil
  1457. }
  1458. if v, err := strconv.Atoi(subvers[2]); err != nil || v < 2 {
  1459. return false, nil
  1460. }
  1461. return true, nil
  1462. }