1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * Copyright (C) 2015 Imagination Technologies
4 * Author: Alex Smith <alex.smith@imgtec.com>
7 static inline bool FUNC(patch_vdso
)(const char *path
, void *vdso
)
9 const ELF(Ehdr
) *ehdr
= vdso
;
12 char *shstrtab
, *name
;
13 uint16_t sh_count
, sh_entsize
, i
;
15 shdrs
= vdso
+ FUNC(swap_uint
)(ehdr
->e_shoff
);
16 sh_count
= swap_uint16(ehdr
->e_shnum
);
17 sh_entsize
= swap_uint16(ehdr
->e_shentsize
);
19 shdr
= shdrs
+ (sh_entsize
* swap_uint16(ehdr
->e_shstrndx
));
20 shstrtab
= vdso
+ FUNC(swap_uint
)(shdr
->sh_offset
);
22 for (i
= 0; i
< sh_count
; i
++) {
23 shdr
= shdrs
+ (i
* sh_entsize
);
24 name
= shstrtab
+ swap_uint32(shdr
->sh_name
);
27 * Ensure there are no relocation sections - ld.so does not
28 * relocate the VDSO so if there are relocations things will
31 switch (swap_uint32(shdr
->sh_type
)) {
35 "%s: '%s' contains relocation sections\n",
40 /* Check for existing sections. */
41 if (strcmp(name
, ".MIPS.abiflags") == 0) {
43 "%s: '%s' already contains a '.MIPS.abiflags' section\n",
48 if (strcmp(name
, ".mips_abiflags") == 0) {
49 strcpy(name
, ".MIPS.abiflags");
50 shdr
->sh_type
= swap_uint32(SHT_MIPS_ABIFLAGS
);
51 shdr
->sh_entsize
= shdr
->sh_size
;
58 static inline bool FUNC(get_symbols
)(const char *path
, void *vdso
)
60 const ELF(Ehdr
) *ehdr
= vdso
;
65 uint16_t sh_count
, sh_entsize
, st_count
, st_entsize
, i
, j
;
69 shdrs
= vdso
+ FUNC(swap_uint
)(ehdr
->e_shoff
);
70 sh_count
= swap_uint16(ehdr
->e_shnum
);
71 sh_entsize
= swap_uint16(ehdr
->e_shentsize
);
73 for (i
= 0; i
< sh_count
; i
++) {
74 shdr
= shdrs
+ (i
* sh_entsize
);
76 if (swap_uint32(shdr
->sh_type
) == SHT_SYMTAB
)
81 fprintf(stderr
, "%s: '%s' has no symbol table\n", program_name
,
87 flags
= swap_uint32(ehdr
->e_flags
);
88 if (elf_class
== ELFCLASS64
)
90 else if (flags
& EF_MIPS_ABI2
)
95 /* Get symbol table. */
96 symtab
= vdso
+ FUNC(swap_uint
)(shdr
->sh_offset
);
97 st_entsize
= FUNC(swap_uint
)(shdr
->sh_entsize
);
98 st_count
= FUNC(swap_uint
)(shdr
->sh_size
) / st_entsize
;
100 /* Get string table. */
101 shdr
= shdrs
+ (swap_uint32(shdr
->sh_link
) * sh_entsize
);
102 strtab
= vdso
+ FUNC(swap_uint
)(shdr
->sh_offset
);
104 /* Write offsets for symbols needed by the kernel. */
105 for (i
= 0; vdso_symbols
[i
].name
; i
++) {
106 if (!(vdso_symbols
[i
].abis
& elf_abi
))
109 for (j
= 0; j
< st_count
; j
++) {
110 sym
= symtab
+ (j
* st_entsize
);
111 name
= strtab
+ swap_uint32(sym
->st_name
);
113 if (!strcmp(name
, vdso_symbols
[i
].name
)) {
114 offset
= FUNC(swap_uint
)(sym
->st_value
);
117 "\t.%s = 0x%" PRIx64
",\n",
118 vdso_symbols
[i
].offset_name
, offset
);
125 "%s: '%s' is missing required symbol '%s'\n",
126 program_name
, path
, vdso_symbols
[i
].name
);