Professional Web Applications Themes

Programinng issue Linux x86/Solaris 64bit - Sun Solaris

Hi, I wrote a C-Programm to read out header data of a binary image file header. I'm getting header information with fread(&image_descriptor_table,sizeof(IDT),1,fz); where image_descriptor_table is a struct containing different data types like uint_t16, uint_32 and char. Now my programm runs fine on linux x86 32bit, but on Solaris 8 sparc 64 bit the values are 256 times as big as on my linux box. I'm using gcc3.3. I tried the m64 flag, but this did not work at all. I checked limits.h but found no difference in data type sizes, so where is my problem? Many thanks in advance, Christopher ...

  1. #1

    Default Programinng issue Linux x86/Solaris 64bit

    Hi,
    I wrote a C-Programm to read out header data of a binary image file header.
    I'm getting header information with
    fread(&image_descriptor_table,sizeof(IDT),1,fz);
    where image_descriptor_table is a struct containing different data types
    like uint_t16, uint_32 and char.
    Now my programm runs fine on linux x86 32bit, but on Solaris 8 sparc 64 bit
    the values are 256 times as big as on my linux box.
    I'm using gcc3.3.
    I tried the m64 flag, but this did not work at all.
    I checked limits.h but found no difference in data type sizes, so where
    is my problem?
    Many thanks in advance,
    Christopher

    --
    Christopher Intemann
    mail:net .~.
    phone/fax:0700/I-N-T-E-M-A-N-N /v\
    Iridium:+881631417758 // \\
    /( _ )\
    PGP-Public-Key: ^^ ^^
    http://www.math.uni-goettingen.de/intemann/pgp

    Christopher Guest

  2. #2

    Default Programinng issue Linux x86/Solaris 64bit

    Hi,
    I wrote a C-Programm to read out header data of a binary image file header.
    I'm getting header information with
    fread(&image_descriptor_table,sizeof(IDT),1,fz);
    where image_descriptor_table is a struct containing different data types
    like uint16_t, uint32_t and char.
    Now my programm runs fine on linux x86 32bit, but on Solaris 8 sparc 64 bit
    the values are 256 times as big as on my linux box.
    I'm using gcc3.3.
    I tried the m64 flag, but this did not work at all.
    I checked limits.h but found no difference in data type sizes, so where
    is my problem?
    Many thanks in advance,
    Christopher

    --
    Christopher Intemann
    mail:net .~.
    phone/fax:0700/I-N-T-E-M-A-N-N /v\
    Iridium:+881631417758 // \\
    /( _ )\
    PGP-Public-Key: ^^ ^^
    http://www.math.uni-goettingen.de/intemann/pgp

    Christopher Guest

  3. #3

    Default Re: Programinng issue Linux x86/Solaris 64bit

    In article <bln84q$1prm$gwdg.de>,
    Christopher Intemann <net> writes: 

    Endianism.

    x86 is little-endian, whereas sparc is big-endian.
    You will find that integer data types larger than a
    byte have the bytes stored in the opposite order.
    Transfering structures between different platforms
    is liable to get you into a number of difficulties,
    this being just one of them.

    --
    Andrew Gabriel
    Consultant Software Engineer
    Andrew Guest

  4. #4

    Default Re: Programinng issue Linux x86/Solaris 64bit


    "Andrew Gabriel" <demon.co.uk> wrote in message
    news:blna60$emv$uk.sun.com...
     

    And the proper fix is: If the header is specified at the byte level,
    decode it at the byte level. File format specifications shouldn't say things
    like 'uint_32' (because there's any number of ways to store an unsigned
    integer in 32 bits), they should say 'four bytes representing an integer in
    network byte order'.

    DS


    David Guest

  5. #5

    Default Re: Programinng issue Linux x86/Solaris 64bit

    Christopher Intemann <net> writes: 

    Note that even for binary files, you can easily write the header in
    ASCII form (just reserve a block or two for it, and fill pad it with
    '\n'). Then you can easily read the header with:

    head my-bin-file


    $ head lux-VOIE-Route.mapfile
    MapFileDS
    Version: 5
    ElementCount: 44291 (indicative)
    GlobalRect: {{845120,2501052},{56747,81480}}
    EOH






    --
    __Pascal_Bourguignon__
    http://www.informatimago.com/
    Do not adjust your mind, there is a fault in reality.
    Pascal Guest

  6. #6

    Default Re: Programinng issue Linux x86/Solaris 64bit

    Hi,
    In comp.unix.solaris David Schwartz <com> wrote:
     
     [/ref]
     

    Ok, I think I got the problem.
    For big endian systems I'd have to swap the bytes somehow.
    I think I'm not the first stuck in this issue, so maybe there is a good source
    somewhere explaining how to deal with it?
    My File Format specification came with an predifned include file where these
    structs are defined.
    How can I convert uint_32 little endian in uint_32 big endian?
    Thanx again,
    Christopher

    Thx,
    Christopher


    --
    Christopher Intemann
    mail:net .~.
    phone/fax:0700/I-N-T-E-M-A-N-N /v\
    Iridium:+881631417758 // \\
    /( _ )\
    PGP-Public-Key: ^^ ^^
    http://www.math.uni-goettingen.de/intemann/pgp

    Christopher Guest

  7. #7

    Default Re: Programinng issue Linux x86/Solaris 64bit

    On Sun, 5 Oct 2003 14:04:41 +0000 (UTC)
    Christopher Intemann <net> wrote:
     
    There are functions, htons (host byte order to net byte order - short),
    ntohs (same in reverse), htonl (this is 32 bits and is a misnomer on 64
    bit systems), and ntohs.
    #include <netinet/in.h>

    These are generally no-ops in big endian systems.

    The networking people decided to use net byte order (eg. big endian) as
    their standard for data transfer. I implemented these in assembler on an
    Alpha a few years ago while converting Purify to Tru64 Unix.
    If you look at the Alpha Assembly Language programming guide, you will
    find a good definition along with pictures:
    http://h30097.www3.hp.com/docs/base_doc/DOENTATION/HTML/AA-PS31D-TET1_html/asm2.html#ordering_section

    if you need to convert from little endian to big endian on Solaris, you
    can use this guide to the byte ordering.
    --
    Jerry Feldman <gaf-nospam-at-blu.org>
    Boston Linux and Unix user group
    http://www.blu.org PGP key id:C5061EA9
    PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
    Jerry Guest

  8. #8

    Default Re: Programinng issue Linux x86/Solaris 64bit


    "Christopher Intemann" <net> wrote in message
    news:blp8dp$1dvl$gwdg.de...
     
    source 
    these 

    To convert a 4 byte integer between little and big endian there are several
    ways. If the bytes are ordered A B C D, then to convert you need to change
    the bytes to the order D C B A. There are several ways to do this.

    uint32 convertInt(uint_32 oldValue)
    {
    union convert {
    uint_32 uint32;
    unsigned char uchar;
    } bytes4;
    uint_32 newValue;

    bytes4.uint32 = oldValue;
    newValue = bytes4.char[3] << 24 + bytes4.char[2] << 16 + bytes4.char[1]
    << 8 + bytes.char[0];
    return newValue;
    }

    Of course, you could all do this with a macro:

    #define convert32(O) (O&0xff << 24) + (O&0xFF00 << 8) + (O&0xFF0000 >> 8) +
    (O&0xFF000000 >> 24)

    Neither of these has been tested, but I believe they should work. The
    conversion is orthog so the same code is used to conver to/from
    big/little endian. I'll leave it to the reader to come up with a
    function/define for a short (2 byte int).

    Brad



    Brad Guest

  9. #9

    Default Re: Programinng issue Linux x86/Solaris 64bit


    Christopher Intemann <net> writes: 

    Note that generally you DON'T need to convert from little endian to
    big endian or vice-versa.

    What you have, is a 32-bit integer value stored either in little
    endian or in big endian, and you want to read or write it.

    If your file specifies big endian, you would have such functions:

    uint32 read_uint32(unsigned char* buffer,int offset)
    {
    return((buffer[offset+0]<<24)
    |(buffer[offset+1]<<16)
    |(buffer[offset+2]<<8)
    |(buffer[offset+3]));
    }

    void write_uint32(unsigned char* buffer,int offset,uint32 value)
    {
    buffer[offset+0]=value>>24;
    buffer[offset+1]=value>>16;
    buffer[offset+2]=value>>8;
    buffer[offset+3]=value;
    }

    and you would just use:

    char buffer[512];

    write_uint32(buffer, 3,1*1000*1000*1000);
    write_uint32(buffer, 7,2*1000*1000*1000);
    write_uint32(buffer,42,3*1000*1000*1000);

    and then:

    uint32 a=read_uint32(buffer,3);
    uint32 b=read_uint32(buffer,7);
    uint32 c=read_uint32(buffer,42);

    Some of the reasons for not taking into account endianness of the
    processor are:

    - the processor may have an endianness different from little
    endian or big endian.

    - the processor may have word size not a multiple of 8.

    - that would imply more work on your part, having to program two
    or more cases instead of one.


    --
    __Pascal_Bourguignon__
    http://www.informatimago.com/
    Do not adjust your mind, there is a fault in reality.
    Pascal Guest

  10. #10

    Default Re: Programinng issue Linux x86/Solaris 64bit

    In article <jgWfb.8936$N94.4389lakeread02>, Brad wrote: 
    > source 
    > these 
    >
    > To convert a 4 byte integer between little and big endian there are several
    > ways. If the bytes are ordered A B C D, then to convert you need to change
    > the bytes to the order D C B A. There are several ways to do this.
    >
    > uint32 convertInt(uint_32 oldValue)
    > {
    > union convert {
    > uint_32 uint32;
    > unsigned char uchar;[/ref]

    You meant: "unsigned char* uchar;", right? 

    (There are a couple typos.)
     


    --
    Jim Cochrane; com
    [When responding by email, include the term non-spam in the subject line to
    get through my spam filter.]
    Jim Guest

  11. #11

    Default Re: Programinng issue Linux x86/Solaris 64bit

    Jim Cochrane <dimensional.com> writes: 
    >
    > You meant: "unsigned char* uchar;", right?[/ref]

    Obviously not. He meant:

    unsigned char uchar[4];
     
    >
    > (There are a couple typos.)[/ref]

    --
    __Pascal_Bourguignon__
    http://www.informatimago.com/
    Do not adjust your mind, there is a fault in reality.
    Pascal Guest

  12. #12

    Default Re: Programinng issue Linux x86/Solaris 64bit


    "Jim Cochrane" <dimensional.com> wrote in message
    news:dimensional.com...
     
    >
    > You meant: "unsigned char* uchar;", right?[/ref]

    Actually, it should have been unsigned char[4] uchar
     [/ref]
    bytes4.char[1] 
    >
    > (There are a couple typos.)[/ref]
    As I said, it wasn't compiled, but I believe the gist of it is there. [/ref]
    8) + 
    >
    >
    > --
    > Jim Cochrane; com
    > [When responding by email, include the term non-spam in the subject line[/ref]
    to 

    Brad



    Brad Guest

  13. #13

    Default Re: Programinng issue Linux x86/Solaris 64bit


    "Pascal Bourguignon" <informatimago.com> wrote in message
    news:informatimago.com... [/ref][/ref]
    several [/ref][/ref]
    change 
    > >
    > > You meant: "unsigned char* uchar;", right?[/ref]
    >
    > Obviously not. He meant:
    >
    > unsigned char uchar[4];[/ref]
    Correct Pascal! Thanx for the correction. [/ref][/ref]
    bytes4.char[1] 
    > >
    > > (There are a couple typos.)[/ref]
    >
    > --
    > __Pascal_Bourguignon__
    > http://www.informatimago.com/
    > Do not adjust your mind, there is a fault in reality.[/ref]

    Brad



    Brad Guest

  14. #14

    Default Re: Programinng issue Linux x86/Solaris 64bit

    In article <blp8dp$1dvl$gwdg.de>,
    Christopher Intemann <net> writes: 

    You should read the XDR specification:

    RFC1832 XDR: External Data Representation Standard. R. Srinivasan. August
    1995. (Format: TXT=47418 bytes) (Status: DRAFT STANDARD)

    XDR is of course a way to resolve this issue, but even if you don't
    choose to use XDR (which may be unsuitable if you already have a
    defined data format), it is a good introduction into all the problems
    you need to solve (and byte ordering is only one of them).

    --
    Andrew Gabriel
    Andrew Guest

  15. Moderated Post

    Default Re: Programinng issue Linux x86/Solaris 64bit

    Removed by Administrator
    Christopher Guest
    Moderated Post

  16. #16

    Default Re: Programinng issue Linux x86/Solaris 64bit


    "Christopher Intemann" <net> wrote in message
    news:blp8dp$1dvl$gwdg.de...
     [/ref]
    things [/ref]
    in [/ref]
     

    Right.
     
    source 

    Just manipulate the individual bytes however you want to.
     
    these 

    Ouch! The problem with that is that the meaning of that include file
    could be specific to a particular platform, compiler, or even compiler
    version. Structures are, for example, packed differently on different
    platforms.
     

    I would strongly recommend you convert the include file into a proper
    specification at the byte level. Then write the code to implement the
    specification in a platform-independent way.

    For example, if the specification says "bytes 7 through 11 inclusive
    contain the frame type as a 32-bit unsigned integer in big-endian order",
    you can write platform-independent code like this:

    uint32_t GetBigEndianU32(unsigned char *ptr)
    {
    uint32_t r = *ptr++;
    r = (r<<8) | (*ptr++);
    r = (r<<8) | (*ptr++);
    return (r<<8) | (*ptr++);
    }

    unsigned char *data; /* pointer to the data as defined in the specification
    */
    uint32_t frame_type=GetBigEndianU32(data+6); /* I'm assuming that the first
    byte (byte 1) is 'data+0',
    so the seventh byte is data+6 */

    This is off the top of my head and untested, but it should give you the
    idea. Notice that this code will work perfectly regardless of the endianness
    of the platform and it doesn't chare whether the pointer you provide is
    aligned or not.

    DS


    David Guest

  17. #17

    Default Re: Programinng issue Linux x86/Solaris 64bit

    Hi all,
    at first I want to thank you very much for your hints.
    The uint32 issue seemed to be solved, everything works fine, but I'm
    right stuck in the next:-(
    I recognized a float value in the struct I also need to convert.
    (I thought I would'nt need it first)
    Anyway, as float is also 4 byte, I decided to try it with the same
    function I already used for uint32, but it did not work.
    Where is the problem here?
    Thanx again,
    Christopher


    --
    Christopher Intemann
    mail:net .~.
    phone/fax:0700/I-N-T-E-M-A-N-N /v\
    Iridium:+881631417758 // \\
    /( _ )\
    PGP-Public-Key: ^^ ^^
    http://www.math.uni-goettingen.de/intemann/pgp

    Christopher Guest

  18. #18

    Default Re: Programinng issue Linux x86/Solaris 64bit

    Hi again,
    In comp.unix.solaris Christopher Intemann <net> wrote: 

    it works now, and the same way like for uint32, I just had an error in my
    code.
    Thx,
    Christopher

    --
    Christopher Intemann
    mail:net .~.
    phone/fax:0700/I-N-T-E-M-A-N-N /v\
    Iridium:+881631417758 // \\
    /( _ )\
    PGP-Public-Key: ^^ ^^
    http://www.math.uni-goettingen.de/intemann/pgp

    Christopher Guest

Similar Threads

  1. Any chance of a 64bit port of the player for Linux
    By kyJoely in forum Macromedia Flash Player
    Replies: 0
    Last Post: August 23rd, 07:27 PM
  2. TIOCOUTQ from Linux to Solaris
    By Giovanni in forum UNIX Programming
    Replies: 2
    Last Post: March 2nd, 03:22 PM
  3. Programinng issue Linux x86/Solaris 64bit
    By Christopher in forum UNIX Programming
    Replies: 14
    Last Post: October 7th, 05:14 PM
  4. Type Def UINT32 Solaris 8 64bit
    By Christopher in forum Sun Solaris
    Replies: 2
    Last Post: October 2nd, 03:27 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139