Discussion:
Any better way to access CPUArchState in vl.c?
陳韋任 (Wei-Ren Chen)
2012-06-18 07:47:56 UTC
Permalink
Hi all,

Say I want to print env->some_field in vl.c. I #include "dyngen-exec.h"
in vl.c, but got compilation error immediately.

/tmp/chenwj/qemu/dyngen-exec.h:64:10: error: attempt to use poisoned "CPUArchState"
/tmp/chenwj/qemu/dyngen-exec.h:64:23: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
/tmp/chenwj/qemu/dyngen-exec.h:64:24: error: attempt to use poisoned "env"

After googling, I figure out QEMU poison some identifiers which cannot be used
in target indenpent code. Although we can get some_field by the following way,

int some_field = &env->some_field;

but it's not very convenient if we have many field of CPUState want to access. Is
there a better way to do so? Thanks!

Regards,
chenwj

[1]
http://stackoverflow.com/questions/9461625/gcc-error-message-attempt-to-use-poisoned-target-i386
--
Wei-Ren Chen (陳韋任)
Computer Systems Lab, Institute of Information Science,
Academia Sinica, Taiwan (R.O.C.)
Tel:886-2-2788-3799 #1667
Homepage: http://people.cs.nctu.edu.tw/~chenwj
Andreas Färber
2012-06-18 10:01:19 UTC
Permalink
Hi Wei-Ren,
Post by 陳韋任 (Wei-Ren Chen)
Say I want to print env->some_field in vl.c. I #include "dyngen-exec.h"
in vl.c, but got compilation error immediately.
/tmp/chenwj/qemu/dyngen-exec.h:64:10: error: attempt to use poisoned "CPUArchState"
/tmp/chenwj/qemu/dyngen-exec.h:64:23: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
/tmp/chenwj/qemu/dyngen-exec.h:64:24: error: attempt to use poisoned "env"
After googling, I figure out QEMU poison some identifiers which cannot be used
in target indenpent code. Although we can get some_field by the following way,
int some_field = &env->some_field;
but it's not very convenient if we have many field of CPUState want to access. Is
there a better way to do so? Thanks!
Poisoned is the "env" variable. You cannot just #include "dyngen-exec.h"
and expect it to be usable since AREG0 targets don't guarantee it's set
properly (may be NULL even with traditional targets at times).

CPUArchState should currently be usable in vl.c, you just need explicit
access to it (e.g., a function argument).
Question is, what are you trying to do? In particular, of which CPU
(think SMP) are you trying to print ->some_field? :)

Regards,
Andreas
--
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
陳韋任 (Wei-Ren Chen)
2012-06-19 09:02:30 UTC
Permalink
Hi Andreas,
Post by Andreas Färber
Poisoned is the "env" variable. You cannot just #include "dyngen-exec.h"
and expect it to be usable since AREG0 targets don't guarantee it's set
properly (may be NULL even with traditional targets at times).
Oops, I miss that point.
Post by Andreas Färber
CPUArchState should currently be usable in vl.c, you just need explicit
access to it (e.g., a function argument).
Question is, what are you trying to do? In particular, of which CPU
(think SMP) are you trying to print ->some_field? :)
Currently we only consider single CPU ARM guest, so there should be only one
env we need to take care of. We add some fields into CPUState and want to print
their value when the VM is terminated. For example,

---
static void main_loop(void)
{
do {
nonblocking = !kvm_enabled() && last_io > 0;
last_io = main_loop_wait(nonblocking);
} while (!main_loop_should_exit());

// print env->some_field1
// print env->some_field2
}
---

If we can access env in vl.c directly, it would make the task easier.

Regards,
chenwj
--
Wei-Ren Chen (陳韋任)
Computer Systems Lab, Institute of Information Science,
Academia Sinica, Taiwan (R.O.C.)
Tel:886-2-2788-3799 #1667
Homepage: http://people.cs.nctu.edu.tw/~chenwj
Andreas Färber
2012-06-19 09:54:46 UTC
Permalink
Hi,
Post by 陳韋任 (Wei-Ren Chen)
Post by Andreas Färber
Question is, what are you trying to do? In particular, of which CPU
(think SMP) are you trying to print ->some_field? :)
Currently we only consider single CPU ARM guest, so there should be only one
env we need to take care of. We add some fields into CPUState and want to print
their value when the VM is terminated. For example,
---
static void main_loop(void)
{
do {
nonblocking = !kvm_enabled() && last_io > 0;
last_io = main_loop_wait(nonblocking);
} while (!main_loop_should_exit());
// print env->some_field1
// print env->some_field2
}
---
If we can access env in vl.c directly, it would make the task easier.
If you only have one CPU then using first_cpu->some_field1 should be
almost as easy. :)

Regards,
Andreas
--
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
陳韋任 (Wei-Ren Chen)
2012-06-19 11:54:03 UTC
Permalink
Post by Andreas Färber
If you only have one CPU then using first_cpu->some_field1 should be
almost as easy. :)
I am afraid first_cpu (CPUArchState) is got poisoned, too. :/
Even I comment out CPUArchState from poison.h,

