Exemple #1
0
void trampoline_target(char * target, char * output)
{
	struct bin_file * bf = load_bin_file(target, output);

	bf_trampoline_basic_blk(bf,
			disasm_bin_file_sym(bf,
			symbol_find(&bf->sym_table, "f1"), TRUE),
			disasm_bin_file_sym(bf,
			symbol_find(&bf->sym_table, "f_trampoline"), TRUE));
	close_bin_file(bf);
}
Exemple #2
0
void
s_ifdef (int test_defined)
{
  /* Points to name of symbol.  */
  char *name;
  /* Points to symbol.  */
  symbolS *symbolP;
  struct conditional_frame cframe;
  char c;

  /* Leading whitespace is part of operand.  */
  SKIP_WHITESPACE ();
  name = input_line_pointer;

  if (!is_name_beginner (*name))
    {
      as_bad (_("invalid identifier for \".ifdef\""));
      obstack_1grow (&cond_obstack, 0);
      ignore_rest_of_line ();
      return;
    }

  c = get_symbol_end ();
  symbolP = symbol_find (name);
  *input_line_pointer = c;

  initialize_cframe (&cframe);
  
  if (cframe.dead_tree)
    cframe.ignoring = 1;
  else
    {
      int is_defined;

      /* Use the same definition of 'defined' as .equiv so that a symbol
	 which has been referenced but not yet given a value/address is
	 considered to be undefined.  */
      is_defined =
	symbolP != NULL
	&& S_IS_DEFINED (symbolP)
	&& S_GET_SEGMENT (symbolP) != reg_section;

      cframe.ignoring = ! (test_defined ^ is_defined);
    }

  current_cframe = ((struct conditional_frame *)
		    obstack_copy (&cond_obstack, &cframe,
				  sizeof (cframe)));

  if (LISTING_SKIP_COND ()
      && cframe.ignoring
      && (cframe.previous_cframe == NULL
	  || ! cframe.previous_cframe->ignoring))
    listing_list (2);

  demand_empty_rest_of_line ();
}
Exemple #3
0
void
pecoff_obj_clear_weak_hook (symbolS *symbolP)
{
  symbolS *alternateP;

  S_SET_STORAGE_CLASS (symbolP, 0);
  SA_SET_SYM_FSIZE (symbolP, 0);

  alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
  S_CLEAR_EXTERNAL (alternateP);
}
Exemple #4
0
pointer symbol_add(VM, char *str) {
  pointer obj;
  int ret;
  khiter_t iter;
  obj = symbol_find(vm, str);  
  
  if (!obj) {
    obj = symbol_alloc(vm, str);
    iter = kh_put(STR, vm->symbol_table, AR_STRING(obj).val, &ret);
    kh_val(vm->symbol_table, iter) = obj;
  }
  return obj;
}
symbolS *
section_symbol (segT sec)
{
  segment_info_type *seginfo = seg_info (sec);
  symbolS *s;

  if (seginfo == 0)
    abort ();
  if (seginfo->sym)
    return seginfo->sym;

#ifndef EMIT_SECTION_SYMBOLS
#define EMIT_SECTION_SYMBOLS 1
#endif

  if (! EMIT_SECTION_SYMBOLS || symbol_table_frozen)
    {
      /* Here we know it won't be going into the symbol table.  */
      s = symbol_create (sec->symbol->name, sec, 0, &zero_address_frag);
    }
  else
    {
      segT seg;
      s = symbol_find (sec->symbol->name);
      /* We have to make sure it is the right symbol when we
	 have multiple sections with the same section name.  */
      if (s == NULL
	  || ((seg = S_GET_SEGMENT (s)) != sec
	      && seg != undefined_section))
	s = symbol_new (sec->symbol->name, sec, 0, &zero_address_frag);
      else if (seg == undefined_section)
	{
	  S_SET_SEGMENT (s, sec);
	  symbol_set_frag (s, &zero_address_frag);
	}
    }

  S_CLEAR_EXTERNAL (s);

  /* Use the BFD section symbol, if possible.  */
  if (obj_sec_sym_ok_for_reloc (sec))
    symbol_set_bfdsym (s, sec->symbol);
  else
    symbol_get_bfdsym (s)->flags |= BSF_SECTION_SYM;

  seginfo->sym = s;
  return s;
}
Exemple #6
0
/* Returns:
 * 	-1	Not enough data available
 * 	0	Constant
 * 	1	Symbol 		*/
