2 * Copyright (C) 2015 Imagination Technologies
3 * Author: Alex Smith <alex.smith@imgtec.com>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
11 static inline bool FUNC(patch_vdso
)(const char *path
, void *vdso
)
13 const ELF(Ehdr
) *ehdr
= vdso
;
16 char *shstrtab
, *name
;
17 uint16_t sh_count
, sh_entsize
, i
;
19 shdrs
= vdso
+ FUNC(swap_uint
)(ehdr
->e_shoff
);
20 sh_count
= swap_uint16(ehdr
->e_shnum
);
21 sh_entsize
= swap_uint16(ehdr
->e_shentsize
);
23 shdr
= shdrs
+ (sh_entsize
* swap_uint16(ehdr
->e_shstrndx
));
24 shstrtab
= vdso
+ FUNC(swap_uint
)(shdr
->sh_offset
);
26 for (i
= 0; i
< sh_count
; i
++) {
27 shdr
= shdrs
+ (i
* sh_entsize
);
28 name
= shstrtab
+ swap_uint32(shdr
->sh_name
);
31 * Ensure there are no relocation sections - ld.so does not
32 * relocate the VDSO so if there are relocations things will
35 switch (swap_uint32(shdr
->sh_type
)) {
39 "%s: '%s' contains relocation sections\n",
44 /* Check for existing sections. */
45 if (strcmp(name
, ".MIPS.abiflags") == 0) {
47 "%s: '%s' already contains a '.MIPS.abiflags' section\n",
52 if (strcmp(name
, ".mips_abiflags") == 0) {
53 strcpy(name
, ".MIPS.abiflags");
54 shdr
->sh_type
= swap_uint32(SHT_MIPS_ABIFLAGS
);
55 shdr
->sh_entsize
= shdr
->sh_size
;
62 static inline bool FUNC(get_symbols
)(const char *path
, void *vdso
)
64 const ELF(Ehdr
) *ehdr
= vdso
;
69 uint16_t sh_count
, sh_entsize
, st_count
, st_entsize
, i
, j
;
73 shdrs
= vdso
+ FUNC(swap_uint
)(ehdr
->e_shoff
);
74 sh_count
= swap_uint16(ehdr
->e_shnum
);
75 sh_entsize
= swap_uint16(ehdr
->e_shentsize
);
77 for (i
= 0; i
< sh_count
; i
++) {
78 shdr
= shdrs
+ (i
* sh_entsize
);
80 if (swap_uint32(shdr
->sh_type
) == SHT_SYMTAB
)
85 fprintf(stderr
, "%s: '%s' has no symbol table\n", program_name
,
91 flags
= swap_uint32(ehdr
->e_flags
);
92 if (elf_class
== ELFCLASS64
)
94 else if (flags
& EF_MIPS_ABI2
)
99 /* Get symbol table. */
100 symtab
= vdso
+ FUNC(swap_uint
)(shdr
->sh_offset
);
101 st_entsize
= FUNC(swap_uint
)(shdr
->sh_entsize
);
102 st_count
= FUNC(swap_uint
)(shdr
->sh_size
) / st_entsize
;
104 /* Get string table. */
105 shdr
= shdrs
+ (swap_uint32(shdr
->sh_link
) * sh_entsize
);
106 strtab
= vdso
+ FUNC(swap_uint
)(shdr
->sh_offset
);
108 /* Write offsets for symbols needed by the kernel. */
109 for (i
= 0; vdso_symbols
[i
].name
; i
++) {
110 if (!(vdso_symbols
[i
].abis
& elf_abi
))
113 for (j
= 0; j
< st_count
; j
++) {
114 sym
= symtab
+ (j
* st_entsize
);
115 name
= strtab
+ swap_uint32(sym
->st_name
);
117 if (!strcmp(name
, vdso_symbols
[i
].name
)) {
118 offset
= FUNC(swap_uint
)(sym
->st_value
);
121 "\t.%s = 0x%" PRIx64
",\n",
122 vdso_symbols
[i
].offset_name
, offset
);
129 "%s: '%s' is missing required symbol '%s'\n",
130 program_name
, path
, vdso_symbols
[i
].name
);