@@ -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 += 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 */
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 ;
@@ -282,15 +294,23 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
282
294
return ;
283
295
case OP_call :
284
296
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 ));
286
303
return ;
287
304
case OP_load_data_address :
288
305
emit (__movw (__AL , rd , ph2_ir -> src0 + elf_data_start ));
289
306
emit (__movt (__AL , rd , ph2_ir -> src0 + elf_data_start ));
290
307
return ;
291
308
case OP_address_of_func :
292
309
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 ;
294
314
emit (__movw (__AL , __r8 , ofs ));
295
315
emit (__movt (__AL , __r8 , ofs ));
296
316
emit (__sw (__AL , __r8 , rn , 0 ));
@@ -447,11 +467,40 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
447
467
}
448
468
}
449
469
470
+ void plt_generate (void );
450
471
void code_generate (void )
451
472
{
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 ));
453
492
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
+ * */
455
504
emit (__movw (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
456
505
emit (__movt (__AL , __r8 , GLOBAL_FUNC -> stack_size ));
457
506
emit (__sub_r (__AL , __sp , __sp , __r8 ));
@@ -466,28 +515,35 @@ void code_generate(void)
466
515
emit (__mov_i (__AL , __r7 , 1 ));
467
516
emit (__svc ());
468
517
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
+ }
479
530
480
531
ph2_ir_t * ph2_ir ;
481
532
for (ph2_ir = GLOBAL_FUNC -> bbs -> ph2_ir_list .head ; ph2_ir ;
482
533
ph2_ir = ph2_ir -> next )
483
534
emit_ph2_ir (ph2_ir );
484
535
485
536
/* 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
+ }
491
547
emit (__bl (__AL , MAIN_BB -> elf_offset - elf_code -> size ));
492
548
493
549
/* exit with main's return value */
@@ -499,3 +555,20 @@ void code_generate(void)
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