To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit 85da4191 authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano
Browse files

Updated name handling (but only on x86-64)

parent d91898d5
......@@ -521,10 +521,7 @@ pub struct CallData {
impl CallData {
fn debug_str(&self, ops: &Vec<P<TreeNode>>) -> String {
let func_name = match ops[self.func].name() {
Some(name) => name,
None => "Anonymous Function".to_string()
};
let func_name = ops[self.func].name();
format!("{:?} {} [{}]", self.convention, func_name, op_vector_str(&self.args, ops))
}
}
......
......@@ -386,7 +386,7 @@ impl FunctionContent {
pub fn get_block_by_name(&self, name: String) -> &Block {
for block in self.blocks.values() {
if block.name().unwrap() == name {
if block.name() == name {
return block;
}
}
......@@ -1108,7 +1108,7 @@ rodal_struct!(MuEntityHeader{id, name});
#[derive(Debug)] // Display, PartialEq, Clone
pub struct MuEntityHeader {
id: MuID,
name: Option<MuName>
name: MuName
}
impl Clone for MuEntityHeader {
......@@ -1120,62 +1120,98 @@ impl Clone for MuEntityHeader {
}
}
pub fn name_check(name: MuName) -> MuName {
let name = name.replace('.', "$");
/// Returns true if name is a valid_c identifier
/// (i.e. it contains only ASCII letters, digits and underscores
/// and does not start with "__" or an digit.
pub fn is_valid_c_identifier(name: &MuName) -> bool {
let mut i = 0;
let mut underscore = false; // whether the first character is an underscore
for c in name.chars() {
match c {
'_' => {
if i == 0 { underscore = true; }
else if i == 1 && underscore { return false; }
},
'0'...'9' => {
if i == 0 { return false; }
},
'a'...'z' | 'A' ... 'Z' => { }
_ => { return false; }
}
i += 1;
}
return true;
}
// change mangle_name to mangle name
// This will always return a valid C identifier
pub fn mangle_name(name: MuName) -> MuName {
let name = name.replace('@', "");
if name.starts_with("__mu_") {
// TODO: Get rid of this, since it will be trigered if a client provides a name starting with "__mu"
// which is totally valid, it's only here for the moment to debug name handling
panic!("Trying to mangle \"{}\", which is allready mangled", name.clone());
}
if name.starts_with("@") || name.starts_with("%") {
let (_, name) = name.split_at(1);
assert!(!name.starts_with("%"));
return name.to_string();
}
// Note: a ':' and '#' is only used by names generated by zebu itself
let name = name.replace('Z', "ZZ").replace('.', "Zd").replace('-', "Zh").replace(':', "Zc").replace('#', "Za");
"__mu_".to_string() + name.as_str()
}
// WARNING: This only reverses mangle_name above when no warning is issued)
pub fn demangle_name(name: MuName) -> MuName {
if name.starts_with("%") {
panic!("The name '{}'' is local", name);
}
if !name.starts_with("__mu_") {
panic!("Trying to demangle \"{}\", which is not mangled", name.clone());
}
let name = name.split_at("__mu_".len()).1.to_string();
let name = name.replace("Za", "#").replace("Zc", ":").replace("Zh", "-").replace("Zd", ".").replace("ZZ", "Z");
name
}
impl MuEntityHeader {
pub fn unnamed(id: MuID) -> MuEntityHeader {
MuEntityHeader {
id: id,
name: None
name: format!("#{}", id)
}
}
pub fn named(id: MuID, name: MuName) -> MuEntityHeader {
MuEntityHeader {
id: id,
name: Some(name_check(name))
name: name.replace('@', "")
}
}
pub fn id(&self) -> MuID {
self.id
}
pub fn name(&self) -> Option<MuName> {
pub fn name(&self) -> MuName {
self.name.clone()
}
fn abbreviate_name(&self) -> Option<MuName> {
match self.name() {
Some(name) => {
let split: Vec<&str> = name.split('$').collect();
fn abbreviate_name(&self) -> MuName {
let split: Vec<&str> = self.name.split('.').collect();
let mut ret = "".to_string();
let mut ret = "".to_string();
for i in 0..split.len() - 1 {
ret.push(match split[i].chars().next() {
Some(c) => c,
None => '_'
});
ret.push('.');
}
for i in 0..split.len() - 1 {
ret.push(match split[i].chars().next() {
Some(c) => c,
None => '_'
});
ret.push('.');
}
ret.push_str(split.last().unwrap());
ret.push_str(split.last().unwrap());
Some(ret)
}
None => None
}
ret
}
pub fn clone_with_id(&self, new_id: MuID) -> MuEntityHeader {
......@@ -1195,24 +1231,16 @@ impl PartialEq for MuEntityHeader {
impl fmt::Display for MuEntityHeader {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if DISPLAY_ID {
if self.name().is_none() {
write!(f, "{}", self.id)
if PRINT_ABBREVIATE_NAME {
write!(f, "{} #{}", self.abbreviate_name(), self.id)
} else {
if PRINT_ABBREVIATE_NAME {
write!(f, "{} #{}", self.abbreviate_name().unwrap(), self.id)
} else {
write!(f, "{} #{}", self.name().unwrap(), self.id)
}
write!(f, "{} #{}", self.name(), self.id)
}
} else {
if self.name().is_none() {
write!(f, "{}", self.id)
if PRINT_ABBREVIATE_NAME {
write!(f, "{}", self.abbreviate_name())
} else {
if PRINT_ABBREVIATE_NAME {
write!(f, "{}", self.abbreviate_name().unwrap())
} else {
write!(f, "{}", self.name().unwrap())
}
write!(f, "{}", self.name())
}
}
}
......@@ -1220,7 +1248,7 @@ impl fmt::Display for MuEntityHeader {
pub trait MuEntity {
fn id(&self) -> MuID;
fn name(&self) -> Option<MuName>;
fn name(&self) -> MuName;
fn as_entity(&self) -> &MuEntity;
}
......@@ -1239,7 +1267,7 @@ impl MuEntity for TreeNode {
}
}
fn name(&self) -> Option<MuName> {
fn name(&self) -> MuName {
match self.v {
TreeNode_::Instruction(ref inst) => inst.name(),
TreeNode_::Value(ref pv) => pv.name()
......@@ -1264,4 +1292,4 @@ pub fn op_vector_str(vec: &Vec<OpIndex>, ops: &Vec<P<TreeNode>>) -> String {
}
}
ret
}
}
\ No newline at end of file
......@@ -14,6 +14,8 @@
#[macro_use]
extern crate rodal;
#[macro_use]
extern crate log;
extern crate simple_logger;
#[macro_use]
extern crate lazy_static;
......@@ -26,7 +28,7 @@ macro_rules! impl_mu_entity {
#[inline(always)]
fn id(&self) -> MuID {self.hdr.id()}
#[inline(always)]
fn name(&self) -> Option<MuName> {self.hdr.name()}
fn name(&self) -> MuName {self.hdr.name()}
fn as_entity(&self) -> &MuEntity {
let ref_ty : &$entity = self;
ref_ty as &MuEntity
......
......@@ -2682,7 +2682,7 @@ pub fn emit_code(fv: &mut MuFunctionVersion, vm: &VM) {
let mut file_path = path::PathBuf::new();
file_path.push(&vm.vm_options.flag_aot_emit_dir);
file_path.push(func.name().unwrap().to_string() + ".s");
file_path.push(func.name().to_string() + ".s");
let mut file = match File::create(file_path.as_path()) {
Err(why) => panic!("couldn't create emission file {}: {}", file_path.to_str().unwrap(), why),
Ok(file) => file
......
......@@ -130,7 +130,7 @@ impl <'a> InstructionSelection {
self.process_dest(&ops, fallthrough_dest, f_content, f_context, vm);
self.process_dest(&ops, branch_dest, f_content, f_context, vm);
let branch_target = f_content.get_block(branch_dest.target).name().unwrap();
let branch_target = f_content.get_block(branch_dest.target).name();
let ref cond = ops[cond];
......@@ -189,7 +189,7 @@ impl <'a> InstructionSelection {
let fallthrough_temp_block = format!("{}_{}_branch_fallthrough", self.current_fv_id, node.id());
self.start_block(fallthrough_temp_block, &vec![]);
let fallthrough_target = f_content.get_block(fallthrough_dest.target).name().unwrap();
let fallthrough_target = f_content.get_block(fallthrough_dest.target).name();
self.backend.emit_b(fallthrough_target);
},
......@@ -3481,7 +3481,7 @@ impl <'a> InstructionSelection {
let potentially_excepting = {
if resumption.is_some() {
let target_id = resumption.unwrap().exn_dest.target;
Some(f_content.get_block(target_id).name().unwrap())
Some(f_content.get_block(target_id).name().unwrap)
} else {
None
}
......@@ -4395,7 +4395,7 @@ impl CompilerPass for InstructionSelection {
self.current_func_start = Some({
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_ver.func_id).unwrap().read().unwrap();
let start_loc = self.backend.start_code(func.name().unwrap(), entry_block.name().unwrap());
let start_loc = self.backend.start_code(func.name(), entry_block.name());
if vm.vm_options.flag_emit_debug_info {
self.backend.add_cfi_sections(".eh_frame, .debug_frame");
self.backend.add_cfi_startproc();
......@@ -4424,7 +4424,7 @@ impl CompilerPass for InstructionSelection {
let is_exception_block = f_content.exception_blocks.contains(&block_id);
let block = f_content.get_block(*block_id);
let block_label = block.name().unwrap();
let block_label = block.name();
self.current_block = Some(block_label.clone());
self.current_block_in_ir = Some(block_label.clone());
......@@ -4479,7 +4479,7 @@ impl CompilerPass for InstructionSelection {
let func_name = {
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func.func_id).unwrap().read().unwrap();
func.name().unwrap()
func.name()
};
// have to do this before 'finish_code()'
......
......@@ -2449,7 +2449,7 @@ fn make_value_symbolic(label: MuName, global: bool, ty: &P<MuType>, vm: &VM) ->
hdr: MuEntityHeader::unnamed(vm.next_id()),
ty : ty.clone(),
v : Value_::Memory(MemoryLocation::Symbolic {
label: label,
label: mangle_name(label)),
is_global: global
})
})
......
......@@ -548,7 +548,7 @@ impl MachineCode for ASMCode {
Some(inst) if inst.code.starts_with("jmp") => {
let split : Vec<&str> = inst.code.split(' ').collect();
Some(ASMCodeGen::unmangle_block_label(self.name.clone(), String::from(split[1])))
Some(demangle_name(String::from(split[1])))
}
_ => None
}
......@@ -560,7 +560,7 @@ impl MachineCode for ASMCode {
Some(inst) if inst.code.ends_with(':') => {
let split : Vec<&str> = inst.code.split(':').collect();
Some(ASMCodeGen::unmangle_block_label(self.name.clone(), String::from(split[0])))
Some(demangle_name(String::from(split[0])))
}
_ => None
}
......@@ -610,7 +610,7 @@ impl MachineCode for ASMCode {
// pick the right reg based on length
let to_reg = x86_64::get_alias_for_length(to, loc.oplen);
let to_reg_tag = to_reg.name().unwrap();
let to_reg_tag = to_reg.name();
let to_reg_string = "%".to_string() + &to_reg_tag;
string_utils::replace(&mut inst_to_patch.code, loc.index, &to_reg_string, to_reg_string.len());
......@@ -621,7 +621,7 @@ impl MachineCode for ASMCode {
// pick the right reg based on length
let to_reg = x86_64::get_alias_for_length(to, loc.oplen);
let to_reg_tag = to_reg.name().unwrap();
let to_reg_tag = to_reg.name();
let to_reg_string = "%".to_string() + &to_reg_tag;
string_utils::replace(&mut inst_to_patch.code, loc.index, &to_reg_string, to_reg_string.len());
......@@ -1011,7 +1011,7 @@ impl ASMCodeGen {
let l = self.line();
self.cur_mut().code.push(ASMInst::symbolic(code));
}
fn add_asm_symbolic(&mut self, code: String){
self.cur_mut().code.push(ASMInst::symbolic(code));
}
......@@ -1322,23 +1322,12 @@ impl ASMCodeGen {
let id = op.extract_ssa_id().unwrap();
if id < MACHINE_ID_END {
// machine reg
format!("%{}", op.name().unwrap())
format!("%{}", op.name())
} else {
// virtual register, use place holder
REG_PLACEHOLDER.clone()
}
}
fn mangle_block_label(&self, label: MuName) -> String {
format!("{}_{}", self.cur().name, label)
}
fn unmangle_block_label(fn_name: MuName, label: String) -> MuName {
// input: _fn_name_BLOCK_NAME
// return BLOCK_NAME
let split : Vec<&str> = label.splitn(2, &(fn_name + "_")).collect();
String::from(split[1])
}
fn finish_code_sequence_asm(&mut self) -> Box<ASMCode> {
self.cur.take().unwrap()
......@@ -1505,7 +1494,7 @@ impl ASMCodeGen {
trace!("emit: {} {}, {} -> {}", inst, src, dest, dest);
let mreg = self.prepare_machine_reg(src);
let mreg_name = src.name().unwrap();
let mreg_name = src.name();
let (reg2, id2, loc2) = self.prepare_reg(dest, inst.len() + 1 + 1 + mreg_name.len() + 1);
let asm = format!("{} %{},{}", inst, mreg_name, reg2);
......@@ -1584,7 +1573,7 @@ impl ASMCodeGen {
trace!("emit: {} {}, {}, {} -> {}", inst, dest, src1, src2, dest);
let mreg = self.prepare_machine_reg(src2);
let mreg_name = src2.name().unwrap();
let mreg_name = src2.name();
let (reg1, id1, loc1) = self.prepare_reg(src1, inst.len() + 1 + 1 + mreg_name.len() + 1);
let (reg2, id2, loc2) = self.prepare_reg(dest, inst.len() + 1 + 1 + mreg_name.len() + 1 + reg1.len() + 1);
......@@ -2016,9 +2005,14 @@ impl CodeGenerator for ASMCodeGen {
}));
// to link with C sources via gcc
let func_symbol = symbol(func_name.clone());
let func_symbol = symbol(mangle_name(func_name.clone()));
self.add_asm_symbolic(directive_globl(func_symbol.clone()));
self.add_asm_symbolic(format!("{}:", func_symbol.clone()));
if is_valid_c_identifier(&func_name) {
let demangled_name = symbol(func_name.clone());
self.add_asm_symbolic(directive_globl(demangled_name.clone()));
self.add_asm_symbolic(directive_equiv(demangled_name, func_symbol.clone()));
}
ValueLocation::Relocatable(RegGroup::GPR, func_name)
}
......@@ -2026,11 +2020,12 @@ impl CodeGenerator for ASMCodeGen {
fn finish_code(&mut self, func_name: MuName) -> (Box<MachineCode + Sync + Send>, ValueLocation) {
let func_end = {
let mut symbol = func_name.clone();
symbol.push_str("_end");
symbol.push_str(":end");
symbol
};
self.add_asm_symbolic(directive_globl(symbol(func_end.clone())));
self.add_asm_symbolic(format!("{}:", symbol(func_end.clone())));
let func_end_sym = symbol(mangle_name(func_end.clone()));
self.add_asm_symbolic(directive_globl(func_end_sym.clone()));
self.add_asm_symbolic(format!("{}:", func_end_sym));
self.cur.as_mut().unwrap().control_flow_analysis();
......@@ -2074,7 +2069,7 @@ impl CodeGenerator for ASMCodeGen {
}
fn start_block(&mut self, block_name: MuName) {
let label = format!("{}:", symbol(self.mangle_block_label(block_name.clone())));
let label = format!("{}:", mangle_name(block_name.clone()));
self.add_asm_block_label(label, block_name.clone());
self.cur_mut().blocks.insert(block_name.clone(), ASMBlock::new());
......@@ -2083,7 +2078,7 @@ impl CodeGenerator for ASMCodeGen {
}
fn start_exception_block(&mut self, block_name: MuName) -> ValueLocation {
let mangled_name = self.mangle_block_label(block_name.clone());
let mangled_name = mangle_name(block_name.clone());
self.add_asm_symbolic(directive_globl(symbol(mangled_name.clone())));
self.start_block(block_name.clone());
......@@ -2919,91 +2914,92 @@ impl CodeGenerator for ASMCodeGen {
trace!("emit: jmp {}", dest_name);
// symbolic label, we dont need to patch it
let asm = format!("jmp {}", symbol(self.mangle_block_label(dest_name.clone())));
let asm = format!("jmp {}", symbol(mangle_name(dest_name.clone())));
self.add_asm_branch(asm, dest_name)
}
fn emit_je(&mut self, dest_name: MuName) {
trace!("emit: je {}", dest_name);
let asm = format!("je {}", symbol(self.mangle_block_label(dest_name.clone())));
let asm = format!("je {}", symbol(mangle_name(dest_name.clone())));
self.add_asm_branch2(asm, dest_name);
}
fn emit_jne(&mut self, dest_name: MuName) {
trace!("emit: jne {}", dest_name);
let asm = format!("jne {}", symbol(self.mangle_block_label(dest_name.clone())));
let asm = format!("jne {}", symbol(mangle_name(dest_name.clone())));
self.add_asm_branch2(asm, dest_name);
}
fn emit_ja(&mut self, dest_name: MuName) {
trace!("emit: ja {}", dest_name);
let asm = format!("ja {}", symbol(self.mangle_block_label(dest_name.clone())));
let asm = format!("ja {}", symbol(mangle_name(dest_name.clone())));
self.add_asm_branch2(asm, dest_name);
}
fn emit_jae(&mut self, dest_name: MuName) {
trace!("emit: jae {}", dest_name);
let asm = format!("jae {}", symbol(self.mangle_block_label(dest_name.clone())));
let asm = format!("jae {}", symbol(mangle_name(dest_name.clone())));
self.add_asm_branch2(asm, dest_name);
}
fn emit_jb(&mut self, dest_name: MuName) {
trace!("emit: jb {}", dest_name);
let asm = format!("jb {}", symbol(self.mangle_block_label(dest_name.clone())));
let asm = format!("jb {}", symbol(mangle_name(dest_name.clone())));
self.add_asm_branch2(asm, dest_name);
}
fn emit_jbe(&mut self, dest_name: MuName) {
trace!("emit: jbe {}", dest_name);
let asm = format!("jbe {}", symbol(self.mangle_block_label(dest_name.clone())));
let asm = format!("jbe {}", symbol(mangle_name(dest_name.clone())));
self.add_asm_branch2(asm, dest_name);
}
fn emit_jg(&mut self, dest_name: MuName) {
trace!("emit: jg {}", dest_name);
let asm = format!("jg {}", symbol(self.mangle_block_label(dest_name.clone())));
let asm = format!("jg {}", symbol(mangle_name(dest_name.clone())));
self.add_asm_branch2(asm, dest_name);
}
fn emit_jge(&mut self, dest_name: MuName) {
trace!("emit: jge {}", dest_name);
let asm = format!("jge {}", symbol(self.mangle_block_label(dest_name.clone())));
let asm = format!("jge {}", symbol(mangle_name(dest_name.clone())));
self.add_asm_branch2(asm, dest_name);
}
fn emit_jl(&mut self, dest_name: MuName) {
trace!("emit: jl {}", dest_name);
let asm = format!("jl {}", symbol(self.mangle_block_label(dest_name.clone())));
let asm = format!("jl {}", symbol(mangle_name(dest_name.clone())));
self.add_asm_branch2(asm, dest_name);
}
fn emit_jle(&mut self, dest_name: MuName) {
trace!("emit: jle {}", dest_name);
let asm = format!("jle {}", symbol(self.mangle_block_label(dest_name.clone())));
let asm = format!("jle {}", symbol(mangle_name(dest_name.clone())));
self.add_asm_branch2(asm, dest_name);
}
fn emit_js(&mut self, dest_name: MuName) {
trace!("emit: js {}", dest_name);
let asm = format!("js {}", symbol(self.mangle_block_label(dest_name.clone())));
let asm = format!("js {}", symbol(mangle_name(dest_name.clone())));
self.add_asm_branch2(asm, dest_name);
}
#[cfg(target_os = "macos")]
fn emit_call_near_rel32(&mut self, callsite: String, func: MuName, pe: Option<MuName>) -> ValueLocation {
trace!("emit: call {}", func);
let callsite = mangle_name(callsite);
let asm = format!("call {}", symbol(func));
self.add_asm_call(asm, pe);
......@@ -3019,9 +3015,8 @@ impl CodeGenerator for ASMCodeGen {
fn emit_call_near_rel32(&mut self, callsite: String, func: MuName, pe: Option<MuName>) -> ValueLocation {
trace!("emit: call {}", func);
let func = func + "@PLT";
let asm = format!("call {}", symbol(func));
let callsite = mangle_name(callsite);
let asm = format!("call {}@PLT", symbol(func));
self.add_asm_call(asm, pe);
let callsite_symbol = symbol(callsite.clone());
......@@ -3033,7 +3028,7 @@ impl CodeGenerator for ASMCodeGen {
fn emit_call_near_r64(&mut self, callsite: String, func: &P<Value>, pe: Option<MuName>) -> ValueLocation {
trace!("emit: call {}", func);
let callsite = mangle_name(callsite);
let (reg, id, loc) = self.prepare_reg(func, 6);
let asm = format!("call *{}", reg);
......@@ -3378,7 +3373,7 @@ pub fn emit_code(fv: &mut MuFunctionVersion, vm: &VM) {
let mut file_path = path::PathBuf::new();
file_path.push(&vm.vm_options.flag_aot_emit_dir);
file_path.push(func.name().unwrap().to_string() + ".s");
file_path.push(func.name() + ".s");
let mut file = match File::create(file_path.as_path()) {
Err(why) => panic!("couldn't create emission file {}: {}", file_path.to_str().unwrap(), why),
Ok(file) => file
......@@ -3574,9 +3569,16 @@ pub fn emit_context_with_reloc(vm: &VM,
// .globl global_cell_name
// global_cell_name:
let global_cell_name = symbol(global_value.name().unwrap());
file.write_fmt(format_args!("\t{}\n", directive_globl(global_cell_name.clone()))).unwrap();
file.write_fmt(format_args!("{}:\n", global_cell_name)).unwrap();
let demangled_name = global_value.name().clone();
let global_cell_name = symbol(mangle_name(demangled_name.clone()));
writeln!(file, "\t{}", directive_globl(global_cell_name.clone())).unwrap();
writeln!(file, "{}:", global_cell_name.clone()).unwrap();
if is_valid_c_identifier(&demangled_name) {
let demangled_name = symbol(demangled_name);
writeln!(file, "\t{}", directive_globl(demangled_name.clone())).unwrap();
writeln!(file, "\t{}", directive_equiv(demangled_name, global_cell_name.clone())).unwrap();
}
}
// dump_label:
......@@ -3684,6 +3686,9 @@ fn directive_globl(name: String) -> String {
format!(".globl {}", name<