diff mbox series

[PULL,2/2] core/register: Specify instance_size in the TypeInfo

Message ID 20200927134609.2358960-3-alistair.francis@wdc.com
State New
Headers show
Series register queue | expand

Commit Message

Alistair Francis Sept. 27, 2020, 1:46 p.m. UTC
Reported-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <4cf1beb7dafb9143c261d266557d3173bf160524.1598376594.git.alistair.francis@wdc.com>
---
 hw/core/register.c | 31 +++++++++++++------------------
 1 file changed, 13 insertions(+), 18 deletions(-)

Comments

Peter Maydell Sept. 29, 2020, 12:55 p.m. UTC | #1
On Sun, 27 Sep 2020 at 15:00, Alistair Francis <alistair.francis@wdc.com> wrote:
>

> Reported-by: Eduardo Habkost <ehabkost@redhat.com>

> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> Message-Id: <4cf1beb7dafb9143c261d266557d3173bf160524.1598376594.git.alistair.francis@wdc.com>

> ---

> @@ -269,13 +258,18 @@ static RegisterInfoArray *register_init_block(DeviceState *owner,

>          int index = rae[i].addr / data_size;

>          RegisterInfo *r = &ri[index];

>

> -        *r = (RegisterInfo) {

> -            .data = data + data_size * index,

> -            .data_size = data_size,

> -            .access = &rae[i],

> -            .opaque = owner,

> -        };

> -        register_init(r);

> +        if (data + data_size * index == 0 || !&rae[i]) {

> +            continue;


Coverity thinks (CID 1432800) that this is dead code, because
"data + data_size * index" can never be NULL[*]. What was this
intending to test for ? (maybe data == NULL? Missing dereference
operator ?)

[*] The C spec is quite strict about what valid pointer arithmetic
is; in particular adding to a NULL pointer is undefined behaviour,
and pointer arithmetic that overflows and wraps around is
undefined behaviour, so there's no way to get a 0 result from
"ptr + offset" without the expression being UB.

thanks
-- PMM
Eduardo Habkost Sept. 29, 2020, 1:22 p.m. UTC | #2
On Tue, Sep 29, 2020 at 01:55:35PM +0100, Peter Maydell wrote:
> On Sun, 27 Sep 2020 at 15:00, Alistair Francis <alistair.francis@wdc.com> wrote:

> >

> > Reported-by: Eduardo Habkost <ehabkost@redhat.com>

> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

> > Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> > Message-Id: <4cf1beb7dafb9143c261d266557d3173bf160524.1598376594.git.alistair.francis@wdc.com>

> > ---

> > @@ -269,13 +258,18 @@ static RegisterInfoArray *register_init_block(DeviceState *owner,

> >          int index = rae[i].addr / data_size;

> >          RegisterInfo *r = &ri[index];

> >

> > -        *r = (RegisterInfo) {

> > -            .data = data + data_size * index,

> > -            .data_size = data_size,

> > -            .access = &rae[i],

> > -            .opaque = owner,

> > -        };

> > -        register_init(r);

> > +        if (data + data_size * index == 0 || !&rae[i]) {

> > +            continue;

> 

> Coverity thinks (CID 1432800) that this is dead code, because

> "data + data_size * index" can never be NULL[*]. What was this

> intending to test for ? (maybe data == NULL? Missing dereference

> operator ?)


I believe the original check in the old register_init() function
were just to make the function more flexible by allowing NULL
arguments, but it was always unnecessary.  We have 4 callers of
register_init_block*() and neither rae or data are NULL on those
calls.

> 

> [*] The C spec is quite strict about what valid pointer arithmetic

> is; in particular adding to a NULL pointer is undefined behaviour,

> and pointer arithmetic that overflows and wraps around is

> undefined behaviour, so there's no way to get a 0 result from

> "ptr + offset" without the expression being UB.

> 

> thanks

> -- PMM

> 


-- 
Eduardo
Alistair Francis Oct. 1, 2020, 3:37 p.m. UTC | #3
On Tue, Sep 29, 2020 at 6:22 AM Eduardo Habkost <ehabkost@redhat.com> wrote:
>

> On Tue, Sep 29, 2020 at 01:55:35PM +0100, Peter Maydell wrote:

> > On Sun, 27 Sep 2020 at 15:00, Alistair Francis <alistair.francis@wdc.com> wrote:

> > >

> > > Reported-by: Eduardo Habkost <ehabkost@redhat.com>

> > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

> > > Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> > > Message-Id: <4cf1beb7dafb9143c261d266557d3173bf160524.1598376594.git.alistair.francis@wdc.com>

> > > ---

> > > @@ -269,13 +258,18 @@ static RegisterInfoArray *register_init_block(DeviceState *owner,

> > >          int index = rae[i].addr / data_size;

> > >          RegisterInfo *r = &ri[index];

> > >

> > > -        *r = (RegisterInfo) {

> > > -            .data = data + data_size * index,

> > > -            .data_size = data_size,

> > > -            .access = &rae[i],

> > > -            .opaque = owner,

> > > -        };

> > > -        register_init(r);

> > > +        if (data + data_size * index == 0 || !&rae[i]) {

> > > +            continue;

> >

> > Coverity thinks (CID 1432800) that this is dead code, because

> > "data + data_size * index" can never be NULL[*]. What was this

> > intending to test for ? (maybe data == NULL? Missing dereference

> > operator ?)

>

> I believe the original check in the old register_init() function

> were just to make the function more flexible by allowing NULL

> arguments, but it was always unnecessary.  We have 4 callers of

> register_init_block*() and neither rae or data are NULL on those

> calls.


In this case *data is an array, I guess the idea was to try and catch
if somehow a point in the array was NULL?

I'll send a patch to remove the check.

Alistair

>

> >

> > [*] The C spec is quite strict about what valid pointer arithmetic

> > is; in particular adding to a NULL pointer is undefined behaviour,

> > and pointer arithmetic that overflows and wraps around is

> > undefined behaviour, so there's no way to get a 0 result from

> > "ptr + offset" without the expression being UB.

> >

> > thanks

> > -- PMM

> >

>

> --

> Eduardo

>
Eduardo Habkost Oct. 1, 2020, 4:04 p.m. UTC | #4
On Thu, Oct 01, 2020 at 08:37:31AM -0700, Alistair Francis wrote:
> On Tue, Sep 29, 2020 at 6:22 AM Eduardo Habkost <ehabkost@redhat.com> wrote:

> >

> > On Tue, Sep 29, 2020 at 01:55:35PM +0100, Peter Maydell wrote:

> > > On Sun, 27 Sep 2020 at 15:00, Alistair Francis <alistair.francis@wdc.com> wrote:

> > > >

> > > > Reported-by: Eduardo Habkost <ehabkost@redhat.com>

> > > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

> > > > Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> > > > Message-Id: <4cf1beb7dafb9143c261d266557d3173bf160524.1598376594.git.alistair.francis@wdc.com>

> > > > ---

> > > > @@ -269,13 +258,18 @@ static RegisterInfoArray *register_init_block(DeviceState *owner,

> > > >          int index = rae[i].addr / data_size;

> > > >          RegisterInfo *r = &ri[index];

> > > >

> > > > -        *r = (RegisterInfo) {

> > > > -            .data = data + data_size * index,

> > > > -            .data_size = data_size,

> > > > -            .access = &rae[i],

> > > > -            .opaque = owner,

> > > > -        };

> > > > -        register_init(r);

> > > > +        if (data + data_size * index == 0 || !&rae[i]) {

> > > > +            continue;

> > >

> > > Coverity thinks (CID 1432800) that this is dead code, because

> > > "data + data_size * index" can never be NULL[*]. What was this

> > > intending to test for ? (maybe data == NULL? Missing dereference

> > > operator ?)

> >

> > I believe the original check in the old register_init() function

> > were just to make the function more flexible by allowing NULL

> > arguments, but it was always unnecessary.  We have 4 callers of

> > register_init_block*() and neither rae or data are NULL on those

> > calls.

> 

> In this case *data is an array, I guess the idea was to try and catch

> if somehow a point in the array was NULL?


I don't understand what you mean.  The area pointed by data
doesn't contain any pointers, just the register values.

> 

> I'll send a patch to remove the check.


Thanks!

-- 
Eduardo
diff mbox series

Patch

diff --git a/hw/core/register.c b/hw/core/register.c
index ddf91eb445..31038bd7cc 100644
--- a/hw/core/register.c
+++ b/hw/core/register.c
@@ -176,17 +176,6 @@  void register_reset(RegisterInfo *reg)
     }
 }
 
-void register_init(RegisterInfo *reg)
-{
-    assert(reg);
-
-    if (!reg->data || !reg->access) {
-        return;
-    }
-
-    object_initialize((void *)reg, sizeof(*reg), TYPE_REGISTER);
-}
-
 void register_write_memory(void *opaque, hwaddr addr,
                            uint64_t value, unsigned size)
 {
@@ -269,13 +258,18 @@  static RegisterInfoArray *register_init_block(DeviceState *owner,
         int index = rae[i].addr / data_size;
         RegisterInfo *r = &ri[index];
 
-        *r = (RegisterInfo) {
-            .data = data + data_size * index,
-            .data_size = data_size,
-            .access = &rae[i],
-            .opaque = owner,
-        };
-        register_init(r);
+        if (data + data_size * index == 0 || !&rae[i]) {
+            continue;
+        }
+
+        /* Init the register, this will zero it. */
+        object_initialize((void *)r, sizeof(*r), TYPE_REGISTER);
+
+        /* Set the properties of the register */
+        r->data = data + data_size * index;
+        r->data_size = data_size;
+        r->access = &rae[i];
+        r->opaque = owner;
 
         r_array->r[i] = r;
     }
@@ -329,6 +323,7 @@  static const TypeInfo register_info = {
     .name  = TYPE_REGISTER,
     .parent = TYPE_DEVICE,
     .class_init = register_class_init,
+    .instance_size = sizeof(RegisterInfo),
 };
 
 static void register_register_types(void)