From dba65f3128fffa752e057417809a624c0a1825ff Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Tue, 18 Jul 2017 10:16:26 +0100 Subject: [PATCH] Remove all namespace changes made within methods --- src/acpi/aml/namedobj.rs | 32 +++++++++++++++---------------- src/acpi/aml/namespace.rs | 1 + src/acpi/aml/namespacemodifier.rs | 7 +++---- src/acpi/aml/parser.rs | 23 ++++++++++++++++++++-- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index f9a308d..612d744 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -187,7 +187,7 @@ fn parse_def_create_bit_field(data: &[u8], let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - ctx.namespace.insert(local_scope_string, AmlValue::BufferField { + ctx.add_to_namespace(local_scope_string, AmlValue::BufferField { source_buf: Box::new(source_buf.val), index: Box::new(bit_index.val), length: Box::new(AmlValue::IntegerConstant(1)) @@ -217,7 +217,7 @@ fn parse_def_create_byte_field(data: &[u8], let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - ctx.namespace.insert(local_scope_string, AmlValue::BufferField { + ctx.add_to_namespace(local_scope_string, AmlValue::BufferField { source_buf: Box::new(source_buf.val), index: Box::new(bit_index.val), length: Box::new(AmlValue::IntegerConstant(8)) @@ -247,7 +247,7 @@ fn parse_def_create_word_field(data: &[u8], let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - ctx.namespace.insert(local_scope_string, AmlValue::BufferField { + ctx.add_to_namespace(local_scope_string, AmlValue::BufferField { source_buf: Box::new(source_buf.val), index: Box::new(bit_index.val), length: Box::new(AmlValue::IntegerConstant(16)) @@ -277,7 +277,7 @@ fn parse_def_create_dword_field(data: &[u8], let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - ctx.namespace.insert(local_scope_string, AmlValue::BufferField { + ctx.add_to_namespace(local_scope_string, AmlValue::BufferField { source_buf: Box::new(source_buf.val), index: Box::new(bit_index.val), length: Box::new(AmlValue::IntegerConstant(32)) @@ -307,7 +307,7 @@ fn parse_def_create_qword_field(data: &[u8], let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - ctx.namespace.insert(local_scope_string, AmlValue::BufferField { + ctx.add_to_namespace(local_scope_string, AmlValue::BufferField { source_buf: Box::new(source_buf.val), index: Box::new(bit_index.val), length: Box::new(AmlValue::IntegerConstant(64)) @@ -338,7 +338,7 @@ fn parse_def_create_field(data: &[u8], let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - ctx.namespace.insert(local_scope_string, AmlValue::BufferField { + ctx.add_to_namespace(local_scope_string, AmlValue::BufferField { source_buf: Box::new(source_buf.val), index: Box::new(bit_index.val), length: Box::new(num_bits.val) @@ -370,7 +370,7 @@ fn parse_def_data_region(data: &[u8], let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - ctx.namespace.insert(local_scope_string, AmlValue::OperationRegion { + ctx.add_to_namespace(local_scope_string, AmlValue::OperationRegion { region: RegionSpace::SystemMemory, offset: Box::new(AmlValue::IntegerConstant(0)), len: Box::new(AmlValue::IntegerConstant(0)) @@ -397,7 +397,7 @@ fn parse_def_event(data: &[u8], let name = parse_name_string(&data[2..], ctx)?; let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - ctx.namespace.insert(local_scope_string, AmlValue::Event); + ctx.add_to_namespace(local_scope_string, AmlValue::Event); Ok(AmlParseType { val: AmlValue::None, @@ -426,7 +426,7 @@ fn parse_def_device(data: &[u8], let obj_list = parse_object_list(&data[2 + pkg_length_len + name.len .. 2 + pkg_length], &mut local_ctx)?; let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - ctx.namespace.insert(local_scope_string, AmlValue::Device(local_ctx.namespace.clone())); + ctx.add_to_namespace(local_scope_string, AmlValue::Device(local_ctx.namespace.clone())); Ok(AmlParseType { val: AmlValue::None, @@ -466,7 +466,7 @@ fn parse_def_op_region(data: &[u8], let len = parse_term_arg(&data[3 + name.len + offset.len..], ctx)?; let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - ctx.namespace.insert(local_scope_string, AmlValue::OperationRegion { + ctx.add_to_namespace(local_scope_string, AmlValue::OperationRegion { region: region, offset: Box::new(offset.val), len: Box::new(len.val) @@ -626,7 +626,7 @@ fn parse_field_element(data: &[u8], let length = if let Ok(field) = parse_named_field(data, ctx) { let local_scope_string = get_namespace_string(ctx.scope.clone(), AmlValue::String(field.val.name.clone())); - ctx.namespace.insert(local_scope_string, AmlValue::FieldUnit { + ctx.add_to_namespace(local_scope_string, AmlValue::FieldUnit { selector: selector.clone(), connection: Box::new(connection.clone()), flags: flags.clone(), @@ -781,7 +781,7 @@ fn parse_def_method(data: &[u8], let term_list = &data[2 + pkg_len_len + name.len .. 1 + pkg_len]; let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - ctx.namespace.insert(local_scope_string, AmlValue::Method(Method { + ctx.add_to_namespace(local_scope_string, AmlValue::Method(Method { arg_count, serialized, sync_level, @@ -811,7 +811,7 @@ fn parse_def_mutex(data: &[u8], let sync_level = flags & 0x0F; let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - ctx.namespace.insert(local_scope_string, AmlValue::Mutex(sync_level)); + ctx.add_to_namespace(local_scope_string, AmlValue::Mutex(sync_level)); Ok(AmlParseType { val: AmlValue::None, @@ -845,7 +845,7 @@ fn parse_def_power_res(data: &[u8], let mut local_ctx = AmlExecutionContext::new(String::new()); parse_object_list(&data[5 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?; - ctx.namespace.insert(local_scope_string, AmlValue::PowerResource { + ctx.add_to_namespace(local_scope_string, AmlValue::PowerResource { system_level, resource_order, obj_list: local_ctx.namespace.clone() @@ -884,7 +884,7 @@ fn parse_def_processor(data: &[u8], let mut local_ctx = AmlExecutionContext::new(String::new()); parse_object_list(&data[8 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?; - ctx.namespace.insert(local_scope_string, AmlValue::Processor { + ctx.add_to_namespace(local_scope_string, AmlValue::Processor { proc_id: proc_id, p_blk: if p_blk_len > 0 { Some(p_blk_addr) } else { None }, obj_list: local_ctx.namespace.clone() @@ -916,7 +916,7 @@ fn parse_def_thermal_zone(data: &[u8], let mut local_ctx = AmlExecutionContext::new(String::new()); parse_object_list(&data[2 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?; - ctx.namespace.insert(local_scope_string, AmlValue::ThermalZone(local_ctx.namespace.clone())); + ctx.add_to_namespace(local_scope_string, AmlValue::ThermalZone(local_ctx.namespace.clone())); Ok(AmlParseType { val: AmlValue::None, diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index 01ffdaf..6b8c598 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -130,6 +130,7 @@ impl Method { ctx.init_arg_vars(parameters); parse_term_list(&self.term_list[..], &mut ctx); + ctx.clean_namespace(); match ctx.state { ExecutionState::RETURN(v) => v, diff --git a/src/acpi/aml/namespacemodifier.rs b/src/acpi/aml/namespacemodifier.rs index 1c72e0a..7d08195 100644 --- a/src/acpi/aml/namespacemodifier.rs +++ b/src/acpi/aml/namespacemodifier.rs @@ -49,9 +49,8 @@ fn parse_alias_op(data: &[u8], let local_scope_string = get_namespace_string(ctx.scope.clone(), source_name.val); let local_alias_string = get_namespace_string(ctx.scope.clone(), alias_name.val); - ctx.namespace.insert(local_scope_string, AmlValue::ObjectReference( - ObjectReference::NamedObj(local_alias_string))); - + ctx.add_to_namespace(local_scope_string, AmlValue::ObjectReference(ObjectReference::NamedObj(local_alias_string)))?; + Ok(AmlParseType { val: AmlValue::None, len: 1 + source_name.len + alias_name.len @@ -75,7 +74,7 @@ fn parse_name_op(data: &[u8], let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - ctx.namespace.insert(local_scope_string, data_ref_obj.val); + ctx.add_to_namespace(local_scope_string, data_ref_obj.val)?; Ok(AmlParseType { val: AmlValue::None, diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs index 269bd6a..6c2468f 100644 --- a/src/acpi/aml/parser.rs +++ b/src/acpi/aml/parser.rs @@ -25,7 +25,8 @@ pub struct AmlExecutionContext { pub scope: String, pub local_vars: [AmlValue; 8], pub arg_vars: [AmlValue; 8], - pub state: ExecutionState + pub state: ExecutionState, + pub namespace_delta: Vec } impl AmlExecutionContext { @@ -49,7 +50,25 @@ impl AmlExecutionContext { AmlValue::Uninitialized, AmlValue::Uninitialized, AmlValue::Uninitialized], - state: ExecutionState::EXECUTING + state: ExecutionState::EXECUTING, + namespace_delta: vec!() + } + } + + pub fn add_to_namespace(&mut self, name: String, value: AmlValue) -> Result<(), AmlError> { + if self.namespace.contains_key(&name) { + return Err(AmlError::AmlValueError); + } + + self.namespace_delta.push(name.clone()); + self.namespace.insert(name, value); + + Ok(()) + } + + pub fn clean_namespace(&mut self) { + for k in &self.namespace_delta { + self.namespace.remove(k); } }