Skip to contentSkip to conversation

hppa64 gcc sizeof() bug?

parisc-linux Richard Hirst 2 participants 4 messages Dec 6, 2000

lore
Share & tools
lore
#0 lore raw

Hi Alan,
The following shows the compiler getting confused over the size
of a struct. This is with a gcc/binutils built since the last fix you did for me.

Richard

[rhirst@rhirst play]$ cat tc.c

typedef unsigned int u32;
#define NULL ((void *)0)

struct kernel_sym32 {
        u32 value;
        char name[60];
};

extern int sys_get_kernel_syms(void *);
extern int thing(struct kernel_sym32 *table);

int sys32_get_kernel_syms(struct kernel_sym32 *table)

{
        int len, i;

        len = sizeof (struct kernel_sym32);
        for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
                if (thing(table))
                        break;
        }
        return i;
}

[rhirst@rhirst play]$ hppa64-linux-gcc -S -o tc.s -O2 tc.c [rhirst@rhirst play]$ cat tc.s

        .LEVEL 2.0w

gcc2_compiled.:
.text
.align 8
.globl sys32_get_kernel_syms
.type sys32_get_kernel_syms,@function
sys32_get_kernel_syms:

        .PROC
        .CALLINFO FRAME=128,CALLS,SAVE_RP,ENTRY_GR=6
        .ENTRY
        std %r2,-16(%r30)
        ldo 128(%r30),%r30
        std %r6,-128(%r30)
        ldi 64,%r6		<<< Good, struct is 64 bytes
        std %r5,-120(%r30)
        ldi 0,%r5
        std %r4,-112(%r30)
        copy %r27,%r4
        std %r3,-104(%r30)
        copy %r26,%r3
.L3:
        copy %r3,%r26
        ldo 4096(%r3),%r3	<<< BAD struct is not 4096 bytes!
        cmpb,<= %r6,%r5,.L4
        ldo -16(%r30),%r29
        b,l thing,%r2
        nop
        copy %r4,%r27
        cmpib,= 0,%r28,.L5
        ldo 1(%r5),%r19
.L4:
        copy %r5,%r28
        ldd -144(%r30),%r2
        ldd -120(%r30),%r5
        ldd -112(%r30),%r4
        ldd -104(%r30),%r3
        bve (%r2)
        ldd,mb -128(%r30),%r6
.L5:
        b .L3
        extrd,s %r19,63,32,%r5
        .EXIT
        .PROCEND
.Lfe1:
        .size   sys32_get_kernel_syms,.Lfe1-sys32_get_kernel_syms
        .ident  "GCC: (GNU) 2.96 20000925 (experimental)"

[rhirst@rhirst play]$

#1 lore raw
Quoted 23 lines · Richard Hirst

Hi Alan,
The following shows the compiler getting confused over the size
of a struct. This is with a gcc/binutils built since the last fix you did for me.

Richard

[rhirst@rhirst play]$ cat tc.c

typedef unsigned int u32;
#define NULL ((void *)0)

struct kernel_sym32 {
        u32 value;
        char name[60];
};

extern int sys_get_kernel_syms(void *);
extern int thing(struct kernel_sym32 *table);

int sys32_get_kernel_syms(struct kernel_sym32 *table)

Quoted 10 lines
{
        int len, i;

        len = sizeof (struct kernel_sym32);
        for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
                if (thing(table))
                        break;
        }
        return i;
}

Just changed it to 'table += 64' and it still generates code that adds 4096, so sizeof is not relevant.

Richard

#2 lore raw
Quoted 1 line · Richard Hirst
Quoted 1 line

int sys32_get_kernel_syms(struct kernel_sym32 *table)

...

Quoted 2 lines

Just changed it to 'table += 64' and it still generates code that adds 4096, so sizeof is not relevant.

Right. sizeof() works fine.
table points to something that is 4096/64 (64 bytes) in size. table+=1 results in adding 4096/64 to table.
The code should read "((char *) table) += 64" or "table++".

grant

Grant Grundler
Unix Systems Enablement Lab
+1.408.447.7253

#3 lore raw
In reply to Richard Hirst
Quoted 4 lines · Richard Hirst

Hi Alan,
The following shows the compiler getting confused over the size
of a struct. This is with a gcc/binutils built since the last fix you did for me.

As Alan has kindly pointed out to me, I goofed. In my defence, I did copy the garbage code from the sparc64 port ;)

Richard