--- vl.c
extern CPUArchState *first_cpu;

static void main_loop(void)
{
... snip ...

printf("%d", first_cpu->created);
}
---

I still get compilation error below,

---
/tmp/chenwj/qemu/vl.c:1548:20: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
/tmp/chenwj/qemu/vl.c: In function 'main_loop':
/tmp/chenwj/qemu/vl.c:1568:18: error: 'first_cpu' undeclared (first use in this function)
---

Any thought on what I am missing? Thanks.

Regards,
chenwj
--
Wei-Ren Chen (陳韋任)
Computer Systems Lab, Institute of Information Science,
Academia Sinica, Taiwan (R.O.C.)
Tel:886-2-2788-3799 #1667
Homepage: http://people.cs.nctu.edu.tw/~chenwj
Peter Maydell
2012-06-19 12:08:47 UTC
Permalink
Post by Andreas Färber
If you only have one CPU then using first_cpu->some_field1 should be
almost as easy. :)
 I am afraid first_cpu (CPUArchState) is got poisoned, too. :/
Yes. You'll need to write a function which lives in a source file which
has access to the poisoned symbols, and then call that from vl.c.
hw_error() might be a useful example to follow.

-- PMM
陳韋任 (Wei-Ren Chen)
2012-06-20 08:03:01 UTC
Permalink
Post by Peter Maydell
Post by Andreas Färber
If you only have one CPU then using first_cpu->some_field1 should be
almost as easy. :)
 I am afraid first_cpu (CPUArchState) is got poisoned, too. :/
Yes. You'll need to write a function which lives in a source file which
has access to the poisoned symbols, and then call that from vl.c.
hw_error() might be a useful example to follow.
I take your approach, thanks. :)

Regards,
chenwj
--
Wei-Ren Chen (陳韋任)
Computer Systems Lab, Institute of Information Science,
Academia Sinica, Taiwan (R.O.C.)
Tel:886-2-2788-3799 #1667
Homepage: http://people.cs.nctu.edu.tw/~chenwj
Peter Crosthwaite
2012-06-19 12:09:24 UTC
Permalink
Andreas, will an attribute((destructor)) work ? Cos if it does you can put
your printf pretty much anwhere rather than vl.c
Post by 陳韋任 (Wei-Ren Chen)
Post by Andreas Färber
If you only have one CPU then using first_cpu->some_field1 should be
almost as easy. :)
I am afraid first_cpu (CPUArchState) is got poisoned, too. :/
Even I comment out CPUArchState from poison.h,
--- vl.c
extern CPUArchState *first_cpu;
static void main_loop(void)
{
... snip ...
printf("%d", first_cpu->created);
}
---
I still get compilation error below,
---
/tmp/chenwj/qemu/vl.c:1548:20: error: expected '=', ',', ';', 'asm' or
'__attribute__' before '*' token
/tmp/chenwj/qemu/vl.c:1568:18: error: 'first_cpu' undeclared (first use in this function)
---
Any thought on what I am missing? Thanks.
Regards,
chenwj
--
Wei-Ren Chen (陳韋任)
Computer Systems Lab, Institute of Information Science,
Academia Sinica, Taiwan (R.O.C.)
Tel:886-2-2788-3799 #1667
Homepage: http://people.cs.nctu.edu.tw/~chenwj
Andreas Färber
2012-06-19 13:21:46 UTC
Permalink
Post by Peter Crosthwaite
Andreas, will an attribute((destructor)) work ? Cos if it does you can
put your printf pretty much anwhere rather than vl.c
Yes, it might. main() only seems to call cpus.c:pause_all_vcpus(), so
neither first_cpu nor the CPU(Arch)State would get cleaned up. But then
again all my comments are based on qemu.git master whereas Wei-Ren is
working on 0.14.x IIRC.

Andreas
--
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Andreas Färber
2012-06-19 12:12:41 UTC
Permalink
Post by 陳韋任 (Wei-Ren Chen)
Post by Andreas Färber
If you only have one CPU then using first_cpu->some_field1 should be
almost as easy. :)
I am afraid first_cpu (CPUArchState) is got poisoned, too. :/
Even I comment out CPUArchState from poison.h,
--- vl.c
extern CPUArchState *first_cpu;
static void main_loop(void)
{
... snip ...
printf("%d", first_cpu->created);
}
---
I still get compilation error below,
---
/tmp/chenwj/qemu/vl.c:1548:20: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
/tmp/chenwj/qemu/vl.c:1568:18: error: 'first_cpu' undeclared (first use in this function)
---
Any thought on what I am missing? Thanks.
Sorry, my mistake: vl.c is not compiled per-target like I thought but
per target_phys_addr_t in libhwX, thus it cannot access cpu.h or
CPUArchState (only CPUState). That means evaluations of fields in
CPUARMState need to be done in target-arm/ and you might want to check
the Notifiers or in the worst case _atexit() to hook some callback
function up. With QOM CPUState there's finalizers in theory but I don't
think they get called yet for anything except linux-user thread exit.

Andreas
--
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Loading...