github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/ld/dwarf.c (about)

     1  // Copyright 2010 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  
     5  // TODO/NICETOHAVE:
     6  //   - eliminate DW_CLS_ if not used
     7  //   - package info in compilation units
     8  //   - assign global variables and types to their packages
     9  //   - gdb uses c syntax, meaning clumsy quoting is needed for go identifiers. eg
    10  //     ptype struct '[]uint8' and qualifiers need to be quoted away
    11  //   - lexical scoping is lost, so gdb gets confused as to which 'main.i' you mean.
    12  //   - file:line info for variables
    13  //   - make strings a typedef so prettyprinters can see the underlying string type
    14  //
    15  #include	"l.h"
    16  #include	"lib.h"
    17  #include	"../ld/dwarf.h"
    18  #include	"../ld/dwarf_defs.h"
    19  #include	"../ld/elf.h"
    20  #include	"../ld/macho.h"
    21  #include	"../ld/pe.h"
    22  #include	"../../pkg/runtime/typekind.h"
    23  
    24  /*
    25   * Offsets and sizes of the debug_* sections in the cout file.
    26   */
    27  
    28  static vlong abbrevo;
    29  static vlong abbrevsize;
    30  static Sym*  abbrevsym;
    31  static vlong abbrevsympos;
    32  static vlong lineo;
    33  static vlong linesize;
    34  static Sym*  linesym;
    35  static vlong linesympos;
    36  static vlong infoo;	// also the base for DWDie->offs and reference attributes.
    37  static vlong infosize;
    38  static Sym*  infosym;
    39  static vlong infosympos;
    40  static vlong frameo;
    41  static vlong framesize;
    42  static Sym*  framesym;
    43  static vlong framesympos;
    44  static vlong pubnameso;
    45  static vlong pubnamessize;
    46  static vlong pubtypeso;
    47  static vlong pubtypessize;
    48  static vlong arangeso;
    49  static vlong arangessize;
    50  static vlong gdbscripto;
    51  static vlong gdbscriptsize;
    52  
    53  static Sym *infosec;
    54  static vlong inforeloco;
    55  static vlong inforelocsize;
    56  
    57  static Sym *arangessec;
    58  static vlong arangesreloco;
    59  static vlong arangesrelocsize;
    60  
    61  static Sym *linesec;
    62  static vlong linereloco;
    63  static vlong linerelocsize;
    64  
    65  static Sym *framesec;
    66  static vlong framereloco;
    67  static vlong framerelocsize;
    68  
    69  static char  gdbscript[1024];
    70  
    71  /*
    72   *  Basic I/O
    73   */
    74  
    75  static void
    76  addrput(vlong addr)
    77  {
    78  	switch(PtrSize) {
    79  	case 4:
    80  		LPUT(addr);
    81  		break;
    82  	case 8:
    83  		VPUT(addr);
    84  		break;
    85  	}
    86  }
    87  
    88  static int
    89  uleb128enc(uvlong v, char* dst)
    90  {
    91  	uint8 c, len;
    92  
    93  	len = 0;
    94  	do {
    95  		c = v & 0x7f;
    96  		v >>= 7;
    97  		if (v)
    98  			c |= 0x80;
    99  		if (dst)
   100  			*dst++ = c;
   101  		len++;
   102  	} while (c & 0x80);
   103  	return len;
   104  };
   105  
   106  static int
   107  sleb128enc(vlong v, char *dst)
   108  {
   109  	uint8 c, s, len;
   110  
   111  	len = 0;
   112  	do {
   113  		c = v & 0x7f;
   114  		s = v & 0x40;
   115  		v >>= 7;
   116  		if ((v != -1 || !s) && (v != 0 || s))
   117  			c |= 0x80;
   118  		if (dst)
   119  			*dst++ = c;
   120  		len++;
   121  	} while(c & 0x80);
   122  	return len;
   123  }
   124  
   125  static void
   126  uleb128put(vlong v)
   127  {
   128  	char buf[10];
   129  	strnput(buf, uleb128enc(v, buf));
   130  }
   131  
   132  static void
   133  sleb128put(vlong v)
   134  {
   135  	char buf[10];
   136  	strnput(buf, sleb128enc(v, buf));
   137  }
   138  
   139  /*
   140   * Defining Abbrevs.  This is hardcoded, and there will be
   141   * only a handful of them.  The DWARF spec places no restriction on
   142   * the ordering of attributes in the Abbrevs and DIEs, and we will
   143   * always write them out in the order of declaration in the abbrev.
   144   * This implementation relies on tag, attr < 127, so they serialize as
   145   * a char.  Higher numbered user-defined tags or attributes can be used
   146   * for storing internal data but won't be serialized.
   147   */
   148  typedef struct DWAttrForm DWAttrForm;
   149  struct DWAttrForm {
   150  	uint8 attr;
   151  	uint8 form;
   152  };
   153  
   154  // Index into the abbrevs table below.
   155  // Keep in sync with ispubname() and ispubtype() below.
   156  // ispubtype considers >= NULLTYPE public
   157  enum
   158  {
   159  	DW_ABRV_NULL,
   160  	DW_ABRV_COMPUNIT,
   161  	DW_ABRV_FUNCTION,
   162  	DW_ABRV_VARIABLE,
   163  	DW_ABRV_AUTO,
   164  	DW_ABRV_PARAM,
   165  	DW_ABRV_STRUCTFIELD,
   166  	DW_ABRV_FUNCTYPEPARAM,
   167  	DW_ABRV_DOTDOTDOT,
   168  	DW_ABRV_ARRAYRANGE,
   169  	DW_ABRV_NULLTYPE,
   170  	DW_ABRV_BASETYPE,
   171  	DW_ABRV_ARRAYTYPE,
   172  	DW_ABRV_CHANTYPE,
   173  	DW_ABRV_FUNCTYPE,
   174  	DW_ABRV_IFACETYPE,
   175  	DW_ABRV_MAPTYPE,
   176  	DW_ABRV_PTRTYPE,
   177  	DW_ABRV_BARE_PTRTYPE, // only for void*, no DW_AT_type attr to please gdb 6.
   178  	DW_ABRV_SLICETYPE,
   179  	DW_ABRV_STRINGTYPE,
   180  	DW_ABRV_STRUCTTYPE,
   181  	DW_ABRV_TYPEDECL,
   182  	DW_NABRV
   183  };
   184  
   185  typedef struct DWAbbrev DWAbbrev;
   186  static struct DWAbbrev {
   187  	uint8 tag;
   188  	uint8 children;
   189  	DWAttrForm attr[30];
   190  } abbrevs[DW_NABRV] = {
   191  	/* The mandatory DW_ABRV_NULL entry. */
   192  	{ 0 },
   193  	/* COMPUNIT */
   194  	{
   195  		DW_TAG_compile_unit, DW_CHILDREN_yes,
   196  		DW_AT_name,	 DW_FORM_string,
   197  		DW_AT_language,	 DW_FORM_data1,
   198  		DW_AT_low_pc,	 DW_FORM_addr,
   199  		DW_AT_high_pc,	 DW_FORM_addr,
   200  		DW_AT_stmt_list, DW_FORM_data4,
   201  		0, 0
   202  	},
   203  	/* FUNCTION */
   204  	{
   205  		DW_TAG_subprogram, DW_CHILDREN_yes,
   206  		DW_AT_name,	 DW_FORM_string,
   207  		DW_AT_low_pc,	 DW_FORM_addr,
   208  		DW_AT_high_pc,	 DW_FORM_addr,
   209  		DW_AT_external,	 DW_FORM_flag,
   210  		0, 0
   211  	},
   212  	/* VARIABLE */
   213  	{
   214  		DW_TAG_variable, DW_CHILDREN_no,
   215  		DW_AT_name,	 DW_FORM_string,
   216  		DW_AT_location,	 DW_FORM_block1,
   217  		DW_AT_type,	 DW_FORM_ref_addr,
   218  		DW_AT_external,	 DW_FORM_flag,
   219  		0, 0
   220  	},
   221  	/* AUTO */
   222  	{
   223  		DW_TAG_variable, DW_CHILDREN_no,
   224  		DW_AT_name,	 DW_FORM_string,
   225  		DW_AT_location,	 DW_FORM_block1,
   226  		DW_AT_type,	 DW_FORM_ref_addr,
   227  		0, 0
   228  	},
   229  	/* PARAM */
   230  	{
   231  		DW_TAG_formal_parameter, DW_CHILDREN_no,
   232  		DW_AT_name,	 DW_FORM_string,
   233  		DW_AT_location,	 DW_FORM_block1,
   234  		DW_AT_type,	 DW_FORM_ref_addr,
   235  		0, 0
   236  	},
   237  	/* STRUCTFIELD */
   238  	{
   239  		DW_TAG_member,	DW_CHILDREN_no,
   240  		DW_AT_name,	DW_FORM_string,
   241  		DW_AT_data_member_location, DW_FORM_block1,
   242  		DW_AT_type,	 DW_FORM_ref_addr,
   243  		0, 0
   244  	},
   245  	/* FUNCTYPEPARAM */
   246  	{
   247  		DW_TAG_formal_parameter, DW_CHILDREN_no,
   248  		// No name!
   249  		DW_AT_type,	 DW_FORM_ref_addr,
   250  		0, 0
   251  	},
   252  
   253  	/* DOTDOTDOT */
   254  	{
   255  		DW_TAG_unspecified_parameters, DW_CHILDREN_no,
   256  		0, 0
   257  	},
   258  	/* ARRAYRANGE */
   259  	{
   260  		DW_TAG_subrange_type, DW_CHILDREN_no,
   261  		// No name!
   262  		DW_AT_type,	 DW_FORM_ref_addr,
   263  		DW_AT_upper_bound, DW_FORM_data1,
   264  		0, 0
   265  	},
   266  
   267  	// Below here are the types considered public by ispubtype
   268  	/* NULLTYPE */
   269  	{
   270  		DW_TAG_unspecified_type, DW_CHILDREN_no,
   271  		DW_AT_name,	DW_FORM_string,
   272  		0, 0
   273  	},
   274  	/* BASETYPE */
   275  	{
   276  		DW_TAG_base_type, DW_CHILDREN_no,
   277  		DW_AT_name,	 DW_FORM_string,
   278  		DW_AT_encoding,	 DW_FORM_data1,
   279  		DW_AT_byte_size, DW_FORM_data1,
   280  		0, 0
   281  	},
   282  	/* ARRAYTYPE */
   283  	// child is subrange with upper bound
   284  	{
   285  		DW_TAG_array_type, DW_CHILDREN_yes,
   286  		DW_AT_name,	DW_FORM_string,
   287  		DW_AT_type,	DW_FORM_ref_addr,
   288  		DW_AT_byte_size, DW_FORM_udata,
   289  		0, 0
   290  	},
   291  
   292  	/* CHANTYPE */
   293  	{
   294  		DW_TAG_typedef, DW_CHILDREN_no,
   295  		DW_AT_name,	DW_FORM_string,
   296  		DW_AT_type,	DW_FORM_ref_addr,
   297  		0, 0
   298  	},
   299  
   300  	/* FUNCTYPE */
   301  	{
   302  		DW_TAG_subroutine_type, DW_CHILDREN_yes,
   303  		DW_AT_name,	DW_FORM_string,
   304  //		DW_AT_type,	DW_FORM_ref_addr,
   305  		0, 0
   306  	},
   307  
   308  	/* IFACETYPE */
   309  	{
   310  		DW_TAG_typedef, DW_CHILDREN_yes,
   311  		DW_AT_name,	 DW_FORM_string,
   312  		DW_AT_type,	DW_FORM_ref_addr,
   313  		0, 0
   314  	},
   315  
   316  	/* MAPTYPE */
   317  	{
   318  		DW_TAG_typedef, DW_CHILDREN_no,
   319  		DW_AT_name,	DW_FORM_string,
   320  		DW_AT_type,	DW_FORM_ref_addr,
   321  		0, 0
   322  	},
   323  
   324  	/* PTRTYPE */
   325  	{
   326  		DW_TAG_pointer_type, DW_CHILDREN_no,
   327  		DW_AT_name,	DW_FORM_string,
   328  		DW_AT_type,	DW_FORM_ref_addr,
   329  		0, 0
   330  	},
   331  	/* BARE_PTRTYPE */
   332  	{
   333  		DW_TAG_pointer_type, DW_CHILDREN_no,
   334  		DW_AT_name,	DW_FORM_string,
   335  		0, 0
   336  	},
   337  
   338  	/* SLICETYPE */
   339  	{
   340  		DW_TAG_structure_type, DW_CHILDREN_yes,
   341  		DW_AT_name,	DW_FORM_string,
   342  		DW_AT_byte_size, DW_FORM_udata,
   343  		0, 0
   344  	},
   345  
   346  	/* STRINGTYPE */
   347  	{
   348  		DW_TAG_structure_type, DW_CHILDREN_yes,
   349  		DW_AT_name,	DW_FORM_string,
   350  		DW_AT_byte_size, DW_FORM_udata,
   351  		0, 0
   352  	},
   353  
   354  	/* STRUCTTYPE */
   355  	{
   356  		DW_TAG_structure_type, DW_CHILDREN_yes,
   357  		DW_AT_name,	DW_FORM_string,
   358  		DW_AT_byte_size, DW_FORM_udata,
   359  		0, 0
   360  	},
   361  
   362  	/* TYPEDECL */
   363  	{
   364  		DW_TAG_typedef, DW_CHILDREN_no,
   365  		DW_AT_name,	DW_FORM_string,
   366  		DW_AT_type,	DW_FORM_ref_addr,
   367  		0, 0
   368  	},
   369  };
   370  
   371  static void
   372  writeabbrev(void)
   373  {
   374  	int i, n;
   375  
   376  	abbrevo = cpos();
   377  	for (i = 1; i < DW_NABRV; i++) {
   378  		// See section 7.5.3
   379  		uleb128put(i);
   380  		uleb128put(abbrevs[i].tag);
   381  		cput(abbrevs[i].children);
   382  		// 0 is not a valid attr or form, and DWAbbrev.attr is
   383  		// 0-terminated, so we can treat it as a string
   384  		n = strlen((char*)abbrevs[i].attr) / 2;
   385  		strnput((char*)abbrevs[i].attr,
   386  			(n+1) * sizeof(DWAttrForm));
   387  	}
   388  	cput(0);
   389  	abbrevsize = cpos() - abbrevo;
   390  }
   391  
   392  /*
   393   * Debugging Information Entries and their attributes.
   394   */
   395  
   396  enum
   397  {
   398  	HASHSIZE = 107
   399  };
   400  
   401  static uint32
   402  hashstr(char* s)
   403  {
   404  	uint32 h;
   405  
   406  	h = 0;
   407  	while (*s)
   408  		h = h+h+h + *s++;
   409  	return h % HASHSIZE;
   410  }
   411  
   412  // For DW_CLS_string and _block, value should contain the length, and
   413  // data the data, for _reference, value is 0 and data is a DWDie* to
   414  // the referenced instance, for all others, value is the whole thing
   415  // and data is null.
   416  
   417  typedef struct DWAttr DWAttr;
   418  struct DWAttr {
   419  	DWAttr *link;
   420  	uint8 atr;  // DW_AT_
   421  	uint8 cls;  // DW_CLS_
   422  	vlong value;
   423  	char *data;
   424  };
   425  
   426  typedef struct DWDie DWDie;
   427  struct DWDie {
   428  	int abbrev;
   429  	DWDie *link;
   430  	DWDie *child;
   431  	DWAttr *attr;
   432  	// offset into .debug_info section, i.e relative to
   433  	// infoo. only valid after call to putdie()
   434  	vlong offs;
   435  	DWDie **hash;  // optional index of children by name, enabled by mkindex()
   436  	DWDie *hlink;  // bucket chain in parent's index
   437  };
   438  
   439  /*
   440   * Root DIEs for compilation units, types and global variables.
   441   */
   442  
   443  static DWDie dwroot;
   444  static DWDie dwtypes;
   445  static DWDie dwglobals;
   446  
   447  static DWAttr*
   448  newattr(DWDie *die, uint8 attr, int cls, vlong value, char *data)
   449  {
   450  	DWAttr *a;
   451  
   452  	a = mal(sizeof *a);
   453  	a->link = die->attr;
   454  	die->attr = a;
   455  	a->atr = attr;
   456  	a->cls = cls;
   457  	a->value = value;
   458  	a->data = data;
   459  	return a;
   460  }
   461  
   462  // Each DIE (except the root ones) has at least 1 attribute: its
   463  // name. getattr moves the desired one to the front so
   464  // frequently searched ones are found faster.
   465  static DWAttr*
   466  getattr(DWDie *die, uint8 attr)
   467  {
   468  	DWAttr *a, *b;
   469  
   470  	if (die->attr->atr == attr)
   471  		return die->attr;
   472  
   473  	a = die->attr;
   474  	b = a->link;
   475  	while (b != nil) {
   476  		if (b->atr == attr) {
   477  			a->link = b->link;
   478  			b->link = die->attr;
   479  			die->attr = b;
   480  			return b;
   481  		}
   482  		a = b;
   483  		b = b->link;
   484  	}
   485  	return nil;
   486  }
   487  
   488  // Every DIE has at least a DW_AT_name attribute (but it will only be
   489  // written out if it is listed in the abbrev).	If its parent is
   490  // keeping an index, the new DIE will be inserted there.
   491  static DWDie*
   492  newdie(DWDie *parent, int abbrev, char *name)
   493  {
   494  	DWDie *die;
   495  	int h;
   496  
   497  	die = mal(sizeof *die);
   498  	die->abbrev = abbrev;
   499  	die->link = parent->child;
   500  	parent->child = die;
   501  
   502  	newattr(die, DW_AT_name, DW_CLS_STRING, strlen(name), name);
   503  
   504  	if (parent->hash) {
   505  		h = hashstr(name);
   506  		die->hlink = parent->hash[h];
   507  		parent->hash[h] = die;
   508  	}
   509  
   510  	return die;
   511  }
   512  
   513  static void
   514  mkindex(DWDie *die)
   515  {
   516  	die->hash = mal(HASHSIZE * sizeof(DWDie*));
   517  }
   518  
   519  static DWDie*
   520  walktypedef(DWDie *die)
   521  {
   522  	DWAttr *attr;
   523  
   524  	// Resolve typedef if present.
   525  	if (die->abbrev == DW_ABRV_TYPEDECL) {
   526  		for (attr = die->attr; attr; attr = attr->link) {
   527  			if (attr->atr == DW_AT_type && attr->cls == DW_CLS_REFERENCE && attr->data != nil) {
   528  				return (DWDie*)attr->data;
   529  			}
   530  		}
   531  	}
   532  	return die;
   533  }
   534  
   535  // Find child by AT_name using hashtable if available or linear scan
   536  // if not.
   537  static DWDie*
   538  find(DWDie *die, char* name)
   539  {
   540  	DWDie *a, *b, *die2;
   541  	int h;
   542  
   543  top:
   544  	if (die->hash == nil) {
   545  		for (a = die->child; a != nil; a = a->link)
   546  			if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
   547  				return a;
   548  		goto notfound;
   549  	}
   550  
   551  	h = hashstr(name);
   552  	a = die->hash[h];
   553  
   554  	if (a == nil)
   555  		goto notfound;
   556  
   557  
   558  	if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
   559  		return a;
   560  
   561  	// Move found ones to head of the list.
   562  	b = a->hlink;
   563  	while (b != nil) {
   564  		if (strcmp(name, getattr(b, DW_AT_name)->data) == 0) {
   565  			a->hlink = b->hlink;
   566  			b->hlink = die->hash[h];
   567  			die->hash[h] = b;
   568  			return b;
   569  		}
   570  		a = b;
   571  		b = b->hlink;
   572  	}
   573  
   574  notfound:
   575  	die2 = walktypedef(die);
   576  	if(die2 != die) {
   577  		die = die2;
   578  		goto top;
   579  	}
   580  
   581  	return nil;
   582  }
   583  
   584  static DWDie*
   585  find_or_diag(DWDie *die, char* name)
   586  {
   587  	DWDie *r;
   588  	r = find(die, name);
   589  	if (r == nil) {
   590  		diag("dwarf find: %s %p has no %s", getattr(die, DW_AT_name)->data, die, name);
   591  		errorexit();
   592  	}
   593  	return r;
   594  }
   595  
   596  static void
   597  adddwarfrel(Sym* sec, Sym* sym, vlong offsetbase, int siz, vlong addend)
   598  {
   599  	Reloc *r;
   600  
   601  	r = addrel(sec);
   602  	r->sym = sym;
   603  	r->xsym = sym;
   604  	r->off = cpos() - offsetbase;
   605  	r->siz = siz;
   606  	r->type = D_ADDR;
   607  	r->add = addend;
   608  	r->xadd = addend;
   609  	if(iself && thechar == '6')
   610  		addend = 0;
   611  	switch(siz) {
   612  	case 4:
   613  		LPUT(addend);
   614  		break;
   615  	case 8:
   616  		VPUT(addend);
   617  		break;
   618  	default:
   619  		diag("bad size in adddwarfrel");
   620  		break;
   621  	}
   622  }
   623  
   624  static DWAttr*
   625  newrefattr(DWDie *die, uint8 attr, DWDie* ref)
   626  {
   627  	if (ref == nil)
   628  		return nil;
   629  	return newattr(die, attr, DW_CLS_REFERENCE, 0, (char*)ref);
   630  }
   631  
   632  static int fwdcount;
   633  
   634  static void
   635  putattr(int abbrev, int form, int cls, vlong value, char *data)
   636  {
   637  	vlong off;
   638  
   639  	switch(form) {
   640  	case DW_FORM_addr:	// address
   641  		if(linkmode == LinkExternal) {
   642  			value -= ((Sym*)data)->value;
   643  			adddwarfrel(infosec, (Sym*)data, infoo, PtrSize, value);
   644  			break;
   645  		}
   646  		addrput(value);
   647  		break;
   648  
   649  	case DW_FORM_block1:	// block
   650  		if(cls == DW_CLS_ADDRESS) {
   651  			cput(1+PtrSize);
   652  			cput(DW_OP_addr);
   653  			if(linkmode == LinkExternal) {
   654  				value -= ((Sym*)data)->value;
   655  				adddwarfrel(infosec, (Sym*)data, infoo, PtrSize, value);
   656  				break;
   657  			}
   658  			addrput(value);
   659  			break;
   660  		}
   661  		value &= 0xff;
   662  		cput(value);
   663  		while(value--)
   664  			cput(*data++);
   665  		break;
   666  
   667  	case DW_FORM_block2:	// block
   668  		value &= 0xffff;
   669  		WPUT(value);
   670  		while(value--)
   671  			cput(*data++);
   672  		break;
   673  
   674  	case DW_FORM_block4:	// block
   675  		value &= 0xffffffff;
   676  		LPUT(value);
   677  		while(value--)
   678  			cput(*data++);
   679  		break;
   680  
   681  	case DW_FORM_block:	// block
   682  		uleb128put(value);
   683  		while(value--)
   684  			cput(*data++);
   685  		break;
   686  
   687  	case DW_FORM_data1:	// constant
   688  		cput(value);
   689  		break;
   690  
   691  	case DW_FORM_data2:	// constant
   692  		WPUT(value);
   693  		break;
   694  
   695  	case DW_FORM_data4:	// constant, {line,loclist,mac,rangelist}ptr
   696  		if(linkmode == LinkExternal && cls == DW_CLS_PTR) {
   697  			adddwarfrel(infosec, linesym, infoo, 4, value);
   698  			break;
   699  		}
   700  		LPUT(value);
   701  		break;
   702  
   703  	case DW_FORM_data8:	// constant, {line,loclist,mac,rangelist}ptr
   704  		VPUT(value);
   705  		break;
   706  
   707  	case DW_FORM_sdata:	// constant
   708  		sleb128put(value);
   709  		break;
   710  
   711  	case DW_FORM_udata:	// constant
   712  		uleb128put(value);
   713  		break;
   714  
   715  	case DW_FORM_string:	// string
   716  		strnput(data, value+1);
   717  		break;
   718  
   719  	case DW_FORM_flag:	// flag
   720  		cput(value?1:0);
   721  		break;
   722  
   723  	case DW_FORM_ref_addr:	// reference to a DIE in the .info section
   724  		// In DWARF 2 (which is what we claim to generate),
   725  		// the ref_addr is the same size as a normal address.
   726  		// In DWARF 3 it is always 32 bits, unless emitting a large
   727  		// (> 4 GB of debug info aka "64-bit") unit, which we don't implement.
   728  		if (data == nil) {
   729  			diag("dwarf: null reference in %d", abbrev);
   730  			if(PtrSize == 8)
   731  				VPUT(0); // invalid dwarf, gdb will complain.
   732  			else
   733  				LPUT(0); // invalid dwarf, gdb will complain.
   734  		} else {
   735  			off = ((DWDie*)data)->offs;
   736  			if (off == 0)
   737  				fwdcount++;
   738  			if(linkmode == LinkExternal) {
   739  				adddwarfrel(infosec, infosym, infoo, PtrSize, off);
   740  				break;
   741  			}
   742  			addrput(off);
   743  		}
   744  		break;
   745  
   746  	case DW_FORM_ref1:	// reference within the compilation unit
   747  	case DW_FORM_ref2:	// reference
   748  	case DW_FORM_ref4:	// reference
   749  	case DW_FORM_ref8:	// reference
   750  	case DW_FORM_ref_udata:	// reference
   751  
   752  	case DW_FORM_strp:	// string
   753  	case DW_FORM_indirect:	// (see Section 7.5.3)
   754  	default:
   755  		diag("dwarf: unsupported attribute form %d / class %d", form, cls);
   756  		errorexit();
   757  	}
   758  }
   759  
   760  // Note that we can (and do) add arbitrary attributes to a DIE, but
   761  // only the ones actually listed in the Abbrev will be written out.
   762  static void
   763  putattrs(int abbrev, DWAttr* attr)
   764  {
   765  	DWAttr *attrs[DW_AT_recursive + 1];
   766  	DWAttrForm* af;
   767  
   768  	memset(attrs, 0, sizeof attrs);
   769  	for( ; attr; attr = attr->link)
   770  		if (attr->atr < nelem(attrs))
   771  			attrs[attr->atr] = attr;
   772  
   773  	for(af = abbrevs[abbrev].attr; af->attr; af++)
   774  		if (attrs[af->attr])
   775  			putattr(abbrev, af->form,
   776  				attrs[af->attr]->cls,
   777  				attrs[af->attr]->value,
   778  				attrs[af->attr]->data);
   779  		else
   780  			putattr(abbrev, af->form, 0, 0, nil);
   781  }
   782  
   783  static void putdie(DWDie* die);
   784  
   785  static void
   786  putdies(DWDie* die)
   787  {
   788  	for(; die; die = die->link)
   789  		putdie(die);
   790  }
   791  
   792  static void
   793  putdie(DWDie* die)
   794  {
   795  	die->offs = cpos() - infoo;
   796  	uleb128put(die->abbrev);
   797  	putattrs(die->abbrev, die->attr);
   798  	if (abbrevs[die->abbrev].children) {
   799  		putdies(die->child);
   800  		cput(0);
   801  	}
   802  }
   803  
   804  static void
   805  reverselist(DWDie** list)
   806  {
   807  	DWDie *curr, *prev;
   808  
   809  	curr = *list;
   810  	prev = nil;
   811  	while(curr != nil) {
   812  		DWDie* next = curr->link;
   813  		curr->link = prev;
   814  		prev = curr;
   815  		curr = next;
   816  	}
   817  	*list = prev;
   818  }
   819  
   820  static void
   821  reversetree(DWDie** list)
   822  {
   823  	 DWDie *die;
   824  
   825  	 reverselist(list);
   826  	 for (die = *list; die != nil; die = die->link)
   827  		 if (abbrevs[die->abbrev].children)
   828  			 reversetree(&die->child);
   829  }
   830  
   831  static void
   832  newmemberoffsetattr(DWDie *die, int32 offs)
   833  {
   834  	char block[10];
   835  	int i;
   836  
   837  	i = 0;
   838  	if (offs != 0) {
   839  		block[i++] = DW_OP_consts;
   840  		i += sleb128enc(offs, block+i);
   841  		block[i++] = DW_OP_plus;
   842  	}
   843  	newattr(die, DW_AT_data_member_location, DW_CLS_BLOCK, i, mal(i));
   844  	memmove(die->attr->data, block, i);
   845  }
   846  
   847  // GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a
   848  // location expression that evals to a const.
   849  static void
   850  newabslocexprattr(DWDie *die, vlong addr, Sym *sym)
   851  {
   852  	newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, (char*)sym);
   853  }
   854  
   855  
   856  // Fake attributes for slices, maps and channel
   857  enum {
   858  	DW_AT_internal_elem_type = 250,	 // channels and slices
   859  	DW_AT_internal_key_type = 251,	 // maps
   860  	DW_AT_internal_val_type = 252,	 // maps
   861  	DW_AT_internal_location = 253,	 // params and locals
   862  };
   863  
   864  static DWDie* defptrto(DWDie *dwtype);	// below
   865  
   866  // Lookup predefined types
   867  static Sym*
   868  lookup_or_diag(char *n)
   869  {
   870  	Sym *s;
   871  
   872  	s = rlookup(n, 0);
   873  	if (s == nil || s->size == 0) {
   874  		diag("dwarf: missing type: %s", n);
   875  		errorexit();
   876  	}
   877  	return s;
   878  }
   879  
   880  static void
   881  dotypedef(DWDie *parent, char *name, DWDie *def)
   882  {
   883  	DWDie *die;
   884  
   885  	// Only emit typedefs for real names.
   886  	if(strncmp(name, "map[", 4) == 0)
   887  		return;
   888  	if(strncmp(name, "struct {", 8) == 0)
   889  		return;
   890  	if(strncmp(name, "chan ", 5) == 0)
   891  		return;
   892  	if(*name == '[' || *name == '*')
   893  		return;
   894  	if(def == nil)
   895  		diag("dwarf: bad def in dotypedef");
   896  
   897  	// The typedef entry must be created after the def,
   898  	// so that future lookups will find the typedef instead
   899  	// of the real definition. This hooks the typedef into any
   900  	// circular definition loops, so that gdb can understand them.
   901  	die = newdie(parent, DW_ABRV_TYPEDECL, name);
   902  	newrefattr(die, DW_AT_type, def);
   903  }
   904  
   905  // Define gotype, for composite ones recurse into constituents.
   906  static DWDie*
   907  defgotype(Sym *gotype)
   908  {
   909  	DWDie *die, *fld;
   910  	Sym *s;
   911  	char *name, *f;
   912  	uint8 kind;
   913  	vlong bytesize;
   914  	int i, nfields;
   915  
   916  	if (gotype == nil)
   917  		return find_or_diag(&dwtypes, "<unspecified>");
   918  
   919  	if (strncmp("type.", gotype->name, 5) != 0) {
   920  		diag("dwarf: type name doesn't start with \".type\": %s", gotype->name);
   921  		return find_or_diag(&dwtypes, "<unspecified>");
   922  	}
   923  	name = gotype->name + 5;  // could also decode from Type.string
   924  
   925  	die = find(&dwtypes, name);
   926  	if (die != nil)
   927  		return die;
   928  
   929  	if (0 && debug['v'] > 2)
   930  		print("new type: %Y\n", gotype);
   931  
   932  	kind = decodetype_kind(gotype);
   933  	bytesize = decodetype_size(gotype);
   934  
   935  	switch (kind) {
   936  	case KindBool:
   937  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
   938  		newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_boolean, 0);
   939  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
   940  		break;
   941  
   942  	case KindInt:
   943  	case KindInt8:
   944  	case KindInt16:
   945  	case KindInt32:
   946  	case KindInt64:
   947  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
   948  		newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_signed, 0);
   949  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
   950  		break;
   951  
   952  	case KindUint:
   953  	case KindUint8:
   954  	case KindUint16:
   955  	case KindUint32:
   956  	case KindUint64:
   957  	case KindUintptr:
   958  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
   959  		newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_unsigned, 0);
   960  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
   961  		break;
   962  
   963  	case KindFloat32:
   964  	case KindFloat64:
   965  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
   966  		newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_float, 0);
   967  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
   968  		break;
   969  
   970  	case KindComplex64:
   971  	case KindComplex128:
   972  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
   973  		newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_complex_float, 0);
   974  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
   975  		break;
   976  
   977  	case KindArray:
   978  		die = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, name);
   979  		dotypedef(&dwtypes, name, die);
   980  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
   981  		s = decodetype_arrayelem(gotype);
   982  		newrefattr(die, DW_AT_type, defgotype(s));
   983  		fld = newdie(die, DW_ABRV_ARRAYRANGE, "range");
   984  		newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0);
   985  		newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
   986  		break;
   987  
   988  	case KindChan:
   989  		die = newdie(&dwtypes, DW_ABRV_CHANTYPE, name);
   990  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
   991  		s = decodetype_chanelem(gotype);
   992  		newrefattr(die, DW_AT_internal_elem_type, defgotype(s));
   993  		break;
   994  
   995  	case KindFunc:
   996  		die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name);
   997  		dotypedef(&dwtypes, name, die);
   998  		newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "void"));
   999  		nfields = decodetype_funcincount(gotype);
  1000  		for (i = 0; i < nfields; i++) {
  1001  			s = decodetype_funcintype(gotype, i);
  1002  			fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s->name+5);
  1003  			newrefattr(fld, DW_AT_type, defgotype(s));
  1004  		}
  1005  		if (decodetype_funcdotdotdot(gotype))
  1006  			newdie(die, DW_ABRV_DOTDOTDOT, "...");
  1007  		nfields = decodetype_funcoutcount(gotype);
  1008  		for (i = 0; i < nfields; i++) {
  1009  			s = decodetype_funcouttype(gotype, i);
  1010  			fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s->name+5);
  1011  			newrefattr(fld, DW_AT_type, defptrto(defgotype(s)));
  1012  		}
  1013  		break;
  1014  
  1015  	case KindInterface:
  1016  		die = newdie(&dwtypes, DW_ABRV_IFACETYPE, name);
  1017  		dotypedef(&dwtypes, name, die);
  1018  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
  1019  		nfields = decodetype_ifacemethodcount(gotype);
  1020  		if (nfields == 0)
  1021  			s = lookup_or_diag("type.runtime.eface");
  1022  		else
  1023  			s = lookup_or_diag("type.runtime.iface");
  1024  		newrefattr(die, DW_AT_type, defgotype(s));
  1025  		break;
  1026  
  1027  	case KindMap:
  1028  		die = newdie(&dwtypes, DW_ABRV_MAPTYPE, name);
  1029  		s = decodetype_mapkey(gotype);
  1030  		newrefattr(die, DW_AT_internal_key_type, defgotype(s));
  1031  		s = decodetype_mapvalue(gotype);
  1032  		newrefattr(die, DW_AT_internal_val_type, defgotype(s));
  1033  		break;
  1034  
  1035  	case KindPtr:
  1036  		die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name);
  1037  		dotypedef(&dwtypes, name, die);
  1038  		s = decodetype_ptrelem(gotype);
  1039  		newrefattr(die, DW_AT_type, defgotype(s));
  1040  		break;
  1041  
  1042  	case KindSlice:
  1043  		die = newdie(&dwtypes, DW_ABRV_SLICETYPE, name);
  1044  		dotypedef(&dwtypes, name, die);
  1045  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
  1046  		s = decodetype_arrayelem(gotype);
  1047  		newrefattr(die, DW_AT_internal_elem_type, defgotype(s));
  1048  		break;
  1049  
  1050  	case KindString:
  1051  		die = newdie(&dwtypes, DW_ABRV_STRINGTYPE, name);
  1052  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
  1053  		break;
  1054  
  1055  	case KindStruct:
  1056  		die = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, name);
  1057  		dotypedef(&dwtypes, name, die);
  1058  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
  1059  		nfields = decodetype_structfieldcount(gotype);
  1060  		for (i = 0; i < nfields; i++) {
  1061  			f = decodetype_structfieldname(gotype, i);
  1062  			s = decodetype_structfieldtype(gotype, i);
  1063  			if (f == nil)
  1064  				f = s->name + 5;	 // skip "type."
  1065  			fld = newdie(die, DW_ABRV_STRUCTFIELD, f);
  1066  			newrefattr(fld, DW_AT_type, defgotype(s));
  1067  			newmemberoffsetattr(fld, decodetype_structfieldoffs(gotype, i));
  1068  		}
  1069  		break;
  1070  
  1071  	case KindUnsafePointer:
  1072  		die = newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, name);
  1073  		break;
  1074  
  1075  	default:
  1076  		diag("dwarf: definition of unknown kind %d: %s", kind, gotype->name);
  1077  		die = newdie(&dwtypes, DW_ABRV_TYPEDECL, name);
  1078  		newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "<unspecified>"));
  1079  	 }
  1080  
  1081  	return die;
  1082  }
  1083  
  1084  // Find or construct *T given T.
  1085  static DWDie*
  1086  defptrto(DWDie *dwtype)
  1087  {
  1088  	char ptrname[1024];
  1089  	DWDie *die;
  1090  
  1091  	snprint(ptrname, sizeof ptrname, "*%s", getattr(dwtype, DW_AT_name)->data);
  1092  	die = find(&dwtypes, ptrname);
  1093  	if (die == nil) {
  1094  		die = newdie(&dwtypes, DW_ABRV_PTRTYPE,
  1095  			     strcpy(mal(strlen(ptrname)+1), ptrname));
  1096  		newrefattr(die, DW_AT_type, dwtype);
  1097  	}
  1098  	return die;
  1099  }
  1100  
  1101  // Copies src's children into dst. Copies attributes by value.
  1102  // DWAttr.data is copied as pointer only.
  1103  static void
  1104  copychildren(DWDie *dst, DWDie *src)
  1105  {
  1106  	DWDie *c;
  1107  	DWAttr *a;
  1108  
  1109  	for (src = src->child; src != nil; src = src->link) {
  1110  		c = newdie(dst, src->abbrev, getattr(src, DW_AT_name)->data);
  1111  		for (a = src->attr; a != nil; a = a->link)
  1112  			newattr(c, a->atr, a->cls, a->value, a->data);
  1113  		copychildren(c, src);
  1114  	}
  1115  	reverselist(&dst->child);
  1116  }
  1117  
  1118  // Search children (assumed to have DW_TAG_member) for the one named
  1119  // field and set its DW_AT_type to dwtype
  1120  static void
  1121  substitutetype(DWDie *structdie, char *field, DWDie* dwtype)
  1122  {
  1123  	DWDie *child;
  1124  	DWAttr *a;
  1125  
  1126  	child = find_or_diag(structdie, field);
  1127  	if (child == nil)
  1128  		return;
  1129  
  1130  	a = getattr(child, DW_AT_type);
  1131  	if (a != nil)
  1132  		a->data = (char*) dwtype;
  1133  	else
  1134  		newrefattr(child, DW_AT_type, dwtype);
  1135  }
  1136  
  1137  static void
  1138  synthesizestringtypes(DWDie* die)
  1139  {
  1140  	DWDie *prototype;
  1141  
  1142  	prototype = walktypedef(defgotype(lookup_or_diag("type.runtime._string")));
  1143  	if (prototype == nil)
  1144  		return;
  1145  
  1146  	for (; die != nil; die = die->link) {
  1147  		if (die->abbrev != DW_ABRV_STRINGTYPE)
  1148  			continue;
  1149  		copychildren(die, prototype);
  1150  	}
  1151  }
  1152  
  1153  static void
  1154  synthesizeslicetypes(DWDie *die)
  1155  {
  1156  	DWDie *prototype, *elem;
  1157  
  1158  	prototype = walktypedef(defgotype(lookup_or_diag("type.runtime.slice")));
  1159  	if (prototype == nil)
  1160  		return;
  1161  
  1162  	for (; die != nil; die = die->link) {
  1163  		if (die->abbrev != DW_ABRV_SLICETYPE)
  1164  			continue;
  1165  		copychildren(die, prototype);
  1166  		elem = (DWDie*) getattr(die, DW_AT_internal_elem_type)->data;
  1167  		substitutetype(die, "array", defptrto(elem));
  1168  	}
  1169  }
  1170  
  1171  static char*
  1172  mkinternaltypename(char *base, char *arg1, char *arg2)
  1173  {
  1174  	char buf[1024];
  1175  	char *n;
  1176  
  1177  	if (arg2 == nil)
  1178  		snprint(buf, sizeof buf, "%s<%s>", base, arg1);
  1179  	else
  1180  		snprint(buf, sizeof buf, "%s<%s,%s>", base, arg1, arg2);
  1181  	n = mal(strlen(buf) + 1);
  1182  	memmove(n, buf, strlen(buf));
  1183  	return n;
  1184  }
  1185  
  1186  // synthesizemaptypes is way too closely married to runtime/hashmap.c
  1187  enum {
  1188  	MaxKeySize = 128,
  1189  	MaxValSize = 128,
  1190  	BucketSize = 8,
  1191  };
  1192  
  1193  static void
  1194  synthesizemaptypes(DWDie *die)
  1195  {
  1196  
  1197  	DWDie *hash, *bucket, *dwh, *dwhk, *dwhv, *dwhb, *keytype, *valtype, *fld;
  1198  	int indirect_key, indirect_val;
  1199  	int keysize, valsize;
  1200  	DWAttr *a;
  1201  
  1202  	hash		= walktypedef(defgotype(lookup_or_diag("type.runtime.hmap")));
  1203  	bucket		= walktypedef(defgotype(lookup_or_diag("type.runtime.bucket")));
  1204  
  1205  	if (hash == nil)
  1206  		return;
  1207  
  1208  	for (; die != nil; die = die->link) {
  1209  		if (die->abbrev != DW_ABRV_MAPTYPE)
  1210  			continue;
  1211  
  1212  		keytype = walktypedef((DWDie*) getattr(die, DW_AT_internal_key_type)->data);
  1213  		valtype = walktypedef((DWDie*) getattr(die, DW_AT_internal_val_type)->data);
  1214  
  1215  		// compute size info like hashmap.c does.
  1216  		a = getattr(keytype, DW_AT_byte_size);
  1217  		keysize = a ? a->value : PtrSize;  // We don't store size with Pointers
  1218  		a = getattr(valtype, DW_AT_byte_size);
  1219  		valsize = a ? a->value : PtrSize;
  1220  		indirect_key = 0;
  1221  		indirect_val = 0;
  1222  		if(keysize > MaxKeySize) {
  1223  			keysize = PtrSize;
  1224  			indirect_key = 1;
  1225  		}
  1226  		if(valsize > MaxValSize) {
  1227  			valsize = PtrSize;
  1228  			indirect_val = 1;
  1229  		}
  1230  
  1231  		// Construct type to represent an array of BucketSize keys
  1232  		dwhk = newdie(&dwtypes, DW_ABRV_ARRAYTYPE,
  1233  			      mkinternaltypename("[]key",
  1234  						 getattr(keytype, DW_AT_name)->data, nil));
  1235  		newattr(dwhk, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize * keysize, 0);
  1236  		newrefattr(dwhk, DW_AT_type, indirect_key ? defptrto(keytype) : keytype);
  1237  		fld = newdie(dwhk, DW_ABRV_ARRAYRANGE, "size");
  1238  		newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, BucketSize, 0);
  1239  		newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
  1240  		
  1241  		// Construct type to represent an array of BucketSize values
  1242  		dwhv = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, 
  1243  			      mkinternaltypename("[]val",
  1244  						 getattr(valtype, DW_AT_name)->data, nil));
  1245  		newattr(dwhv, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize * valsize, 0);
  1246  		newrefattr(dwhv, DW_AT_type, indirect_val ? defptrto(valtype) : valtype);
  1247  		fld = newdie(dwhv, DW_ABRV_ARRAYRANGE, "size");
  1248  		newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, BucketSize, 0);
  1249  		newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
  1250  
  1251  		// Construct bucket<K,V>
  1252  		dwhb = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
  1253  			      mkinternaltypename("bucket",
  1254  						 getattr(keytype, DW_AT_name)->data,
  1255  						 getattr(valtype, DW_AT_name)->data));
  1256  		copychildren(dwhb, bucket);
  1257  		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "keys");
  1258  		newrefattr(fld, DW_AT_type, dwhk);
  1259  		newmemberoffsetattr(fld, BucketSize + PtrSize);
  1260  		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "values");
  1261  		newrefattr(fld, DW_AT_type, dwhv);
  1262  		newmemberoffsetattr(fld, BucketSize + PtrSize + BucketSize * keysize);
  1263  		newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize + PtrSize + BucketSize * keysize + BucketSize * valsize, 0);
  1264  		substitutetype(dwhb, "overflow", defptrto(dwhb));
  1265  
  1266  		// Construct hash<K,V>
  1267  		dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
  1268  			mkinternaltypename("hash",
  1269  				getattr(keytype, DW_AT_name)->data,
  1270  				getattr(valtype, DW_AT_name)->data));
  1271  		copychildren(dwh, hash);
  1272  		substitutetype(dwh, "buckets", defptrto(dwhb));
  1273  		substitutetype(dwh, "oldbuckets", defptrto(dwhb));
  1274  		newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT,
  1275  			getattr(hash, DW_AT_byte_size)->value, nil);
  1276  
  1277  		// make map type a pointer to hash<K,V>
  1278  		newrefattr(die, DW_AT_type, defptrto(dwh));
  1279  	}
  1280  }
  1281  
  1282  static void
  1283  synthesizechantypes(DWDie *die)
  1284  {
  1285  	DWDie *sudog, *waitq, *hchan,
  1286  		*dws, *dww, *dwh, *elemtype;
  1287  	DWAttr *a;
  1288  	int elemsize, sudogsize;
  1289  
  1290  	sudog = walktypedef(defgotype(lookup_or_diag("type.runtime.sudog")));
  1291  	waitq = walktypedef(defgotype(lookup_or_diag("type.runtime.waitq")));
  1292  	hchan = walktypedef(defgotype(lookup_or_diag("type.runtime.hchan")));
  1293  	if (sudog == nil || waitq == nil || hchan == nil)
  1294  		return;
  1295  
  1296  	sudogsize = getattr(sudog, DW_AT_byte_size)->value;
  1297  
  1298  	for (; die != nil; die = die->link) {
  1299  		if (die->abbrev != DW_ABRV_CHANTYPE)
  1300  			continue;
  1301  		elemtype = (DWDie*) getattr(die, DW_AT_internal_elem_type)->data;
  1302  		a = getattr(elemtype, DW_AT_byte_size);
  1303  		elemsize = a ? a->value : PtrSize;
  1304  
  1305  		// sudog<T>
  1306  		dws = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
  1307  			mkinternaltypename("sudog",
  1308  				getattr(elemtype, DW_AT_name)->data, nil));
  1309  		copychildren(dws, sudog);
  1310  		substitutetype(dws, "elem", elemtype);
  1311  		newattr(dws, DW_AT_byte_size, DW_CLS_CONSTANT,
  1312  			sudogsize + (elemsize > 8 ? elemsize - 8 : 0), nil);
  1313  
  1314  		// waitq<T>
  1315  		dww = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
  1316  			mkinternaltypename("waitq", getattr(elemtype, DW_AT_name)->data, nil));
  1317  		copychildren(dww, waitq);
  1318  		substitutetype(dww, "first", defptrto(dws));
  1319  		substitutetype(dww, "last",  defptrto(dws));
  1320  		newattr(dww, DW_AT_byte_size, DW_CLS_CONSTANT,
  1321  			getattr(waitq, DW_AT_byte_size)->value, nil);
  1322  
  1323  		// hchan<T>
  1324  		dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
  1325  			mkinternaltypename("hchan", getattr(elemtype, DW_AT_name)->data, nil));
  1326  		copychildren(dwh, hchan);
  1327  		substitutetype(dwh, "recvq", dww);
  1328  		substitutetype(dwh, "sendq", dww);
  1329  		newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT,
  1330  			getattr(hchan, DW_AT_byte_size)->value, nil);
  1331  
  1332  		newrefattr(die, DW_AT_type, defptrto(dwh));
  1333  	}
  1334  }
  1335  
  1336  // For use with pass.c::genasmsym
  1337  static void
  1338  defdwsymb(Sym* sym, char *s, int t, vlong v, vlong size, int ver, Sym *gotype)
  1339  {
  1340  	DWDie *dv, *dt;
  1341  
  1342  	USED(size);
  1343  	if (strncmp(s, "go.string.", 10) == 0)
  1344  		return;
  1345  
  1346  	if (strncmp(s, "type.", 5) == 0 && strcmp(s, "type.*") != 0 && strncmp(s, "type..", 6) != 0) {
  1347  		defgotype(sym);
  1348  		return;
  1349  	}
  1350  
  1351  	dv = nil;
  1352  
  1353  	switch (t) {
  1354  	default:
  1355  		return;
  1356  	case 'd':
  1357  	case 'b':
  1358  	case 'D':
  1359  	case 'B':
  1360  		dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s);
  1361  		newabslocexprattr(dv, v, sym);
  1362  		if (ver == 0)
  1363  			newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0);
  1364  		// fallthrough
  1365  	case 'a':
  1366  	case 'p':
  1367  		dt = defgotype(gotype);
  1368  	}
  1369  
  1370  	if (dv != nil)
  1371  		newrefattr(dv, DW_AT_type, dt);
  1372  }
  1373  
  1374  // TODO(lvd) For now, just append them all to the first compilation
  1375  // unit (that should be main), in the future distribute them to the
  1376  // appropriate compilation units.
  1377  static void
  1378  movetomodule(DWDie *parent)
  1379  {
  1380  	DWDie *die;
  1381  
  1382  	for (die = dwroot.child->child; die->link != nil; die = die->link) /* nix */;
  1383  	die->link = parent->child;
  1384  }
  1385  
  1386  /*
  1387   * Filename fragments for the line history stack.
  1388   */
  1389  
  1390  static char **ftab;
  1391  static int ftabsize;
  1392  
  1393  void
  1394  dwarfaddfrag(int n, char *frag)
  1395  {
  1396  	int s;
  1397  
  1398  	if (n >= ftabsize) {
  1399  		s = ftabsize;
  1400  		ftabsize = 1 + n + (n >> 2);
  1401  		ftab = erealloc(ftab, ftabsize * sizeof(ftab[0]));
  1402  		memset(ftab + s, 0, (ftabsize - s) * sizeof(ftab[0]));
  1403  	}
  1404  
  1405  	if (*frag == '<')
  1406  		frag++;
  1407  	ftab[n] = frag;
  1408  }
  1409  
  1410  // Returns a malloc'ed string, piecewise copied from the ftab.
  1411  static char *
  1412  decodez(char *s)
  1413  {
  1414  	int len, o;
  1415  	char *ss, *f;
  1416  	char *r, *rb, *re;
  1417  
  1418  	len = 0;
  1419  	ss = s + 1;	// first is 0
  1420  	while((o = ((uint8)ss[0] << 8) | (uint8)ss[1]) != 0) {
  1421  		if (o < 0 || o >= ftabsize) {
  1422  			diag("dwarf: corrupt z entry");
  1423  			return 0;
  1424  		}
  1425  		f = ftab[o];
  1426  		if (f == nil) {
  1427  			diag("dwarf: corrupt z entry");
  1428  			return 0;
  1429  		}
  1430  		len += strlen(f) + 1;	// for the '/'
  1431  		ss += 2;
  1432  	}
  1433  
  1434  	if (len == 0)
  1435  		return 0;
  1436  
  1437  	r = malloc(len + 1);
  1438  	if(r == nil) {
  1439  		diag("out of memory");
  1440  		errorexit();
  1441  	}
  1442  	rb = r;
  1443  	re = rb + len + 1;
  1444  
  1445  	s++;
  1446  	while((o = ((uint8)s[0] << 8) | (uint8)s[1]) != 0) {
  1447  		f = ftab[o];
  1448  		if (rb == r || rb[-1] == '/')
  1449  			rb = seprint(rb, re, "%s", f);
  1450  		else
  1451  			rb = seprint(rb, re, "/%s", f);
  1452  		s += 2;
  1453  	}
  1454  	return r;
  1455  }
  1456  
  1457  /*
  1458   * The line history itself
  1459   */
  1460  
  1461  static char **histfile;	   // [0] holds "<eof>", DW_LNS_set_file arguments must be > 0.
  1462  static int  histfilesize;
  1463  static int  histfilecap;
  1464  
  1465  static void
  1466  clearhistfile(void)
  1467  {
  1468  	int i;
  1469  
  1470  	// [0] holds "<eof>"
  1471  	for (i = 1; i < histfilesize; i++)
  1472  		free(histfile[i]);
  1473  	histfilesize = 0;
  1474  }
  1475  
  1476  static int
  1477  addhistfile(char *zentry)
  1478  {
  1479  	char *fname;
  1480  
  1481  	if (histfilesize == histfilecap) {
  1482  		histfilecap = 2 * histfilecap + 2;
  1483  		histfile = erealloc(histfile, histfilecap * sizeof(char*));
  1484  	}
  1485  	if (histfilesize == 0)
  1486  		histfile[histfilesize++] = "<eof>";
  1487  
  1488  	fname = decodez(zentry);
  1489  //	print("addhistfile %d: %s\n", histfilesize, fname);
  1490  	if (fname == 0)
  1491  		return -1;
  1492  
  1493  	// Don't fill with duplicates (check only top one).
  1494  	if (strcmp(fname, histfile[histfilesize-1]) == 0) {
  1495  		free(fname);
  1496  		return histfilesize - 1;
  1497  	}
  1498  
  1499  	histfile[histfilesize++] = fname;
  1500  	return histfilesize - 1;
  1501  }
  1502  
  1503  // if the histfile stack contains ..../runtime/runtime_defs.go
  1504  // use that to set gdbscript
  1505  static void
  1506  finddebugruntimepath(void)
  1507  {
  1508  	int i, l;
  1509  	char *c;
  1510  
  1511  	for (i = 1; i < histfilesize; i++) {
  1512  		if ((c = strstr(histfile[i], "runtime/zruntime_defs")) != nil) {
  1513  			l = c - histfile[i];
  1514  			memmove(gdbscript, histfile[i], l);
  1515  			memmove(gdbscript + l, "runtime/runtime-gdb.py", strlen("runtime/runtime-gdb.py") + 1);
  1516  			break;
  1517  		}
  1518  	}
  1519  }
  1520  
  1521  // Go's runtime C sources are sane, and Go sources nest only 1 level,
  1522  // so a handful would be plenty, if it weren't for the fact that line
  1523  // directives can push an unlimited number of them.
  1524  static struct {
  1525  	int file;
  1526  	vlong line;
  1527  } *includestack;
  1528  static int includestacksize;
  1529  static int includetop;
  1530  static vlong absline;
  1531  
  1532  typedef struct Linehist Linehist;
  1533  struct Linehist {
  1534  	Linehist *link;
  1535  	vlong absline;
  1536  	vlong line;
  1537  	int file;
  1538  };
  1539  
  1540  static Linehist *linehist;
  1541  
  1542  static void
  1543  checknesting(void)
  1544  {
  1545  	if (includetop < 0) {
  1546  		diag("dwarf: corrupt z stack");
  1547  		errorexit();
  1548  	}
  1549  	if (includetop >= includestacksize) {
  1550  		includestacksize += 1;
  1551  		includestacksize <<= 2;
  1552  //		print("checknesting: growing to %d\n", includestacksize);
  1553  		includestack = erealloc(includestack, includestacksize * sizeof *includestack);	       
  1554  	}
  1555  }
  1556  
  1557  /*
  1558   * Return false if the a->link chain contains no history, otherwise
  1559   * returns true and finds z and Z entries in the Auto list (of a
  1560   * Prog), and resets the history stack
  1561   */
  1562  static int
  1563  inithist(Auto *a)
  1564  {
  1565  	Linehist *lh;
  1566  
  1567  	for (; a; a = a->link)
  1568  		if (a->type == D_FILE)
  1569  			break;
  1570  	if (a==nil)
  1571  		return 0;
  1572  
  1573  	// We have a new history.  They are guaranteed to come completely
  1574  	// at the beginning of the compilation unit.
  1575  	if (a->aoffset != 1) {
  1576  		diag("dwarf: stray 'z' with offset %d", a->aoffset);
  1577  		return 0;
  1578  	}
  1579  
  1580  	// Clear the history.
  1581  	clearhistfile();
  1582  	includetop = 0;
  1583  	checknesting();
  1584  	includestack[includetop].file = 0;
  1585  	includestack[includetop].line = -1;
  1586  	absline = 0;
  1587  	while (linehist != nil) {
  1588  		lh = linehist->link;
  1589  		free(linehist);
  1590  		linehist = lh;
  1591  	}
  1592  
  1593  	// Construct the new one.
  1594  	for (; a; a = a->link) {
  1595  		if (a->type == D_FILE) {  // 'z'
  1596  			int f = addhistfile(a->asym->name);
  1597  			if (f < 0) {	// pop file
  1598  				includetop--;
  1599  				checknesting();
  1600  			} else {	// pushed a file (potentially same)
  1601  				includestack[includetop].line += a->aoffset - absline;
  1602  				includetop++;
  1603  				checknesting();
  1604  				includestack[includetop].file = f;
  1605  				includestack[includetop].line = 1;
  1606  			}
  1607  			absline = a->aoffset;
  1608  		} else if (a->type == D_FILE1) {  // 'Z'
  1609  			// We could just fixup the current
  1610  			// linehist->line, but there doesn't appear to
  1611  			// be a guarantee that every 'Z' is preceded
  1612  			// by its own 'z', so do the safe thing and
  1613  			// update the stack and push a new Linehist
  1614  			// entry
  1615  			includestack[includetop].line =	 a->aoffset;
  1616  		} else
  1617  			continue;
  1618  		if (linehist == 0 || linehist->absline != absline) {
  1619  			Linehist* lh = malloc(sizeof *lh);
  1620  			if(lh == nil) {
  1621  				diag("out of memory");
  1622  				errorexit();
  1623  			}
  1624  			lh->link = linehist;
  1625  			lh->absline = absline;
  1626  			linehist = lh;
  1627  		}
  1628  		linehist->file = includestack[includetop].file;
  1629  		linehist->line = includestack[includetop].line;
  1630  	}
  1631  	return 1;
  1632  }
  1633  
  1634  static Linehist *
  1635  searchhist(vlong absline)
  1636  {
  1637  	Linehist *lh;
  1638  
  1639  	for (lh = linehist; lh; lh = lh->link)
  1640  		if (lh->absline <= absline)
  1641  			break;
  1642  	return lh;
  1643  }
  1644  
  1645  static int
  1646  guesslang(char *s)
  1647  {
  1648  	if(strlen(s) >= 3 && strcmp(s+strlen(s)-3, ".go") == 0)
  1649  		return DW_LANG_Go;
  1650  
  1651  	return DW_LANG_C;
  1652  }
  1653  
  1654  /*
  1655   * Generate short opcodes when possible, long ones when necessary.
  1656   * See section 6.2.5
  1657   */
  1658  
  1659  enum {
  1660  	LINE_BASE = -1,
  1661  	LINE_RANGE = 4,
  1662  	OPCODE_BASE = 5
  1663  };
  1664  
  1665  static void
  1666  putpclcdelta(vlong delta_pc, vlong delta_lc)
  1667  {
  1668  	if (LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE) {
  1669  		vlong opcode = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc);
  1670  		if (OPCODE_BASE <= opcode && opcode < 256) {
  1671  			cput(opcode);
  1672  			return;
  1673  		}
  1674  	}
  1675  
  1676  	if (delta_pc) {
  1677  		cput(DW_LNS_advance_pc);
  1678  		sleb128put(delta_pc);
  1679  	}
  1680  
  1681  	cput(DW_LNS_advance_line);
  1682  	sleb128put(delta_lc);
  1683  	cput(DW_LNS_copy);
  1684  }
  1685  
  1686  static void
  1687  newcfaoffsetattr(DWDie *die, int32 offs)
  1688  {
  1689  	char block[10];
  1690  	int i;
  1691  
  1692  	i = 0;
  1693  
  1694  	block[i++] = DW_OP_call_frame_cfa;
  1695  	if (offs != 0) {
  1696  		block[i++] = DW_OP_consts;
  1697  		i += sleb128enc(offs, block+i);
  1698  		block[i++] = DW_OP_plus;
  1699  	}
  1700  	newattr(die, DW_AT_location, DW_CLS_BLOCK, i, mal(i));
  1701  	memmove(die->attr->data, block, i);
  1702  }
  1703  
  1704  static char*
  1705  mkvarname(char* name, int da)
  1706  {
  1707  	char buf[1024];
  1708  	char *n;
  1709  
  1710  	snprint(buf, sizeof buf, "%s#%d", name, da);
  1711  	n = mal(strlen(buf) + 1);
  1712  	memmove(n, buf, strlen(buf));
  1713  	return n;
  1714  }
  1715  
  1716  /*
  1717   * Walk prog table, emit line program and build DIE tree.
  1718   */
  1719  
  1720  // flush previous compilation unit.
  1721  static void
  1722  flushunit(DWDie *dwinfo, vlong pc, Sym *pcsym, vlong unitstart, int32 header_length)
  1723  {
  1724  	vlong here;
  1725  
  1726  	if (dwinfo != nil && pc != 0) {
  1727  		newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, (char*)pcsym);
  1728  	}
  1729  
  1730  	if (unitstart >= 0) {
  1731  		cput(0);  // start extended opcode
  1732  		uleb128put(1);
  1733  		cput(DW_LNE_end_sequence);
  1734  
  1735  		here = cpos();
  1736  		cseek(unitstart);
  1737  		LPUT(here - unitstart - sizeof(int32));	 // unit_length
  1738  		WPUT(2);  // dwarf version
  1739  		LPUT(header_length); // header length starting here
  1740  		cseek(here);
  1741  	}
  1742  }
  1743  
  1744  static void
  1745  writelines(void)
  1746  {
  1747  	Prog *q;
  1748  	Sym *s, *epcs;
  1749  	Auto *a;
  1750  	vlong unitstart, headerend, offs;
  1751  	vlong pc, epc, lc, llc, lline;
  1752  	int currfile;
  1753  	int i, lang, da, dt;
  1754  	Linehist *lh;
  1755  	DWDie *dwinfo, *dwfunc, *dwvar, **dws;
  1756  	DWDie *varhash[HASHSIZE];
  1757  	char *n, *nn;
  1758  
  1759  	if(linesec == S)
  1760  		linesec = lookup(".dwarfline", 0);
  1761  	linesec->nr = 0;
  1762  
  1763  	unitstart = -1;
  1764  	headerend = -1;
  1765  	pc = 0;
  1766  	epc = 0;
  1767  	epcs = S;
  1768  	lc = 1;
  1769  	llc = 1;
  1770  	currfile = -1;
  1771  	lineo = cpos();
  1772  	dwinfo = nil;
  1773  
  1774  	for(cursym = textp; cursym != nil; cursym = cursym->next) {
  1775  		s = cursym;
  1776  		if(s->text == P)
  1777  			continue;
  1778  
  1779  		// Look for history stack.  If we find one,
  1780  		// we're entering a new compilation unit
  1781  
  1782  		if (inithist(s->autom)) {
  1783  			flushunit(dwinfo, epc, epcs, unitstart, headerend - unitstart - 10);
  1784  			unitstart = cpos();
  1785  
  1786  			if(debug['v'] > 1) {
  1787  				print("dwarf writelines found %s\n", histfile[1]);
  1788  				Linehist* lh;
  1789  				for (lh = linehist; lh; lh = lh->link)
  1790  					print("\t%8lld: [%4lld]%s\n",
  1791  					      lh->absline, lh->line, histfile[lh->file]);
  1792  			}
  1793  
  1794  			lang = guesslang(histfile[1]);
  1795  			finddebugruntimepath();
  1796  
  1797  			dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, estrdup(histfile[1]));
  1798  			newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT,lang, 0);
  1799  			newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart - lineo, 0);
  1800  			newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s->text->pc, (char*)s);
  1801  
  1802  			// Write .debug_line Line Number Program Header (sec 6.2.4)
  1803  			// Fields marked with (*) must be changed for 64-bit dwarf
  1804  			LPUT(0);   // unit_length (*), will be filled in by flushunit.
  1805  			WPUT(2);   // dwarf version (appendix F)
  1806  			LPUT(0);   // header_length (*), filled in by flushunit.
  1807  			// cpos == unitstart + 4 + 2 + 4
  1808  			cput(1);   // minimum_instruction_length
  1809  			cput(1);   // default_is_stmt
  1810  			cput(LINE_BASE);     // line_base
  1811  			cput(LINE_RANGE);    // line_range
  1812  			cput(OPCODE_BASE);   // opcode_base (we only use 1..4)
  1813  			cput(0);   // standard_opcode_lengths[1]
  1814  			cput(1);   // standard_opcode_lengths[2]
  1815  			cput(1);   // standard_opcode_lengths[3]
  1816  			cput(1);   // standard_opcode_lengths[4]
  1817  			cput(0);   // include_directories  (empty)
  1818  
  1819  			for (i=1; i < histfilesize; i++) {
  1820  				strnput(histfile[i], strlen(histfile[i]) + 4);
  1821  				// 4 zeros: the string termination + 3 fields.
  1822  			}
  1823  
  1824  			cput(0);   // terminate file_names.
  1825  			headerend = cpos();
  1826  
  1827  			pc = s->text->pc;
  1828  			epc = pc;
  1829  			epcs = s;
  1830  			currfile = 1;
  1831  			lc = 1;
  1832  			llc = 1;
  1833  
  1834  			cput(0);  // start extended opcode
  1835  			uleb128put(1 + PtrSize);
  1836  			cput(DW_LNE_set_address);
  1837  
  1838  			if(linkmode == LinkExternal)
  1839  				adddwarfrel(linesec, s, lineo, PtrSize, 0);
  1840  			else
  1841  				addrput(pc);
  1842  		}
  1843  		if(s->text == nil)
  1844  			continue;
  1845  
  1846  		if (unitstart < 0) {
  1847  			diag("dwarf: reachable code before seeing any history: %P", s->text);
  1848  			continue;
  1849  		}
  1850  
  1851  		dwfunc = newdie(dwinfo, DW_ABRV_FUNCTION, s->name);
  1852  		newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s->value, (char*)s);
  1853  		epc = s->value + s->size;
  1854  		newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, (char*)s);
  1855  		if (s->version == 0)
  1856  			newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0);
  1857  
  1858  		if(s->text->link == nil)
  1859  			continue;
  1860  
  1861  		for(q = s->text; q != P; q = q->link) {
  1862  			lh = searchhist(q->line);
  1863  			if (lh == nil) {
  1864  				diag("dwarf: corrupt history or bad absolute line: %P", q);
  1865  				continue;
  1866  			}
  1867  
  1868  			if (lh->file < 1) {  // 0 is the past-EOF entry.
  1869  				// diag("instruction with line number past EOF in %s: %P", histfile[1], q);
  1870  				continue;
  1871  			}
  1872  
  1873  			lline = lh->line + q->line - lh->absline;
  1874  			if (debug['v'] > 1)
  1875  				print("%6llux %s[%lld] %P\n", (vlong)q->pc, histfile[lh->file], lline, q);
  1876  
  1877  			if (q->line == lc)
  1878  				continue;
  1879  			if (currfile != lh->file) {
  1880  				currfile = lh->file;
  1881  				cput(DW_LNS_set_file);
  1882  				uleb128put(currfile);
  1883  			}
  1884  			putpclcdelta(q->pc - pc, lline - llc);
  1885  			pc  = q->pc;
  1886  			lc  = q->line;
  1887  			llc = lline;
  1888  		}
  1889  
  1890  		da = 0;
  1891  		dwfunc->hash = varhash;	 // enable indexing of children by name
  1892  		memset(varhash, 0, sizeof varhash);
  1893  		for(a = s->autom; a; a = a->link) {
  1894  			switch (a->type) {
  1895  			case D_AUTO:
  1896  				dt = DW_ABRV_AUTO;
  1897  				offs = a->aoffset - PtrSize;
  1898  				break;
  1899  			case D_PARAM:
  1900  				dt = DW_ABRV_PARAM;
  1901  				offs = a->aoffset;
  1902  				break;
  1903  			default:
  1904  				continue;
  1905  			}
  1906  			if (strstr(a->asym->name, ".autotmp_"))
  1907  				continue;
  1908  			if (find(dwfunc, a->asym->name) != nil)
  1909  				n = mkvarname(a->asym->name, da);
  1910  			else
  1911  				n = a->asym->name;
  1912  			// Drop the package prefix from locals and arguments.
  1913  			nn = strrchr(n, '.');
  1914  			if (nn)
  1915  				n = nn + 1;
  1916  
  1917  			dwvar = newdie(dwfunc, dt, n);
  1918  			newcfaoffsetattr(dwvar, offs);
  1919  			newrefattr(dwvar, DW_AT_type, defgotype(a->gotype));
  1920  
  1921  			// push dwvar down dwfunc->child to preserve order
  1922  			newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, nil);
  1923  			dwfunc->child = dwvar->link;  // take dwvar out from the top of the list
  1924  			for (dws = &dwfunc->child; *dws != nil; dws = &(*dws)->link)
  1925  				if (offs > getattr(*dws, DW_AT_internal_location)->value)
  1926  					break;
  1927  			dwvar->link = *dws;
  1928  			*dws = dwvar;
  1929  
  1930  			da++;
  1931  		}
  1932  
  1933  		dwfunc->hash = nil;
  1934  	}
  1935  
  1936  	flushunit(dwinfo, epc, epcs, unitstart, headerend - unitstart - 10);
  1937  	linesize = cpos() - lineo;
  1938  }
  1939  
  1940  /*
  1941   *  Emit .debug_frame
  1942   */
  1943  enum
  1944  {
  1945  	CIERESERVE = 16,
  1946  	DATAALIGNMENTFACTOR = -4,	// TODO -PtrSize?
  1947  	FAKERETURNCOLUMN = 16		// TODO gdb6 doesn't like > 15?
  1948  };
  1949  
  1950  static void
  1951  putpccfadelta(vlong deltapc, vlong cfa)
  1952  {
  1953  	if (deltapc < 0x40) {
  1954  		cput(DW_CFA_advance_loc + deltapc);
  1955  	} else if (deltapc < 0x100) {
  1956  		cput(DW_CFA_advance_loc1);
  1957  		cput(deltapc);
  1958  	} else if (deltapc < 0x10000) {
  1959  		cput(DW_CFA_advance_loc2);
  1960  		WPUT(deltapc);
  1961  	} else {
  1962  		cput(DW_CFA_advance_loc4);
  1963  		LPUT(deltapc);
  1964  	}
  1965  
  1966  	cput(DW_CFA_def_cfa_offset_sf);
  1967  	sleb128put(cfa / DATAALIGNMENTFACTOR);
  1968  }
  1969  
  1970  static void
  1971  writeframes(void)
  1972  {
  1973  	Prog *p, *q;
  1974  	Sym *s;
  1975  	vlong fdeo, fdesize, pad, cfa, pc;
  1976  
  1977  	if(framesec == S)
  1978  		framesec = lookup(".dwarfframe", 0);
  1979  	framesec->nr = 0;
  1980  	frameo = cpos();
  1981  
  1982  	// Emit the CIE, Section 6.4.1
  1983  	LPUT(CIERESERVE);	// initial length, must be multiple of PtrSize
  1984  	LPUT(0xffffffff);	// cid.
  1985  	cput(3);		// dwarf version (appendix F)
  1986  	cput(0);		// augmentation ""
  1987  	uleb128put(1);		// code_alignment_factor
  1988  	sleb128put(DATAALIGNMENTFACTOR); // guess
  1989  	uleb128put(FAKERETURNCOLUMN);	// return_address_register
  1990  
  1991  	cput(DW_CFA_def_cfa);
  1992  	uleb128put(DWARFREGSP);	// register SP (**ABI-dependent, defined in l.h)
  1993  	uleb128put(PtrSize);	// offset
  1994  
  1995  	cput(DW_CFA_offset + FAKERETURNCOLUMN);	 // return address
  1996  	uleb128put(-PtrSize / DATAALIGNMENTFACTOR);  // at cfa - x*4
  1997  
  1998  	// 4 is to exclude the length field.
  1999  	pad = CIERESERVE + frameo + 4 - cpos();
  2000  	if (pad < 0) {
  2001  		diag("dwarf: CIERESERVE too small by %lld bytes.", -pad);
  2002  		errorexit();
  2003  	}
  2004  	strnput("", pad);
  2005  
  2006  	for(cursym = textp; cursym != nil; cursym = cursym->next) {
  2007  		s = cursym;
  2008  		if(s->text == nil)
  2009  			continue;
  2010  
  2011  		fdeo = cpos();
  2012  		// Emit a FDE, Section 6.4.1, starting wit a placeholder.
  2013  		LPUT(0);	// length, must be multiple of PtrSize
  2014  		LPUT(0);	// Pointer to the CIE above, at offset 0
  2015  		addrput(0);	// initial location
  2016  		addrput(0);	// address range
  2017  
  2018  		cfa = PtrSize;	// CFA starts at sp+PtrSize
  2019  		p = s->text;
  2020  		pc = p->pc;
  2021  
  2022  		for(q = p; q->link != P; q = q->link) {
  2023  			if (q->spadj == 0)
  2024  				continue;
  2025  			cfa += q->spadj;
  2026  			putpccfadelta(q->link->pc - pc, cfa);
  2027  			pc = q->link->pc;
  2028  		}
  2029  
  2030  		fdesize = cpos() - fdeo - 4;	// exclude the length field.
  2031  		pad = rnd(fdesize, PtrSize) - fdesize;
  2032  		strnput("", pad);
  2033  		fdesize += pad;
  2034  
  2035  		// Emit the FDE header for real, Section 6.4.1.
  2036  		cseek(fdeo);
  2037  		LPUT(fdesize);
  2038  		if(linkmode == LinkExternal) {
  2039  			adddwarfrel(framesec, framesym, frameo, 4, 0);
  2040  			adddwarfrel(framesec, s, frameo, PtrSize, 0);
  2041  		}
  2042  		else {
  2043  			LPUT(0);
  2044  			addrput(p->pc);
  2045  		}
  2046  		addrput(s->size);
  2047  		cseek(fdeo + 4 + fdesize);
  2048  	}
  2049  
  2050  	cflush();
  2051  	framesize = cpos() - frameo;
  2052  }
  2053  
  2054  /*
  2055   *  Walk DWarfDebugInfoEntries, and emit .debug_info
  2056   */
  2057  enum
  2058  {
  2059  	COMPUNITHEADERSIZE = 4+2+4+1
  2060  };
  2061  
  2062  static void
  2063  writeinfo(void)
  2064  {
  2065  	DWDie *compunit;
  2066  	vlong unitstart, here;
  2067  
  2068  	fwdcount = 0;
  2069  	if (infosec == S)
  2070  		infosec = lookup(".dwarfinfo", 0);
  2071  	infosec->nr = 0;
  2072  
  2073  	if(arangessec == S)
  2074  		arangessec = lookup(".dwarfaranges", 0);
  2075  	arangessec->nr = 0;
  2076  
  2077  	for (compunit = dwroot.child; compunit; compunit = compunit->link) {
  2078  		unitstart = cpos();
  2079  
  2080  		// Write .debug_info Compilation Unit Header (sec 7.5.1)
  2081  		// Fields marked with (*) must be changed for 64-bit dwarf
  2082  		// This must match COMPUNITHEADERSIZE above.
  2083  		LPUT(0);	// unit_length (*), will be filled in later.
  2084  		WPUT(2);	// dwarf version (appendix F)
  2085  
  2086  		// debug_abbrev_offset (*)
  2087  		if(linkmode == LinkExternal)
  2088  			adddwarfrel(infosec, abbrevsym, infoo, 4, 0);
  2089  		else
  2090  			LPUT(0);
  2091  
  2092  		cput(PtrSize);	// address_size
  2093  
  2094  		putdie(compunit);
  2095  
  2096  		here = cpos();
  2097  		cseek(unitstart);
  2098  		LPUT(here - unitstart - 4);	// exclude the length field.
  2099  		cseek(here);
  2100  	}
  2101  	cflush();
  2102  }
  2103  
  2104  /*
  2105   *  Emit .debug_pubnames/_types.  _info must have been written before,
  2106   *  because we need die->offs and infoo/infosize;
  2107   */
  2108  static int
  2109  ispubname(DWDie *die)
  2110  {
  2111  	DWAttr *a;
  2112  
  2113  	switch(die->abbrev) {
  2114  	case DW_ABRV_FUNCTION:
  2115  	case DW_ABRV_VARIABLE:
  2116  		a = getattr(die, DW_AT_external);
  2117  		return a && a->value;
  2118  	}
  2119  	return 0;
  2120  }
  2121  
  2122  static int
  2123  ispubtype(DWDie *die)
  2124  {
  2125  	return die->abbrev >= DW_ABRV_NULLTYPE;
  2126  }
  2127  
  2128  static vlong
  2129  writepub(int (*ispub)(DWDie*))
  2130  {
  2131  	DWDie *compunit, *die;
  2132  	DWAttr *dwa;
  2133  	vlong unitstart, unitend, sectionstart, here;
  2134  
  2135  	sectionstart = cpos();
  2136  
  2137  	for (compunit = dwroot.child; compunit != nil; compunit = compunit->link) {
  2138  		unitstart = compunit->offs - COMPUNITHEADERSIZE;
  2139  		if (compunit->link != nil)
  2140  			unitend = compunit->link->offs - COMPUNITHEADERSIZE;
  2141  		else
  2142  			unitend = infoo + infosize;
  2143  
  2144  		// Write .debug_pubnames/types	Header (sec 6.1.1)
  2145  		LPUT(0);			// unit_length (*), will be filled in later.
  2146  		WPUT(2);			// dwarf version (appendix F)
  2147  		LPUT(unitstart);		// debug_info_offset (of the Comp unit Header)
  2148  		LPUT(unitend - unitstart);	// debug_info_length
  2149  
  2150  		for (die = compunit->child; die != nil; die = die->link) {
  2151  			if (!ispub(die)) continue;
  2152  			LPUT(die->offs - unitstart);
  2153  			dwa = getattr(die, DW_AT_name);
  2154  			strnput(dwa->data, dwa->value + 1);
  2155  		}
  2156  		LPUT(0);
  2157  
  2158  		here = cpos();
  2159  		cseek(sectionstart);
  2160  		LPUT(here - sectionstart - 4);	// exclude the length field.
  2161  		cseek(here);
  2162  
  2163  	}
  2164  
  2165  	return sectionstart;
  2166  }
  2167  
  2168  /*
  2169   *  emit .debug_aranges.  _info must have been written before,
  2170   *  because we need die->offs of dw_globals.
  2171   */
  2172  static vlong
  2173  writearanges(void)
  2174  {
  2175  	DWDie *compunit;
  2176  	DWAttr *b, *e;
  2177  	int headersize;
  2178  	vlong sectionstart;
  2179  	vlong value;
  2180  
  2181  	sectionstart = cpos();
  2182  	headersize = rnd(4+2+4+1+1, PtrSize);  // don't count unit_length field itself
  2183  
  2184  	for (compunit = dwroot.child; compunit != nil; compunit = compunit->link) {
  2185  		b = getattr(compunit,  DW_AT_low_pc);
  2186  		if (b == nil)
  2187  			continue;
  2188  		e = getattr(compunit,  DW_AT_high_pc);
  2189  		if (e == nil)
  2190  			continue;
  2191  
  2192  		// Write .debug_aranges	 Header + entry	 (sec 6.1.2)
  2193  		LPUT(headersize + 4*PtrSize - 4);	// unit_length (*)
  2194  		WPUT(2);	// dwarf version (appendix F)
  2195  
  2196  		value = compunit->offs - COMPUNITHEADERSIZE;	// debug_info_offset
  2197  		if(linkmode == LinkExternal)
  2198  			adddwarfrel(arangessec, infosym, sectionstart, 4, value);
  2199  		else
  2200  			LPUT(value);
  2201  
  2202  		cput(PtrSize);	// address_size
  2203  		cput(0);	// segment_size
  2204  		strnput("", headersize - (4+2+4+1+1));	// align to PtrSize
  2205  
  2206  		if(linkmode == LinkExternal)
  2207  			adddwarfrel(arangessec, (Sym*)b->data, sectionstart, PtrSize, b->value-((Sym*)b->data)->value);
  2208  		else
  2209  			addrput(b->value);
  2210  
  2211  		addrput(e->value - b->value);
  2212  		addrput(0);
  2213  		addrput(0);
  2214  	}
  2215  	cflush();
  2216  	return sectionstart;
  2217  }
  2218  
  2219  static vlong
  2220  writegdbscript(void)
  2221  {
  2222  	vlong sectionstart;
  2223  
  2224  	sectionstart = cpos();
  2225  
  2226  	if (gdbscript[0]) {
  2227  		cput(1);  // magic 1 byte?
  2228  		strnput(gdbscript, strlen(gdbscript)+1);
  2229  		cflush();
  2230  	}
  2231  	return sectionstart;
  2232  }
  2233  
  2234  static void
  2235  align(vlong size)
  2236  {
  2237  	if(HEADTYPE == Hwindows) // Only Windows PE need section align.
  2238  		strnput("", rnd(size, PEFILEALIGN) - size);
  2239  }
  2240  
  2241  static vlong
  2242  writedwarfreloc(Sym* s)
  2243  {
  2244  	int i;
  2245  	vlong start;
  2246  	Reloc *r;
  2247  	
  2248  	start = cpos();
  2249  	for(r = s->r; r < s->r+s->nr; r++) {
  2250  		if(iself)
  2251  			i = elfreloc1(r, r->off);
  2252  		else if(HEADTYPE == Hdarwin)
  2253  			i = machoreloc1(r, r->off);
  2254  		else
  2255  			i = -1;
  2256  		if(i < 0)
  2257  			diag("unsupported obj reloc %d/%d to %s", r->type, r->siz, r->sym->name);
  2258  	}
  2259  	return start;
  2260  }
  2261  
  2262  /*
  2263   * This is the main entry point for generating dwarf.  After emitting
  2264   * the mandatory debug_abbrev section, it calls writelines() to set up
  2265   * the per-compilation unit part of the DIE tree, while simultaneously
  2266   * emitting the debug_line section.  When the final tree contains
  2267   * forward references, it will write the debug_info section in 2
  2268   * passes.
  2269   *
  2270   */
  2271  void
  2272  dwarfemitdebugsections(void)
  2273  {
  2274  	vlong infoe;
  2275  	DWDie* die;
  2276  
  2277  	if(debug['w'])  // disable dwarf
  2278  		return;
  2279  
  2280  	if(linkmode == LinkExternal && !iself)
  2281  		return;
  2282  
  2283  	// For diagnostic messages.
  2284  	newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, strlen("dwtypes"), "dwtypes");
  2285  
  2286  	mkindex(&dwroot);
  2287  	mkindex(&dwtypes);
  2288  	mkindex(&dwglobals);
  2289  
  2290  	// Some types that must exist to define other ones.
  2291  	newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>");
  2292  	newdie(&dwtypes, DW_ABRV_NULLTYPE, "void");
  2293  	newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer");
  2294  	die = newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr");  // needed for array size
  2295  	newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_unsigned, 0);
  2296  	newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, PtrSize, 0);
  2297  
  2298  	// Needed by the prettyprinter code for interface inspection.
  2299  	defgotype(lookup_or_diag("type.runtime.rtype"));
  2300  	defgotype(lookup_or_diag("type.runtime.interfaceType"));
  2301  	defgotype(lookup_or_diag("type.runtime.itab"));
  2302  
  2303  	genasmsym(defdwsymb);
  2304  
  2305  	writeabbrev();
  2306  	align(abbrevsize);
  2307  	writelines();
  2308  	align(linesize);
  2309  	writeframes();
  2310  	align(framesize);
  2311  
  2312  	synthesizestringtypes(dwtypes.child);
  2313  	synthesizeslicetypes(dwtypes.child);
  2314  	synthesizemaptypes(dwtypes.child);
  2315  	synthesizechantypes(dwtypes.child);
  2316  
  2317  	reversetree(&dwroot.child);
  2318  	reversetree(&dwtypes.child);
  2319  	reversetree(&dwglobals.child);
  2320  
  2321  	movetomodule(&dwtypes);
  2322  	movetomodule(&dwglobals);
  2323  
  2324  	infoo = cpos();
  2325  	writeinfo();
  2326  	infoe = cpos();
  2327  	pubnameso = infoe;
  2328  	pubtypeso = infoe;
  2329  	arangeso = infoe;
  2330  	gdbscripto = infoe;
  2331  
  2332  	if (fwdcount > 0) {
  2333  		if (debug['v'])
  2334  			Bprint(&bso, "%5.2f dwarf pass 2.\n", cputime());
  2335  		cseek(infoo);
  2336  		writeinfo();
  2337  		if (fwdcount > 0) {
  2338  			diag("dwarf: unresolved references after first dwarf info pass");
  2339  			errorexit();
  2340  		}
  2341  		if (infoe != cpos()) {
  2342  			diag("dwarf: inconsistent second dwarf info pass");
  2343  			errorexit();
  2344  		}
  2345  	}
  2346  	infosize = infoe - infoo;
  2347  	align(infosize);
  2348  
  2349  	pubnameso  = writepub(ispubname);
  2350  	pubnamessize  = cpos() - pubnameso;
  2351  	align(pubnamessize);
  2352  
  2353  	pubtypeso  = writepub(ispubtype);
  2354  	pubtypessize  = cpos() - pubtypeso;
  2355  	align(pubtypessize);
  2356  
  2357  	arangeso   = writearanges();
  2358  	arangessize   = cpos() - arangeso;
  2359  	align(arangessize);
  2360  
  2361  	gdbscripto = writegdbscript();
  2362  	gdbscriptsize = cpos() - gdbscripto;
  2363  	align(gdbscriptsize);
  2364  
  2365  	while(cpos()&7)
  2366  		cput(0);
  2367  	inforeloco = writedwarfreloc(infosec);
  2368  	inforelocsize = cpos() - inforeloco;
  2369  	align(inforelocsize);
  2370  
  2371  	arangesreloco = writedwarfreloc(arangessec);
  2372  	arangesrelocsize = cpos() - arangesreloco;
  2373  	align(arangesrelocsize);
  2374  
  2375  	linereloco = writedwarfreloc(linesec);
  2376  	linerelocsize = cpos() - linereloco;
  2377  	align(linerelocsize);
  2378  
  2379  	framereloco = writedwarfreloc(framesec);
  2380  	framerelocsize = cpos() - framereloco;
  2381  	align(framerelocsize);
  2382  }
  2383  
  2384  /*
  2385   *  Elf.
  2386   */
  2387  enum
  2388  {
  2389  	ElfStrDebugAbbrev,
  2390  	ElfStrDebugAranges,
  2391  	ElfStrDebugFrame,
  2392  	ElfStrDebugInfo,
  2393  	ElfStrDebugLine,
  2394  	ElfStrDebugLoc,
  2395  	ElfStrDebugMacinfo,
  2396  	ElfStrDebugPubNames,
  2397  	ElfStrDebugPubTypes,
  2398  	ElfStrDebugRanges,
  2399  	ElfStrDebugStr,
  2400  	ElfStrGDBScripts,
  2401  	ElfStrRelDebugInfo,
  2402  	ElfStrRelDebugAranges,
  2403  	ElfStrRelDebugLine,
  2404  	ElfStrRelDebugFrame,
  2405  	NElfStrDbg
  2406  };
  2407  
  2408  vlong elfstrdbg[NElfStrDbg];
  2409  
  2410  void
  2411  dwarfaddshstrings(Sym *shstrtab)
  2412  {
  2413  	if(debug['w'])  // disable dwarf
  2414  		return;
  2415  
  2416  	elfstrdbg[ElfStrDebugAbbrev]   = addstring(shstrtab, ".debug_abbrev");
  2417  	elfstrdbg[ElfStrDebugAranges]  = addstring(shstrtab, ".debug_aranges");
  2418  	elfstrdbg[ElfStrDebugFrame]    = addstring(shstrtab, ".debug_frame");
  2419  	elfstrdbg[ElfStrDebugInfo]     = addstring(shstrtab, ".debug_info");
  2420  	elfstrdbg[ElfStrDebugLine]     = addstring(shstrtab, ".debug_line");
  2421  	elfstrdbg[ElfStrDebugLoc]      = addstring(shstrtab, ".debug_loc");
  2422  	elfstrdbg[ElfStrDebugMacinfo]  = addstring(shstrtab, ".debug_macinfo");
  2423  	elfstrdbg[ElfStrDebugPubNames] = addstring(shstrtab, ".debug_pubnames");
  2424  	elfstrdbg[ElfStrDebugPubTypes] = addstring(shstrtab, ".debug_pubtypes");
  2425  	elfstrdbg[ElfStrDebugRanges]   = addstring(shstrtab, ".debug_ranges");
  2426  	elfstrdbg[ElfStrDebugStr]      = addstring(shstrtab, ".debug_str");
  2427  	elfstrdbg[ElfStrGDBScripts]    = addstring(shstrtab, ".debug_gdb_scripts");
  2428  	if(linkmode == LinkExternal) {
  2429  		if(thechar == '6') {
  2430  			elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rela.debug_info");
  2431  			elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rela.debug_aranges");
  2432  			elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rela.debug_line");
  2433  			elfstrdbg[ElfStrRelDebugFrame] = addstring(shstrtab, ".rela.debug_frame");
  2434  		} else {
  2435  			elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rel.debug_info");
  2436  			elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rel.debug_aranges");
  2437  			elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rel.debug_line");
  2438  			elfstrdbg[ElfStrRelDebugFrame] = addstring(shstrtab, ".rel.debug_frame");
  2439  		}
  2440  
  2441  		infosym = lookup(".debug_info", 0);
  2442  		infosym->hide = 1;
  2443  
  2444  		abbrevsym = lookup(".debug_abbrev", 0);
  2445  		abbrevsym->hide = 1;
  2446  
  2447  		linesym = lookup(".debug_line", 0);
  2448  		linesym->hide = 1;
  2449  
  2450  		framesym = lookup(".debug_frame", 0);
  2451  		framesym->hide = 1;
  2452  	}
  2453  }
  2454  
  2455  // Add section symbols for DWARF debug info.  This is called before
  2456  // dwarfaddelfheaders.
  2457  void
  2458  dwarfaddelfsectionsyms()
  2459  {
  2460  	if(infosym != nil) {
  2461  		infosympos = cpos();
  2462  		putelfsectionsym(infosym, 0);
  2463  	}
  2464  	if(abbrevsym != nil) {
  2465  		abbrevsympos = cpos();
  2466  		putelfsectionsym(abbrevsym, 0);
  2467  	}
  2468  	if(linesym != nil) {
  2469  		linesympos = cpos();
  2470  		putelfsectionsym(linesym, 0);
  2471  	}
  2472  	if(framesym != nil) {
  2473  		framesympos = cpos();
  2474  		putelfsectionsym(framesym, 0);
  2475  	}
  2476  }
  2477  
  2478  static void
  2479  dwarfaddelfrelocheader(int elfstr, ElfShdr *shdata, vlong off, vlong size)
  2480  {
  2481  	ElfShdr *sh;
  2482  
  2483  	sh = newElfShdr(elfstrdbg[elfstr]);
  2484  	if(thechar == '6') {
  2485  		sh->type = SHT_RELA;
  2486  	} else {
  2487  		sh->type = SHT_REL;
  2488  	}
  2489  	sh->entsize = PtrSize*(2+(sh->type==SHT_RELA));
  2490  	sh->link = elfshname(".symtab")->shnum;
  2491  	sh->info = shdata->shnum;
  2492  	sh->off = off;
  2493  	sh->size = size;
  2494  	sh->addralign = PtrSize;
  2495  	
  2496  }
  2497  
  2498  void
  2499  dwarfaddelfheaders(void)
  2500  {
  2501  	ElfShdr *sh, *shinfo, *sharanges, *shline, *shframe;
  2502  
  2503  	if(debug['w'])  // disable dwarf
  2504  		return;
  2505  
  2506  	sh = newElfShdr(elfstrdbg[ElfStrDebugAbbrev]);
  2507  	sh->type = SHT_PROGBITS;
  2508  	sh->off = abbrevo;
  2509  	sh->size = abbrevsize;
  2510  	sh->addralign = 1;
  2511  	if(abbrevsympos > 0)
  2512  		putelfsymshndx(abbrevsympos, sh->shnum);
  2513  
  2514  	sh = newElfShdr(elfstrdbg[ElfStrDebugLine]);
  2515  	sh->type = SHT_PROGBITS;
  2516  	sh->off = lineo;
  2517  	sh->size = linesize;
  2518  	sh->addralign = 1;
  2519  	if(linesympos > 0)
  2520  		putelfsymshndx(linesympos, sh->shnum);
  2521  	shline = sh;
  2522  
  2523  	sh = newElfShdr(elfstrdbg[ElfStrDebugFrame]);
  2524  	sh->type = SHT_PROGBITS;
  2525  	sh->off = frameo;
  2526  	sh->size = framesize;
  2527  	sh->addralign = 1;
  2528  	if(framesympos > 0)
  2529  		putelfsymshndx(framesympos, sh->shnum);
  2530  	shframe = sh;
  2531  
  2532  	sh = newElfShdr(elfstrdbg[ElfStrDebugInfo]);
  2533  	sh->type = SHT_PROGBITS;
  2534  	sh->off = infoo;
  2535  	sh->size = infosize;
  2536  	sh->addralign = 1;
  2537  	if(infosympos > 0)
  2538  		putelfsymshndx(infosympos, sh->shnum);
  2539  	shinfo = sh;
  2540  
  2541  	if (pubnamessize > 0) {
  2542  		sh = newElfShdr(elfstrdbg[ElfStrDebugPubNames]);
  2543  		sh->type = SHT_PROGBITS;
  2544  		sh->off = pubnameso;
  2545  		sh->size = pubnamessize;
  2546  		sh->addralign = 1;
  2547  	}
  2548  
  2549  	if (pubtypessize > 0) {
  2550  		sh = newElfShdr(elfstrdbg[ElfStrDebugPubTypes]);
  2551  		sh->type = SHT_PROGBITS;
  2552  		sh->off = pubtypeso;
  2553  		sh->size = pubtypessize;
  2554  		sh->addralign = 1;
  2555  	}
  2556  
  2557  	sharanges = nil;
  2558  	if (arangessize) {
  2559  		sh = newElfShdr(elfstrdbg[ElfStrDebugAranges]);
  2560  		sh->type = SHT_PROGBITS;
  2561  		sh->off = arangeso;
  2562  		sh->size = arangessize;
  2563  		sh->addralign = 1;
  2564  		sharanges = sh;
  2565  	}
  2566  
  2567  	if (gdbscriptsize) {
  2568  		sh = newElfShdr(elfstrdbg[ElfStrGDBScripts]);
  2569  		sh->type = SHT_PROGBITS;
  2570  		sh->off = gdbscripto;
  2571  		sh->size = gdbscriptsize;
  2572  		sh->addralign = 1;
  2573  	}
  2574  
  2575  	if(inforelocsize)
  2576  		dwarfaddelfrelocheader(ElfStrRelDebugInfo, shinfo, inforeloco, inforelocsize);
  2577  
  2578  	if(arangesrelocsize)
  2579  		dwarfaddelfrelocheader(ElfStrRelDebugAranges, sharanges, arangesreloco, arangesrelocsize);
  2580  
  2581  	if(linerelocsize)
  2582  		dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize);
  2583  
  2584  	if(framerelocsize)
  2585  		dwarfaddelfrelocheader(ElfStrRelDebugFrame, shframe, framereloco, framerelocsize);
  2586  }
  2587  
  2588  /*
  2589   * Macho
  2590   */
  2591  void
  2592  dwarfaddmachoheaders(void)
  2593  {
  2594  	MachoSect *msect;
  2595  	MachoSeg *ms;
  2596  	vlong fakestart;
  2597  	int nsect;
  2598  
  2599  	if(debug['w'])  // disable dwarf
  2600  		return;
  2601  
  2602  	// Zero vsize segments won't be loaded in memory, even so they
  2603  	// have to be page aligned in the file.
  2604  	fakestart = abbrevo & ~0xfff;
  2605  
  2606  	nsect = 4;
  2607  	if (pubnamessize  > 0)
  2608  		nsect++;
  2609  	if (pubtypessize  > 0)
  2610  		nsect++;
  2611  	if (arangessize	  > 0)
  2612  		nsect++;
  2613  	if (gdbscriptsize > 0)
  2614  		nsect++;
  2615  
  2616  	ms = newMachoSeg("__DWARF", nsect);
  2617  	ms->fileoffset = fakestart;
  2618  	ms->filesize = abbrevo-fakestart;
  2619  
  2620  	msect = newMachoSect(ms, "__debug_abbrev", "__DWARF");
  2621  	msect->off = abbrevo;
  2622  	msect->size = abbrevsize;
  2623  	ms->filesize += msect->size;
  2624  
  2625  	msect = newMachoSect(ms, "__debug_line", "__DWARF");
  2626  	msect->off = lineo;
  2627  	msect->size = linesize;
  2628  	ms->filesize += msect->size;
  2629  
  2630  	msect = newMachoSect(ms, "__debug_frame", "__DWARF");
  2631  	msect->off = frameo;
  2632  	msect->size = framesize;
  2633  	ms->filesize += msect->size;
  2634  
  2635  	msect = newMachoSect(ms, "__debug_info", "__DWARF");
  2636  	msect->off = infoo;
  2637  	msect->size = infosize;
  2638  	ms->filesize += msect->size;
  2639  
  2640  	if (pubnamessize > 0) {
  2641  		msect = newMachoSect(ms, "__debug_pubnames", "__DWARF");
  2642  		msect->off = pubnameso;
  2643  		msect->size = pubnamessize;
  2644  		ms->filesize += msect->size;
  2645  	}
  2646  
  2647  	if (pubtypessize > 0) {
  2648  		msect = newMachoSect(ms, "__debug_pubtypes", "__DWARF");
  2649  		msect->off = pubtypeso;
  2650  		msect->size = pubtypessize;
  2651  		ms->filesize += msect->size;
  2652  	}
  2653  
  2654  	if (arangessize > 0) {
  2655  		msect = newMachoSect(ms, "__debug_aranges", "__DWARF");
  2656  		msect->off = arangeso;
  2657  		msect->size = arangessize;
  2658  		ms->filesize += msect->size;
  2659  	}
  2660  
  2661  	// TODO(lvd) fix gdb/python to load MachO (16 char section name limit)
  2662  	if (gdbscriptsize > 0) {
  2663  		msect = newMachoSect(ms, "__debug_gdb_scripts", "__DWARF");
  2664  		msect->off = gdbscripto;
  2665  		msect->size = gdbscriptsize;
  2666  		ms->filesize += msect->size;
  2667  	}
  2668  }
  2669  
  2670  /*
  2671   * Windows PE
  2672   */
  2673  void
  2674  dwarfaddpeheaders(void)
  2675  {
  2676  	if(debug['w'])  // disable dwarf
  2677  		return;
  2678  
  2679  	newPEDWARFSection(".debug_abbrev", abbrevsize);
  2680  	newPEDWARFSection(".debug_line", linesize);
  2681  	newPEDWARFSection(".debug_frame", framesize);
  2682  	newPEDWARFSection(".debug_info", infosize);
  2683  	newPEDWARFSection(".debug_pubnames", pubnamessize);
  2684  	newPEDWARFSection(".debug_pubtypes", pubtypessize);
  2685  	newPEDWARFSection(".debug_aranges", arangessize);
  2686  	newPEDWARFSection(".debug_gdb_scripts", gdbscriptsize);
  2687  }