⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ld-insn.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
			 void *data,			 insn_handler *handler){  insn *instruction;  for (instruction = table->insns;       instruction != NULL;       instruction = instruction->next) {    handler(table, file, data, instruction, 0);  }}/****************************************************************/typedef enum {  field_constant_int = 1,  field_constant_slash = 2,  field_constant_string = 3} constant_field_types;static intinsn_field_is_constant(insn_field *field,		       decode_table *rule){  /* field is an integer */  if (field->is_int)    return field_constant_int;  /* field is `/' and treating that as a constant */  if (field->is_slash && rule->force_slash)    return field_constant_slash;  /* field, though variable is on the list */  if (field->is_string && rule->force_expansion != NULL) {    char *forced_fields = rule->force_expansion;    while (*forced_fields != '\0') {      int field_len;      char *end = strchr(forced_fields, ',');      if (end == NULL)	field_len = strlen(forced_fields);      else	field_len = end-forced_fields;      if (strncmp(forced_fields, field->val_string, field_len) == 0	  && field->val_string[field_len] == '\0')	return field_constant_string;      forced_fields += field_len;      if (*forced_fields == ',')	forced_fields++;    }  }  return 0;}static opcode_field *insn_table_find_opcode_field(insn *insns,			     decode_table *rule,			     int string_only){  opcode_field *curr_opcode = ZALLOC(opcode_field);  insn *entry;  ASSERT(rule);  curr_opcode->first = insn_bit_size;  curr_opcode->last = -1;  for (entry = insns; entry != NULL; entry = entry->next) {    insn_fields *fields = entry->fields;    opcode_field new_opcode;    /* find a start point for the opcode field */    new_opcode.first = rule->first;    while (new_opcode.first <= rule->last	   && (!string_only	       || insn_field_is_constant(fields->bits[new_opcode.first],					 rule) != field_constant_string)	   && (string_only	       || !insn_field_is_constant(fields->bits[new_opcode.first],					  rule)))      new_opcode.first = fields->bits[new_opcode.first]->last + 1;    ASSERT(new_opcode.first > rule->last	   || (string_only	       && insn_field_is_constant(fields->bits[new_opcode.first],					 rule) == field_constant_string)	   || (!string_only	       && insn_field_is_constant(fields->bits[new_opcode.first],					 rule)));      /* find the end point for the opcode field */    new_opcode.last = rule->last;    while (new_opcode.last >= rule->first	   && (!string_only	       || insn_field_is_constant(fields->bits[new_opcode.last],					 rule) != field_constant_string)	   && (string_only	       || !insn_field_is_constant(fields->bits[new_opcode.last],					  rule)))      new_opcode.last = fields->bits[new_opcode.last]->first - 1;    ASSERT(new_opcode.last < rule->first	   || (string_only	       && insn_field_is_constant(fields->bits[new_opcode.last],					 rule) == field_constant_string)	   || (!string_only	       && insn_field_is_constant(fields->bits[new_opcode.last],					 rule)));    /* now see if our current opcode needs expanding */    if (new_opcode.first <= rule->last	&& curr_opcode->first > new_opcode.first)      curr_opcode->first = new_opcode.first;    if (new_opcode.last >= rule->first	&& curr_opcode->last < new_opcode.last)      curr_opcode->last = new_opcode.last;      }  /* was any thing interesting found? */  if (curr_opcode->first > rule->last) {    ASSERT(curr_opcode->last < rule->first);    return NULL;  }  ASSERT(curr_opcode->last >= rule->first);  ASSERT(curr_opcode->first <= rule->last);  /* if something was found, check it includes the forced field range */  if (!string_only      && curr_opcode->first > rule->force_first) {    curr_opcode->first = rule->force_first;  }  if (!string_only      && curr_opcode->last < rule->force_last) {    curr_opcode->last = rule->force_last;  }  /* handle special case elminating any need to do shift after mask */  if (string_only      && rule->force_last == insn_bit_size-1) {    curr_opcode->last = insn_bit_size-1;  }  /* handle any special cases */  switch (rule->type) {  case normal_decode_rule:    /* let the above apply */    break;  case expand_forced_rule:    /* expand a limited nr of bits, ignoring the rest */    curr_opcode->first = rule->force_first;    curr_opcode->last = rule->force_last;    break;  case boolean_rule:    curr_opcode->is_boolean = 1;    curr_opcode->boolean_constant = rule->special_constant;    break;  default:    error("Something is going wrong\n");  }  return curr_opcode;}static voidinsn_table_insert_expanded(insn_table *table,			   insn *old_insn,			   int new_opcode_nr,			   insn_bits *new_bits){  insn_table **ptr_to_cur_entry = &table->entries;  insn_table *cur_entry = *ptr_to_cur_entry;  /* find the new table for this entry */  while (cur_entry != NULL	 && cur_entry->opcode_nr < new_opcode_nr) {    ptr_to_cur_entry = &cur_entry->sibling;    cur_entry = *ptr_to_cur_entry;  }  if (cur_entry == NULL || cur_entry->opcode_nr != new_opcode_nr) {    insn_table *new_entry = ZALLOC(insn_table);    new_entry->opcode_nr = new_opcode_nr;    new_entry->expanded_bits = new_bits;    new_entry->opcode_rule = table->opcode_rule->next;    new_entry->sibling = cur_entry;    new_entry->parent = table;    *ptr_to_cur_entry = new_entry;    cur_entry = new_entry;    table->nr_entries++;  }  /* ASSERT new_bits == cur_entry bits */  ASSERT(cur_entry != NULL && cur_entry->opcode_nr == new_opcode_nr);  insn_table_insert_insn(cur_entry,			 old_insn->file_entry,			 old_insn->fields);}static voidinsn_table_expand_opcode(insn_table *table,			 insn *instruction,			 int field_nr,			 int opcode_nr,			 insn_bits *bits){  if (field_nr > table->opcode->last) {    insn_table_insert_expanded(table, instruction, opcode_nr, bits);  }  else {    insn_field *field = instruction->fields->bits[field_nr];    if (field->is_int || field->is_slash) {      ASSERT(field->first >= table->opcode->first	     && field->last <= table->opcode->last);      insn_table_expand_opcode(table, instruction, field->last+1,			       ((opcode_nr << field->width) + field->val_int),			       bits);    }    else {      int val;      int last_pos = ((field->last < table->opcode->last)			? field->last : table->opcode->last);      int first_pos = ((field->first > table->opcode->first)			 ? field->first : table->opcode->first);      int width = last_pos - first_pos + 1;      int last_val = (table->opcode->is_boolean		      ? 2 : (1 << width));      for (val = 0; val < last_val; val++) {	insn_bits *new_bits = ZALLOC(insn_bits);	new_bits->field = field;	new_bits->value = val;	new_bits->last = bits;	new_bits->opcode = table->opcode;	insn_table_expand_opcode(table, instruction, last_pos+1,				 ((opcode_nr << width) | val),				 new_bits);      }    }  }}static voidinsn_table_insert_expanding(insn_table *table,			    insn *entry){  insn_table_expand_opcode(table,			   entry,			   table->opcode->first,			   0,			   table->expanded_bits);}extern voidinsn_table_expand_insns(insn_table *table){  ASSERT(table->nr_insn >= 1);  /* determine a valid opcode */  while (table->opcode_rule) {    /* specials only for single instructions */    if ((table->nr_insn > 1	 && table->opcode_rule->special_mask == 0	 && table->opcode_rule->type == normal_decode_rule)	|| (table->nr_insn == 1	    && table->opcode_rule->special_mask != 0	    && ((table->insns->fields->value		 & table->opcode_rule->special_mask)		== table->opcode_rule->special_value))	|| (generate_expanded_instructions	    && table->opcode_rule->special_mask == 0	    && table->opcode_rule->type == normal_decode_rule))      table->opcode =	insn_table_find_opcode_field(table->insns,				     table->opcode_rule,				     table->nr_insn == 1/*string*/				     );    if (table->opcode != NULL)      break;    table->opcode_rule = table->opcode_rule->next;  }  /* did we find anything */  if (table->opcode == NULL) {    return;  }  ASSERT(table->opcode != NULL);  /* back link what we found to its parent */  if (table->parent != NULL) {    ASSERT(table->parent->opcode != NULL);    table->opcode->parent = table->parent->opcode;  }  /* expand the raw instructions according to the opcode */  {    insn *entry;    for (entry = table->insns; entry != NULL; entry = entry->next) {      insn_table_insert_expanding(table, entry);    }  }  /* and do the same for the sub entries */  {    insn_table *entry;    for (entry = table->entries; entry != NULL; entry =  entry->sibling) {      insn_table_expand_insns(entry);    }  }}#ifdef MAINstatic voiddump_insn_field(insn_field *field,		int indent){  printf("(insn_field*)0x%x\n", (unsigned)field);  dumpf(indent, "(first %d)\n", field->first);  dumpf(indent, "(last %d)\n", field->last);  dumpf(indent, "(width %d)\n", field->width);  if (field->is_int)    dumpf(indent, "(is_int %d)\n", field->val_int);  if (field->is_slash)    dumpf(indent, "(is_slash)\n");  if (field->is_string)    dumpf(indent, "(is_string `%s')\n", field->val_string);    dumpf(indent, "(next 0x%x)\n", field->next);    dumpf(indent, "(prev 0x%x)\n", field->prev);  }static voiddump_insn_fields(insn_fields *fields,		 int indent){  int i;  printf("(insn_fields*)%p\n", fields);  dumpf(indent, "(first 0x%x)\n", fields->first);  dumpf(indent, "(last 0x%x)\n", fields->last);  dumpf(indent, "(value 0x%x)\n", fields->value);  for (i = 0; i < insn_bit_size; i++) {    dumpf(indent, "(bits[%d] ", i, fields->bits[i]);    dump_insn_field(fields->bits[i], indent+1);    dumpf(indent, " )\n");  }}static voiddump_opcode_field(opcode_field *field, int indent, int levels){  printf("(opcode_field*)%p\n", field);  if (levels && field != NULL) {    dumpf(indent, "(first %d)\n", field->first);    dumpf(indent, "(last %d)\n", field->last);    dumpf(indent, "(is_boolean %d)\n", field->is_boolean);    dumpf(indent, "(parent ");    dump_opcode_field(field->parent, indent, levels-1);  }}static voiddump_insn_bits(insn_bits *bits, int indent, int levels){  printf("(insn_bits*)%p\n", bits);  if (levels && bits != NULL) {    dumpf(indent, "(value %d)\n", bits->value);    dumpf(indent, "(opcode ");    dump_opcode_field(bits->opcode, indent+1, 0);    dumpf(indent, " )\n");    dumpf(indent, "(field ");    dump_insn_field(bits->field, indent+1);    dumpf(indent, " )\n");    dumpf(indent, "(last ");    dump_insn_bits(bits->last, indent+1, levels-1);  }}static voiddump_insn(insn *entry, int indent, int levels){  printf("(insn*)%p\n", entry);  if (levels && entry != NULL) {    dumpf(indent, "(file_entry ");    dump_table_entry(entry->file_entry, indent+1);    dumpf(indent, " )\n");    dumpf(indent, "(fields ");    dump_insn_fields(entry->fields, indent+1);    dumpf(indent, " )\n");    dumpf(indent, "(next ");    dump_insn(entry->next, indent+1, levels-1);    dumpf(indent, " )\n");  }}static voiddump_insn_table(insn_table *table,		int indent, int levels){  printf("(insn_table*)%p\n", table);  if (levels && table != NULL) {    dumpf(indent, "(opcode_nr %d)\n", table->opcode_nr);    dumpf(indent, "(expanded_bits ");    dump_insn_bits(table->expanded_bits, indent+1, -1);    dumpf(indent, " )\n");    dumpf(indent, "(int nr_insn %d)\n", table->nr_insn);    dumpf(indent, "(insns ");    dump_insn(table->insns, indent+1, table->nr_insn);    dumpf(indent, " )\n");    dumpf(indent, "(opcode_rule ");    dump_decode_rule(table->opcode_rule, indent+1);    dumpf(indent, " )\n");    dumpf(indent, "(opcode ");    dump_opcode_field(table->opcode, indent+1, 1);    dumpf(indent, " )\n");    dumpf(indent, "(nr_entries %d)\n", table->entries);    dumpf(indent, "(entries ");    dump_insn_table(table->entries, indent+1, table->nr_entries);    dumpf(indent, " )\n");    dumpf(indent, "(sibling ", table->sibling);    dump_insn_table(table->sibling, indent+1, levels-1);    dumpf(indent, " )\n");    dumpf(indent, "(parent ", table->parent);    dump_insn_table(table->parent, indent+1, 0);    dumpf(indent, " )\n");  }}int insn_bit_size = max_insn_bit_size;int hi_bit_nr;int generate_expanded_instructions;intmain(int argc, char **argv){  filter *filters = NULL;  decode_table *decode_rules = NULL;  insn_table *instructions = NULL;  cache_table *cache_rules = NULL;  if (argc != 5)    error("Usage: insn <filter> <hi-bit-nr> <decode-table> <insn-table>\n");  filters = new_filter(argv[1], filters);  hi_bit_nr = a2i(argv[2]);  ASSERT(hi_bit_nr < insn_bit_size);  decode_rules = load_decode_table(argv[3], hi_bit_nr);  instructions = load_insn_table(argv[4], decode_rules, filters, NULL,				 &cache_rules);  insn_table_expand_insns(instructions);  dump_insn_table(instructions, 0, -1);  return 0;}#endif

⌨️ 快捷键说明

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