@@ -55,11 +55,13 @@ forge ElfFormat {
5555 const R_X86_64_GOTPCREL: UInt32 = 9;
5656 const R_X86_64_32: UInt32 = 10;
5757 const R_X86_64_32S: UInt32 = 11;
58+ const R_X86_64_PC64: UInt32 = 24;
5859 const R_X86_64_GOTPCRELX: UInt32 = 41;
5960 const R_X86_64_REX_GOTPCRELX: UInt32 = 42;
6061 const R_AARCH64_NONE: UInt32 = 0;
6162 const R_AARCH64_ABS64: UInt32 = 257;
6263 const R_AARCH64_ABS32: UInt32 = 258;
64+ const R_AARCH64_PREL64: UInt32 = 260;
6365 const R_AARCH64_PREL32: UInt32 = 261;
6466
6567 const ELF64_HEADER_SIZE: UInt32 = 64;
@@ -206,7 +208,10 @@ forge ElfFormat {
206208 if reloc_type == R_X86_64_GOTPCREL {
207209 return 0;
208210 } else {
209- if reloc_type == R_X86_64_GOTPCRELX {
211+ if reloc_type == R_X86_64_PC64 {
212+ return 0;
213+ } else {
214+ if reloc_type == R_X86_64_GOTPCRELX {
210215 return 0;
211216 } else {
212217 if reloc_type == R_X86_64_REX_GOTPCRELX {
@@ -215,6 +220,7 @@ forge ElfFormat {
215220 return 6;
216221 }
217222 }
223+ }
218224 }
219225 }
220226 }
@@ -441,11 +447,7 @@ forge ElfFormat {
441447 if offset >= section_size {
442448 return 6;
443449 } else {
444- if addend > 9223372036854775807 {
445- return 6;
446- } else {
447- return 0;
448- }
450+ return 0;
449451 }
450452 }
451453 }
@@ -461,11 +463,15 @@ forge ElfFormat {
461463 if reloc_type == R_AARCH64_ABS32 {
462464 return 0;
463465 } else {
464- if reloc_type == R_AARCH64_PREL32 {
466+ if reloc_type == R_AARCH64_PREL64 {
467+ return 0;
468+ } else {
469+ if reloc_type == R_AARCH64_PREL32 {
465470 return 0;
466471 } else {
467472 return 6;
468473 }
474+ }
469475 }
470476 }
471477 }
@@ -566,6 +572,73 @@ forge ElfFormat {
566572 return r_info - (sym * 4294967296);
567573 }
568574
575+ proc K::implicit_rel_addend_width(reloc_type: UInt32, machine: UInt16) -> UInt32 {
576+ if machine == EM_X86_64 {
577+ if reloc_type == R_X86_64_64 {
578+ return 8;
579+ } else {
580+ if reloc_type == R_X86_64_GLOB_DAT {
581+ return 8;
582+ } else {
583+ if reloc_type == R_X86_64_JUMP_SLOT {
584+ return 8;
585+ } else {
586+ if reloc_type == R_X86_64_RELATIVE {
587+ return 8;
588+ } else {
589+ if reloc_type == R_X86_64_PC64 {
590+ return 8;
591+ } else {
592+ return 4;
593+ }
594+ }
595+ }
596+ }
597+ }
598+ }
599+ if machine == EM_AARCH64 {
600+ if reloc_type == R_AARCH64_ABS64 {
601+ return 8;
602+ } else {
603+ if reloc_type == R_AARCH64_PREL64 {
604+ return 8;
605+ } else {
606+ return 4;
607+ }
608+ }
609+ }
610+ return 4;
611+ }
612+
613+ proc K::read_implicit_rel_addend(
614+ path: UInt64,
615+ machine: UInt16,
616+ target_section_type: UInt32,
617+ target_section_off: UInt64,
618+ target_section_size: UInt64,
619+ reloc_offset: UInt64,
620+ reloc_type: UInt32
621+ ) -> UInt64 {
622+ if target_section_type == SHT_NOBITS {
623+ return 0;
624+ } else {
625+ let width = implicit_rel_addend_width(reloc_type, machine);
626+ if width == 8 {
627+ if reloc_offset + 8 > target_section_size {
628+ return 0;
629+ } else {
630+ return read_u64_file(path, target_section_off + reloc_offset);
631+ }
632+ } else {
633+ if reloc_offset + 4 > target_section_size {
634+ return 0;
635+ } else {
636+ return read_u32_file(path, target_section_off + reloc_offset);
637+ }
638+ }
639+ }
640+ }
641+
569642 proc K::ingest_symbol_records(
570643 path: UInt64,
571644 sym_off: UInt64,
@@ -681,6 +754,77 @@ forge ElfFormat {
681754 }
682755 }
683756
757+ proc K::ingest_relocation_records_rel(
758+ path: UInt64,
759+ machine: UInt16,
760+ reloc_off: UInt64,
761+ reloc_entsize: UInt64,
762+ reloc_count: UInt32,
763+ index: UInt32,
764+ target_section: UInt32,
765+ target_section_size: UInt64,
766+ target_section_type: UInt32,
767+ target_section_off: UInt64,
768+ symbol_count: UInt32
769+ ) -> UInt32 {
770+ if index >= reloc_count {
771+ return 0;
772+ } else {
773+ let rec_off = reloc_off + (index * reloc_entsize);
774+ let r_offset = read_u64_file(path, rec_off + 0);
775+ let r_info = read_u64_file(path, rec_off + 8);
776+ let sym_index = decode_r_info_sym(r_info);
777+ let reloc_type = decode_r_info_type(r_info);
778+ let r_addend = read_implicit_rel_addend(
779+ path,
780+ machine,
781+ target_section_type,
782+ target_section_off,
783+ target_section_size,
784+ r_offset,
785+ reloc_type
786+ );
787+
788+ let validate_status = parse_relocation_record_fields(
789+ r_offset,
790+ reloc_type,
791+ machine,
792+ sym_index,
793+ r_addend,
794+ target_section_size,
795+ symbol_count
796+ );
797+ if validate_status ! 0 {
798+ return validate_status;
799+ } else {
800+ let register_status = host_linker_object_add_relocation(
801+ target_section,
802+ r_offset,
803+ reloc_type,
804+ sym_index,
805+ r_addend
806+ );
807+ if register_status ! 0 {
808+ return register_status;
809+ } else {
810+ return ingest_relocation_records_rel(
811+ path,
812+ machine,
813+ reloc_off,
814+ reloc_entsize,
815+ reloc_count,
816+ index + 1,
817+ target_section,
818+ target_section_size,
819+ target_section_type,
820+ target_section_off,
821+ symbol_count
822+ );
823+ }
824+ }
825+ }
826+ }
827+
684828 proc K::ingest_section_records(
685829 path: UInt64,
686830 machine: UInt16,
@@ -767,9 +911,11 @@ forge ElfFormat {
767911 let symbol_table_size_rel = section_size(path, shoff, shentsize, sec_link);
768912 let symbol_table_entsize_rel = section_entsize(path, shoff, shentsize, sec_link);
769913 let symbol_count_rel = symbol_record_count(symbol_table_size_rel, symbol_table_entsize_rel);
914+ let target_type_rel = section_type(path, shoff, shentsize, sec_info);
915+ let target_off_rel = section_offset(path, shoff, shentsize, sec_info);
770916 let target_size_rel = section_size(path, shoff, shentsize, sec_info);
771917 let reloc_count_rel = symbol_record_count(sec_size, sec_entsize);
772- let reloc_status_rel = ingest_relocation_records (
918+ let reloc_status_rel = ingest_relocation_records_rel (
773919 path,
774920 machine,
775921 sec_offset,
@@ -778,6 +924,8 @@ forge ElfFormat {
778924 0,
779925 sec_info,
780926 target_size_rel,
927+ target_type_rel,
928+ target_off_rel,
781929 symbol_count_rel
782930 );
783931 if reloc_status_rel ! 0 {
0 commit comments