0

I am currently working on porting a piece of code written and compiled for SGI using MIPSPro to RHEL 6.7 with gcc 4.4.7. My target architecture is x86_64 I was able to generate an executable for this code and now I am trying to run it.

I am trying to read a binary data from a file, this file was generated in the SGI system by basically casting object's pointer to a char* and saving that to a file. The piece of binary data that I am trying to read has more or less this format:

[ Header, Object A , Object B, ..., Object N ]

Where each object is an instantiation of different classes.

The way the code currently processes the file is by reading it all into memory, and taking the pointer to where the object starts and using reinterpret_class<Class A>(pointer) to it. Something tells me that the people who original designed this were not concerned about portability.

So far I was able to deal with the endianness of the Header object by just swapping the bytes. Unfortunately, Objects A, B, .., N all contain fields of type double and trying to do a byte-swap for 8 bytes does not seem to work.

My question then is, are doubles in SGI/MIPSPro structured differently than in Linux? I know that the sizeof(double) in the SGI machine returns 8 so I think they are of the same size.

tadman
  • 208,517
  • 23
  • 234
  • 262
Iliketoproveit
  • 445
  • 6
  • 15

1 Answers1

2

According to the MIPSPro ABI:

the MIPS processors conform to the IEEE 754 floating point standard

Your target platform, x86_64, shares this quality.

As such, double means IEEE-754 double-precision float on both platforms.

When it comes to endianness, x86_64 processors are little-endian; but, according to the MIPSpro assembly programmers' guide, some MIPSPro processors are big-endian:

For R4000 and earlier systems, byte ordering is configurable into either big-endian or little-endian byte ordering (configuration occurs during hardware reset). When configured as a big-endian system, byte 0 is always the most-significant (leftmost) byte. When configured as a little-endian system, byte 0 is always the least-significant (rightmost byte).

The R8000 CPU, at present, supports big-endian only

So, you will have to check the datasheet for the original platform and see whether any byte swapping is needed.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • So in theory, by doing a 8 byte endianess swap it should work? – Iliketoproveit Mar 07 '18 at 22:34
  • 1
    @roscoe: As far as I can tell. You could test it ;) – Lightness Races in Orbit Mar 07 '18 at 22:35
  • I did, unfortunately I still got weird results. It seems that the way its reading these objects into memory is misaligned, I can't see what else could cause this issue. I may be getting off topic here, but do you know how enums are formatted in both these architectures? – Iliketoproveit Mar 07 '18 at 22:40
  • Should I ask a new question about enum formats or just update my question to include that? – Iliketoproveit Mar 07 '18 at 22:41
  • @roscoe: enums are not a factor of computer architecture. The value of an enum is just an integer. Account for type width and endianness and you should be fine (though yes you are going to have to be careful with alignment - prefer `std::copy` over `reinterpret_cast`) – Lightness Races in Orbit Mar 07 '18 at 22:43
  • How would I even deal with alignment? Is the way that objects are structured between the two systems different? If so, not sure if that problem is even fixable – Iliketoproveit Mar 07 '18 at 22:54
  • @roscoe: Alignment and padding are not quite the same. If composite objects have been serialised with unknown padding, then that problem isn't particularly fixable, no (hopefully it was serialised in an unpadded format, as common sense dictates). You should research _alignment_, _padding_ and _serialisation_. – Lightness Races in Orbit Mar 07 '18 at 23:30