summaryrefslogtreecommitdiff
path: root/arch/x86/vdso/vdso2c.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/vdso/vdso2c.h')
-rw-r--r--arch/x86/vdso/vdso2c.h23
1 files changed, 18 insertions, 5 deletions
diff --git a/arch/x86/vdso/vdso2c.h b/arch/x86/vdso/vdso2c.h
index d9f6f61aef1c..c6eefaf389b9 100644
--- a/arch/x86/vdso/vdso2c.h
+++ b/arch/x86/vdso/vdso2c.h
@@ -18,6 +18,8 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
const char *secstrings;
uint64_t syms[NSYMS] = {};
+ uint64_t fake_sections_value = 0, fake_sections_size = 0;
+
Elf_Phdr *pt = (Elf_Phdr *)(addr + GET_LE(&hdr->e_phoff));
/* Walk the segment table. */
@@ -84,6 +86,7 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
GET_LE(&symtab_hdr->sh_entsize) * i;
const char *name = addr + GET_LE(&strtab_hdr->sh_offset) +
GET_LE(&sym->st_name);
+
for (k = 0; k < NSYMS; k++) {
if (!strcmp(name, required_syms[k])) {
if (syms[k]) {
@@ -93,6 +96,13 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
syms[k] = GET_LE(&sym->st_value);
}
}
+
+ if (!strcmp(name, "vdso_fake_sections")) {
+ if (fake_sections_value)
+ fail("duplicate vdso_fake_sections\n");
+ fake_sections_value = GET_LE(&sym->st_value);
+ fake_sections_size = GET_LE(&sym->st_size);
+ }
}
/* Validate mapping addresses. */
@@ -112,11 +122,14 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
if (syms[sym_end_mapping] % 4096)
fail("end_mapping must be a multiple of 4096\n");
- /* Remove sections. */
- hdr->e_shoff = 0;
- hdr->e_shentsize = 0;
- hdr->e_shnum = 0;
- hdr->e_shstrndx = SHN_UNDEF; /* SHN_UNDEF == 0 */
+ /* Remove sections or use fakes */
+ if (fake_sections_size % sizeof(Elf_Shdr))
+ fail("vdso_fake_sections size is not a multiple of %ld\n",
+ (long)sizeof(Elf_Shdr));
+ PUT_LE(&hdr->e_shoff, fake_sections_value);
+ PUT_LE(&hdr->e_shentsize, fake_sections_value ? sizeof(Elf_Shdr) : 0);
+ PUT_LE(&hdr->e_shnum, fake_sections_size / sizeof(Elf_Shdr));
+ PUT_LE(&hdr->e_shstrndx, SHN_UNDEF);
if (!name) {
fwrite(addr, load_size, 1, outfile);