From 2925db1f486e3d84abb9a1c9fe59f335abbe7ce5 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 20 Feb 2017 13:16:04 +0000 Subject: eval_with_fields(): Evaluate string in context of calling package Commit 6a3647ae8918 moved eval_with_fields() into risugen_common.pm, which broke !constraint and !memory blocks which call functions defined in the cpu-specific backend packages, because the eval string is now being evaluated inside the risugen_common package rather than the risugen_$ARCH package. Fix this by adding a "package" statement to the code we evaluate so it is evaluated in the context of the module which calls eval_with_fields(). The ideal solution to this problem would be to tighten up the way we evaluate strings from risu files, so that they're run in their own package which only has imported into it the specific functions that we want to give them access to. Sadly that is more work than can really be justified at this point, so we settle for describing the preferred approach in a comment. Signed-off-by: Peter Maydell --- risugen_common.pm | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/risugen_common.pm b/risugen_common.pm index 1da07d4..5db2e32 100644 --- a/risugen_common.pm +++ b/risugen_common.pm @@ -102,8 +102,19 @@ sub eval_with_fields($$$$$) { # set corresponding to the variable fields for the insn. # Return the result of the eval; we die with a useful error # message in case of syntax error. + # + # At the moment we just evaluate the string in the environment + # of the calling package. + # What we *ought* to do here is to give the config snippets + # their own package, and explicitly import into it only the + # functions that we want to be accessible to the config. + # That would provide better separation and an explicitly set up + # environment that doesn't allow config file code to accidentally + # change state it shouldn't have access to, and avoid the need to + # use 'caller' to get the package name of our calling function. my ($insnname, $insn, $rec, $blockname, $block) = @_; - my $evalstr = "{ "; + my $calling_package = caller; + my $evalstr = "{ package $calling_package; "; for my $tuple (@{ $rec->{fields} }) { my ($var, $pos, $mask) = @$tuple; my $val = ($insn >> $pos) & $mask; -- cgit v1.2.3