LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Porting 32bit application to 64bit on 64bit RedHat 5.4 (https://www.linuxquestions.org/questions/programming-9/porting-32bit-application-to-64bit-on-64bit-redhat-5-4-a-821525/)

pvpnguyen 07-22-2010 11:16 AM

Porting 32bit application to 64bit on 64bit RedHat 5.4
 
Hello all, I have an 32bit application and I try to port it to 64bit by recompiling it on a 64 bit Redhat 5.4. But I get these error messages. Could you please show me some light on this? Your help is much appreciated. Thank you.

g++ -c -Wall -Wno-unknown-pragmas -fpermissive -fPIC -DUNIX -DDLG_UNIX_OS -DDLG_LINUX_OS -D_GNU_SOURCE -Dx86_64 -DNDEBUG -O2 -DLIBRTFMT_EXPORTS -m64 -I. -I./../../../../components/include -I./../../../../import/include/unix -I./../../../../import/include -I./../../../../include/external/unix -I./../../../../include/external -I./../../../../include/internal/unix -I./../../../../include/internal -I./ -I../MemoryStream -I../Messages -I../PerformanceCounter -I../RtfANSIAPI -I../RtfConfigFileReader -I../RtfService -I../Serialization -I../ServiceMonitor -I../Settings -I../Support -I../Tinyxml -I../TraceConfig -I../TraceData -I../TraceFiltering -I../TraceService -I../RtfDataTextExporter -I../MultiFileStream -o./../../../../build/objs/unix/gcc4.1.2/release/librtfmt.o librtfmt.cpp
../Serialization/Serialization.h:112: warning: class Serializer has virtual functions but non-virtual destructor
../Serialization/Serialization.h:140: warning: class Deserializer has virtual functions but non-virtual destructor
../ServiceMonitor/ServiceMonitor.h:259: warning: class WatchServiceStartUsingPIDFile has virtual functions but non-virtual destructor
../ServiceMonitor/ServiceMonitor.h:359: warning: class WatchServiceStopUsingPID has virtual functions but non-virtual destructor
../RtfConfigFileReader/RtfConfigFileReader.h:50: warning: class BaseConfigProcessor has virtual functions but non-virtual destructor
../RtfService/RtfConfigProcessor.h:176: warning: class RtfServerConfigProcessor has virtual functions but non-virtual destructor
../RtfService/RtfRecordSequencegenerator.h: In member function long unsigned int RtfRecordSequenceGenerator::operator++(int):
../RtfService/RtfRecordSequencegenerator.h:56: warning: dereferencing type-punned pointer will break strict-aliasing rules
../MultiFileStream/MultiFileStream.h: In constructor MultiFileOutputStream<SupportClass, HeaderSize>::MultiFileOutputStream(const std::string&, const std::string&, const std::string&, bool, size_t, size_t, size_t, size_t):
../MultiFileStream/MultiFileStream.h:331: warning: there are no arguments to GetHeader that depend on a template parameter, so a declaration of GetHeader must be available
../MultiFileStream/MultiFileStream.h: In member function void MultiFileInputStream<SupportClass, HeaderSize>::GetAllLogFiles(const std::string&, const std::string&, const std::string&, const std::string&):
../MultiFileStream/MultiFileStream.h:574: warning: there are no arguments to GetHeader that depend on a template parameter, so a declaration of GetHeader must be available
../TraceData/TraceDataReader.h: At global scope:
../TraceData/TraceDataReader.h:273: warning: specialization of template<class _Tp> struct std::greater in different namespace
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_function.h:214: warning: from definition of template<class _Tp> struct std::greater
../RtfService/RtfConfigProcessor.h: In instantiation of RtfClientConfigProcessor<RtfFilterManager>:
../RtfService/RtfServiceClient.h:82: instantiated from here
../RtfService/RtfConfigProcessor.h:43: warning: class RtfClientConfigProcessor<RtfFilterManager> has virtual functions but non-virtual destructor
../RtfANSIAPI/RtfANSIAPI.h: In function int RtfTraceEnabledEx(MODULEHANDLE, CLIENTHANDLE, LABELHANDLE):
../RtfANSIAPI/RtfANSIAPI.h:826: warning: Filter.RtfFilter::m_ModuleName may be used uninitialized in this function
../RtfANSIAPI/RtfANSIAPI.h:826: warning: Filter.RtfFilter::m_ClientName may be used uninitialized in this function
../RtfANSIAPI/RtfANSIAPI.h:826: warning: Filter.RtfFilter::m_LabelName may be used uninitialized in this function
/tmp/ccKzCY8W.s: Assembler messages:
/tmp/ccKzCY8W.s:37608: Error: Incorrect register `%rax' used with `l' suffix
/tmp/ccKzCY8W.s:38168: Error: Incorrect register `%rax' used with `l' suffix
/tmp/ccKzCY8W.s:38890: Error: Incorrect register `%rax' used with `l' suffix
/tmp/ccKzCY8W.s:39464: Error: Incorrect register `%rax' used with `l' suffix
/tmp/ccKzCY8W.s:42406: Error: Incorrect register `%rax' used with `l' suffix
/tmp/ccKzCY8W.s:43575: Error: Incorrect register `%rax' used with `l' suffix
/tmp/ccKzCY8W.s:49270: Error: Incorrect register `%rax' used with `l' suffix
/tmp/ccKzCY8W.s:50221: Error: Incorrect register `%rax' used with `l' suffix
make: *** [../../../../build/objs/unix/gcc4.1.2/release/./librtfmt.o] Error 1

pvpnguyen 07-22-2010 04:28 PM

Hello all, the problem was because the use of cmpxchgl, xchgl and xaddl in __asm__. I replaced cmpxchgl, xchgl, xaddl with cmpxchg, xchg, xadd and it compiled fine now. The question now is why cmpxchgl, xchgl, xaddl cannot be used to compile code on 64bit environment? Thank you.

Does not compile on 64 bit environment:

void *lock( void **dest, void *val )
{
void *ret;
__asm__ ( "lock; xchgl %0,(%1)"
: "=r" (ret) : "r" (dest), "0" (val) : "memory" );
return ret;
}

Compiles on 64 bit environment:

void *lock( void **dest, void *val )
{
void *ret;
__asm__ ( "lock; xchg %0,(%1)"
: "=r" (ret) : "r" (dest), "0" (val) : "memory" );
return ret;
}

resetreset 07-23-2010 02:29 AM

what do "cmpxchgl, xchgl and xaddl " do? sorry, but I don't have an opcode reference near me right now. what's the ending "l" for?

johnsfine 07-23-2010 06:40 AM

Quote:

Originally Posted by pvpnguyen (Post 4042363)
Code:

    __asm__ ( "lock; xchgl %0,(%1)"

Notice the l that I marked in red. It means 32 bit. Without that l the assembler will figure out the size by itself.

Notice the %0. It implies the size is the native size of the current architecture. So you have something in that instruction specifying that the operand size is 32 bit and something else indicating it is 64 bit. Those contradict each other.

Either operand size would work OK in a 64 bit program. But it must be one or the other. You can't specify the operand size of one instruction as both 32 bit and 64 bit.

If you wanted a 32 bit instruction in 64 bit mode, I don't know how you change the %0 and/or the other things in your function to specify that. If I understand your code correctly, the value you are reading/writing is a void*, so in fact you don't want a 32 bit instruction. A void* is 64 bits.

johnsfine 07-23-2010 06:52 AM

Quote:

Originally Posted by pvpnguyen (Post 4042363)
the problem was

Better to say "a problem was". That wasn't the only problem.

Look at some more of your output:

Code:

dereferencing type-punned pointer will break strict-aliasing rules
That is not related to a 32 bit to 64 bit porting. It is related to porting from a compiler that doesn't enforce the standard to one that does. But it is a serious bug and you should fix it. Your code probably will not run correctly with that bug, even if it compiles and links.

Code:

warning: there are no arguments to GetHeader that depend on a template parameter, so a declaration of GetHeader must be available
That is another problem in porting to a compiler that enforces the standard. Your code is wrong and should be corrected. I'm not quite sure why that is warning not an error. I can't deduce the details from that message, but a message like that often means you are using a function inherited from a templated base class. To inherit a function from a templated base class you should have a using declaration in your class definition to declare that you will be inheriting that function (not required when inheriting from a non templated base class).

Code:

specialization of template<class _Tp> struct std::greater in different namespace
I don't know much about that one, but it also sounds like the warning is telling about an error in your code.

Code:

has virtual functions but non-virtual destructor
I've always considered that a very lame warning. Forgetting a virtual destructor that was required is a messy bug (complicated symptoms that may be very hard to track back to the cause). So a warning when it appears you made that mistake would be helpful. But in serious programming there isn't that much correlation between having virtual functions and needing a virtual destructor. A class might need a virtual destructor despite having no other virtual functions and plenty of classes have virtual functions with no need of a virtual destructor.

The bigger problem is likely to be all the 32 to 64 bit porting issues that don't even generate a warning. These warnings (especially the one about "type-punned pointer") imply a style of coding that is unlikely to transition cleanly from 32 bit to 64 bit.

In 32 bit, int, long, std::size_t, and void* are all the same size. In x86_64, int is still 32 bit but all those others are 64 bit.

It is very common for code to accidentally or intentionally assume that int is the same size as one of those other types. When you port that code to 64 bit, it will be doing the wrong thing.


All times are GMT -5. The time now is 09:51 PM.