#include <stdio.h>
#include <stdlib.h>>
#include <unistd.h>
#include <fcntl.h>
/*                                                                                                                      
 * Como usarlo (caso intel):                                                                                                 *	      ./loader  suma.bin                                                                                       *                                                                                                                      
 *      donde  suma.bin  contiene los raw opcodes a ejecutar:                                                           
 *                                                                                                                      
 *      objdump -d suma.o                                                                                               
 *       suma.o:     file format elf64-x86-64                                                                           
 *        Disassembly of section .text:                                                                                 
 *         0000000000000000 <suma>:                                                                                     
 *            0:   55                      push   %rbp                                                                  
 *            1:   48 89 e5                mov    %rsp,%rbp                                                             
 *            4:   b8 ff 00 00 00          mov    $0xff,%eax                                                            
 *            9:   c9                      leaveq                                                                       
 *            a:   c3                      retq                                                                         
 * 
 *
 * El archivo suma contiene el codigo raw a ejecutar                                                                    
 * /home/soporte/vi6x877/src/loader % hexdump suma.bin                                                                   
 *0000000 4855 e589 c3c9 9090 9090                                                                                      
 *000000a                                                                                                               
 */                                                                                                                     
                                                                                                                        
int main( int argc, char *argv[] ){                                                                                     
        unsigned char (*proc)();                                                                                        
        unsigned int i =1       ;                                                                                       
        unsigned int fdprog=0;                                                                                          
        unsigned char *rcode=0;                                                                                         
        unsigned char *exec_code=NULL;                                                                                  
        unsigned char *ptr=NULL;                                                                                        
        unsigned long  salida=0x0;                                                                                      
                                                                                                                        
        exec_code=(char *) malloc( sizeof(unsigned char) * 100 );                                                       
        ptr=exec_code;                                                                                                  
        fdprog=open(argv[1], S_IRUSR );                                                                                 
                                                                                                                        
        printf("Opcodes to exec:\n");                                                                                   
        while(   read(fdprog, ptr, sizeof(unsigned char))     ){                                                        
                 printf(" %02x ",  *ptr );                                                                                
                 ptr++;                                                                                                 
                 i++;                                                                                                   
        }                                                                                                               
                                                                                                                        
        printf("\nEnd opcodes\n");                                                                                      
        printf("direccion de exec_code =%p \n",exec_code);                                                              
        proc=(unsigned char (*)() ) exec_code;                                                                          
        printf("direccion de proc = %p \n",proc);                                                                       
	/* Ejecutamos los opcodes cargados en el buf al que apunta el apuntador a funcion proc 
	   el fichero cargado contiene una funcion que hace un return devolviendo el valor en el registro
	   acomulador, el compilador se encarga de generar codigo para copiar contenido del registro anterior
	   en la variable salida, en este caso producto de la asignacion (igual  = ) */

	/* toda la preparacion del stack frame, la carga del valor en el registro y la restauracion del stack frame anterior	       queda  a cargo del codigo ejecutable escrito en el fichero de carga */
        salida= (*proc)();                                                                                              
                                                                                                                        
        /*                                                                                                              
         *              la comunicacion entre las variables y las funciones cuando                                    
         *se realiza una asignacion del tipo  var= myfunction()                                                       
         *se realiza atraves del registro eax  ( en Intel ) o en el registro acumulador en alguna otra arquitectura     
         */                                                                                                             
                                                                                                                        
        printf("output :[eax, Intel],[ r3, PPC]  %lx \n",salida);                                                                            
                                                                                                                        
return 0;                                                                                                               
}                                                                                                                       


/*
En Mac OS X para extraer el codigo  a ejecutar :

$ otool sum.o -td|sed -n '3,$p'|awk '{ print $0}'
00000000 bfc1fff8 9421ffd0 7c3e0b78 38000000  <--opcodes, valor en hex
00000010 6000aaff 7c030378 80210000 bbc1fff8 
00000020 4e800020 
Para generar el fichero en formato binario:
otool sum.o -td|sed -n '3,$p'|awk '{ print $0}'|xxd -r >  fff  (xxd -r transforma la salida a formato binario)

El fichero a cargar seria : ./loader fff

$ otool sum.o -tv
sum.o:
(__TEXT,__text) section
_sum:
00000000	stmw	r30,0xfff8(r1)
00000004	stwu	r1,0xffd0(r1)
00000008	or	r30,r1,r1
0000000c	li	r0,0x0
00000010	ori	r0,r0,0xaaff  <--- a cargar el valor inmediato 0xaaff
00000014	or	r3,r0,r0
00000018	lwz	r1,0x0(r1)
0000001c	lmw	r30,0xfff8(r1)
00000020	blr

Tambien se puede obtener un vector con el hexdump en formato C:
otool sum.o -td|sed -n '3,$p'|
	awk '{ print $0}'    |
	xxd -i |awk 'BEGIN{print "shell[]={ "}
		{print $0} 
		END{ print "\};"  }'

shell[]={ 
  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x62, 0x66, 0x63,
  0x31, 0x66, 0x66, 0x66, 0x38, 0x20, 0x39, 0x34, 0x32, 0x31, 0x66, 0x66,
  0x64, 0x30, 0x20, 0x37, 0x63, 0x33, 0x65, 0x30, 0x62, 0x37, 0x38, 0x20,
  0x33, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x0a, 0x30, 0x30,
  0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x20, 0x36, 0x30, 0x30, 0x30, 0x61,
  0x61, 0x66, 0x66, 0x20, 0x37, 0x63, 0x30, 0x33, 0x30, 0x33, 0x37, 0x38,
  0x20, 0x38, 0x30, 0x32, 0x31, 0x30, 0x30, 0x30, 0x30, 0x20, 0x62, 0x62,
  0x63, 0x31, 0x66, 0x66, 0x66, 0x38, 0x20, 0x0a, 0x30, 0x30, 0x30, 0x30,
  0x30, 0x30, 0x32, 0x30, 0x20, 0x34, 0x65, 0x38, 0x30, 0x30, 0x30, 0x32,
  0x30, 0x20, 0x0a
};


*/