int ckrange(int skip, char *str) 
{
	int val, off;
	struct symbol *symb;

	if(t[skip+0]==-1 || t[skip+1]==-1) {
		/* not enough data in file */
		return -1;
	}
	val=t[skip+0]+256*t[skip+1];

	if(pass==1 || pass==2 || (!a_labels)) {
		/* on first two passes don't bother printing labels (or if
		 * labels are disabled) */
		sprintf(str,"0%04xh",val);
		return 0;
	}

	/* not in area covered by file being disassembled */

	/* NOTE: such symbols should already be 
	 * removed by symbol_remove_nonlabels() */
/*
	if((val<start) || (val>end)) {
		sprintf(str,"0%04xh",val);
		return 0;
	}
*/
	symb=symbol_find(val);
	if(symb!=NULL) {
		/* exact match */
		sprintf(str,"%s", symb->name);
		return 1;
	}

	symb=symbol_find_range(val);
	if(symb!=NULL) {
		f_smc=1;
		off=val-symb->val;
		sprintf(str,"%s+%d", symb->name, off);
		return 1;
	}

	/* no label found */
	sprintf(str, "0%04xh", val);

	return 0;
}
Exemple #7
0
/* Returns:
 * 	-1	Not enough data available
 * 	0	Constant
 * 	1	Symbol 		*/
int ckrange_rel(int skip, int pc, char *str) 
{
	int val;
	struct symbol *symb=NULL;

	if(t[skip]==-1) return -1;

	if(a_labels) {
		if(t[skip]<128) {
			val=pc+2+t[skip];
		} else {
			val=pc+2+t[skip]-256;
		}

		symb=symbol_find(val & 0xffff);
	}

	if(a_labels && symb!=NULL) {
		/* print a label */
		sprintf(str, "%s", symb->name);
		return 1;
	} else {
		if(a_zilog) {
			/* old Zilog za.com */
			if(t[1]<128) {
				sprintf(str,"%d",t[1]+2);
			} else { 
				sprintf(str,"%d",t[1]+2-256);
			}
		} else {
			/* zasm by Günter Woigk and
			 * z80asm */
			if(t[1]<128) {
				sprintf(str,"$%+d",t[1]+2);
			} else {
				sprintf(str,"$%+d",t[1]+2-256);
			}
		}
		return 0;
	}
}
Exemple #8
0
/*
 * layout_indirect_symbols() setups the indirect symbol tables by looking up or
 * creating symbol from the indirect symbol names and recording the symbol
 * pointers.  It returns the total count of indirect symbol table entries.
 */
