@@ -136,10 +136,18 @@ void update_elf_offset(ph2_ir_t *ph2_ir)
136136
137137void cfg_flatten (void )
138138{
139- func_t * func = find_func ("__syscall" );
140- func -> bbs -> elf_offset = 48 ; /* offset of start + branch + exit in codegen */
139+ func_t * func ;
140+
141+ if (dynlink )
142+ elf_offset =
143+ 84 ; /* offset of __libc_start_main + main_wrapper in codegen */
144+ else {
145+ func = find_func ("__syscall" );
146+ func -> bbs -> elf_offset = 48 ; /* offset of start + exit in codegen */
147+ elf_offset =
148+ 84 ; /* offset of start + branch + exit + syscall in codegen */
149+ }
141150
142- elf_offset = 84 ; /* offset of start + branch + exit + syscall in codegen */
143151 GLOBAL_FUNC -> bbs -> elf_offset = elf_offset ;
144152
145153 for (ph2_ir_t * ph2_ir = GLOBAL_FUNC -> bbs -> ph2_ir_list .head ; ph2_ir ;
@@ -148,7 +156,10 @@ void cfg_flatten(void)
148156 }
149157
150158 /* prepare 'argc' and 'argv', then proceed to 'main' function */
151- elf_offset += 32 ; /* 6 insns for main call + 2 for exit */
159+ if (dynlink )
160+ elf_offset += 12 ;
161+ else
162+ elf_offset += 32 ; /* 6 insns for main call + 2 for exit */
152163
153164 for (func = FUNC_LIST .head ; func ; func = func -> next ) {
154165 /* Skip function declarations without bodies */
@@ -287,7 +298,16 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
287298 return ;
288299 case OP_call :
289300 func = find_func (ph2_ir -> func_name );
290- 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 if (dynlink )
304+ ofs = (elf_plt_start + func -> plt_offset ) -
305+ (elf_code_start + elf_code -> size );
306+ else {
307+ printf ("The '%s' function is not implemented\n" , ph2_ir -> func_name );
308+ abort ();
309+ }
310+ emit (__bl (__AL , ofs ));
291311 return ;
292312 case OP_load_data_address :
293313 emit (__movw (__AL , rd , ph2_ir -> src0 + elf_data_start ));
@@ -299,7 +319,14 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
299319 return ;
300320 case OP_address_of_func :
301321 func = find_func (ph2_ir -> func_name );
302- ofs = elf_code_start + func -> bbs -> elf_offset ;
322+ if (func -> bbs )
323+ ofs = elf_code_start + func -> bbs -> elf_offset ;
324+ else if (dynlink )
325+ ofs = elf_plt_start + func -> plt_offset ;
326+ else {
327+ printf ("The '%s' function is not implemented\n" , ph2_ir -> func_name );
328+ abort ();
329+ }
303330 emit (__movw (__AL , __r8 , ofs ));
304331 emit (__movt (__AL , __r8 , ofs ));
305332 emit (__sw (__AL , __r8 , rn , 0 ));
@@ -456,39 +483,74 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
456483 }
457484}
458485
486+ void plt_generate (void );
459487void code_generate (void )
460488{
461- elf_data_start = elf_code_start + elf_offset ;
462- elf_rodata_start = elf_data_start + elf_data -> size ;
463- elf_bss_start = elf_rodata_start + elf_rodata -> size ;
489+ if (dynlink ) {
490+ plt_generate ();
491+ /* Call __libc_start_main() */
492+ emit (__mov_i (__AL , __r11 , 0 ));
493+ emit (__mov_i (__AL , __lr , 0 ));
494+ emit (__pop_word (__AL , __r1 ));
495+ emit (__mov_r (__AL , __r2 , __sp ));
496+ emit (__push_reg (__AL , __r2 ));
497+ emit (__push_reg (__AL , __r0 ));
498+ emit (__mov_i (__AL , __r12 , 0 ));
499+ emit (__push_reg (__AL , __r12 ));
464500
465- /* start */
501+ int main_wrapper_offset = elf_code -> size + 28 ;
502+ emit (__movw (__AL , __r0 , elf_code_start + main_wrapper_offset ));
503+ emit (__movt (__AL , __r0 , elf_code_start + main_wrapper_offset ));
504+ emit (__mov_i (__AL , __r3 , 0 ));
505+ emit (__bl (__AL , (elf_plt_start + PLT_FIXUP_SIZE ) -
506+ (elf_code_start + elf_code -> size )));
507+ /* Call '_exit' (syscall) to terminate the program if __libc_start_main
508+ * returns. */
509+ emit (__mov_i (__AL , __r0 , 127 ));
510+ emit (__mov_i (__AL , __r7 , 1 ));
511+ emit (__svc ());
512+
513+ /* If the compiled program is dynamic linking, the starting
514+ * point of 'main_wrapper' is located here.
515+ *
516+ * Preserve 'argc' and 'argv' for the 'main' function.
517+ * */
518+ emit (__mov_r (__AL , __r9 , __r0 ));
519+ emit (__mov_r (__AL , __r10 , __r1 ));
520+ }
521+ /* For both static and dynamic linking, we need to set up the stack
522+ * and call the main function.
523+ * */
466524 emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
467525 emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
468526 emit (__sub_r (__AL , __sp , __sp , __r8 ));
469527 emit (__mov_r (__AL , __r12 , __sp ));
470- emit (__bl (__AL , GLOBAL_FUNC -> bbs -> elf_offset - elf_code -> size ));
471- /* After global init, jump to main preparation */
472- emit (__b (__AL , 56 )); /* PC+8: skip exit (24) + syscall (36) + ret (4) - 8 */
473528
474- /* exit */
475- emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
476- emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
477- emit (__add_r (__AL , __sp , __sp , __r8 ));
478- emit (__mov_r (__AL , __r0 , __r0 ));
479- emit (__mov_i (__AL , __r7 , 1 ));
480- emit (__svc ());
481-
482- /* syscall */
483- emit (__mov_r (__AL , __r7 , __r0 ));
484- emit (__mov_r (__AL , __r0 , __r1 ));
485- emit (__mov_r (__AL , __r1 , __r2 ));
486- emit (__mov_r (__AL , __r2 , __r3 ));
487- emit (__mov_r (__AL , __r3 , __r4 ));
488- emit (__mov_r (__AL , __r4 , __r5 ));
489- emit (__mov_r (__AL , __r5 , __r6 ));
490- emit (__svc ());
491- emit (__bx (__AL , __lr ));
529+ if (!dynlink ) {
530+ emit (__bl (__AL , GLOBAL_FUNC -> bbs -> elf_offset - elf_code -> size ));
531+ /* After global init, jump to main preparation */
532+ emit (__b (__AL ,
533+ 56 )); /* PC+8: skip exit (24) + syscall (36) + ret (4) - 8 */
534+
535+ /* exit - only for static linking */
536+ emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
537+ emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
538+ emit (__add_r (__AL , __sp , __sp , __r8 ));
539+ emit (__mov_r (__AL , __r0 , __r0 ));
540+ emit (__mov_i (__AL , __r7 , 1 ));
541+ emit (__svc ());
542+
543+ /* syscall */
544+ emit (__mov_r (__AL , __r7 , __r0 ));
545+ emit (__mov_r (__AL , __r0 , __r1 ));
546+ emit (__mov_r (__AL , __r1 , __r2 ));
547+ emit (__mov_r (__AL , __r2 , __r3 ));
548+ emit (__mov_r (__AL , __r3 , __r4 ));
549+ emit (__mov_r (__AL , __r4 , __r5 ));
550+ emit (__mov_r (__AL , __r5 , __r6 ));
551+ emit (__svc ());
552+ emit (__bx (__AL , __lr ));
553+ }
492554
493555 ph2_ir_t * ph2_ir ;
494556 for (ph2_ir = GLOBAL_FUNC -> bbs -> ph2_ir_list .head ; ph2_ir ;
@@ -497,20 +559,51 @@ void code_generate(void)
497559
498560 /* prepare 'argc' and 'argv', then proceed to 'main' function */
499561 if (MAIN_BB ) {
500- emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
501- emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
502- emit (__add_r (__AL , __r8 , __r12 , __r8 ));
503- emit (__lw (__AL , __r0 , __r8 , 0 ));
504- emit (__add_i (__AL , __r1 , __r8 , 4 ));
505- emit (__bl (__AL , MAIN_BB -> elf_offset - elf_code -> size ));
562+ if (dynlink ) {
563+ emit (__mov_r (__AL , __r0 , __r9 ));
564+ emit (__mov_r (__AL , __r1 , __r10 ));
565+ /* Jump directly to the main function.
566+ *
567+ * When the main function returns, the program
568+ * will return to __libc_start_main. */
569+ emit (__b (__AL , MAIN_BB -> elf_offset - elf_code -> size ));
570+ } else {
571+ emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
572+ emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
573+ emit (__add_r (__AL , __r8 , __r12 , __r8 ));
574+ emit (__lw (__AL , __r0 , __r8 , 0 ));
575+ emit (__add_i (__AL , __r1 , __r8 , 4 ));
506576
507- /* exit with main's return value - r0 already has the return value */
508- emit (__mov_i (__AL , __r7 , 1 ));
509- emit (__svc ());
577+ /* Call main function, and call '_exit' syscall to
578+ * terminate the program. */
579+ emit (__bl (__AL , MAIN_BB -> elf_offset - elf_code -> size ));
580+
581+ /* exit with main's return value - r0 already has the
582+ * return value */
583+ emit (__mov_i (__AL , __r7 , 1 ));
584+ emit (__svc ());
585+ }
510586 }
511587
512588 for (int i = 0 ; i < ph2_ir_idx ; i ++ ) {
513589 ph2_ir = PH2_IR_FLATTEN [i ];
514590 emit_ph2_ir (ph2_ir );
515591 }
516592}
593+
594+ void plt_generate (void )
595+ {
596+ int addr_of_got = elf_got_start + PTR_SIZE * 2 ;
597+ int end = plt_size - PLT_FIXUP_SIZE ;
598+ elf_write_int (elf_plt , __push_reg (__AL , __lr ));
599+ elf_write_int (elf_plt , __movw (__AL , __r10 , addr_of_got ));
600+ elf_write_int (elf_plt , __movt (__AL , __r10 , addr_of_got ));
601+ elf_write_int (elf_plt , __mov_r (__AL , __lr , __r10 ));
602+ elf_write_int (elf_plt , __lw (__AL , __pc , __lr , 0 ));
603+ for (int i = 0 ; i * PLT_ENT_SIZE < end ; i ++ ) {
604+ addr_of_got = elf_got_start + PTR_SIZE * (i + 3 );
605+ elf_write_int (elf_plt , __movw (__AL , __r12 , addr_of_got ));
606+ elf_write_int (elf_plt , __movt (__AL , __r12 , addr_of_got ));
607+ elf_write_int (elf_plt , __lw (__AL , __pc , __r12 , 0 ));
608+ }
609+ }
0 commit comments