0 post

Posts Tagged ‘porting’


Porting gotchas

Posted by Alen Zukich   January 25th, 2011

If you’ve ever gone through the process of porting an application, you know the pain.  Porting can be difficult if you’re not vigilant from the outset.  There are tons of written guidelines and best practices for specific platforms or architectures, such as those going to 64 bit for Windows apps or Intel architecture and Mac OS.

In the past, we have talked about Endian issues, which are very specific to porting from different architectures (big-endian vs little-endian).  This time I want to take you through some general porting issues to show you how you can now use static analysis tools to help you through this process.

A very common gotcha are situations in which an expression is cast to a type of potentially different size.  Code written for a particular architecture’s data model can face significant challenges in porting when the new architecture imposes a new data model. For example, when porting between 32 bit and 64 bit data models, the new data model typically leaves ‘int’ at 32 bits, but uses ‘long’ as a 64 bit value, breaking any assumed equality in data type size that worked under the 32 bit data model.  Using static analysis tools can help you find this automatically.  In the example below all casts will throw an error:

void bad(){
 unsigned char uc = 0;
 unsigned short us = 0;
 unsigned int ui = 0;
 unsigned long long ull = 0;
 long l=0;

 l = (long)ull; //porting issue
 uc = (unsigned char)l; //porting issue
 us = (unsigned short)l; //porting issue
 ui = (unsigned int)l; //porting issue
}

Another gotcha is using bit fields within a structure.  When you define a data structure using bit fields, you are relying on the endian representation of a particular compiler. Moving to a different compiler can modify this layout, resulting in problems when that data structure is projected onto a byte buffer.  Again static analysis tools can be used to identify where the bit field definition exists and NOT properly covered by a big-endian or little-endian macro.  For example flag this:

struct mystruct{
   unsigned short x : 4;
   unsigned short y : 5;
   unsigned short z : 7;
} test;

But don’t flag the same thing with conditional compilation:

#ifdef BIG_ENDIAN
struct mystruct{
   unsigned short x : 4;
   unsigned short y : 5;
   unsigned short z : 7;
} test;
...

There are tons of other gotchas as well, such as using a custom byte swap macro without checking endianness, an incompatible type is used with a network macro such as ‘ntohl’, compiler-dependent option is used, macro describing a builtin numeric type is used, and many more.

Using static analysis tools not only detects porting issues, but provides metrics and reporting capabilities that allow you to prioritize and identify the scope of work involved.  For example, Top 10 porting issues (see the diagram above) helps you identify the bulk of the issues that need to be addressed.  Or you can use the component diagram report to identify specific components of your software code base you may have to concentrate on going forward.


0010 0000 or 0000 0010 which one are you?

Posted by Eric Hollebone   August 10th, 2010

I love this quote by Carl Ek from  Code Integrity solutions:

There are 0010 0000 kinds of people in the world: Those that understand the difference between Big Endian and Little Endian, and those that do not.

Issues with Endianism and processor architecture ports are becoming more and more common these days as more desktop source code moves into different arenas.  Gone are the days when the 32-bit memory model or little-endian format dominate. Software changes are required to support the growth occurring not at the desktop, but in the server  and mobile platforms.

Mobile devices especially have opened a Pandora’s box of Endian and memory problems, with variety of processor architectures with ARM[1] leading the way.  Add to this mix,  end-consumers are demanding desktop features like Adobe Flash or Office apps on mobile devices, many a stable codebase will fall apart when ported to either mobile or server.

For developers porting to different platforms, there are some significant challenges.  Just to list a few:

  • CPU optimizations need to be reviewed
  • inline assembly calls require rewriting or removal
  • machine word (WORD) allocations may require refactoring
  • any binary data exchanged over the network stacks require verification

None of these are  new, they’re just not a common skillset for most developers.

Source code analysis can be a boon in two ways. Firstly, in the planning phase by helping you determine the breadth of the effort,  and secondly by identifying any existing  issues, particularly of the memory allocation and Endian varieties.

For more in depth information, there are two recent articles available from Dr. Dobbs:

[1] Note: Some ARM processors support both big and little Endian formats.