static
uint32_t
layout_indirect_symbols(void)
{
    struct frchain *frchainP;
    uint32_t section_type, total, count, stride;
    isymbolS *isymbolP;
    symbolS *symbolP;

	/*
	 * Mark symbols that only appear in a lazy section with 
	 * REFERENCE_FLAG_UNDEFINED_LAZY.  To do this we first make sure a
	 * symbol exists for all non-lazy symbols.  Then we make a pass looking
	 * up the lazy symbols and if not there we make the symbol and mark it
	 * with REFERENCE_FLAG_UNDEFINED_LAZY.
	 */
	for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
	    section_type = frchainP->frch_section.flags & SECTION_TYPE;
	    if(section_type == S_NON_LAZY_SYMBOL_POINTERS){
		for(isymbolP = frchainP->frch_isym_root;
		    isymbolP != NULL;
		    isymbolP = isymbolP->isy_next){
/*
(void)symbol_find_or_make(isymbolP->isy_name);
*/
		    symbolP = symbol_find(isymbolP->isy_name);
		    if(symbolP == NULL){
			symbolP = symbol_new(isymbolP->isy_name, N_UNDF, 0, 0,
					     0, &zero_address_frag);
			symbol_table_insert(symbolP);
		    }
		}
	    }
	}
	for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
	    section_type = frchainP->frch_section.flags & SECTION_TYPE;
	    if(section_type == S_LAZY_SYMBOL_POINTERS ||
	       section_type == S_SYMBOL_STUBS){
		for(isymbolP = frchainP->frch_isym_root;
		    isymbolP != NULL;
		    isymbolP = isymbolP->isy_next){

		    symbolP = symbol_find(isymbolP->isy_name);
		    if(symbolP == NULL){
			symbolP = symbol_find_or_make(isymbolP->isy_name);
			symbolP->sy_desc |= REFERENCE_FLAG_UNDEFINED_LAZY;
		    }
		}
	    }
	}

	total = 0;
	for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
	    section_type = frchainP->frch_section.flags & SECTION_TYPE;
	    if(section_type == S_LAZY_SYMBOL_POINTERS ||
	       section_type == S_NON_LAZY_SYMBOL_POINTERS ||
	       section_type == S_SYMBOL_STUBS){
		count = 0;
		for(isymbolP = frchainP->frch_isym_root;
		    isymbolP != NULL;
		    isymbolP = isymbolP->isy_next){

/*
symbolP = symbol_find_or_make(isymbolP->isy_name);
*/
		    symbolP = symbol_find(isymbolP->isy_name);
		    if(symbolP == NULL){
			symbolP = symbol_new(isymbolP->isy_name, N_UNDF, 0, 0,
					     0, &zero_address_frag);
			symbol_table_insert(symbolP);
		    }
		    isymbolP->isy_symbol = symbolP;
		    count++;
		}
		/*
		 * Check for missing indirect symbols.
		 */
		if(section_type == S_SYMBOL_STUBS)
		    stride = frchainP->frch_section.reserved2;
		else
		    stride = sizeof(signed_target_addr_t);
		if(frchainP->frch_section.size / stride != count)
		    as_bad("missing indirect symbols for section (%s,%s)",
			    frchainP->frch_section.segname,
			    frchainP->frch_section.sectname);
		/*
		 * Set the index into the indirect symbol table for this
		 * section into the reserved1 field.
		 */
		frchainP->frch_section.reserved1 = total;
		total += count;
	    }
	}
	return(total);
}
Exemple #9
0
static void
obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
{
  symbolS *symbolP = NULL;

  dim_index = 0;
  if (def_symbol_in_progress == NULL)
    {
      as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
      demand_empty_rest_of_line ();
      return;
    }

  /* Set the section number according to storage class.  */
  switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
    {
    case C_STRTAG:
    case C_ENTAG:
    case C_UNTAG:
      SF_SET_TAG (def_symbol_in_progress);
      /* Fall through.  */
    case C_FILE:
    case C_TPDEF:
      SF_SET_DEBUG (def_symbol_in_progress);
      S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
      break;

    case C_EFCN:
      SF_SET_LOCAL (def_symbol_in_progress);	/* Do not emit this symbol.  */
      /* Fall through.  */
    case C_BLOCK:
      SF_SET_PROCESS (def_symbol_in_progress);	/* Will need processing before writing.  */
      /* Fall through.  */
    case C_FCN:
      {
	const char *name;

	S_SET_SEGMENT (def_symbol_in_progress, text_section);

	name = S_GET_NAME (def_symbol_in_progress);
	if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
	  {
	    switch (name[1])
	      {
	      case 'b':
		/* .bf */
		if (! in_function ())
		  as_warn (_("`%s' symbol without preceding function"), name);
		/* Will need relocating.  */
		SF_SET_PROCESS (def_symbol_in_progress);
		clear_function ();
		break;
#ifdef TE_PE
	      case 'e':
		/* .ef */
		/* The MS compilers output the actual endline, not the
		   function-relative one... we want to match without
		   changing the assembler input.  */
		SA_SET_SYM_LNNO (def_symbol_in_progress,
				 (SA_GET_SYM_LNNO (def_symbol_in_progress)
				  + coff_line_base));
		break;
#endif
	      }
	  }
      }
      break;

#ifdef C_AUTOARG
    case C_AUTOARG:
#endif /* C_AUTOARG */
    case C_AUTO:
    case C_REG:
    case C_ARG:
    case C_REGPARM:
    case C_FIELD:

    /* According to the COFF documentation:

       http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html

       A special section number (-2) marks symbolic debugging symbols,
       including structure/union/enumeration tag names, typedefs, and
       the name of the file. A section number of -1 indicates that the
       symbol has a value but is not relocatable. Examples of
       absolute-valued symbols include automatic and register variables,
       function arguments, and .eos symbols.

       But from Ian Lance Taylor:

       http://sources.redhat.com/ml/binutils/2000-08/msg00202.html

       the actual tools all marked them as section -1. So the GNU COFF
       assembler follows historical COFF assemblers.

       However, it causes problems for djgpp

       http://sources.redhat.com/ml/binutils/2000-08/msg00210.html

       By defining STRICTCOFF, a COFF port can make the assembler to
       follow the documented behavior.  */
#ifdef STRICTCOFF
    case C_MOS:
    case C_MOE:
    case C_MOU:
    case C_EOS:
#endif
      SF_SET_DEBUG (def_symbol_in_progress);
      S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
      break;

#ifndef STRICTCOFF
    case C_MOS:
    case C_MOE:
    case C_MOU:
    case C_EOS:
      S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
      break;
#endif

    case C_EXT:
    case C_WEAKEXT:
#ifdef TE_PE
    case C_NT_WEAK:
#endif
    case C_STAT:
    case C_LABEL:
      /* Valid but set somewhere else (s_comm, s_lcomm, colon).  */
      break;

    default:
    case C_USTATIC:
    case C_EXTDEF:
    case C_ULABEL:
      as_warn (_("unexpected storage class %d"),
	       S_GET_STORAGE_CLASS (def_symbol_in_progress));
      break;
    }

  /* Now that we have built a debug symbol, try to find if we should
     merge with an existing symbol or not.  If a symbol is C_EFCN or
     absolute_section or untagged SEG_DEBUG it never merges.  We also
     don't merge labels, which are in a different namespace, nor
     symbols which have not yet been defined since they are typically
     unique, nor do we merge tags with non-tags.  */

  /* Two cases for functions.  Either debug followed by definition or
     definition followed by debug.  For definition first, we will
     merge the debug symbol into the definition.  For debug first, the
     lineno entry MUST point to the definition function or else it
     will point off into space when obj_crawl_symbol_chain() merges
     the debug symbol into the real symbol.  Therefor, let's presume
     the debug symbol is a real function reference.  */

  /* FIXME-SOON If for some reason the definition label/symbol is
     never seen, this will probably leave an undefined symbol at link
     time.  */

  if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
      || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
      || (streq (bfd_get_section_name (stdoutput,
				       S_GET_SEGMENT (def_symbol_in_progress)),
		 "*DEBUG*")
	  && !SF_GET_TAG (def_symbol_in_progress))
      || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
      || ! symbol_constant_p (def_symbol_in_progress)
      || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL
      || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
    {
      /* If it already is at the end of the symbol list, do nothing */
      if (def_symbol_in_progress != symbol_lastP)
	{
	  symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
	  symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
			 &symbol_lastP);
	}
    }
  else
    {
      /* This symbol already exists, merge the newly created symbol
	 into the old one.  This is not mandatory. The linker can
	 handle duplicate symbols correctly. But I guess that it save
	 a *lot* of space if the assembly file defines a lot of
	 symbols. [loic]  */

      /* The debug entry (def_symbol_in_progress) is merged into the
	 previous definition.  */

      c_symbol_merge (def_symbol_in_progress, symbolP);
      symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);

      def_symbol_in_progress = symbolP;

      if (SF_GET_FUNCTION (def_symbol_in_progress)
	  || SF_GET_TAG (def_symbol_in_progress)
	  || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
	{
	  /* For functions, and tags, and static symbols, the symbol
	     *must* be where the debug symbol appears.  Move the
	     existing symbol to the current place.  */
	  /* If it already is at the end of the symbol list, do nothing.  */
	  if (def_symbol_in_progress != symbol_lastP)
	    {
	      symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
	      symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
	    }
	}
    }

  if (SF_GET_TAG (def_symbol_in_progress))
    {
      symbolS *oldtag;

      oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress));
      if (oldtag == NULL || ! SF_GET_TAG (oldtag))
	tag_insert (S_GET_NAME (def_symbol_in_progress),
		    def_symbol_in_progress);
    }

  if (SF_GET_FUNCTION (def_symbol_in_progress))
    {
      know (sizeof (def_symbol_in_progress) <= sizeof (long));
      set_function (def_symbol_in_progress);
      SF_SET_PROCESS (def_symbol_in_progress);

      if (symbolP == NULL)
	/* That is, if this is the first time we've seen the
	   function.  */
	symbol_table_insert (def_symbol_in_progress);

    }

  def_symbol_in_progress = NULL;
  demand_empty_rest_of_line ();
}
Exemple #10
0
Fichier : macro.c Projet : lhz/acme
// Parse macro call ("+MACROTITLE"). Has to be re-entrant.
void Macro_parse_call(void)	// Now GotByte = dot or first char of macro name
{
    char		local_gotbyte;
    struct symbol	*symbol;
    struct section	new_section,
                *outer_section;
    struct input	new_input,
                  *outer_input;
    struct macro	*actual_macro;
    struct rwnode	*macro_node,
                 *symbol_node;
    zone_t		macro_zone,
                symbol_zone;
    int		arg_count	= 0;

    // Enter deeper nesting level
    // Quit program if recursion too deep.
    if (--macro_recursions_left < 0)
        Throw_serious_error("Too deeply nested. Recursive macro calls?");
    macro_zone = get_zone_and_title();
    // now GotByte = first non-space after title
    // internal_name = MacroTitle ARG_SEPARATOR (grows to signature)
    // Accept n>=0 comma-separated arguments before CHAR_EOS.
    // Valid argument formats are:
    // EXPRESSION (everything that does NOT start with '~'
    // ~.LOCAL_LABEL_BY_REFERENCE
    // ~GLOBAL_LABEL_BY_REFERENCE
    // now GotByte = non-space
    if (GotByte != CHAR_EOS) {	// any at all?
        do {
            // if arg table cannot take another element, enlarge
            if (argtable_size <= arg_count)
                enlarge_arg_table();
            // Decide whether call-by-reference or call-by-value
            // In both cases, GlobalDynaBuf may be used.
            if (GotByte == REFERENCE_CHAR) {
                // read call-by-reference arg
                DynaBuf_append(internal_name, ARGTYPE_NUM_REF);
                GetByte();	// skip '~' character
                Input_read_zone_and_keyword(&symbol_zone);
                // GotByte = illegal char
                arg_table[arg_count].symbol = symbol_find(symbol_zone, 0);
            } else {
                // read call-by-value arg
                DynaBuf_append(internal_name, ARGTYPE_NUM_VAL);
                ALU_any_result(&(arg_table[arg_count].result));
            }
            ++arg_count;
        } while (Input_accept_comma());
    }
    // now arg_table contains the arguments
    // now GlobalDynaBuf = unused
    // check for "unknown macro"
    // Search for macro. Do not create if not found.
    search_for_macro(&macro_node, macro_zone, FALSE);
    if (macro_node == NULL) {
        Throw_error("Macro not defined (or wrong signature).");
        Input_skip_remainder();
    } else {
        // make macro_node point to the macro struct
        actual_macro = macro_node->body;
        local_gotbyte = GotByte;	// CAUTION - ugly kluge
        // set up new input
        new_input.original_filename = actual_macro->def_filename;
        new_input.line_number = actual_macro->def_line_number;
        new_input.source_is_ram = TRUE;
        new_input.state = INPUTSTATE_NORMAL;	// FIXME - fix others!
        new_input.src.ram_ptr = actual_macro->parameter_list;
        // remember old input
        outer_input = Input_now;
        // activate new input
        Input_now = &new_input;
        // remember old section
        outer_section = Section_now;
        // start new section (with new zone)
        // FALSE = title mustn't be freed
        Section_new_zone(&new_section, "Macro", actual_macro->original_name, FALSE);
        GetByte();	// fetch first byte of parameter list
        // assign arguments
        if (GotByte != CHAR_EOS) {	// any at all?
            arg_count = 0;
            do {
                // Decide whether call-by-reference
                // or call-by-value
                // In both cases, GlobalDynaBuf may be used.
                if (GotByte == REFERENCE_CHAR) {
                    // assign call-by-reference arg
                    GetByte();	// skip '~' character
                    Input_read_zone_and_keyword(&symbol_zone);
                    if ((Tree_hard_scan(&symbol_node, symbols_forest, symbol_zone, TRUE) == FALSE)
                            && (pass_count == 0))
                        Throw_error("Macro parameter twice.");
                    symbol_node->body = arg_table[arg_count].symbol;
                } else {
                    // assign call-by-value arg
                    Input_read_zone_and_keyword(&symbol_zone);
                    symbol = symbol_find(symbol_zone, 0);
// FIXME - add a possibility to symbol_find to make it possible to find out
// whether symbol was just created. Then check for the same error message here
// as above ("Macro parameter twice.").
                    symbol->result = arg_table[arg_count].result;
                }
                ++arg_count;
            } while (Input_accept_comma());
        }
        // and now, finally, parse the actual macro body
        Input_now->state = INPUTSTATE_NORMAL;	// FIXME - fix others!
// maybe call parse_ram_block(actual_macro->def_line_number, actual_macro->body)
        Input_now->src.ram_ptr = actual_macro->body;
        Parse_until_eob_or_eof();
        if (GotByte != CHAR_EOB)
            Bug_found("IllegalBlockTerminator", GotByte);
        // end section (free title memory, if needed)
        Section_finalize(&new_section);
        // restore previous section
        Section_now = outer_section;
        // restore previous input:
        Input_now = outer_input;
        // restore old Gotbyte context
        GotByte = local_gotbyte;	// CAUTION - ugly kluge
        Input_ensure_EOS();
    }
    ++macro_recursions_left;	// leave this nesting level
}