// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright ( C ) 2023 - Google LLC
* Author : Ard Biesheuvel < ardb @ google . com >
*/
#include <elf.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define HOST_ORDER ELFDATA2LSB
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define HOST_ORDER ELFDATA2MSB
#endif
static Elf64_Ehdr *ehdr;
static Elf64_Shdr *shdr;
static const char *strtab;
static bool swap;
static uint64_t swab_elfxword(uint64_t val)
{
return swap ? __builtin_bswap64(val) : val;
}
static uint32_t swab_elfword(uint32_t val)
{
return swap ? __builtin_bswap32(val) : val;
}
static uint16_t swab_elfhword(uint16_t val)
{
return swap ? __builtin_bswap16(val) : val;
}
int main(int argc, char *argv[])
{
struct stat stat;
int fd, ret;
if (argc < 3 ) {
fprintf(stderr, "file arguments missing\n" );
exit (EXIT_FAILURE);
}
fd = open(argv[1 ], O_RDWR);
if (fd < 0 ) {
fprintf(stderr, "failed to open %s\n" , argv[1 ]);
exit (EXIT_FAILURE);
}
ret = fstat(fd, &stat);
if (ret < 0 ) {
fprintf(stderr, "failed to stat() %s\n" , argv[1 ]);
exit (EXIT_FAILURE);
}
ehdr = mmap(0 , stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
if (ehdr == MAP_FAILED) {
fprintf(stderr, "failed to mmap() %s\n" , argv[1 ]);
exit (EXIT_FAILURE);
}
swap = ehdr->e_ident[EI_DATA] != HOST_ORDER;
shdr = (void *)ehdr + swab_elfxword(ehdr->e_shoff);
strtab = (void *)ehdr +
swab_elfxword(shdr[swab_elfhword(ehdr->e_shstrndx)].sh_offset);
for (int i = 0 ; i < swab_elfhword(ehdr->e_shnum); i++) {
unsigned long info, flags;
bool prel64 = false ;
Elf64_Rela *rela;
int numrela;
if (swab_elfword(shdr[i].sh_type) != SHT_RELA)
continue ;
/* only consider RELA sections operating on data */
info = swab_elfword(shdr[i].sh_info);
flags = swab_elfxword(shdr[info].sh_flags);
if ((flags & (SHF_ALLOC | SHF_EXECINSTR)) != SHF_ALLOC)
continue ;
/*
* We generally don ' t permit ABS64 relocations in the code that
* runs before relocation processing occurs . If statically
* initialized absolute symbol references are unavoidable , they
* may be emitted into a * . rodata . prel64 section and they will
* be converted to place - relative 64 - bit references . This
* requires special handling in the referring code .
*/
if (strstr(strtab + swab_elfword(shdr[info].sh_name),
".rodata.prel64" )) {
prel64 = true ;
}
rela = (void *)ehdr + swab_elfxword(shdr[i].sh_offset);
numrela = swab_elfxword(shdr[i].sh_size) / sizeof (*rela);
for (int j = 0 ; j < numrela; j++) {
uint64_t info = swab_elfxword(rela[j].r_info);
if (ELF64_R_TYPE(info) != R_AARCH64_ABS64)
continue ;
if (prel64) {
/* convert ABS64 into PREL64 */
info ^= R_AARCH64_ABS64 ^ R_AARCH64_PREL64;
rela[j].r_info = swab_elfxword(info);
} else {
fprintf(stderr,
"Unexpected absolute relocations detected in %s\n" ,
argv[2 ]);
close(fd);
unlink(argv[1 ]);
exit (EXIT_FAILURE);
}
}
}
close(fd);
return 0 ;
}
Messung V0.5 in Prozent C=97 H=93 G=94
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland