Skip to content

Commit ccf2cda

Browse files
committed
Refactor
1 parent 8f27689 commit ccf2cda

File tree

1 file changed

+53
-49
lines changed

1 file changed

+53
-49
lines changed

macho/arch-arm64.cc

Lines changed: 53 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -469,25 +469,9 @@ void RangeExtensionThunk<E>::copy_buf(Context<E> &ctx) {
469469
#define ASSERT_RANGE(val, start, size) \
470470
assert((start) <= (val) && (val) < ((start) + (size)))
471471

472-
static void relax_adrp_ldr_got_ldr(Context<E> &ctx, ObjectFile<E> *file,
473-
std::string_view &hints) {
474-
i64 addr1 = read_uleb(hints);
475-
i64 addr2 = read_uleb(hints);
476-
i64 addr3 = read_uleb(hints);
477-
478-
Subsection<E> *subsec = file->find_subsection(ctx, addr1);
479-
if (!subsec || !subsec->is_alive)
480-
return;
481-
482-
ASSERT_RANGE(addr1, subsec->input_addr, subsec->input_size);
483-
ASSERT_RANGE(addr2, subsec->input_addr, subsec->input_size);
484-
ASSERT_RANGE(addr3, subsec->input_addr, subsec->input_size);
485-
486-
i64 offset1 = addr1 - subsec->input_addr;
487-
i64 offset2 = addr2 - subsec->input_addr;
488-
i64 offset3 = addr3 - subsec->input_addr;
489-
490-
u8 *loc = ctx.buf + subsec->isec.osec.hdr.offset + subsec->output_offset;
472+
static void relax_adrp_ldr_got_ldr(Context<E> &ctx, Subsection<E> &subsec,
473+
i64 offset1, i64 offset2, i64 offset3) {
474+
u8 *loc = ctx.buf + subsec.isec.osec.hdr.offset + subsec.output_offset;
491475
ul32 *loc1 = (ul32 *)(loc + offset1);
492476
ul32 *loc2 = (ul32 *)(loc + offset2);
493477
ul32 *loc3 = (ul32 *)(loc + offset3);
@@ -501,9 +485,9 @@ static void relax_adrp_ldr_got_ldr(Context<E> &ctx, ObjectFile<E> *file,
501485
(*loc2 & 0xffc0'0000) != 0xf940'0000)
502486
return;
503487

504-
u64 got_addr = page(subsec->get_addr(ctx) + offset1) +
505-
(bits(*loc1, 23, 5) << 14) + (bits(*loc1, 30, 29) << 12) +
506-
(bits(*loc2, 21, 10) << 3);
488+
u64 got_addr = page(subsec.get_addr(ctx) + offset1) +
489+
(bits(*loc1, 23, 5) << 14) + (bits(*loc1, 30, 29) << 12) +
490+
(bits(*loc2, 21, 10) << 3);
507491

508492
ASSERT_RANGE(got_addr, ctx.got.hdr.addr, ctx.got.hdr.size);
509493

@@ -516,7 +500,7 @@ static void relax_adrp_ldr_got_ldr(Context<E> &ctx, ObjectFile<E> *file,
516500
switch (*loc3 & 0xffc0'0000) {
517501
case 0xf940'0000: { // ldr Xc, [Xb, #imm]
518502
u64 imm = bits(*loc3, 21, 10) * 8;
519-
i64 disp = got_value + imm - subsec->get_addr(ctx) - offset3;
503+
i64 disp = got_value + imm - subsec.get_addr(ctx) - offset3;
520504
if (disp == sign_extend(disp, 20) && (disp & 0b11) == 0) {
521505
*loc1 = 0xd503'201f; // nop
522506
*loc2 = 0xd503'201f; // nop
@@ -527,7 +511,7 @@ static void relax_adrp_ldr_got_ldr(Context<E> &ctx, ObjectFile<E> *file,
527511
}
528512
case 0xb940'0000: { // ldr Wc, [Xb, #imm]
529513
u64 imm = bits(*loc3, 21, 10) * 4;
530-
i64 disp = got_value + imm - subsec->get_addr(ctx) - offset3;
514+
i64 disp = got_value + imm - subsec.get_addr(ctx) - offset3;
531515
if (disp == sign_extend(disp, 20) && (disp & 0b11) == 0) {
532516
*loc1 = 0xd503'201f; // nop
533517
*loc2 = 0xd503'201f; // nop
@@ -540,30 +524,17 @@ static void relax_adrp_ldr_got_ldr(Context<E> &ctx, ObjectFile<E> *file,
540524
}
541525

542526
// If the GOT slot is close enough to PC, we can eliminate ADRP.
543-
if (i64 disp = got_addr - subsec->get_addr(ctx) - offset2;
527+
if (i64 disp = got_addr - subsec.get_addr(ctx) - offset2;
544528
disp == sign_extend(disp, 20) && (disp & 0b11) == 0) {
545529
*loc1 = 0xd503'201f; // nop
546530
*loc2 = 0x5800'0000 | (bits(disp, 20, 2) << 5) |
547531
bits(*loc2, 4, 0); // ldr Xb, _foo@GOT
548532
}
549533
}
550534

551-
static void relax_adrp_add(Context<E> &ctx, ObjectFile<E> *file,
552-
std::string_view &hints) {
553-
i64 addr1 = read_uleb(hints);
554-
i64 addr2 = read_uleb(hints);
555-
556-
Subsection<E> *subsec = file->find_subsection(ctx, addr1);
557-
if (!subsec || !subsec->is_alive)
558-
return;
559-
560-
ASSERT_RANGE(addr1, subsec->input_addr, subsec->input_size);
561-
ASSERT_RANGE(addr2, subsec->input_addr, subsec->input_size);
562-
563-
i64 offset1 = addr1 - subsec->input_addr;
564-
i64 offset2 = addr2 - subsec->input_addr;
565-
566-
u8 *loc = ctx.buf + subsec->isec.osec.hdr.offset + subsec->output_offset;
535+
static void relax_adrp_add(Context<E> &ctx, Subsection<E> &subsec,
536+
i64 offset1, i64 offset2) {
537+
u8 *loc = ctx.buf + subsec.isec.osec.hdr.offset + subsec.output_offset;
567538
ul32 *loc1 = (ul32 *)(loc + offset1);
568539
ul32 *loc2 = (ul32 *)(loc + offset2);
569540

@@ -575,10 +546,10 @@ static void relax_adrp_add(Context<E> &ctx, ObjectFile<E> *file,
575546
(*loc2 & 0xffc0'0000) != 0x9100'0000)
576547
return;
577548

578-
u64 addr = page(subsec->get_addr(ctx) + offset1) +
579-
(bits(*loc1, 23, 5) << 14) + (bits(*loc1, 30, 29) << 12) +
580-
bits(*loc2, 21, 10);
581-
i64 disp = addr - subsec->get_addr(ctx) - offset2;
549+
u64 addr = page(subsec.get_addr(ctx) + offset1) +
550+
(bits(*loc1, 23, 5) << 14) + (bits(*loc1, 30, 29) << 12) +
551+
bits(*loc2, 21, 10);
552+
i64 disp = addr - subsec.get_addr(ctx) - offset2;
582553

583554
if (disp == sign_extend(disp, 20)) {
584555
*loc1 = 0xd503'201f; // nop
@@ -618,12 +589,45 @@ void apply_linker_optimization_hints(Context<E> &ctx) {
618589
i64 nargs = read_uleb(hints);
619590

620591
switch (type) {
621-
case LOH_ARM64_ADRP_LDR_GOT_LDR:
622-
relax_adrp_ldr_got_ldr(ctx, file, hints);
592+
case LOH_ARM64_ADRP_LDR_GOT_LDR: {
593+
assert(nargs == 3);
594+
i64 addr1 = read_uleb(hints);
595+
i64 addr2 = read_uleb(hints);
596+
i64 addr3 = read_uleb(hints);
597+
598+
Subsection<E> *subsec = file->find_subsection(ctx, addr1);
599+
if (!subsec || !subsec->is_alive)
600+
return;
601+
602+
ASSERT_RANGE(addr1, subsec->input_addr, subsec->input_size);
603+
ASSERT_RANGE(addr2, subsec->input_addr, subsec->input_size);
604+
ASSERT_RANGE(addr3, subsec->input_addr, subsec->input_size);
605+
606+
i64 offset1 = addr1 - subsec->input_addr;
607+
i64 offset2 = addr2 - subsec->input_addr;
608+
i64 offset3 = addr3 - subsec->input_addr;
609+
610+
relax_adrp_ldr_got_ldr(ctx, *subsec, offset1, offset2, offset3);
623611
break;
624-
case LOH_ARM64_ADRP_ADD:
625-
relax_adrp_add(ctx, file, hints);
612+
}
613+
case LOH_ARM64_ADRP_ADD: {
614+
assert(nargs == 2);
615+
i64 addr1 = read_uleb(hints);
616+
i64 addr2 = read_uleb(hints);
617+
618+
Subsection<E> *subsec = file->find_subsection(ctx, addr1);
619+
if (!subsec || !subsec->is_alive)
620+
return;
621+
622+
ASSERT_RANGE(addr1, subsec->input_addr, subsec->input_size);
623+
ASSERT_RANGE(addr2, subsec->input_addr, subsec->input_size);
624+
625+
i64 offset1 = addr1 - subsec->input_addr;
626+
i64 offset2 = addr2 - subsec->input_addr;
627+
628+
relax_adrp_add(ctx, *subsec, offset1, offset2);
626629
break;
630+
}
627631
default:
628632
// Skip unsupported optimizations hints.
629633
for (i64 i = 0; i < nargs; i++)

0 commit comments

Comments
 (0)