Wednesday, June 3, 2015

Link C++ Library in EDK II Module

It is hard to write C++ code in cpp and put it in EDK II INF file to build a driver with EDK2 build system because build failures occur. There are two ways to solve it.

1) We use native C++ compiler (e.g., VC++) to pack C++ code in a library with wrapped pure C function first, copy the library in your UEFI driver source code, and put the lib file in the EDK II INF file.

2) We write C++ code in a cpp file and to put the cpp file in the driver INF file.

This page describes the first way. I will describe the second way in another page, Use C++ in EDK II.

When we select the first way, build failure occurs on link errors,

error LNK2001: unresolved external symbol "void __cdecl `eh vector constructor iterator' ...

error LNK2001: unresolved external symbol "void __cdecl `eh vector destructor iterator' ...

The root cause is, we use new/delete operator to create/destroy an object array. VC++ needs the both symbols to handle the new-delete-object-array operations. The errors don't occur when building a Windows program because Windows environment provides symbols in a Windows specific library. But the link error occurs in UEFI building environment because it lacks the library.

I cannot find a regular and simple solution. My workaround is to modify C++ code to avoid to use new operator in class array.

MY_OBJ *ObjArray = new MY_OBJ [100];
delete[] ObjArray;                  

I use malloc/free instead of new/delete as below for an object array;

MY_OBJ **ObjArray = (MY_OBJ **) malloc (sizeof (MY_OBJ *) * 100);
for (int i = 0; i < 100; i++) {                                  
  ObjArray [i] = new MY_OBJ;                                     
}                                                                
                                                                 
for (int i = 0; i < 100; i++) {                                  
  delete ObjArray [i];                                           
}                                                                
free (ObjArray);                                                 

The regular solution is to use C struct instead of C++ class for platform portability.

Another link error occurs as below.

error LNK2001: unresolved external symbol __CxxFrameHandler3

The symbol __CxxFrameHandler3 is to check buffer overflow. The UEFI building environment lacks the symbol so that the link error occurs.

My solution is to create a dummy __CxxFrameHandler3 function in UEFI source code to avoid the link error.

void __CxxFrameHandler3 (void)
{
  return;
}

-Count


No comments:

Post a Comment