[Top][All Lists]
[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;
}