@@ -136,10 +136,17 @@ void update_elf_offset(ph2_ir_t *ph2_ir)
136
136
137
137
void cfg_flatten (void )
138
138
{
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 = 88 ; /* offset of start + branch + exit 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
+ }
141
149
142
- elf_offset = 84 ; /* offset of start + branch + exit + syscall in codegen */
143
150
GLOBAL_FUNC -> bbs -> elf_offset = elf_offset ;
144
151
145
152
for (ph2_ir_t * ph2_ir = GLOBAL_FUNC -> bbs -> ph2_ir_list .head ; ph2_ir ;
@@ -148,7 +155,10 @@ void cfg_flatten(void)
148
155
}
149
156
150
157
/* 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 */
152
162
153
163
for (func = FUNC_LIST .head ; func ; func = func -> next ) {
154
164
/* Skip function declarations without bodies */
@@ -287,7 +297,12 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
287
297
return ;
288
298
case OP_call :
289
299
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 ));
291
306
return ;
292
307
case OP_load_data_address :
293
308
emit (__movw (__AL , rd , ph2_ir -> src0 + elf_data_start ));
@@ -299,7 +314,10 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
299
314
return ;
300
315
case OP_address_of_func :
301
316
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 ;
303
321
emit (__movw (__AL , __r8 , ofs ));
304
322
emit (__movt (__AL , __r8 , ofs ));
305
323
emit (__sw (__AL , __r8 , rn , 0 ));
@@ -456,13 +474,42 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
456
474
}
457
475
}
458
476
477
+ void plt_generate (void );
459
478
void code_generate (void )
460
479
{
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 ));
464
501
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
+ * */
466
513
emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
467
514
emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
468
515
emit (__sub_r (__AL , __sp , __sp , __r8 ));
@@ -471,24 +518,26 @@ void code_generate(void)
471
518
/* After global init, jump to main preparation */
472
519
emit (__b (__AL , 56 )); /* PC+8: skip exit (24) + syscall (36) + ret (4) - 8 */
473
520
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 ());
521
+ if (!dynlink ) {
522
+ /* exit - only for static linking */
523
+ emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
524
+ emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
525
+ emit (__add_r (__AL , __sp , __sp , __r8 ));
526
+ emit (__mov_r (__AL , __r0 , __r0 ));
527
+ emit (__mov_i (__AL , __r7 , 1 ));
528
+ emit (__svc ());
481
529
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 ));
530
+ /* syscall */
531
+ emit (__mov_r (__AL , __r7 , __r0 ));
532
+ emit (__mov_r (__AL , __r0 , __r1 ));
533
+ emit (__mov_r (__AL , __r1 , __r2 ));
534
+ emit (__mov_r (__AL , __r2 , __r3 ));
535
+ emit (__mov_r (__AL , __r3 , __r4 ));
536
+ emit (__mov_r (__AL , __r4 , __r5 ));
537
+ emit (__mov_r (__AL , __r5 , __r6 ));
538
+ emit (__svc ());
539
+ emit (__bx (__AL , __lr ));
540
+ }
492
541
493
542
ph2_ir_t * ph2_ir ;
494
543
for (ph2_ir = GLOBAL_FUNC -> bbs -> ph2_ir_list .head ; ph2_ir ;
@@ -497,11 +546,16 @@ void code_generate(void)
497
546
498
547
/* prepare 'argc' and 'argv', then proceed to 'main' function */
499
548
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 ));
549
+ if (dynlink ) {
550
+ emit (__mov_r (__AL , __r0 , __r9 ));
551
+ emit (__mov_r (__AL , __r1 , __r10 ));
552
+ } else {
553
+ emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
554
+ emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
555
+ emit (__add_r (__AL , __r8 , __r12 , __r8 ));
556
+ emit (__lw (__AL , __r0 , __r8 , 0 ));
557
+ emit (__add_i (__AL , __r1 , __r8 , 4 ));
558
+ }
505
559
emit (__bl (__AL , MAIN_BB -> elf_offset - elf_code -> size ));
506
560
507
561
/* exit with main's return value - r0 already has the return value */
@@ -514,3 +568,20 @@ void code_generate(void)
514
568
emit_ph2_ir (ph2_ir );
515
569
}
516
570
}
571
+
572
+ void plt_generate (void )
573
+ {
574
+ int addr_of_got = elf_got_start + PTR_SIZE * 2 ;
575
+ int end = plt_size - PLT_FIXUP_SIZE ;
576
+ elf_write_int (elf_plt , __push_reg (__AL , __lr ));
577
+ elf_write_int (elf_plt , __movw (__AL , __r10 , addr_of_got ));
578
+ elf_write_int (elf_plt , __movt (__AL , __r10 , addr_of_got ));
579
+ elf_write_int (elf_plt , __mov_r (__AL , __lr , __r10 ));
580
+ elf_write_int (elf_plt , __lw (__AL , __pc , __lr , 0 ));
581
+ for (int i = 0 ; i * PLT_ENT_SIZE < end ; i ++ ) {
582
+ addr_of_got = elf_got_start + PTR_SIZE * (i + 3 );
583
+ elf_write_int (elf_plt , __movw (__AL , __r12 , addr_of_got ));
584
+ elf_write_int (elf_plt , __movt (__AL , __r12 , addr_of_got ));
585
+ elf_write_int (elf_plt , __lw (__AL , __pc , __r12 , 0 ));
586
+ }
587
+ }
0 commit comments