/* * A new sign in group 'groupname' is added. If the group is not present, * create it. Otherwise reference the group. */ static signgroup_T * sign_group_ref(char_u *groupname) { hash_T hash; hashitem_T *hi; signgroup_T *group; hash = hash_hash(groupname); hi = hash_lookup(&sg_table, groupname, hash); if (HASHITEM_EMPTY(hi)) { // new group group = (signgroup_T *)alloc( (unsigned)(sizeof(signgroup_T) + STRLEN(groupname))); if (group == NULL) return NULL; STRCPY(group->sg_name, groupname); group->refcount = 1; group->next_sign_id = 1; hash_add_item(&sg_table, hi, group->sg_name, hash); } else { // existing group group = HI2SG(hi); group->refcount++; } return group; }
/* Reads all the environment variables from envp and populates * a hashmap for use through out the execution of the command */ void set_env_opts( memmgr **mm, /* memory manager */ job_data **env_attr, char **envp) { int var_num = 0; char *name = NULL; char *value = NULL; int rc = PBSE_NONE; while (envp[var_num] != NULL) { rc = parse_env_line(mm, envp[var_num], &name, &value); if (rc == PBSE_NONE) { hash_add_item(mm, env_attr, name, value, ENV_DATA, SET); memmgr_free(mm, name); name = NULL; memmgr_free(mm, value); value = NULL; } var_num++; } } /* END set_env_opts() */
/* Add all symbols in data_symbols to the original symbols hash. * since the data must be last it will be incresed in IC of its original position */ void reorder_symbols(int IC) { HashNode *i; for_each_item(i,data_symbols) { hash_add_item(symbols,i->key+IC,i->value); }
static unsigned int hash_reinit(pool_t *p, hash_t *h) { hash_t *rehash = NULL; int i = 0; hash_item_t * item; hash_item_t *next; rehash =(hash_t *) palloc(p, sizeof(hash_t)); rehash->buckets = NULL; rehash->size = (h->size)<<1; rehash->count = 0; rehash->mask = rehash->size - 1; rehash->buckets = (bucket_t *)pcalloc(p, sizeof(bucket_t)*rehash->size); for(i = 0; i < h->size; i++){ item = h->buckets[i].items; while(item) { next = item->next; hash_add_item(rehash, item); item = next; } } memcpy(h, rehash, sizeof(hash_t)); return 0; }
/* Reads all the environment variables from envp and populates * a hashmap for use through out the execution of the command */ void set_env_opts( memmgr **mm, /* memory manager */ job_data **env_attr, char **envp) { int var_num = 0; char *name = NULL; char *value = NULL; int rc = PBSE_NONE; while (envp[var_num] != NULL) { rc = parse_env_line(mm, envp[var_num], &name, &value); if (rc != PBSE_NONE) { fprintf(stderr, "Malformed environment variable %s. Will not add to job environment\n", envp[var_num]); ; exit(1); } /* strtolower(name); */ hash_add_item(mm, env_attr, name, value, ENV_DATA, SET); memmgr_free(mm, name); name = NULL; memmgr_free(mm, value); value = NULL; var_num++; } } /* END set_env_opts() */
/// Add item with key "key" to hashtable "ht". /// /// @param ht /// @param key /// /// @returns FAIL when out of memory or the key is already present. int hash_add(hashtab_T *ht, char_u *key) { hash_T hash = hash_hash(key); hashitem_T *hi = hash_lookup(ht, key, hash); if (!HASHITEM_EMPTY(hi)) { EMSG2(_(e_intern2), "hash_add()"); return FAIL; } return hash_add_item(ht, hi, key, hash); }
/* A wrapper for hash to accomodate for memory allocation errors */ void hash_add_or_exit( job_data_container *head, /* M - hashmap */ const char *name, /* I - The item being added to the hashmap */ const char *val, /* I - Sets the value of variable */ int var_type) /* I - Sets the type of the variable */ { if (hash_add_item(head, name, val, var_type, SET) == FALSE) { fprintf(stderr, "Error allocating memory for hash (%s)-(%s)\n", name, val); exit(1); } }
static int hash_add(pool_t *p, hash_t *h ,const char * key, int keyLen, void * ptr, int type) { hash_item_t * newItem = (hash_item_t *)pcalloc(p, sizeof(hash_item_t)); newItem->key = string_init_from_ptr(p, key, keyLen); newItem->type = type; newItem->next = NULL; if((h->count+1) > h->size) { int reint = hash_reinit(p, h); if(reint) { return reint; } } switch(type) { case HASH_ITEM_VALUE_TYPE_INT: newItem->value.i = *(int*)ptr; break; case HASH_ITEM_VALUE_TYPE_LONG: newItem->value.l = *(long int*)ptr; break; case HASH_ITEM_VALUE_TYPE_DOUBLE: newItem->value.d = *(double*)ptr; break; case HASH_ITEM_VALUE_TYPE_STRING: newItem->value.str = (string *) ptr; break; case HASH_ITEM_VALUE_TYPE_PTR: newItem->value.ptr = (void *) ptr; break; default: return -1; } hash_add_item(h, newItem); return 0; }
/* Reads all the environment variables from envp and populates * a hashmap for use through out the execution of the command */ void set_env_opts( job_data_container *env_attr, char **envp) { int var_num = 0; char *name = NULL; char *value = NULL; int rc = PBSE_NONE; while (envp[var_num] != NULL) { rc = parse_env_line(envp[var_num], &name, &value); if (rc == PBSE_NONE) { hash_add_item(env_attr, name, value, ENV_DATA, SET); free(name); name = NULL; free(value); value = NULL; } var_num++; } } /* END set_env_opts() */
/* Merge the contents of src hash into dest hash * If overwrite_existing is set, existing contents will be overwritten * This allocates memory for the new hash entries * returns qty of items added */ int hash_add_hash( job_data_container *dest, job_data_container *src, int overwrite_existing) { int cntr = 0; job_data *en; job_data *tmp; src->lock(); job_data_iterator *it = src->get_iterator(); while ((en = it->get_next_item()) != NULL) { if (overwrite_existing) { dest->lock(); dest->insert(new job_data(en->name.c_str(),en->value.c_str(), en->var_type, en->op_type),en->name.c_str(),true); dest->unlock(); cntr++; } else if (hash_find(dest, en->name.c_str(), &tmp) != TRUE) { hash_add_item(dest, en->name.c_str(), en->value.c_str(), en->var_type, en->op_type); cntr++; } } delete it; src->unlock(); dest->unlock(); return cntr; }
/* This is the main initialization function. * The function allocates memory to all of the global system hashes above * The function also fills the system hashes with the relevant data (commands, registers...) */ void init() { /* init list of errors */ errors = new_hash(); /* init list of registers */ registers = new_hash(); hash_add_item(registers,0,"r0"); hash_add_item(registers,1,"r1"); hash_add_item(registers,2,"r2"); hash_add_item(registers,3,"r3"); hash_add_item(registers,4,"r4"); hash_add_item(registers,5,"r5"); hash_add_item(registers,6,"r6"); hash_add_item(registers,7,"r7"); /* init list of commands */ commands = new_hash(); hash_add_item(commands,0,"mov"); hash_add_item(commands,1,"cmp"); hash_add_item(commands,2,"add"); hash_add_item(commands,3,"sub"); hash_add_item(commands,4,"ror"); hash_add_item(commands,5,"shr"); hash_add_item(commands,6,"lea"); hash_add_item(commands,7,"inc"); hash_add_item(commands,8,"dec"); hash_add_item(commands,9,"jmp"); hash_add_item(commands,10,"bne"); hash_add_item(commands,11,"red"); hash_add_item(commands,12,"prn"); hash_add_item(commands,13,"jsr"); hash_add_item(commands,14,"rts"); hash_add_item(commands,15,"hlt"); /* init list of commands types */ operand_types = new_hash(); hash_add_item(operand_types,0,"#"); hash_add_item(operand_types,3,"*"); /* init global hashes */ symbols = new_hash(); data_symbols = new_hash(); externals = new_hash(); entry = new_hash(); }
static int masm_main_loop(char * obj_file,char * src_file) { FILE * obj_fp, *src_fp; char buf[BUFSIZ] = {0}; int length; char * p, * q; src_fp = obj_fp = NULL; uint32_t counter = 0; uint32_t lines = 0; hash_table * label_hash = hash_create(512); char op_name[128]; char label[128]; char rd[6]; char rs[6]; char rt[6]; char imm[20]; int32_t rd_num,rs_num,rt_num,imm_num; if((src_fp = fopen(src_file,"r")) == NULL) { printf("Can not open %s:%s\n",src_file,strerror(errno)); } if((obj_fp = fopen(obj_file,"w+")) == NULL) { printf("Can not open %s:%s\n",obj_file,strerror(errno)); } int total_lines = get_file_lines(src_fp); uint32_t * instruction = calloc(1,total_lines * sizeof(uint32_t)); var_t * var = calloc(1,total_lines * sizeof(var_t)); int var_count = 0; fseek(src_fp,0L,SEEK_SET); while(1) { fgets(buf,BUFSIZ,src_fp); if(feof(src_fp)) { break; } lines++; length = strlen(buf); p = buf; //skip whitespace while(length > 0 &&isspace(p[0])) { length--; p++; } //printf("length=%d\t%s",length,buf+i); if(p[0] == ';' || p[0] == '\0') { continue; } q = get_first_token(p); strncpy(op_name, p , q-p); op_name[q-p] = '\0'; if(line_has_label(p)) { /* it is label */ label_t l; l.name = op_name; l.real_line = lines; l.line = counter; hash_add_item(&label_hash,str2hash(op_name),&l); p = skip_label_wthie(q); /* 获得字符串 */ q = get_opcode_token(p); strncpy(op_name, p , q-p); op_name[q-p] = '\0'; //printf("%s",op_name); } /* p now a opcode start q-p is opecode */ int op_index = verify_opcode(op_name,lines); q = skip_wthie(q); p = q; /* now at rd */ switch(op_index) { #if 1 case ADD: case SUB: case MUL: case DIV: case MOD: case AND: case OR: case NOT: case XOR: case LWORD: case SWORD: /* 获得字符串 */ q = get_reg_token(p); strncpy(rd, p , q-p); rd[q-p] = '\0'; q = skip_reg_wthie(q); p = q; q = get_reg_token(p); strncpy(rs, p , q-p); rs[q-p] = '\0'; q = skip_reg_wthie(q); p = q; q = get_reg_token(p); strncpy(rt, p , q-p); rt[q-p] = '\0'; rd_num = get_reg_index(rd,lines); rs_num = get_reg_index(rs,lines); rt_num = get_reg_index(rt,lines); instruction[counter] = (op_index << 26) | (rd_num << 21) | (rs_num << 16)| (rt_num << 11); break; ///C语言中的左移就是逻辑左移,而右移, ///对于无符号数来说就是逻辑右移, ///对有符号来说就是算术右移 ///想要实现符号左移,比较麻烦一点,首先保存最高位,然后左移之后补上最高位。 case SLL: case SLR: case SAL: case SAR: case ADDI: case ANDI: ///这里的立即数是0扩展的。 case ORI: case XORI: case LUI: ///哦,载入高16位数啊,靠,那么低位怎么载入呢?用ori q = get_reg_token(p); strncpy(rd, p , q-p); rd[q-p] = '\0'; q = skip_reg_wthie(q); p = q; q = get_reg_token(p); strncpy(rs, p , q-p); rs[q-p] = '\0'; q = skip_reg_wthie(q); p = q; q = get_reg_token(p); strncpy(imm, p , q-p); imm[q-p] = '\0'; rd_num = get_reg_index(rd,lines); rs_num = get_reg_index(rs,lines); imm_num = atoi(imm); if(imm_num > 32767 || imm_num < -32768) { printf("________\n"); printf("[ERROR 6] line: %d imm num is too lager or too smaller\n",lines); } instruction[counter] = (op_index << 26) | (rd_num << 21) | (rs_num << 16)| (imm_num & 0x0000ffff); break; case LESS: case GREAT: case LESSE: case GREATE: case LESSU: case GREATU: case LESSEU: case GREATEU: case EQUAL: case UEQUAL: q = get_reg_token(p); strncpy(rd, p , q-p); rd[q-p] = '\0'; q = skip_reg_wthie(q); p = q; q = get_reg_token(p); strncpy(rs, p , q-p); rs[q-p] = '\0'; q = skip_reg_wthie(q); p = q; q = get_reg_token(p); strncpy(label, p , q-p); label[q-p] = '\0'; rd_num = get_reg_index(rd,lines); rs_num = get_reg_index(rs,lines); var[var_count].name = malloc(strlen(label) + 1); strcpy(var[var_count].name, label); var[var_count].line = counter; var_count++; instruction[counter] = (op_index << 26) | (rd_num << 21) | (rs_num << 16) | 0x0; break; case JMP: q = get_reg_token(p); strncpy(label, p , q-p); label[q-p] = '\0'; var[var_count].name = malloc(strlen(label) + 1); strcpy(var[var_count].name, label); var[var_count].line = counter; var_count++; instruction[counter] = (op_index << 26); break; /* 存储指令 */ case MOV: q = get_reg_token(p); strncpy(rd, p , q-p); rd[q-p] = '\0'; q = skip_reg_wthie(q); p = q; q = get_reg_token(p); strncpy(rs, p , q-p); rs[q-p] = '\0'; rd_num = get_reg_index(rd,lines); rs_num = get_reg_index(rs,lines); instruction[counter] = (op_index << 26) | (rd_num << 21) | (rs_num << 16) | 0x0; break; default: break; #endif } counter++; } /* 第二趟汇编 */ struct blist * head; for(int i = 0; i < var_count; i++) { if((head = hash_lookup_item(label_hash,str2hash(var[i].name),&var[i])) != NULL) { label_t * node = head->item; int imm_2 = node->line - var[i].line; if((instruction[var[i].line] >> 26) == JMP) { if(imm_2 > 33554431 || imm_2 < -33554432) { printf("[ERROR 7] line: %d imm num is too lager or too smaller\n",lines); } instruction[var[i].line] |= imm_2 & 0x03ffffff; } else { if(imm_2 > 32767 || imm_2 < -32768) { printf("[ERROR 6] line: %d imm num is too lager or too smaller\n",lines); } instruction[var[i].line] |= imm_2 & 0x0000ffff; } }