2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * cfgexport - load/configure the EXPORT kernel extension
15 #include <sys/types.h>
16 #include <sys/device.h>
17 #include <sys/sysconfig.h>
19 #include <sys/xcoff.h>
26 extern char *malloc(), *optarg;
28 extern int sysconfig(int cmd, void *arg, int len);
33 #include "AFS_component_version_number.c"
37 register add, del, opts;
41 struct cfg_load cload;
48 * The following signal action for AIX is necessary so that in case of a
49 * crash (i.e. core is generated) we can include the user's data section
50 * in the core dump. Unfortunately, by default, only a partial core is
51 * generated which, in many cases, isn't too useful.
55 sigemptyset(&nsa.sa_mask);
56 nsa.sa_handler = SIG_DFL;
57 nsa.sa_flags = SA_FULLDUMP;
58 sigaction(SIGSEGV, &nsa, NULL);
62 while ((c = getopt(argc, argv, "a:s:Z:d:")) != EOF) {
64 case 'Z': /* Zdebug option */
100 buf[1] = "cfgexport";
101 get_syms(&conf, syms);
104 if (sysconfig(SYS_KLOAD, &cload, sizeof(cload)) == -1) {
105 loadquery(L_GETMESSAGES, &buf[2], sizeof buf - 8);
106 execvp("/etc/execerror", buf);
111 cmod.kmid = cload.kmid;
113 cmod.mdiptr = (caddr_t) &conf;
114 cmod.mdilen = sizeof (conf);
116 if (sysconfig(SYS_CFGKMOD, &cmod, sizeof(cmod)) == -1) {
117 perror("SYS_CFGKMOD");
118 cload.kmid = cload.kmid;
119 sysconfig(SYS_KULOAD, &cload, sizeof(cload));
123 printf("cfgexport -d 0x%x # to remove EXPORT\n", cload.kmid);
125 strcpy(PidFile, file);
126 strcat(PidFile, ".kmid");
127 fp = fopen(PidFile, "w");
129 (void) fprintf(fp, "%d\n", cload.kmid);
132 printf("Can't open for write file %s (error=%d); ignored\n", PidFile, errno);
138 strcpy(PidFile, file);
139 strcat(PidFile, ".kmid");
140 fp = fopen(PidFile, "r");
142 printf("Can't read %s file (error=%d); aborting\n", PidFile, errno);
145 (void) fscanf(fp, "%d\n", &kmid);
153 if (sysconfig(SYS_CFGKMOD, &cmod, sizeof(cmod)) == -1) {
154 perror("SYS_CFGKMOD");
159 if (sysconfig(SYS_KULOAD, &cload, sizeof(cload)) == -1) {
160 perror("SYS_KULOAD");
169 error("usage: cfgexport [-a mod_file [-s symbols]] [-d mod_file]\n");
173 * get_syms - get kernel symbol table info.
176 * conf - ^ to EXPORT extension configuration struct
177 * syms - ^ to name of file containing XCOFF symbols
183 register sym_t *k_symtab, *ksp;
184 register struct syment *x_symtab, *xsp, *xsq;
185 register char *xstrings;
187 struct xcoffhdr hdr; /* XCOFF header from symbol file*/
188 sym_t k_sym; /* export version of symbol */
189 struct syment xcoff_sym; /* xcoff version of symbol */
190 register i, nsyms, nksyms, nxsyms;
191 int xstr_size, kstr_size;
195 fp = fopen(syms, "r");
199 if (fread(&hdr, sizeof (hdr), 1, fp) != 1)
202 if (hdr.filehdr.f_nsyms == 0)
203 error("%s: no symbols", syms);
205 switch (hdr.filehdr.f_magic) {
215 error("%s: funny magic number 0%o"
216 , syms, hdr.filehdr.f_magic);
219 nsyms = hdr.filehdr.f_nsyms;
221 printf("nsyms = %d\n", nsyms);
223 x_symtab = (struct syment *) malloc(nsyms * SYMESZ);
225 error("no memory for symbol table");
228 * try to snarf the string table: should be just past the
229 * symbol table: first 4 bytes is length of rest.
231 if (fseek(fp, hdr.filehdr.f_symptr + nsyms * SYMESZ, 0) < 0)
232 sys_error("%s: seek to strtab", syms);
234 if (fread(&xstr_size, sizeof (xstr_size), 1, fp) != 1)
235 error("%s: reading string table size", syms);
237 xstrings = malloc(xstr_size + sizeof (xstr_size));
239 error("no memory for string table");
242 * seek back to the start of the strings
244 if (fseek(fp, hdr.filehdr.f_symptr + nsyms * SYMESZ, 0) < 0)
245 sys_error("%s: seek to strtab", syms);
247 if (fread(xstrings, sizeof (*xstrings), xstr_size, fp) != xstr_size)
248 error("%s: reading string table");
251 * now seek back to the start of the symbol table, and read it
254 if (fseek(fp, hdr.filehdr.f_symptr, 0) < 0)
255 sys_error("%s: seek to symtab", syms);
259 for (i = nxsyms = 0; i < nsyms; ++i) {
262 if (fread(&xcoff_sym, SYMESZ, 1, fp) != 1)
263 error("%s: reading symbol entry", syms);
265 if (xcoff_sym.n_zeroes == 0) {
267 * Need to relocate string table offset
269 p = xcoff_sym.n_nptr = xstrings + xcoff_sym.n_offset;
271 strncpy(name, xcoff_sym.n_name, 8);
277 dump_xsym(&xcoff_sym);
279 switch (xcoff_sym.n_sclass) {
280 case C_EXT: /* external */
281 case C_HIDEXT: /* hidden external (sic) */
283 * filtre out the ones with the strange names
285 if (strchr(p, '@') || strchr(p, '$') || p[0] == 0)
292 dump_xsym(&xcoff_sym);
297 if (xcoff_sym.n_numaux) {
298 fseek(fp, xcoff_sym.n_numaux * AUXESZ, 1);
299 i += xcoff_sym.n_numaux;
306 * sort the symbol table
308 qsort((char *) x_symtab, nxsyms, sizeof (*x_symtab), xsym_compar);
311 * we will need no more than `nxsyms' symbols.
313 k_symtab = (sym_t *) malloc(nxsyms * sizeof (sym_t));
315 error("no memory for EXPORT symbol table");
318 * uniquify it, and xlate to funny EXPORT format
320 xsp = xsq = x_symtab;
326 bzero(xsq = &xcoff_sym, sizeof (*xsq));
328 for (i = 1; i < nxsyms; ++i, xsq = xsp++) {
329 if (xsp->n_zeroes != xsq->n_zeroes
330 || xsp->n_offset != xsq->n_offset
331 || xsp->n_value != xsq->n_value) {
332 xlate_xtok(xsp, ksp++, &kstrings, &kstr_size);
338 * place the symbol table info into the `conf' data structure
340 * XXXXX: for today only, leave the string table the same.
342 conf->nsyms = nksyms;
343 conf->symt_sz = nksyms * sizeof (sym_t);
344 conf->str_sz = kstr_size;
345 conf->symtab = (caddr_t) k_symtab;
346 conf->strtab = kstrings;
351 * xlate_xtok - xlate XCOFF to EXPORT format
354 * xp - ^ to XCOFF symbol
355 * kp - ^ to EXPORT symbol save area
356 * strp - ^ to ^ to EXPORT string table
357 * szp - ^ to EXPORT string table size
359 xlate_xtok(xp, kp, strp, szp)
360 register struct syment *xp;
365 static char *export_strings, *prev = "";
366 static left, offset, sz;
368 if (!export_strings) {
369 export_strings = malloc(sz=1024);
371 error("no memory for EXPORT string table");
373 *strp = export_strings;
374 *szp = offset = sizeof (uint);
375 left = 1024 - offset;
377 export_strings += offset;
379 *(uint *) export_strings = 0; /* initial 4 bytes */
382 if (kp->n_zeroes = xp->n_zeroes) { /* sic */
383 kp->n_zeroes = xp->n_zeroes;
384 kp->n_offset = xp->n_offset;
385 } else if (strcmp(prev, xp->n_nptr) == 0) {
387 * same name as previous entry: just use previous
389 kp->n_offset = offset - strlen(xp->n_nptr) - 1;
390 } else if (find_suffix(xp->n_nptr, *strp, offset, &kp->n_offset)) {
392 * found a string that we are a suffix of
397 * need to add to our string table
399 len = strlen(xp->n_nptr) + 1;
400 while (len >= left) {
401 export_strings = (char *)realloc(*strp, sz += 1024);
403 error("no memory for EXPORT string table");
404 *strp = export_strings;
406 prev = ""; /* lazy */
409 strcpy(prev = *strp + offset, xp->n_nptr);
411 kp->n_offset = offset;
417 kp->n_value = xp->n_value;
420 dump_ksym(kp, *strp);
424 * find_suffix - look for a string that arg string is suffix of
427 * p - ^ to string we hope is a suffix of another
428 * strings - ^ to string table
429 * max - max offset of valid string in strings
430 * offp - ^ to place to store offset, if containing string found
433 * 0 - no containing string found
434 * !0 - string found of which `p' is a suffix
437 * This is rather inefficient.
439 find_suffix(p, strings, max, offp)
440 register char *p, *strings;
442 register char *q, *e;
443 register len = strlen(p) - 1;
445 strings += sizeof (uint);
446 max -= sizeof (uint);
448 for (e = strings + max; e > strings; ) {
450 * adjust `e' to point at last non-blank
457 for (q = p + len; q > p && *q == *e; )
462 printf("found_suffix: %s\n", p);
463 return *offp = e - strings + sizeof (uint);
467 while (*e && e > strings)
475 * xsym_compar - compare two XCOFF symbol table entries
477 * If the names are the same, sort by descending storage class, so that
481 register struct syment *xp, *xq; {
482 register char *p, *q;
485 p = (xp->n_zeroes ? xp->n_name : xp->n_nptr);
486 q = (xq->n_zeroes ? xq->n_name : xq->n_nptr);
488 if (xp->n_zeroes || xq->n_zeroes)
489 compar = strncmp(p, q, 8);
491 compar = strcmp(p, q);
494 compar = xp->n_sclass - xq->n_sclass;
500 * dump_xsym - print to XCOFF symbol
503 struct syment *xsp; {
507 "nptr <%-8.8s %8.8s> val %8.8x sc# %4.4x type %4.4x sclass %2.2x naux %2.2x\n"
511 , xsp->n_scnum & 0xffff
518 "nptr <%-17.17s> val %8.8x sc# %4.4x type %4.4x sclass %2.2x naux %2.2x\n"
521 , xsp->n_scnum & 0xffff
527 dump_ksym(ksp, strings)
532 printf("%8.8x %-8.8s\n", ksp->n_value, ksp->n_name);
534 printf("%8.8x %s\n", ksp->n_value, ksp->n_offset + strings);
537 error(p, a, b, c, d, e)
540 fprintf(stderr, p, a, b, c, d, e);
541 fprintf(stderr, "\n");
545 sys_error(p, a, b, c, d, e)
549 fprintf(stderr, p, a, b, c, d, e);
554 warn(p, a, b, c, d, e)
558 fprintf(stderr, p, a, b, c, d, e);
559 fprintf(stderr, "\n");