@@ -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 += 32 ; /* 6 insns for main call + 2 for exit */
156+ if (dynlink )
157+ elf_offset += 20 ;
158+ else
159+ elf_offset += 32 ; /* 6 insns for main call + 2 for exit */
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 ;
@@ -282,15 +294,23 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
282294 return ;
283295 case OP_call :
284296 func = find_func (ph2_ir -> func_name );
285- emit (__bl (__AL , func -> bbs -> elf_offset - elf_code -> size ));
297+ if (func -> bbs )
298+ ofs = func -> bbs -> elf_offset - elf_code -> size ;
299+ else
300+ ofs = (elf_plt_start + func -> plt_offset ) -
301+ (elf_code_start + elf_code -> size );
302+ emit (__bl (__AL , ofs ));
286303 return ;
287304 case OP_load_data_address :
288305 emit (__movw (__AL , rd , ph2_ir -> src0 + elf_data_start ));
289306 emit (__movt (__AL , rd , ph2_ir -> src0 + elf_data_start ));
290307 return ;
291308 case OP_address_of_func :
292309 func = find_func (ph2_ir -> func_name );
293- ofs = elf_code_start + func -> bbs -> elf_offset ;
310+ if (func -> bbs )
311+ ofs = elf_code_start + func -> bbs -> elf_offset ;
312+ else
313+ ofs = elf_plt_start + func -> plt_offset ;
294314 emit (__movw (__AL , __r8 , ofs ));
295315 emit (__movt (__AL , __r8 , ofs ));
296316 emit (__sw (__AL , __r8 , rn , 0 ));
@@ -447,11 +467,40 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
447467 }
448468}
449469
470+ void plt_generate (void );
450471void code_generate (void )
451472{
452- elf_data_start = elf_code_start + elf_offset ;
473+ if (dynlink ) {
474+ plt_generate ();
475+ /* Call __libc_start_main() */
476+ emit (__mov_i (__AL , __r11 , 0 ));
477+ emit (__mov_i (__AL , __lr , 0 ));
478+ emit (__pop_word (__AL , __r1 ));
479+ emit (__mov_r (__AL , __r2 , __sp ));
480+ emit (__push_reg (__AL , __r2 ));
481+ emit (__push_reg (__AL , __r0 ));
482+ emit (__mov_i (__AL , __r12 , 0 ));
483+ emit (__push_reg (__AL , __r12 ));
484+ emit (__movw (__AL , __r0 , elf_code_start + 56 ));
485+ emit (__movt (__AL , __r0 , elf_code_start + 56 ));
486+ emit (__mov_i (__AL , __r3 , 0 ));
487+ emit (__bl (__AL , (elf_plt_start + PLT_FIXUP_SIZE ) -
488+ (elf_code_start + elf_code -> size )));
489+ /* Goto the 'exit' code snippet if __libc_start_main returns */
490+ emit (__mov_i (__AL , __r0 , 127 ));
491+ emit (__bl (__AL , 28 ));
453492
454- /* start */
493+ /* If the compiled program is dynamic linking, the starting
494+ * point of 'start' is located here.
495+ *
496+ * Preserve the 'argc' and 'argv' for the 'main' function.
497+ * */
498+ emit (__mov_r (__AL , __r9 , __r0 ));
499+ emit (__mov_r (__AL , __r10 , __r1 ));
500+ }
501+ /* If the compiled program is static linking, the starting point
502+ * of 'start' is here.
503+ * */
455504 emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
456505 emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
457506 emit (__sub_r (__AL , __sp , __sp , __r8 ));
@@ -466,28 +515,35 @@ void code_generate(void)
466515 emit (__mov_i (__AL , __r7 , 1 ));
467516 emit (__svc ());
468517
469- /* syscall */
470- emit (__mov_r (__AL , __r7 , __r0 ));
471- emit (__mov_r (__AL , __r0 , __r1 ));
472- emit (__mov_r (__AL , __r1 , __r2 ));
473- emit (__mov_r (__AL , __r2 , __r3 ));
474- emit (__mov_r (__AL , __r3 , __r4 ));
475- emit (__mov_r (__AL , __r4 , __r5 ));
476- emit (__mov_r (__AL , __r5 , __r6 ));
477- emit (__svc ());
478- emit (__mov_r (__AL , __pc , __lr ));
518+ if (!dynlink ) {
519+ /* syscall */
520+ emit (__mov_r (__AL , __r7 , __r0 ));
521+ emit (__mov_r (__AL , __r0 , __r1 ));
522+ emit (__mov_r (__AL , __r1 , __r2 ));
523+ emit (__mov_r (__AL , __r2 , __r3 ));
524+ emit (__mov_r (__AL , __r3 , __r4 ));
525+ emit (__mov_r (__AL , __r4 , __r5 ));
526+ emit (__mov_r (__AL , __r5 , __r6 ));
527+ emit (__svc ());
528+ emit (__mov_r (__AL , __pc , __lr ));
529+ }
479530
480531 ph2_ir_t * ph2_ir ;
481532 for (ph2_ir = GLOBAL_FUNC -> bbs -> ph2_ir_list .head ; ph2_ir ;
482533 ph2_ir = ph2_ir -> next )
483534 emit_ph2_ir (ph2_ir );
484535
485536 /* prepare 'argc' and 'argv', then proceed to 'main' function */
486- emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
487- emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
488- emit (__add_r (__AL , __r8 , __r12 , __r8 ));
489- emit (__lw (__AL , __r0 , __r8 , 0 ));
490- emit (__add_i (__AL , __r1 , __r8 , 4 ));
537+ if (dynlink ) {
538+ emit (__mov_r (__AL , __r0 , __r9 ));
539+ emit (__mov_r (__AL , __r1 , __r10 ));
540+ } else {
541+ emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
542+ emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
543+ emit (__add_r (__AL , __r8 , __r12 , __r8 ));
544+ emit (__lw (__AL , __r0 , __r8 , 0 ));
545+ emit (__add_i (__AL , __r1 , __r8 , 4 ));
546+ }
491547 emit (__bl (__AL , MAIN_BB -> elf_offset - elf_code -> size ));
492548
493549 /* exit with main's return value */
@@ -499,3 +555,20 @@ void code_generate(void)
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