@@ -135,10 +135,16 @@ void update_elf_offset(ph2_ir_t *ph2_ir)
135135
136136void  cfg_flatten (void )
137137{
138-     func_t  * func  =  find_func ("__syscall" );
139-     func -> bbs -> elf_offset  =  44 ; /* offset of start + exit in codegen */ 
138+     func_t  * func ;
139+ 
140+     if  (dynlink )
141+         elf_offset  =  108 ; /* offset of start + exit in codegen */ 
142+     else  {
143+         func  =  find_func ("__syscall" );
144+         func -> bbs -> elf_offset  =  44 ; /* offset of start + exit in codegen */ 
145+         elf_offset  =  80 ; /* offset of start + exit + syscall in codegen */ 
146+     }
140147
141-     elf_offset  =  80 ; /* offset of start + exit + syscall in codegen */ 
142148    GLOBAL_FUNC -> bbs -> elf_offset  =  elf_offset ;
143149
144150    for  (ph2_ir_t  * ph2_ir  =  GLOBAL_FUNC -> bbs -> ph2_ir_list .head ; ph2_ir ;
@@ -147,9 +153,15 @@ void cfg_flatten(void)
147153    }
148154
149155    /* prepare 'argc' and 'argv', then proceed to 'main' function */ 
150-     elf_offset  +=  24 ;
156+     if  (dynlink )
157+         elf_offset  +=  12 ;
158+     else 
159+         elf_offset  +=  24 ;
151160
152161    for  (func  =  FUNC_LIST .head ; func ; func  =  func -> next ) {
162+         if  (!func -> bbs )
163+             continue ;
164+ 
153165        /* reserve stack */ 
154166        ph2_ir_t  * flatten_ir  =  add_ph2_ir (OP_define );
155167        flatten_ir -> src0  =  func -> stack_size ;
@@ -286,15 +298,23 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
286298        return ;
287299    case  OP_call :
288300        func  =  find_func (ph2_ir -> func_name );
289-         emit (__bl (__AL , func -> bbs -> elf_offset  -  elf_code -> size ));
301+         if  (func -> bbs )
302+             ofs  =  func -> bbs -> elf_offset  -  elf_code -> size ;
303+         else 
304+             ofs  =  (elf_plt_start  +  func -> plt_offset ) - 
305+                   (elf_code_start  +  elf_code -> size );
306+         emit (__bl (__AL , ofs ));
290307        return ;
291308    case  OP_load_data_address :
292309        emit (__movw (__AL , rd , ph2_ir -> src0  +  elf_data_start ));
293310        emit (__movt (__AL , rd , ph2_ir -> src0  +  elf_data_start ));
294311        return ;
295312    case  OP_address_of_func :
296313        func  =  find_func (ph2_ir -> func_name );
297-         ofs  =  elf_code_start  +  func -> bbs -> elf_offset ;
314+         if  (func -> bbs )
315+             ofs  =  elf_code_start  +  func -> bbs -> elf_offset ;
316+         else 
317+             ofs  =  elf_plt_start  +  func -> plt_offset ;
298318        emit (__movw (__AL , __r8 , ofs ));
299319        emit (__movt (__AL , __r8 , ofs ));
300320        emit (__sw (__AL , __r8 , rn , 0 ));
@@ -451,11 +471,40 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
451471    }
452472}
453473
474+ void  plt_generate (void );
454475void  code_generate (void )
455476{
456-     elf_data_start  =  elf_code_start  +  elf_offset ;
477+     if  (dynlink ) {
478+         plt_generate ();
479+         /* Call __libc_start_main() */ 
480+         emit (__mov_i (__AL , __r11 , 0 ));
481+         emit (__mov_i (__AL , __lr , 0 ));
482+         emit (__pop_word (__AL , __r1 ));
483+         emit (__mov_r (__AL , __r2 , __sp ));
484+         emit (__push_reg (__AL , __r2 ));
485+         emit (__push_reg (__AL , __r0 ));
486+         emit (__mov_i (__AL , __r12 , 0 ));
487+         emit (__push_reg (__AL , __r12 ));
488+         emit (__movw (__AL , __r0 , elf_code_start  +  56 ));
489+         emit (__movt (__AL , __r0 , elf_code_start  +  56 ));
490+         emit (__mov_i (__AL , __r3 , 0 ));
491+         emit (__bl (__AL , (elf_plt_start  +  PLT_FIXUP_SIZE ) - 
492+                             (elf_code_start  +  elf_code -> size )));
493+         /* Goto the 'exit' code snippet if __libc_start_main returns */ 
494+         emit (__mov_i (__AL , __r0 , 127 ));
495+         emit (__bl (__AL , 28 ));
457496
458-     /* start */ 
497+         /* If the compiled program is dynamic linking, the starting 
498+          * point of 'start' is located here. 
499+          * 
500+          * Preserve the 'argc' and 'argv' for the 'main' function. 
501+          * */ 
502+         emit (__mov_r (__AL , __r9 , __r0 ));
503+         emit (__mov_r (__AL , __r10 , __r1 ));
504+     }
505+     /* If the compiled program is static linking, the starting point 
506+      * of 'start' is here. 
507+      * */ 
459508    emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
460509    emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
461510    emit (__sub_r (__AL , __sp , __sp , __r8 ));
@@ -470,32 +519,56 @@ void code_generate(void)
470519    emit (__mov_i (__AL , __r7 , 1 ));
471520    emit (__svc ());
472521
473-     /* syscall */ 
474-     emit (__mov_r (__AL , __r7 , __r0 ));
475-     emit (__mov_r (__AL , __r0 , __r1 ));
476-     emit (__mov_r (__AL , __r1 , __r2 ));
477-     emit (__mov_r (__AL , __r2 , __r3 ));
478-     emit (__mov_r (__AL , __r3 , __r4 ));
479-     emit (__mov_r (__AL , __r4 , __r5 ));
480-     emit (__mov_r (__AL , __r5 , __r6 ));
481-     emit (__svc ());
482-     emit (__mov_r (__AL , __pc , __lr ));
522+     if  (!dynlink ) {
523+         /* syscall */ 
524+         emit (__mov_r (__AL , __r7 , __r0 ));
525+         emit (__mov_r (__AL , __r0 , __r1 ));
526+         emit (__mov_r (__AL , __r1 , __r2 ));
527+         emit (__mov_r (__AL , __r2 , __r3 ));
528+         emit (__mov_r (__AL , __r3 , __r4 ));
529+         emit (__mov_r (__AL , __r4 , __r5 ));
530+         emit (__mov_r (__AL , __r5 , __r6 ));
531+         emit (__svc ());
532+         emit (__mov_r (__AL , __pc , __lr ));
533+     }
483534
484535    ph2_ir_t  * ph2_ir ;
485536    for  (ph2_ir  =  GLOBAL_FUNC -> bbs -> ph2_ir_list .head ; ph2_ir ;
486537         ph2_ir  =  ph2_ir -> next )
487538        emit_ph2_ir (ph2_ir );
488539
489540    /* prepare 'argc' and 'argv', then proceed to 'main' function */ 
490-     emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
491-     emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
492-     emit (__add_r (__AL , __r8 , __r12 , __r8 ));
493-     emit (__lw (__AL , __r0 , __r8 , 0 ));
494-     emit (__add_i (__AL , __r1 , __r8 , 4 ));
541+     if  (dynlink ) {
542+         emit (__mov_r (__AL , __r0 , __r9 ));
543+         emit (__mov_r (__AL , __r1 , __r10 ));
544+     } else  {
545+         emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
546+         emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
547+         emit (__add_r (__AL , __r8 , __r12 , __r8 ));
548+         emit (__lw (__AL , __r0 , __r8 , 0 ));
549+         emit (__add_i (__AL , __r1 , __r8 , 4 ));
550+     }
495551    emit (__b (__AL , MAIN_BB -> elf_offset  -  elf_code -> size ));
496552
497553    for  (int  i  =  0 ; i  <  ph2_ir_idx ; i ++ ) {
498554        ph2_ir  =  PH2_IR_FLATTEN [i ];
499555        emit_ph2_ir (ph2_ir );
500556    }
501557}
558+ 
559+ void  plt_generate (void )
560+ {
561+     int  addr_of_got  =  elf_got_start  +  PTR_SIZE  *  2 ;
562+     int  end  =  plt_sz  -  PLT_FIXUP_SIZE ;
563+     elf_write_int (elf_plt , __push_reg (__AL , __lr ));
564+     elf_write_int (elf_plt , __movw (__AL , __r10 , addr_of_got ));
565+     elf_write_int (elf_plt , __movt (__AL , __r10 , addr_of_got ));
566+     elf_write_int (elf_plt , __mov_r (__AL , __lr , __r10 ));
567+     elf_write_int (elf_plt , __lw (__AL , __pc , __lr , 0 ));
568+     for  (int  i  =  0 ; i  *  PLT_ENT_SIZE  <  end ; i ++ ) {
569+         addr_of_got  =  elf_got_start  +  PTR_SIZE  *  (i  +  3 );
570+         elf_write_int (elf_plt , __movw (__AL , __r12 , addr_of_got ));
571+         elf_write_int (elf_plt , __movt (__AL , __r12 , addr_of_got ));
572+         elf_write_int (elf_plt , __lw (__AL , __pc , __r12 , 0 ));
573+     }
574+ }
0 commit comments