//
// BREWe2modFilter
// "BREW Elf TO MOD FILTER" or "BREW Elf TO Mod Object Dump FILTER"
//
// This filter transforms the output of a recent arm-elf-objdump, such
// as that provided in WinARM, so that the Qualcomm-provided
// BREWelf2mod can consume it. This is necessary for applets that use
// the thumb instruction set.
//
// Along the way, it also removes relocations for __cxa_pure_virtual,
// which should never be called at applet runtime. This makes the
// relocation table the module has to carry around smaller by a few
// (to a few hundred) bytes. Note you still have to satisfy this
// __cxa_pure_virtual for the linker, however -- either with a
// do-nothing function, or in the linker script, or with ld's --defsym
// switch.
//
// Put this in a batch file, say e2m_wrapper.bat, with something like
// the following line inside it:
//
//    \WinARM\bin\arm-elf-objdump.exe %* | BREWe2modFilter.exe
//
// Then, invoke BREWelf2mod with:
//
//    BREWelf2mod myapp.elf myapp.mod e2m_wrapper
//
// This is freeware for your dining and dancing pleasure.
//
// See: http://brew.wardco.com for information.
//
// HISTORY
// 09May06  Ward Willats       First-try
// 10May06  Ward Willats       Try remapping R_ARM_CALL to PLT32 
//                             too for CodeSourcery 2005q4, and
//                             R_ARM_JUMP24 to PLT32. Might not
//                             work or work reliabley though.

#include <string>
#include <iostream>
using namespace std;

char buffer[ 4096 ];

int main( int, char ** )
{
    string strThumbCall( "R_ARM_THM_CALL" );
    string strPC22( "R_ARM_THM_PC22" );
    string strPureVirtual( "__cxa_pure_virtual" );

    string strArmCall( "R_ARM_CALL" );  // sourcery makes these
    string strPLT32( "R_ARM_PLT32" );   // try remapping to this (both ((S+A)|T)-P)
    string strJUMP24( "R_ARM_JUMP24" );   // sourcery makes these

    string str;
    while( cin )
    {
        cin.getline( buffer, 4096 );
        if( !cin )
            break;
        str = buffer;

        // if rellocation for __cxa_pure_virtual, drop it

        if ( str.find( strPureVirtual ) != -1 )
            continue;

        // if R_ARM_THM_CALL change to R_ARM_THM_PC22

        size_t pos = str.find( strThumbCall );
        if ( pos != -1 )
        {
            str.replace( pos, strThumbCall.length(), strPC22 );
            goto squirt;
        }

#if 0 // turn this on for code sourcery experimental support 

        // Experimental for sourcery: if R_ARM_CALL, asso
        // change to R_ARM_PLT32 since both have same op

        pos = str.find( strArmCall );
        if ( pos != -1 )
        {
            str.replace( pos, strArmCall.length(), strPLT32 );
            goto squirt;
        }

        // Experimental for sourcery: if R_ARM_JUMP24, 
        // change to R_ARM_THM_PC22 since both have same op
        
        pos = str.find( strJUMP24 );
        if ( pos != -1 )
        {
            str.replace( pos, strJUMP24.length(), strPLT32 );
            goto squirt;
        }
#endif // experimental


squirt:
        cout << str << endl;

    }
    return 0;
}

// end: BREWe2modFilter.cpp

