dwarf2dbg.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,313 行 · 第 1/3 页

C
1,313
字号
out_byte (byte)     int byte;{  FRAG_APPEND_1_CHAR (byte);}/* Emit a statement program opcode into the current segment.  */static inline voidout_opcode (opc)     int opc;{  out_byte (opc);}/* Emit a two-byte word into the current segment.  */static inline voidout_two (data)     int data;{  md_number_to_chars (frag_more (2), data, 2);}/* Emit a four byte word into the current segment.  */static inline voidout_four (data)     int data;{  md_number_to_chars (frag_more (4), data, 4);}/* Emit an unsigned "little-endian base 128" number.  */static voidout_uleb128 (value)     addressT value;{  output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);}/* Emit a tuple for .debug_abbrev.  */static inline voidout_abbrev (name, form)     int name, form;{  out_uleb128 (name);  out_uleb128 (form);}/* Create a new fake symbol whose value is the current position.  */static symbolS *symbol_new_now (){  return symbol_new (fake_label_name, now_seg, frag_now_fix (), frag_now);}/* Set the value of SYM to the current position in the current segment.  */static voidset_symbol_value_now (sym)     symbolS *sym;{  S_SET_SEGMENT (sym, now_seg);  S_SET_VALUE (sym, frag_now_fix ());  symbol_set_frag (sym, frag_now);}/* Get the size of a fragment.  */static offsetTget_frag_fix (frag)     fragS *frag;{  frchainS *fr;  if (frag->fr_next)    return frag->fr_fix;  /* If a fragment is the last in the chain, special measures must be     taken to find its size before relaxation, since it may be pending     on some subsegment chain.  */  for (fr = frchain_root; fr; fr = fr->frch_next)    if (fr->frch_last == frag)      {	return ((char *) obstack_next_free (&fr->frch_obstack)		- frag->fr_literal);      }  abort ();}/* Set an absolute address (may result in a relocation entry).  */static voidout_set_addr (seg, frag, ofs)     segT seg;     fragS *frag;     addressT ofs;{  expressionS expr;  symbolS *sym;  sym = symbol_new (fake_label_name, seg, ofs, frag);  out_opcode (DW_LNS_extended_op);  out_uleb128 (sizeof_address + 1);  out_opcode (DW_LNE_set_address);  expr.X_op = O_symbol;  expr.X_add_symbol = sym;  expr.X_add_number = 0;  emit_expr (&expr, sizeof_address);}/* Encode a pair of line and address skips as efficiently as possible.   Note that the line skip is signed, whereas the address skip is unsigned.   The following two routines *must* be kept in sync.  This is   enforced by making emit_inc_line_addr abort if we do not emit   exactly the expected number of bytes.  */static intsize_inc_line_addr (line_delta, addr_delta)     int line_delta;     addressT addr_delta;{  unsigned int tmp, opcode;  int len = 0;  /* Scale the address delta by the minimum instruction length.  */#if DWARF2_LINE_MIN_INSN_LENGTH > 1  assert (addr_delta % DWARF2_LINE_MIN_INSN_LENGTH == 0);  addr_delta /= DWARF2_LINE_MIN_INSN_LENGTH;#endif  /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence.     We cannot use special opcodes here, since we want the end_sequence     to emit the matrix entry.  */  if (line_delta == INT_MAX)    {      if (addr_delta == MAX_SPECIAL_ADDR_DELTA)	len = 1;      else	len = 1 + sizeof_leb128 (addr_delta, 0);      return len + 3;    }  /* Bias the line delta by the base.  */  tmp = line_delta - DWARF2_LINE_BASE;  /* If the line increment is out of range of a special opcode, we     must encode it with DW_LNS_advance_line.  */  if (tmp >= DWARF2_LINE_RANGE)    {      len = 1 + sizeof_leb128 (line_delta, 1);      line_delta = 0;      tmp = 0 - DWARF2_LINE_BASE;    }  /* Bias the opcode by the special opcode base.  */  tmp += DWARF2_LINE_OPCODE_BASE;  /* Avoid overflow when addr_delta is large.  */  if (addr_delta < 256 + MAX_SPECIAL_ADDR_DELTA)    {      /* Try using a special opcode.  */      opcode = tmp + addr_delta * DWARF2_LINE_RANGE;      if (opcode <= 255)	return len + 1;      /* Try using DW_LNS_const_add_pc followed by special op.  */      opcode = tmp + (addr_delta - MAX_SPECIAL_ADDR_DELTA) * DWARF2_LINE_RANGE;      if (opcode <= 255)	return len + 2;    }  /* Otherwise use DW_LNS_advance_pc.  */  len += 1 + sizeof_leb128 (addr_delta, 0);  /* DW_LNS_copy or special opcode.  */  len += 1;  return len;}static voidemit_inc_line_addr (line_delta, addr_delta, p, len)     int line_delta;     addressT addr_delta;     char *p;     int len;{  unsigned int tmp, opcode;  int need_copy = 0;  char *end = p + len;#if DWARF2_LINE_MIN_INSN_LENGTH > 1  /* Scale the address delta by the minimum instruction length.  */  assert (addr_delta % DWARF2_LINE_MIN_INSN_LENGTH == 0);  addr_delta /= DWARF2_LINE_MIN_INSN_LENGTH;#endif  /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence.     We cannot use special opcodes here, since we want the end_sequence     to emit the matrix entry.  */  if (line_delta == INT_MAX)    {      if (addr_delta == MAX_SPECIAL_ADDR_DELTA)	*p++ = DW_LNS_const_add_pc;      else	{	  *p++ = DW_LNS_advance_pc;	  p += output_leb128 (p, addr_delta, 0);	}      *p++ = DW_LNS_extended_op;      *p++ = 1;      *p++ = DW_LNE_end_sequence;      goto done;    }  /* Bias the line delta by the base.  */  tmp = line_delta - DWARF2_LINE_BASE;  /* If the line increment is out of range of a special opcode, we     must encode it with DW_LNS_advance_line.  */  if (tmp >= DWARF2_LINE_RANGE)    {      *p++ = DW_LNS_advance_line;      p += output_leb128 (p, line_delta, 1);      /* Prettier, I think, to use DW_LNS_copy instead of a	 "line +0, addr +0" special opcode.  */      if (addr_delta == 0)	{	  *p++ = DW_LNS_copy;	  goto done;	}      line_delta = 0;      tmp = 0 - DWARF2_LINE_BASE;      need_copy = 1;    }  /* Bias the opcode by the special opcode base.  */  tmp += DWARF2_LINE_OPCODE_BASE;  /* Avoid overflow when addr_delta is large.  */  if (addr_delta < 256 + MAX_SPECIAL_ADDR_DELTA)    {      /* Try using a special opcode.  */      opcode = tmp + addr_delta * DWARF2_LINE_RANGE;      if (opcode <= 255)	{	  *p++ = opcode;	  goto done;	}      /* Try using DW_LNS_const_add_pc followed by special op.  */      opcode = tmp + (addr_delta - MAX_SPECIAL_ADDR_DELTA) * DWARF2_LINE_RANGE;      if (opcode <= 255)	{	  *p++ = DW_LNS_const_add_pc;	  *p++ = opcode;	  goto done;	}    }  /* Otherwise use DW_LNS_advance_pc.  */  *p++ = DW_LNS_advance_pc;  p += output_leb128 (p, addr_delta, 0);  if (need_copy)    *p++ = DW_LNS_copy;  else    *p++ = tmp; done:  assert (p == end);}/* Handy routine to combine calls to the above two routines.  */static voidout_inc_line_addr (line_delta, addr_delta)     int line_delta;     addressT addr_delta;{  int len = size_inc_line_addr (line_delta, addr_delta);  emit_inc_line_addr (line_delta, addr_delta, frag_more (len), len);}/* Generate a variant frag that we can use to relax address/line   increments between fragments of the target segment.  */static voidrelax_inc_line_addr (line_delta, seg, to_frag, to_ofs, from_frag, from_ofs)     int line_delta;     segT seg;     fragS *to_frag, *from_frag;     addressT to_ofs, from_ofs;{  symbolS *to_sym, *from_sym;  expressionS expr;  int max_chars;  to_sym = symbol_new (fake_label_name, seg, to_ofs, to_frag);  from_sym = symbol_new (fake_label_name, seg, from_ofs, from_frag);  expr.X_op = O_subtract;  expr.X_add_symbol = to_sym;  expr.X_op_symbol = from_sym;  expr.X_add_number = 0;  /* The maximum size of the frag is the line delta with a maximum     sized address delta.  */  max_chars = size_inc_line_addr (line_delta, -DWARF2_LINE_MIN_INSN_LENGTH);  frag_var (rs_dwarf2dbg, max_chars, max_chars, 1,	    make_expr_symbol (&expr), line_delta, NULL);}/* The function estimates the size of a rs_dwarf2dbg variant frag   based on the current values of the symbols.  It is called before   the relaxation loop.  We set fr_subtype to the expected length.  */intdwarf2dbg_estimate_size_before_relax (frag)     fragS *frag;{  offsetT addr_delta;  int size;  addr_delta = resolve_symbol_value (frag->fr_symbol, 0);  size = size_inc_line_addr (frag->fr_offset, addr_delta);  frag->fr_subtype = size;  return size;}/* This function relaxes a rs_dwarf2dbg variant frag based on the   current values of the symbols.  fr_subtype is the current length   of the frag.  This returns the change in frag length.  */intdwarf2dbg_relax_frag (frag)     fragS *frag;{  int old_size, new_size;  old_size = frag->fr_subtype;  new_size = dwarf2dbg_estimate_size_before_relax (frag);  return new_size - old_size;}/* This function converts a rs_dwarf2dbg variant frag into a normal   fill frag.  This is called after all relaxation has been done.   fr_subtype will be the desired length of the frag.  */voiddwarf2dbg_convert_frag (frag)     fragS *frag;{  offsetT addr_diff;  addr_diff = resolve_symbol_value (frag->fr_symbol, 1);  /* fr_var carries the max_chars that we created the fragment with.     fr_subtype carries the current expected length.  We must, of     course, have allocated enough memory earlier.  */  assert (frag->fr_var >= (int) frag->fr_subtype);  emit_inc_line_addr (frag->fr_offset, addr_diff,		      frag->fr_literal + frag->fr_fix, frag->fr_subtype);  frag->fr_fix += frag->fr_subtype;  frag->fr_type = rs_fill;  frag->fr_var = 0;  frag->fr_offset = 0;}/* Generate .debug_line content for the chain of line number entries   beginning at E, for segment SEG.  */static voidprocess_entries (seg, e)     segT seg;     struct line_entry *e;{  unsigned filenum = 1;  unsigned line = 1;  unsigned column = 0;  unsigned flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_BEGIN_STMT : 0;  fragS *frag = NULL;  fragS *last_frag;  addressT frag_ofs = 0;  addressT last_frag_ofs;  struct line_entry *next;  while (e)    {      int changed = 0;      if (filenum != e->loc.filenum)	{	  filenum = e->loc.filenum;	  out_opcode (DW_LNS_set_file);	  out_uleb128 (filenum);	  changed = 1;	}      if (column != e->loc.column)	{	  column = e->loc.column;	  out_opcode (DW_LNS_set_column);	  out_uleb128 (column);	  changed = 1;	}      if ((e->loc.flags ^ flags) & DWARF2_FLAG_BEGIN_STMT)	{	  flags = e->loc.flags;	  out_opcode (DW_LNS_negate_stmt);	  changed = 1;	}      if (e->loc.flags & DWARF2_FLAG_BEGIN_BLOCK)	{	  out_opcode (DW_LNS_set_basic_block);	  changed = 1;	}      /* Don't try to optimize away redundant entries; gdb wants two

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?