bug-glibc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: stat-calls fail with certain gcc-switches


From: Wolfram Gloger
Subject: Re: stat-calls fail with certain gcc-switches
Date: Mon, 30 Dec 2002 10:56:34 +0100 ("MET)

Hi,

> >   Please add a note in your docs that is not possible to compile
> >    the GNU-libc (i tried it with 2.3.1) with the options
> >    "-malign-double" and/or "-m128bit-long-double".

Ok, could you first explain _why_ you would want to do such a thing?
Isn't it widely known that these switches change the ABI?

Anyway, I got interested in this:

>    ---------------------------- file: io/fts.c
> 
>    /* Largest alignment size needed, minus one.
>      Usually long double is the worst case.  */
>    #ifndef ALIGNBYTES
>    #define ALIGNBYTES (__alignof__ (long double) - 1)
>    #endif
>    /* Align P to that size.  */
>    #ifndef ALIGN
>    #define    ALIGN(p)        (((unsigned long int) (p) + ALIGNBYTES) & 
> ~ALIGNBYTES)
>    #endif
> 
>    ...
> 
>    static FTSENT *
>    internal_function
>    fts_alloc(sp, name, namelen)
>       FTS *sp;
>       const char *name;
>       register int namelen;
>    {
>       register FTSENT *p;
>       size_t len;
> 
>       len = sizeof(FTSENT) + namelen;
>       if (!ISSET(FTS_NOSTAT))
>               len += sizeof(struct stat) + ALIGNBYTES;
>       if ((p = malloc(len)) == NULL)
>               return (NULL);
> 
>       memmove(p->fts_name, name, namelen);
>       p->fts_name[namelen] = '\0';
> 
>       if (!ISSET(FTS_NOSTAT))
>               p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2);
> 
>     ----------------------------
> 
>  I dont understand what long doubles have to do with stat-calls,
>  but when you increase the alignment of them to 16 instead of 4, which is
>  one consequence of the gcc-switches 
>    "-malign-double" and/or "-m128bit-long-double"
>  every stat-call will fail with errno set to EOVERFLOW.

So you are saying that the malloc(len) call fails here?

I can't reproduce this; please try the appended example.
I get:

/home/wmglo/src/test% gcc-3.2 -Wall -m128bit-long-double align.c
/home/wmglo/src/test% ./a.out 
len=179
0x80495d0 errno=0
/home/wmglo/src/test% gcc-3.2 -Wall  align.c
/home/wmglo/src/test% ./a.out 
len=167
0x80495d0 errno=0

Regards,
Wolfram.

================================ align.c ========================
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>

/* Largest alignment size needed, minus one.
   Usually long double is the worst case.  */
#ifndef ALIGNBYTES
#define ALIGNBYTES      (__alignof__ (long double) - 1)
#endif
/* Align P to that size.  */
#ifndef ALIGN
#define ALIGN(p)        (((unsigned long int) (p) + ALIGNBYTES) & ~ALIGNBYTES)
#endif

typedef struct _ftsent {
        struct _ftsent *fts_cycle;      /* cycle node */
        struct _ftsent *fts_parent;     /* parent directory */
        struct _ftsent *fts_link;       /* next file in directory */
        long fts_number;                /* local numeric value */
        void *fts_pointer;              /* local address value */
        char *fts_accpath;              /* access path */
        char *fts_path;                 /* root path */
        int fts_errno;                  /* errno for this node */
        int fts_symfd;                  /* fd for symlink */
        u_short fts_pathlen;            /* strlen(fts_path) */
        u_short fts_namelen;            /* strlen(fts_name) */
        ino_t fts_ino;                  /* inode */
        dev_t fts_dev;                  /* device */
        nlink_t fts_nlink;              /* link count */
        short fts_level;                /* depth (-1 to N) */
        u_short fts_info;               /* user flags for FTSENT structure */
        u_short fts_flags;              /* private flags for FTSENT structure */
        u_short fts_instr;              /* fts_set() instructions */
        struct stat *fts_statp;         /* stat(2) information */
        char fts_name[1];               /* file name */
} FTSENT;

static void *
__attribute__ ((regparm (3), stdcall))
fts_alloc(sp, name, namelen)
void *sp;
const char *name;
register int namelen;
{
    register FTSENT *p;
    size_t len;

    len = sizeof(FTSENT) + namelen;
    len += sizeof(struct stat) + ALIGNBYTES;
    printf("len=%ld\n", (long)len);
    if ((p = malloc(len)) == NULL)
        return (NULL);
    return p;
}

int main()
{
    void * p;

    p = fts_alloc(0, "test", 4);
    printf("%p errno=%d\n", p, errno);
    return 0;
}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]