phonet: fix building with clang
[GitHub/exynos8895/android_kernel_samsung_universal8895.git] / scripts / kaslr_fips.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <elf.h>
4
5 typedef unsigned long long uint64;
6
7 //SHIFT must be 16KB / 2MB align according to KALSR config
8
9 #define SHIFT(idx) ((uint64)(idx) * 0x4000)
10
11 #ifndef R_AARCH64_RELATIVE
12 #define R_AARCH64_RELATIVE 1027
13 #endif
14 #ifndef R_AARCH64_ABS64
15 #define R_AARCH64_ABS64 257
16 #endif
17
18 /*
19 * The rela section uses the VA
20 * the VA to file offset is:
21 */
22 uint64 va_to_file;
23 int patch_rela(char *, uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64);
24 int main(int argc, char *argv[]){
25 uint64 rs_offset = 0, re_offset = 0, ds_offset = 0;
26 int index;
27 char *file = NULL;
28 int ret;
29 if (argc != 11)
30 {
31 printf ("\nUsage : \n");
32 printf ("kaslr_fips vmlinux_file reloc_start_addr reloc_end_addr dynsym_addr index first_crypto_rodata last_crypto_rodata first_fmp_rodata last_fmp_rodata");
33 printf ("\n");
34 return -1;
35 }
36
37 file = argv[1];
38 rs_offset = atol(argv[2]);
39 re_offset = atol(argv[3]);
40 ds_offset = atol(argv[4]);
41 index = atoi(argv[5]);
42 va_to_file = atol(argv[10]);
43
44 if( !file || !rs_offset || !re_offset || !ds_offset )
45 {
46 printf ("kaslr_fips vmlinux_file reloc_start_addr reloc_end_addr dynsym_add\n");
47 printf ("kaslr_fips index %d\n", index);
48 return -1;
49 }
50
51 // printf("----- start patching %s with reloc_s %llx reloc_e %llx dynsym_s %llx index %d----\n", file, rs_offset, re_offset, ds_offset, index);
52 ret = patch_rela(file, rs_offset, re_offset, ds_offset, SHIFT(index), atol(argv[6]), atol(argv[7]), atol(argv[8]), atol(argv[9]));
53 if(ret) return ret;
54 // printf("----- end patching %s -----\n", file);
55 return 0;
56 }
57
58 /*
59 * rela_start: relocation section start in the vmlinux
60 * rela_end
61 * dynsym_start
62 */
63
64 int patch_rela(char *file, uint64 rela_start, uint64 rela_end, uint64 dynsym_start, uint64 offset, uint64 first_crypto_rodata, uint64 last_crypto_rodata, uint64 first_fmp_rodata, uint64 last_fmp_rodata){
65 uint64 rs_offset = rela_start - va_to_file;
66 uint64 re_offset = rela_end - va_to_file;
67 uint64 ds_offset = dynsym_start - va_to_file;
68
69 FILE *fp = NULL;
70
71 fp = fopen(file, "r+");
72 if (NULL == fp){
73 printf ("Unable to open file : %s", file);
74 return -1;
75 }
76
77 Elf64_Rela rela_entry;
78 Elf64_Sym sym_entry;
79 uint64 addr = 0, value = 0;
80 size_t read_size = 0;
81 for (; rs_offset < re_offset; rs_offset += sizeof(Elf64_Rela)){
82 //seek and read the rela entry
83 if(0 != fseek(fp, rs_offset, SEEK_SET)){
84 fclose(fp);
85 return -1;
86 }
87
88 read_size = fread((void*) &rela_entry, sizeof(rela_entry), 1, fp);
89 if(0 == read_size) continue;
90 /*printf("%llx, %llx\n", ELF64_R_TYPE(rela_entry.r_info), R_AARCH64_RELATIVE);*/
91 addr = rela_entry.r_offset;
92 if (0x0 == addr) continue;
93
94 if ( !((addr >= first_crypto_rodata && addr <= last_crypto_rodata) ||
95 (addr >= first_fmp_rodata && addr <= last_fmp_rodata)))
96 continue;
97
98 if (ELF64_R_TYPE(rela_entry.r_info) == R_AARCH64_RELATIVE) {
99 value = offset + rela_entry.r_addend;
100
101 } else if(ELF64_R_TYPE(rela_entry.r_info) == R_AARCH64_ABS64) {
102 uint64 sym_index = ELF64_R_SYM(rela_entry.r_info);
103 uint64 sym_offset = ds_offset + sym_index * (sizeof(Elf64_Sym));
104
105 //seek to the start of the symbol table entry
106 if (0 !=fseek(fp, sym_offset, SEEK_SET)){
107 fclose(fp);
108 return -1;
109 }
110 read_size = fread((void*) &sym_entry, sizeof(sym_entry), 1, fp);
111 if(0 == read_size) continue;
112
113 value = sym_entry.st_value + rela_entry.r_addend + offset;
114 } else {
115 // printf("Try to patch none supported type %llx\n", (uint64)ELF64_R_TYPE(rela_entry.r_info));
116 }
117 /*printf("%llx, %llx, %llx, %llx, %llx\n", (uint64) rela_entry.r_offset, */
118 /*(uint64)rela_entry.r_info, */
119 /*(uint64)rela_entry.r_addend, */
120 /*addr - VA_TO_FILE, value);*/
121 if (0 != fseek(fp, addr - va_to_file, SEEK_SET)){
122 fclose(fp);
123 return -1;
124 }
125
126 if (fwrite((const void *) &value, sizeof(uint64), 1, fp) != 1){
127 fclose(fp);
128 return -1;
129 }
130 }
131
132 fclose(fp);
133 return 0;
134 }
135