@@ -139,10 +139,18 @@ void update_elf_offset(ph2_ir_t *ph2_ir)
139
139
140
140
void cfg_flatten (void )
141
141
{
142
- func_t * func = find_func ("__syscall" );
143
- func -> bbs -> elf_offset = 48 ; /* offset of start + branch + exit in codegen */
142
+ func_t * func ;
143
+
144
+ if (dynlink )
145
+ elf_offset =
146
+ 84 ; /* offset of __libc_start_main + main_wrapper in codegen */
147
+ else {
148
+ func = find_func ("__syscall" );
149
+ func -> bbs -> elf_offset = 48 ; /* offset of start + exit in codegen */
150
+ elf_offset =
151
+ 84 ; /* offset of start + branch + exit + syscall in codegen */
152
+ }
144
153
145
- elf_offset = 84 ; /* offset of start + branch + exit + syscall in codegen */
146
154
GLOBAL_FUNC -> bbs -> elf_offset = elf_offset ;
147
155
148
156
for (ph2_ir_t * ph2_ir = GLOBAL_FUNC -> bbs -> ph2_ir_list .head ; ph2_ir ;
@@ -151,7 +159,10 @@ void cfg_flatten(void)
151
159
}
152
160
153
161
/* prepare 'argc' and 'argv', then proceed to 'main' function */
154
- elf_offset += 32 ; /* 6 insns for main call + 2 for exit */
162
+ if (dynlink )
163
+ elf_offset += 12 ;
164
+ else
165
+ elf_offset += 32 ; /* 6 insns for main call + 2 for exit */
155
166
156
167
for (func = FUNC_LIST .head ; func ; func = func -> next ) {
157
168
/* Skip function declarations without bodies */
@@ -294,7 +305,16 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
294
305
return ;
295
306
case OP_call :
296
307
func = find_func (ph2_ir -> func_name );
297
- emit (__bl (__AL , func -> bbs -> elf_offset - elf_code -> size ));
308
+ if (func -> bbs )
309
+ ofs = func -> bbs -> elf_offset - elf_code -> size ;
310
+ else if (dynlink )
311
+ ofs = (elf_plt_start + func -> plt_offset ) -
312
+ (elf_code_start + elf_code -> size );
313
+ else {
314
+ printf ("The '%s' function is not implemented\n" , ph2_ir -> func_name );
315
+ abort ();
316
+ }
317
+ emit (__bl (__AL , ofs ));
298
318
return ;
299
319
case OP_load_data_address :
300
320
emit (__movw (__AL , rd , ph2_ir -> src0 + elf_data_start ));
@@ -306,7 +326,14 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
306
326
return ;
307
327
case OP_address_of_func :
308
328
func = find_func (ph2_ir -> func_name );
309
- ofs = elf_code_start + func -> bbs -> elf_offset ;
329
+ if (func -> bbs )
330
+ ofs = elf_code_start + func -> bbs -> elf_offset ;
331
+ else if (dynlink )
332
+ ofs = elf_plt_start + func -> plt_offset ;
333
+ else {
334
+ printf ("The '%s' function is not implemented\n" , ph2_ir -> func_name );
335
+ abort ();
336
+ }
310
337
emit (__movw (__AL , __r8 , ofs ));
311
338
emit (__movt (__AL , __r8 , ofs ));
312
339
emit (__sw (__AL , __r8 , rn , 0 ));
@@ -470,39 +497,74 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
470
497
}
471
498
}
472
499
500
+ void plt_generate (void );
473
501
void code_generate (void )
474
502
{
475
- elf_data_start = elf_code_start + elf_offset ;
476
- elf_rodata_start = elf_data_start + elf_data -> size ;
477
- elf_bss_start = elf_rodata_start + elf_rodata -> size ;
503
+ if (dynlink ) {
504
+ plt_generate ();
505
+ /* Call __libc_start_main() */
506
+ emit (__mov_i (__AL , __r11 , 0 ));
507
+ emit (__mov_i (__AL , __lr , 0 ));
508
+ emit (__pop_word (__AL , __r1 ));
509
+ emit (__mov_r (__AL , __r2 , __sp ));
510
+ emit (__push_reg (__AL , __r2 ));
511
+ emit (__push_reg (__AL , __r0 ));
512
+ emit (__mov_i (__AL , __r12 , 0 ));
513
+ emit (__push_reg (__AL , __r12 ));
478
514
479
- /* start */
515
+ int main_wrapper_offset = elf_code -> size + 28 ;
516
+ emit (__movw (__AL , __r0 , elf_code_start + main_wrapper_offset ));
517
+ emit (__movt (__AL , __r0 , elf_code_start + main_wrapper_offset ));
518
+ emit (__mov_i (__AL , __r3 , 0 ));
519
+ emit (__bl (__AL , (elf_plt_start + PLT_FIXUP_SIZE ) -
520
+ (elf_code_start + elf_code -> size )));
521
+ /* Call '_exit' (syscall) to terminate the program if __libc_start_main
522
+ * returns. */
523
+ emit (__mov_i (__AL , __r0 , 127 ));
524
+ emit (__mov_i (__AL , __r7 , 1 ));
525
+ emit (__svc ());
526
+
527
+ /* If the compiled program is dynamic linking, the starting
528
+ * point of 'main_wrapper' is located here.
529
+ *
530
+ * Preserve 'argc' and 'argv' for the 'main' function.
531
+ * */
532
+ emit (__mov_r (__AL , __r9 , __r0 ));
533
+ emit (__mov_r (__AL , __r10 , __r1 ));
534
+ }
535
+ /* For both static and dynamic linking, we need to set up the stack
536
+ * and call the main function.
537
+ * */
480
538
emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
481
539
emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
482
540
emit (__sub_r (__AL , __sp , __sp , __r8 ));
483
541
emit (__mov_r (__AL , __r12 , __sp ));
484
- emit (__bl (__AL , GLOBAL_FUNC -> bbs -> elf_offset - elf_code -> size ));
485
- /* After global init, jump to main preparation */
486
- emit (__b (__AL , 56 )); /* PC+8: skip exit (24) + syscall (36) + ret (4) - 8 */
487
542
488
- /* exit */
489
- emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
490
- emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
491
- emit (__add_r (__AL , __sp , __sp , __r8 ));
492
- emit (__mov_r (__AL , __r0 , __r0 ));
493
- emit (__mov_i (__AL , __r7 , 1 ));
494
- emit (__svc ());
495
-
496
- /* syscall */
497
- emit (__mov_r (__AL , __r7 , __r0 ));
498
- emit (__mov_r (__AL , __r0 , __r1 ));
499
- emit (__mov_r (__AL , __r1 , __r2 ));
500
- emit (__mov_r (__AL , __r2 , __r3 ));
501
- emit (__mov_r (__AL , __r3 , __r4 ));
502
- emit (__mov_r (__AL , __r4 , __r5 ));
503
- emit (__mov_r (__AL , __r5 , __r6 ));
504
- emit (__svc ());
505
- emit (__bx (__AL , __lr ));
543
+ if (!dynlink ) {
544
+ emit (__bl (__AL , GLOBAL_FUNC -> bbs -> elf_offset - elf_code -> size ));
545
+ /* After global init, jump to main preparation */
546
+ emit (__b (__AL ,
547
+ 56 )); /* PC+8: skip exit (24) + syscall (36) + ret (4) - 8 */
548
+
549
+ /* exit - only for static linking */
550
+ emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
551
+ emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
552
+ emit (__add_r (__AL , __sp , __sp , __r8 ));
553
+ emit (__mov_r (__AL , __r0 , __r0 ));
554
+ emit (__mov_i (__AL , __r7 , 1 ));
555
+ emit (__svc ());
556
+
557
+ /* syscall */
558
+ emit (__mov_r (__AL , __r7 , __r0 ));
559
+ emit (__mov_r (__AL , __r0 , __r1 ));
560
+ emit (__mov_r (__AL , __r1 , __r2 ));
561
+ emit (__mov_r (__AL , __r2 , __r3 ));
562
+ emit (__mov_r (__AL , __r3 , __r4 ));
563
+ emit (__mov_r (__AL , __r4 , __r5 ));
564
+ emit (__mov_r (__AL , __r5 , __r6 ));
565
+ emit (__svc ());
566
+ emit (__bx (__AL , __lr ));
567
+ }
506
568
507
569
ph2_ir_t * ph2_ir ;
508
570
for (ph2_ir = GLOBAL_FUNC -> bbs -> ph2_ir_list .head ; ph2_ir ;
@@ -511,20 +573,51 @@ void code_generate(void)
511
573
512
574
/* prepare 'argc' and 'argv', then proceed to 'main' function */
513
575
if (MAIN_BB ) {
514
- emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
515
- emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
516
- emit (__add_r (__AL , __r8 , __r12 , __r8 ));
517
- emit (__lw (__AL , __r0 , __r8 , 0 ));
518
- emit (__add_i (__AL , __r1 , __r8 , 4 ));
519
- emit (__bl (__AL , MAIN_BB -> elf_offset - elf_code -> size ));
576
+ if (dynlink ) {
577
+ emit (__mov_r (__AL , __r0 , __r9 ));
578
+ emit (__mov_r (__AL , __r1 , __r10 ));
579
+ /* Jump directly to the main function.
580
+ *
581
+ * When the main function returns, the program
582
+ * will return to __libc_start_main. */
583
+ emit (__b (__AL , MAIN_BB -> elf_offset - elf_code -> size ));
584
+ } else {
585
+ emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
586
+ emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
587
+ emit (__add_r (__AL , __r8 , __r12 , __r8 ));
588
+ emit (__lw (__AL , __r0 , __r8 , 0 ));
589
+ emit (__add_i (__AL , __r1 , __r8 , 4 ));
520
590
521
- /* exit with main's return value - r0 already has the return value */
522
- emit (__mov_i (__AL , __r7 , 1 ));
523
- emit (__svc ());
591
+ /* Call main function, and call '_exit' syscall to
592
+ * terminate the program. */
593
+ emit (__bl (__AL , MAIN_BB -> elf_offset - elf_code -> size ));
594
+
595
+ /* exit with main's return value - r0 already has the
596
+ * return value */
597
+ emit (__mov_i (__AL , __r7 , 1 ));
598
+ emit (__svc ());
599
+ }
524
600
}
525
601
526
602
for (int i = 0 ; i < ph2_ir_idx ; i ++ ) {
527
603
ph2_ir = PH2_IR_FLATTEN [i ];
528
604
emit_ph2_ir (ph2_ir );
529
605
}
530
606
}
607
+
608
+ void plt_generate (void )
609
+ {
610
+ int addr_of_got = elf_got_start + PTR_SIZE * 2 ;
611
+ int end = plt_size - PLT_FIXUP_SIZE ;
612
+ elf_write_int (elf_plt , __push_reg (__AL , __lr ));
613
+ elf_write_int (elf_plt , __movw (__AL , __r10 , addr_of_got ));
614
+ elf_write_int (elf_plt , __movt (__AL , __r10 , addr_of_got ));
615
+ elf_write_int (elf_plt , __mov_r (__AL , __lr , __r10 ));
616
+ elf_write_int (elf_plt , __lw (__AL , __pc , __lr , 0 ));
617
+ for (int i = 0 ; i * PLT_ENT_SIZE < end ; i ++ ) {
618
+ addr_of_got = elf_got_start + PTR_SIZE * (i + 3 );
619
+ elf_write_int (elf_plt , __movw (__AL , __r12 , addr_of_got ));
620
+ elf_write_int (elf_plt , __movt (__AL , __r12 , addr_of_got ));
621
+ elf_write_int (elf_plt , __lw (__AL , __pc , __r12 , 0 ));
622
+ }
623
+ }
0 commit comments