//Register exact MD for each global variable. //Note you should call this function as early as possible, e.g, before process //all regions. Because that will assign smaller MD id to global variable. void RegionMgr::registerGlobalMD() { //Only top region can do initialize MD for global variable. ASSERT0(m_var_mgr); VarVec * varvec = m_var_mgr->get_var_vec(); for (INT i = 0; i <= varvec->get_last_idx(); i++) { VAR * v = varvec->get(i); if (v == NULL || VAR_is_local(v)) { continue; } ASSERT0(VAR_is_global(v)); //User sometime intentionally declare non-allocable //global variable to custmized usage. //ASSERT0(VAR_allocable(v)); if (v->is_string() && genDedicateStrMD() != NULL) { continue; } //We allocate MDTab for VAR which is func-decl or fake as well. //Since some Passes such as AA may need fake VAR to do analysis. MD md; MD_base(&md) = v; MD_ofst(&md) = 0; MD_size(&md) = v->getByteSize(get_type_mgr()); if (VAR_is_fake(v) || VAR_is_func_decl(v)) { MD_ty(&md) = MD_UNBOUND; } else { MD_ty(&md) = MD_EXACT; } m_md_sys->registerMD(md); } }
/* Return VAR if there is already related to 's', otherwise create a new VAR. 'var_name': name of the variable, it is optional. 's': string's content. */ VAR * VAR_MGR::register_str(CHAR const* var_name, SYM * s, UINT align) { IS_TRUE0(s != NULL); VAR * v; if ((v = m_str_tab.get(s)) != NULL) { return v; } v = new_var(); CHAR buf[64]; if (var_name == NULL) { sprintf(buf, ".rodata_%zu", m_str_count++); VAR_name(v) = m_ru_mgr->add_to_symtab(buf); } else { VAR_name(v) = m_ru_mgr->add_to_symtab(var_name); } VAR_str(v) = s; VAR_data_type(v) = D_STR; VAR_elem_type(v) = D_UNDEF; IS_TRUE0(sizeof(CHAR) == 1); VAR_data_size(v) = xstrlen(SYM_name(s)) + 1; VAR_align(v) = align; VAR_is_global(v) = 1; //store in .data or .rodata assign_var_id(v); m_str_tab.set(s, v); return v; }