@@ -135,10 +135,16 @@ void update_elf_offset(ph2_ir_t *ph2_ir)
135
135
136
136
void cfg_flatten (void )
137
137
{
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
+ }
140
147
141
- elf_offset = 80 ; /* offset of start + exit + syscall in codegen */
142
148
GLOBAL_FUNC -> bbs -> elf_offset = elf_offset ;
143
149
144
150
for (ph2_ir_t * ph2_ir = GLOBAL_FUNC -> bbs -> ph2_ir_list .head ; ph2_ir ;
@@ -147,9 +153,15 @@ void cfg_flatten(void)
147
153
}
148
154
149
155
/* 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 ;
151
160
152
161
for (func = FUNC_LIST .head ; func ; func = func -> next ) {
162
+ if (!func -> bbs )
163
+ continue ;
164
+
153
165
/* reserve stack */
154
166
ph2_ir_t * flatten_ir = add_ph2_ir (OP_define );
155
167
flatten_ir -> src0 = func -> stack_size ;
@@ -286,15 +298,23 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
286
298
return ;
287
299
case OP_call :
288
300
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 ));
290
307
return ;
291
308
case OP_load_data_address :
292
309
emit (__movw (__AL , rd , ph2_ir -> src0 + elf_data_start ));
293
310
emit (__movt (__AL , rd , ph2_ir -> src0 + elf_data_start ));
294
311
return ;
295
312
case OP_address_of_func :
296
313
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 ;
298
318
emit (__movw (__AL , __r8 , ofs ));
299
319
emit (__movt (__AL , __r8 , ofs ));
300
320
emit (__sw (__AL , __r8 , rn , 0 ));
@@ -451,11 +471,40 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
451
471
}
452
472
}
453
473
474
+ void plt_generate (void );
454
475
void code_generate (void )
455
476
{
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 ));
457
496
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
+ * */
459
508
emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
460
509
emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
461
510
emit (__sub_r (__AL , __sp , __sp , __r8 ));
@@ -470,32 +519,56 @@ void code_generate(void)
470
519
emit (__mov_i (__AL , __r7 , 1 ));
471
520
emit (__svc ());
472
521
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
+ }
483
534
484
535
ph2_ir_t * ph2_ir ;
485
536
for (ph2_ir = GLOBAL_FUNC -> bbs -> ph2_ir_list .head ; ph2_ir ;
486
537
ph2_ir = ph2_ir -> next )
487
538
emit_ph2_ir (ph2_ir );
488
539
489
540
/* 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
+ }
495
551
emit (__b (__AL , MAIN_BB -> elf_offset - elf_code -> size ));
496
552
497
553
for (int i = 0 ; i < ph2_ir_idx ; i ++ ) {
498
554
ph2_ir = PH2_IR_FLATTEN [i ];
499
555
emit_ph2_ir (ph2_ir );
500
556
}
501
557
}
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