@@ -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