@@ -136,10 +136,17 @@ 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 = 80 ; /* offset of __libc_start_main + start in codegen */
143+ else {
144+ func = find_func ("__syscall" );
145+ func -> bbs -> elf_offset = 48 ; /* offset of start + exit in codegen */
146+ elf_offset =
147+ 84 ; /* offset of start + branch + exit + syscall in codegen */
148+ }
141149
142- elf_offset = 84 ; /* offset of start + branch + exit + syscall in codegen */
143150 GLOBAL_FUNC -> bbs -> elf_offset = elf_offset ;
144151
145152 for (ph2_ir_t * ph2_ir = GLOBAL_FUNC -> bbs -> ph2_ir_list .head ; ph2_ir ;
@@ -148,7 +155,10 @@ void cfg_flatten(void)
148155 }
149156
150157 /* prepare 'argc' and 'argv', then proceed to 'main' function */
151- elf_offset += 32 ; /* 6 insns for main call + 2 for exit */
158+ if (dynlink )
159+ elf_offset += 20 ;
160+ else
161+ elf_offset += 32 ; /* 6 insns for main call + 2 for exit */
152162
153163 for (func = FUNC_LIST .head ; func ; func = func -> next ) {
154164 /* Skip function declarations without bodies */
@@ -287,7 +297,12 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
287297 return ;
288298 case OP_call :
289299 func = find_func (ph2_ir -> func_name );
290- emit (__bl (__AL , func -> bbs -> elf_offset - elf_code -> size ));
300+ if (func -> bbs )
301+ ofs = func -> bbs -> elf_offset - elf_code -> size ;
302+ else
303+ ofs = (elf_plt_start + func -> plt_offset ) -
304+ (elf_code_start + elf_code -> size );
305+ emit (__bl (__AL , ofs ));
291306 return ;
292307 case OP_load_data_address :
293308 emit (__movw (__AL , rd , ph2_ir -> src0 + elf_data_start ));
@@ -299,7 +314,10 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
299314 return ;
300315 case OP_address_of_func :
301316 func = find_func (ph2_ir -> func_name );
302- ofs = elf_code_start + func -> bbs -> elf_offset ;
317+ if (func -> bbs )
318+ ofs = elf_code_start + func -> bbs -> elf_offset ;
319+ else
320+ ofs = elf_plt_start + func -> plt_offset ;
303321 emit (__movw (__AL , __r8 , ofs ));
304322 emit (__movt (__AL , __r8 , ofs ));
305323 emit (__sw (__AL , __r8 , rn , 0 ));
@@ -456,39 +474,72 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
456474 }
457475}
458476
477+ void plt_generate (void );
459478void code_generate (void )
460479{
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 ;
480+ if (dynlink ) {
481+ plt_generate ();
482+ /* Call __libc_start_main() */
483+ emit (__mov_i (__AL , __r11 , 0 ));
484+ emit (__mov_i (__AL , __lr , 0 ));
485+ emit (__pop_word (__AL , __r1 ));
486+ emit (__mov_r (__AL , __r2 , __sp ));
487+ emit (__push_reg (__AL , __r2 ));
488+ emit (__push_reg (__AL , __r0 ));
489+ emit (__mov_i (__AL , __r12 , 0 ));
490+ emit (__push_reg (__AL , __r12 ));
491+
492+ int main_wrapper_offset = elf_code -> size + 24 ;
493+ emit (__movw (__AL , __r0 , elf_code_start + main_wrapper_offset ));
494+ emit (__movt (__AL , __r0 , elf_code_start + main_wrapper_offset ));
495+ emit (__mov_i (__AL , __r3 , 0 ));
496+ emit (__bl (__AL , (elf_plt_start + PLT_FIXUP_SIZE ) -
497+ (elf_code_start + elf_code -> size )));
498+ /* Goto the 'exit' code snippet if __libc_start_main returns */
499+ emit (__mov_i (__AL , __r0 , 127 ));
500+ emit (__bl (__AL , 28 ));
464501
465- /* start */
502+ /* If the compiled program is dynamic linking, the starting
503+ * point of 'start' is located here.
504+ *
505+ * Preserve 'argc' and 'argv' for the 'main' function.
506+ * */
507+ emit (__mov_r (__AL , __r9 , __r0 ));
508+ emit (__mov_r (__AL , __r10 , __r1 ));
509+ }
510+ /* For both static and dynamic linking, we need to set up the stack
511+ * and call the main function.
512+ * */
466513 emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
467514 emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
468515 emit (__sub_r (__AL , __sp , __sp , __r8 ));
469516 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 */
473517
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 ));
518+ if (!dynlink ) {
519+ emit (__bl (__AL , GLOBAL_FUNC -> bbs -> elf_offset - elf_code -> size ));
520+ /* After global init, jump to main preparation */
521+ emit (__b (__AL ,
522+ 56 )); /* PC+8: skip exit (24) + syscall (36) + ret (4) - 8 */
523+
524+ /* exit - only for static linking */
525+ emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
526+ emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
527+ emit (__add_r (__AL , __sp , __sp , __r8 ));
528+ emit (__mov_r (__AL , __r0 , __r0 ));
529+ emit (__mov_i (__AL , __r7 , 1 ));
530+ emit (__svc ());
531+
532+ /* syscall */
533+ emit (__mov_r (__AL , __r7 , __r0 ));
534+ emit (__mov_r (__AL , __r0 , __r1 ));
535+ emit (__mov_r (__AL , __r1 , __r2 ));
536+ emit (__mov_r (__AL , __r2 , __r3 ));
537+ emit (__mov_r (__AL , __r3 , __r4 ));
538+ emit (__mov_r (__AL , __r4 , __r5 ));
539+ emit (__mov_r (__AL , __r5 , __r6 ));
540+ emit (__svc ());
541+ emit (__bx (__AL , __lr ));
542+ }
492543
493544 ph2_ir_t * ph2_ir ;
494545 for (ph2_ir = GLOBAL_FUNC -> bbs -> ph2_ir_list .head ; ph2_ir ;
@@ -497,11 +548,16 @@ void code_generate(void)
497548
498549 /* prepare 'argc' and 'argv', then proceed to 'main' function */
499550 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 ));
551+ if (dynlink ) {
552+ emit (__mov_r (__AL , __r0 , __r9 ));
553+ emit (__mov_r (__AL , __r1 , __r10 ));
554+ } else {
555+ emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
556+ emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
557+ emit (__add_r (__AL , __r8 , __r12 , __r8 ));
558+ emit (__lw (__AL , __r0 , __r8 , 0 ));
559+ emit (__add_i (__AL , __r1 , __r8 , 4 ));
560+ }
505561 emit (__bl (__AL , MAIN_BB -> elf_offset - elf_code -> size ));
506562
507563 /* exit with main's return value - r0 already has the return value */
@@ -514,3 +570,20 @@ void code_generate(void)
514570 emit_ph2_ir (ph2_ir );
515571 }
516572}
573+
574+ void plt_generate (void )
575+ {
576+ int addr_of_got = elf_got_start + PTR_SIZE * 2 ;
577+ int end = plt_size - PLT_FIXUP_SIZE ;
578+ elf_write_int (elf_plt , __push_reg (__AL , __lr ));
579+ elf_write_int (elf_plt , __movw (__AL , __r10 , addr_of_got ));
580+ elf_write_int (elf_plt , __movt (__AL , __r10 , addr_of_got ));
581+ elf_write_int (elf_plt , __mov_r (__AL , __lr , __r10 ));
582+ elf_write_int (elf_plt , __lw (__AL , __pc , __lr , 0 ));
583+ for (int i = 0 ; i * PLT_ENT_SIZE < end ; i ++ ) {
584+ addr_of_got = elf_got_start + PTR_SIZE * (i + 3 );
585+ elf_write_int (elf_plt , __movw (__AL , __r12 , addr_of_got ));
586+ elf_write_int (elf_plt , __movt (__AL , __r12 , addr_of_got ));
587+ elf_write_int (elf_plt , __lw (__AL , __pc , __r12 , 0 ));
588+ }
589+ }
0 commit comments