Re: GCC 4.7.2 error handling type short

2012-11-26 Thread Paul_Koning

On Nov 26, 2012, at 3:57 PM, Bill Beech (NJ7P) wrote:

> I have run into a problem with both 4.6.1 and 4.7.2 of the gcc compiler 
> handling type short.  Sizeof(unsigned short) returns a length of 2 as 
> expected, but when I use a union of a character buffer and some fields 
> including a unsigned short the value returned is 2 bytes but the buffer 
> pointer is moved 4 bytes.
> ...
> As you can see the value at 0410 in the file, 6601 is returned as 358, which 
> is correct.  The 4-byte
> value following 67 01 00 00 is not returned for the unsigned int but rather 
> 00 00 30 00 is returned next (which equals 3145728 decimal).  While a 
> sizeof(unsigned short) returns 2 bytes, in this case the pointer into the 
> unioned buffer is moved 4 bytes.
> 
> This bug makes it hell to you any of your products to build emulators for the 
> 16-bit processors.
> 
> Is there a definition for a 16-bit quantity that will work in a union?
> 
> Thanks!
> 
> Bill Beech
> NJ7P

You meant struct, right, not union?

Every field has a size as well as an alignment.  The starting address of each 
field is forced to be a multiple of its alignment.  In many cases, for 
primitive data types (like the various size integers) the alignment equals the 
size; for example, a 4-byte int has alignment 4.

So if you have a struct of short then int, the compiler has to insert 2 bytes 
of padding before the int to obey the alignment.

In some cases, there are types that don't have alignment == sizeof, for example 
long long int on Intel is size 8 but (by default) alignment 4.

Since you mentioned 16-bit processors -- are you talking about a port for a 
16-bit processor, where you want int (size 4) to be aligned 2?  (For example, 
that would be sensible on a PDP-11.)  If so, you'd want to tell the compiler 
how to do that; I'm not sure of the details, presumably they are in the GCC 
Internals manual.

Or are you talking about an existing port which has defined the alignment of 
int to be 4?  If so, that might be because unaligned accesses would cause 
exceptions.  Or it may just be a convention.  In either case, you can use the 
"packed" attribute to override the normal alignment of fields.  See the GCC 
documentation for details.

paul



GCC 4.7.2 error handling type short

2012-11-26 Thread Bill Beech (NJ7P)
I have run into a problem with both 4.6.1 and 4.7.2 of the gcc compiler 
handling type short.  Sizeof(unsigned short) returns a length of 2 as 
expected, but when I use a union of a character buffer and some fields 
including a unsigned short the value returned is 2 bytes but the buffer 
pointer is moved 4 bytes.


Here is the code for the union of the fs structure with the buffer (the 
super block structure and union are at the bottom of the listing):


/* taken from filsys.h for Intel Xenix */
#defineu_shortunsigned short
#definedaddr_tunsigned int
#defineino_tunsigned short
#definetime_tunsigned int

#define FS_CLEAN106
#defineBMAPSIZE994/* Max size of CG bit map */
/* Equals BSIZE-sizeof(struct cylinder)*/

#define MAXCGS80/* Max CG's per filsys */
#defineMAXEXTSIZE32/* Max extent size */
#define FNEWCG64/* When a file grows beyond FNEWCG KB,
   allocate blocks from a new
   cylinder group */
#define SNEWCG512/* Move to a new cylinder group after
   every subsequent SNEWCG KB */

/*
 * Cylinder group header
 */
struct cylinder {
daddr_tcg_doffset;/* offset to first data block 
from start of filsys */
daddr_tcg_ioffset;/* offset to first inode 
block from start of filsys */

u_shortcg_dblocks;/* number of data blocks in cg */
ino_tcg_ifirst;/* next free inode in linked list */
charcg_number;/* cg sequence number in filsys */
charcg_currextent;/* current extent size */
u_shortcg_lowat;/* if free blocks drop below 
cg_lowat, recompute cg_currextent */
u_shortcg_hiwat;/* if free blocks increase 
beyond cg_hiwat, recompute cg_currextent */
u_shortcg_erotor;/* position of next candidate 
block for allocation */

charcg_ilock;/* inode manipulation lock */
charcg_reserved[9];/* reserved field. (9 to align 
on word boundary) */
charcg_bits[BMAPSIZE];/* bit map. 0 = allocated. 1 = 
free */

};

/*
 * Contains global policy information.
 * Stored in the superblock.
 */
structcginfo {
u_shortfs_cgincore;/* points to buf structure 
containing cg header. Null if not in core */

daddr_tfs_cgblk;/* disk address of cg header */
u_shortfs_cgffree;/* number of free data blocks 
in cg */

ino_tfs_cgifree;/* number of free inodes in cg */
ino_tfs_cgdirs;/* number of directories in cg */
};

/*
 * Super block
 */
struct filsys {
charfs_fname[6];/* file system name */
charfs_fpack[6];/* pack name */
daddr_tfs_fsize;/* number of data blocks in fs */
u_shortfs_cgblocks;/* number of blocks per cg */
daddr_tfs_maxblock;/* max disk block in fs */
ino_tfs_cginodes;/* number of inodes per cg */
ino_tfs_maxino;/* max inumber in fs */
time_tfs_time;/* time last modified */
charfs_fmod;/* modified flag */
charfs_ronly;/* read-only fs */
charfs_clean;/* fs was cleanly unmounted */
charfs_type;/* fs type and version */
u_shortfs_fnewcg;/* contains FNEWCG */
u_shortfs_snewcg;/* contains SNEWCG */
daddr_tfs_ffree;/* number of free data blocks 
in fs */

ino_tfs_ifree;/* number of free inodes in fs */
ino_tfs_dirs;/* number of directories in fs */
charfs_extentsize;/* native extent size */
charfs_cgnum;/* number of cg's in fs */
charfs_cgrotor;/* next cg to be searched */
charfs_reserved[15];/* reserved. (15 to align on word 
boundary) */
structcginfo fs_cylinder[MAXCGS];/* contains global policy 
information

per cylinder group */
};

I use this routine to to dump the info from the superblock:

void dumpsuper(void)
{
if (*super.fs.fs_fname)
printf("fs_fname = %s\n", super.fs.fs_fname);
if (*super.fs.fs_fname)
printf("fs_fpack = %s\n", super.fs.fs_fpack);
printf("fs_fsize = %d\n", super.fs.fs_fsize);
printf("fs_cgblocks = %d\n", super.fs.fs_cgblocks);
printf("fs_maxblock = %d\n", super.fs.fs_maxblock);
printf("fs_cginodes = %d\n", super.fs.fs_cginodes);
printf("fs_maxino = %d\n", super.fs.fs_maxino);
printf("len = %d\n", sizeof(unsigned short));
dumphex(1024, 256);
}

When run, I get this result:

MAKI