1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2023 - Google LLC
4 * Author: Ard Biesheuvel <ardb@google.com>
15 #include <sys/types.h>
18 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
19 #define HOST_ORDER ELFDATA2LSB
20 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
21 #define HOST_ORDER ELFDATA2MSB
24 static Elf64_Ehdr
*ehdr
;
25 static Elf64_Shdr
*shdr
;
26 static const char *strtab
;
29 static uint64_t swab_elfxword(uint64_t val
)
31 return swap
? __builtin_bswap64(val
) : val
;
34 static uint32_t swab_elfword(uint32_t val
)
36 return swap
? __builtin_bswap32(val
) : val
;
39 static uint16_t swab_elfhword(uint16_t val
)
41 return swap
? __builtin_bswap16(val
) : val
;
44 int main(int argc
, char *argv
[])
50 fprintf(stderr
, "file arguments missing\n");
54 fd
= open(argv
[1], O_RDWR
);
56 fprintf(stderr
, "failed to open %s\n", argv
[1]);
60 ret
= fstat(fd
, &stat
);
62 fprintf(stderr
, "failed to stat() %s\n", argv
[1]);
66 ehdr
= mmap(0, stat
.st_size
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
, 0);
67 if (ehdr
== MAP_FAILED
) {
68 fprintf(stderr
, "failed to mmap() %s\n", argv
[1]);
72 swap
= ehdr
->e_ident
[EI_DATA
] != HOST_ORDER
;
73 shdr
= (void *)ehdr
+ swab_elfxword(ehdr
->e_shoff
);
74 strtab
= (void *)ehdr
+
75 swab_elfxword(shdr
[swab_elfhword(ehdr
->e_shstrndx
)].sh_offset
);
77 for (int i
= 0; i
< swab_elfhword(ehdr
->e_shnum
); i
++) {
78 unsigned long info
, flags
;
83 if (swab_elfword(shdr
[i
].sh_type
) != SHT_RELA
)
86 /* only consider RELA sections operating on data */
87 info
= swab_elfword(shdr
[i
].sh_info
);
88 flags
= swab_elfxword(shdr
[info
].sh_flags
);
89 if ((flags
& (SHF_ALLOC
| SHF_EXECINSTR
)) != SHF_ALLOC
)
93 * We generally don't permit ABS64 relocations in the code that
94 * runs before relocation processing occurs. If statically
95 * initialized absolute symbol references are unavoidable, they
96 * may be emitted into a *.rodata.prel64 section and they will
97 * be converted to place-relative 64-bit references. This
98 * requires special handling in the referring code.
100 if (strstr(strtab
+ swab_elfword(shdr
[info
].sh_name
),
105 rela
= (void *)ehdr
+ swab_elfxword(shdr
[i
].sh_offset
);
106 numrela
= swab_elfxword(shdr
[i
].sh_size
) / sizeof(*rela
);
108 for (int j
= 0; j
< numrela
; j
++) {
109 uint64_t info
= swab_elfxword(rela
[j
].r_info
);
111 if (ELF64_R_TYPE(info
) != R_AARCH64_ABS64
)
115 /* convert ABS64 into PREL64 */
116 info
^= R_AARCH64_ABS64
^ R_AARCH64_PREL64
;
117 rela
[j
].r_info
= swab_elfxword(info
);
120 "Unexpected absolute relocations detected in %s\n",