~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/sparc/vdso/vdso2c.h

Version: ~ [ linux-5.11-rc3 ] ~ [ linux-5.10.7 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.89 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.167 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.215 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.251 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.251 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
  3  */
  4 
  5 /*
  6  * This file is included up to twice from vdso2c.c.  It generates code for
  7  * 32-bit and 64-bit vDSOs.  We will eventually need both for 64-bit builds,
  8  * since 32-bit vDSOs will then be built for 32-bit userspace.
  9  */
 10 
 11 static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
 12                          void *stripped_addr, size_t stripped_len,
 13                          FILE *outfile, const char *name)
 14 {
 15         int found_load = 0;
 16         unsigned long load_size = -1;  /* Work around bogus warning */
 17         unsigned long mapping_size;
 18         int i;
 19         unsigned long j;
 20         ELF(Shdr) *symtab_hdr = NULL, *strtab_hdr;
 21         ELF(Ehdr) *hdr = (ELF(Ehdr) *)raw_addr;
 22         ELF(Dyn) *dyn = 0, *dyn_end = 0;
 23         INT_BITS syms[NSYMS] = {};
 24 
 25         ELF(Phdr) *pt = (ELF(Phdr) *)(raw_addr + GET_BE(&hdr->e_phoff));
 26 
 27         /* Walk the segment table. */
 28         for (i = 0; i < GET_BE(&hdr->e_phnum); i++) {
 29                 if (GET_BE(&pt[i].p_type) == PT_LOAD) {
 30                         if (found_load)
 31                                 fail("multiple PT_LOAD segs\n");
 32 
 33                         if (GET_BE(&pt[i].p_offset) != 0 ||
 34                             GET_BE(&pt[i].p_vaddr) != 0)
 35                                 fail("PT_LOAD in wrong place\n");
 36 
 37                         if (GET_BE(&pt[i].p_memsz) != GET_BE(&pt[i].p_filesz))
 38                                 fail("cannot handle memsz != filesz\n");
 39 
 40                         load_size = GET_BE(&pt[i].p_memsz);
 41                         found_load = 1;
 42                 } else if (GET_BE(&pt[i].p_type) == PT_DYNAMIC) {
 43                         dyn = raw_addr + GET_BE(&pt[i].p_offset);
 44                         dyn_end = raw_addr + GET_BE(&pt[i].p_offset) +
 45                                 GET_BE(&pt[i].p_memsz);
 46                 }
 47         }
 48         if (!found_load)
 49                 fail("no PT_LOAD seg\n");
 50 
 51         if (stripped_len < load_size)
 52                 fail("stripped input is too short\n");
 53 
 54         /* Walk the dynamic table */
 55         for (i = 0; dyn + i < dyn_end &&
 56                      GET_BE(&dyn[i].d_tag) != DT_NULL; i++) {
 57                 typeof(dyn[i].d_tag) tag = GET_BE(&dyn[i].d_tag);
 58                 typeof(dyn[i].d_un.d_val) val = GET_BE(&dyn[i].d_un.d_val);
 59 
 60                 if ((tag == DT_RELSZ || tag == DT_RELASZ) && (val != 0))
 61                         fail("vdso image contains dynamic relocations\n");
 62         }
 63 
 64         /* Walk the section table */
 65         for (i = 0; i < GET_BE(&hdr->e_shnum); i++) {
 66                 ELF(Shdr) *sh = raw_addr + GET_BE(&hdr->e_shoff) +
 67                         GET_BE(&hdr->e_shentsize) * i;
 68                 if (GET_BE(&sh->sh_type) == SHT_SYMTAB)
 69                         symtab_hdr = sh;
 70         }
 71 
 72         if (!symtab_hdr)
 73                 fail("no symbol table\n");
 74 
 75         strtab_hdr = raw_addr + GET_BE(&hdr->e_shoff) +
 76                 GET_BE(&hdr->e_shentsize) * GET_BE(&symtab_hdr->sh_link);
 77 
 78         /* Walk the symbol table */
 79         for (i = 0;
 80              i < GET_BE(&symtab_hdr->sh_size) / GET_BE(&symtab_hdr->sh_entsize);
 81              i++) {
 82                 int k;
 83 
 84                 ELF(Sym) *sym = raw_addr + GET_BE(&symtab_hdr->sh_offset) +
 85                         GET_BE(&symtab_hdr->sh_entsize) * i;
 86                 const char *name = raw_addr + GET_BE(&strtab_hdr->sh_offset) +
 87                         GET_BE(&sym->st_name);
 88 
 89                 for (k = 0; k < NSYMS; k++) {
 90                         if (!strcmp(name, required_syms[k].name)) {
 91                                 if (syms[k]) {
 92                                         fail("duplicate symbol %s\n",
 93                                              required_syms[k].name);
 94                                 }
 95 
 96                                 /*
 97                                  * Careful: we use negative addresses, but
 98                                  * st_value is unsigned, so we rely
 99                                  * on syms[k] being a signed type of the
100                                  * correct width.
101                                  */
102                                 syms[k] = GET_BE(&sym->st_value);
103                         }
104                 }
105         }
106 
107         /* Validate mapping addresses. */
108         if (syms[sym_vvar_start] % 8192)
109                 fail("vvar_begin must be a multiple of 8192\n");
110 
111         if (!name) {
112                 fwrite(stripped_addr, stripped_len, 1, outfile);
113                 return;
114         }
115 
116         mapping_size = (stripped_len + 8191) / 8192 * 8192;
117 
118         fprintf(outfile, "/* AUTOMATICALLY GENERATED -- DO NOT EDIT */\n\n");
119         fprintf(outfile, "#include <linux/cache.h>\n");
120         fprintf(outfile, "#include <asm/vdso.h>\n");
121         fprintf(outfile, "\n");
122         fprintf(outfile,
123                 "static unsigned char raw_data[%lu] __ro_after_init __aligned(8192)= {",
124                 mapping_size);
125         for (j = 0; j < stripped_len; j++) {
126                 if (j % 10 == 0)
127                         fprintf(outfile, "\n\t");
128                 fprintf(outfile, "0x%02X, ",
129                         (int)((unsigned char *)stripped_addr)[j]);
130         }
131         fprintf(outfile, "\n};\n\n");
132 
133         fprintf(outfile, "const struct vdso_image %s_builtin = {\n", name);
134         fprintf(outfile, "\t.data = raw_data,\n");
135         fprintf(outfile, "\t.size = %lu,\n", mapping_size);
136         for (i = 0; i < NSYMS; i++) {
137                 if (required_syms[i].export && syms[i])
138                         fprintf(outfile, "\t.sym_%s = %" PRIi64 ",\n",
139                                 required_syms[i].name, (int64_t)syms[i]);
140         }
141         fprintf(outfile, "};\n");
142 }
143 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp