1

I'm reading in the first Bytes of an File with fread:

fread(&example_struct, sizeof(example_struct), 1, fp_input);

Which ends up with different results under linux and solaris? Whereby the example_struct (Elf32_Ehdr) is part of Standart GNU C Liborary defined in elf.h? I would be happy to know why this happens?

General the struct looks the following:

typedef struct
{
  unsigned char e_ident[LENGTH];    
  TYPE_Half e_type;         
} example_struct;

The Debugcode:

for(i=0;paul<sizeof(example_struct);i++){
    printf("example_struct->e_ident[%i]:(%x) \n",i,example_struct.e_ident[i]);
}
printf("example_struct->e_type: (%x) \n",example_struct.e_type);
printf("example_struct->e_machine: (%x) \n",example_struct.e_machine);

Solaris output:

Elf32_Ehead->e_ident[0]: (7f) 
Elf32_Ehead->e_ident[1]: (45) 
...
Elf32_Ehead->e_ident[16]: (2) 
Elf32_Ehead->e_ident[17]: (0)
...
Elf32_Ehead->e_type: (200) 
Elf32_Ehead->e_machine: (6900) 

Linux output:

Elf32_Ehead->e_ident[0]: (7f) 
Elf32_Ehead->e_ident[1]: (45) 
...
Elf32_Ehead->e_ident[16]: (2) 
Elf32_Ehead->e_ident[17]: (0)
...
Elf32_Ehead->e_type: (2) 
Elf32_Ehead->e_machine: (69)

Maybe similar to: http://forums.devarticles.com/c-c-help-52/file-io-linux-and-solaris-108308.html

eactor
  • 862
  • 3
  • 14
  • 34

2 Answers2

5

You don't mention what CPU you have in the machines, maybe Sparc64 in the Solaris machine and x86_64 in the Linux box, but I would guess that you're having an endianness issue. Intel, ARM and most other common architectures today are what is known as little-endian, the Sparc architecture is big-endian.

Let's assume we have the value 0x1234 in a CPU register and we want to store it in memory (or on hard drive, it doesn't matter where). Let N be the memory address we want to write to. We will need to store this 16 bit integer as two bytes in memory, here comes the confusing part:

Using a big-endian machine will store 0x12 at address N and 0x34 at address N+1. A little-endian machine will store 0x34 at address N and 0x12 at address N+1. If we store a value using a little endian machine and read it back using a big endian machine we will have swapped the two bytes around and you'll get the issue that you are seeing.

Joakim Nohlgård
  • 1,832
  • 16
  • 16
  • Ok the Solaris runs on a UltraSPARC T2 and the LinuxBox on normal x86 architecture. The Confusing is that the software writing the file (not from me) is doing it the same way but my read in does diffrent things on the two machines – eactor Nov 08 '12 at 22:14
  • So is there a good way to write a struct read in, which runs on both machines, or do I have do detect the actual system the software is running on? – eactor Nov 08 '12 at 22:16
  • This question has some good answers including example C code for swapping byte order: http://stackoverflow.com/questions/2182002/convert-big-endian-to-little-endian-in-c-without-using-provided-func – Joakim Nohlgård Nov 09 '12 at 08:45
1

Probably because of differences in the structure packing between the two platforms. It's a bad idea to read structures directly (as units) from external media, since issues like these tend to pop up.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • I though of an endianess issue also, but this would assume reading the one OS's disk with the other OS, wouldn't it? – alk Nov 08 '12 at 14:24