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
13 #include <afsconfig.h>
14 #include <afs/param.h>
20 #include <sys/types.h>
21 #include <sys/device.h>
22 #include <sys/sysconfig.h>
24 #include <sys/xcoff.h>
31 extern char *malloc(), *optarg
;
32 extern int sysconfig(int cmd
, void *arg
, int len
);
38 #include "AFS_component_version_number.c"
47 struct cfg_load cload
;
54 * The following signal action for AIX is necessary so that in case of a
55 * crash (i.e. core is generated) we can include the user's data section
56 * in the core dump. Unfortunately, by default, only a partial core is
57 * generated which, in many cases, isn't too useful.
61 sigemptyset(&nsa
.sa_mask
);
62 nsa
.sa_handler
= SIG_DFL
;
63 nsa
.sa_flags
= SA_FULLDUMP
;
64 sigaction(SIGSEGV
, &nsa
, NULL
);
68 while ((c
= getopt(argc
, argv
, "a:s:Z:d:")) != EOF
) {
70 case 'Z': /* Zdebug option */
105 buf
[0] = "execerror";
106 buf
[1] = "cfgexport";
107 get_syms(&conf
, syms
);
110 if (sysconfig(SYS_KLOAD
, &cload
, sizeof(cload
)) == -1) {
111 loadquery(L_GETMESSAGES
, &buf
[2], sizeof buf
- 8);
112 execvp("/etc/execerror", buf
);
117 cmod
.kmid
= cload
.kmid
;
119 cmod
.mdiptr
= (caddr_t
) & conf
;
120 cmod
.mdilen
= sizeof(conf
);
122 if (sysconfig(SYS_CFGKMOD
, &cmod
, sizeof(cmod
)) == -1) {
123 perror("SYS_CFGKMOD");
124 cload
.kmid
= cload
.kmid
;
125 sysconfig(SYS_KULOAD
, &cload
, sizeof(cload
));
129 printf("cfgexport -d 0x%x # to remove EXPORT\n", cload
.kmid
);
131 strcpy(PidFile
, file
);
132 strcat(PidFile
, ".kmid");
133 fp
= fopen(PidFile
, "w");
135 (void)fprintf(fp
, "%d\n", cload
.kmid
);
138 printf("Can't open for write file %s (error=%d); ignored\n",
145 strcpy(PidFile
, file
);
146 strcat(PidFile
, ".kmid");
147 fp
= fopen(PidFile
, "r");
149 printf("Can't read %s file (error=%d); aborting\n", PidFile
,
153 (void)fscanf(fp
, "%d\n", &kmid
);
161 if (sysconfig(SYS_CFGKMOD
, &cmod
, sizeof(cmod
)) == -1) {
162 perror("SYS_CFGKMOD");
167 if (sysconfig(SYS_KULOAD
, &cload
, sizeof(cload
)) == -1) {
168 perror("SYS_KULOAD");
178 error("usage: cfgexport [-a mod_file [-s symbols]] [-d mod_file]\n");
182 * get_syms - get kernel symbol table info.
185 * conf - ^ to EXPORT extension configuration struct
186 * syms - ^ to name of file containing XCOFF symbols
192 sym_t
*k_symtab
, *ksp
;
193 struct syment
*x_symtab
, *xsp
, *xsq
;
195 struct xcoffhdr hdr
; /* XCOFF header from symbol file */
196 sym_t k_sym
; /* export version of symbol */
197 struct syment xcoff_sym
; /* xcoff version of symbol */
198 int i
, nsyms
, nksyms
, nxsyms
= 0;
199 int xstr_size
, kstr_size
;
204 sys_error("syms is NULL");
205 fp
= fopen(syms
, "r");
209 if (fread(&hdr
, sizeof(hdr
), 1, fp
) != 1)
212 if (hdr
.filehdr
.f_nsyms
== 0)
213 error("%s: no symbols", syms
);
215 switch (hdr
.filehdr
.f_magic
) {
228 error("%s: funny magic number 0%o", syms
, hdr
.filehdr
.f_magic
);
231 nsyms
= hdr
.filehdr
.f_nsyms
;
233 printf("nsyms = %d\n", nsyms
);
235 x_symtab
= malloc(nsyms
* SYMESZ
);
237 error("no memory for symbol table");
240 * try to snarf the string table: should be just past the
241 * symbol table: first 4 bytes is length of rest.
243 if (fseek(fp
, hdr
.filehdr
.f_symptr
+ nsyms
* SYMESZ
, 0) < 0)
244 sys_error("%s: seek to strtab", syms
);
246 if (fread(&xstr_size
, sizeof(xstr_size
), 1, fp
) != 1)
247 error("%s: reading string table size", syms
);
249 xstrings
= malloc(xstr_size
+ sizeof(xstr_size
));
251 error("no memory for string table");
254 * seek back to the start of the strings
256 if (fseek(fp
, hdr
.filehdr
.f_symptr
+ nsyms
* SYMESZ
, 0) < 0)
257 sys_error("%s: seek to strtab", syms
);
259 if (fread(xstrings
, sizeof(*xstrings
), xstr_size
, fp
) != xstr_size
)
260 error("%s: reading string table");
263 * now seek back to the start of the symbol table, and read it
266 if (fseek(fp
, hdr
.filehdr
.f_symptr
, 0) < 0)
267 sys_error("%s: seek to symtab", syms
);
271 for (i
= nxsyms
= 0; i
< nsyms
; ++i
) {
274 if (fread(&xcoff_sym
, SYMESZ
, 1, fp
) != 1)
275 error("%s: reading symbol entry", syms
);
278 p
= xstrings
+ xcoff_sym
.n_offset
;
280 if (xcoff_sym
.n_zeroes
== 0) {
282 * Need to relocate string table offset
284 p
= xcoff_sym
.n_nptr
= xstrings
+ xcoff_sym
.n_offset
;
286 strncpy(name
, xcoff_sym
.n_name
, 8);
293 dump_xsym(&xcoff_sym
);
295 switch (xcoff_sym
.n_sclass
) {
296 case C_EXT
: /* external */
297 case C_HIDEXT
: /* hidden external (sic) */
299 * filtre out the ones with the strange names
301 if (strchr(p
, '@') || strchr(p
, '$') || p
[0] == 0)
308 dump_xsym(&xcoff_sym
);
313 if (xcoff_sym
.n_numaux
) {
314 fseek(fp
, xcoff_sym
.n_numaux
* AUXESZ
, 1);
315 i
+= xcoff_sym
.n_numaux
;
322 * sort the symbol table
324 qsort((char *)x_symtab
, nxsyms
, sizeof(*x_symtab
), xsym_compar
);
327 * we will need no more than `nxsyms' symbols.
329 k_symtab
= malloc(nxsyms
* sizeof(sym_t
));
331 error("no memory for EXPORT symbol table");
334 * uniquify it, and xlate to funny EXPORT format
336 xsp
= xsq
= x_symtab
;
342 memset(xsq
= &xcoff_sym
, 0, sizeof(*xsq
));
344 for (i
= 1; i
< nxsyms
; ++i
, xsq
= xsp
++) {
346 if (xsp
->n_offset
!= xsq
->n_offset
|| xsp
->n_value
!= xsq
->n_value
) {
348 if (xsp
->n_zeroes
!= xsq
->n_zeroes
|| xsp
->n_offset
!= xsq
->n_offset
349 || xsp
->n_value
!= xsq
->n_value
) {
351 xlate_xtok(xsp
, ksp
++, &kstrings
, &kstr_size
);
357 * place the symbol table info into the `conf' data structure
359 * XXXXX: for today only, leave the string table the same.
361 conf
->nsyms
= nksyms
;
362 conf
->symt_sz
= nksyms
* sizeof(sym_t
);
363 conf
->str_sz
= kstr_size
;
364 conf
->symtab
= (caddr_t
) k_symtab
;
365 conf
->strtab
= kstrings
;
370 * xlate_xtok - xlate XCOFF to EXPORT format
373 * xp - ^ to XCOFF symbol
374 * kp - ^ to EXPORT symbol save area
375 * strp - ^ to ^ to EXPORT string table
376 * szp - ^ to EXPORT string table size
378 #define SYMBUFSIZE 1048576
379 xlate_xtok(xp
, kp
, strp
, szp
)
386 static char *export_strings
= NULL
, *prev
= "";
387 static left
, offset
, sz
;
389 if (!export_strings
) {
390 export_strings
= malloc(sz
= SYMBUFSIZE
);
392 error("no memory for EXPORT string table");
394 *strp
= export_strings
;
395 *szp
= offset
= sizeof(uint
);
396 left
= SYMBUFSIZE
- offset
;
398 export_strings
+= offset
;
400 *(uint
*) export_strings
= 0; /* initial 4 bytes */
403 if (strcmp(prev
, xstrings
+ xp
->n_offset
) == 0) {
405 * same name as previous entry: just use previous
407 kp
->n_offset
= offset
- strlen(*strp
+ xp
->n_offset
) - 1;
410 (xstrings
+ xp
->n_offset
, *strp
, offset
, &kp
->n_offset
)) {
412 * found a string that we are a suffix of
417 * need to add to our string table
419 len
= strlen(xstrings
+ xp
->n_offset
) + 1;
420 while (len
>= left
) {
421 fprintf(stderr
, "cfgexport: Out of memory. Increase SYMBUFSIZE and recompile\n");
424 /* Something is broken with this code, after being here
425 cfgexport segfaults */
426 export_strings
= (char *)realloc(*strp
, sz
+= SYMBUFSIZE
);
428 error("no memory for EXPORT string table");
429 *strp
= export_strings
;
431 prev
= ""; /* lazy */
435 strcpy(prev
= *strp
+ offset
, xstrings
+ xp
->n_offset
);
437 kp
->n_offset
= offset
;
443 if (kp
->n_zeroes
= xp
->n_zeroes
) { /* sic */
444 kp
->n_zeroes
= xp
->n_zeroes
;
445 kp
->n_offset
= xp
->n_offset
;
446 } else if (strcmp(prev
, xp
->n_nptr
) == 0) {
448 * same name as previous entry: just use previous
450 kp
->n_offset
= offset
- strlen(xp
->n_nptr
) - 1;
451 } else if (find_suffix(xp
->n_nptr
, *strp
, offset
, &kp
->n_offset
)) {
453 * found a string that we are a suffix of
458 * need to add to our string table
460 len
= strlen(xp
->n_nptr
) + 1;
461 while (len
>= left
) {
462 export_strings
= realloc(*strp
, sz
+= SYMBUFSIZE
);
464 error("no memory for EXPORT string table");
465 *strp
= export_strings
;
467 prev
= ""; /* lazy */
470 strcpy(prev
= *strp
+ offset
, xp
->n_nptr
);
472 kp
->n_offset
= offset
;
479 kp
->n_value
= xp
->n_value
;
482 dump_ksym(kp
, *strp
);
486 * find_suffix - look for a string that arg string is suffix of
489 * p - ^ to string we hope is a suffix of another
490 * strings - ^ to string table
491 * max - max offset of valid string in strings
492 * offp - ^ to place to store offset, if containing string found
495 * 0 - no containing string found
496 * !0 - string found of which `p' is a suffix
499 * This is rather inefficient.
501 find_suffix(p
, strings
, max
, offp
)
506 int len
= strlen(p
) - 1;
508 strings
+= sizeof(uint
);
511 for (e
= strings
+ max
; e
> strings
;) {
513 * adjust `e' to point at last non-blank
520 for (q
= p
+ len
; q
> p
&& *q
== *e
;)
525 printf("found_suffix: %s\n", p
);
526 return *offp
= e
- strings
+ sizeof(uint
);
530 while (*e
&& e
> strings
)
538 * xsym_compar - compare two XCOFF symbol table entries
540 * If the names are the same, sort by descending storage class, so that
544 struct syment
*xp
, *xq
;
550 p
= (xp
->n_zeroes
? xp
->n_name
: xp
->n_nptr
);
551 q
= (xq
->n_zeroes
? xq
->n_name
: xq
->n_nptr
);
553 if (xp
->n_zeroes
|| xq
->n_zeroes
)
554 compar
= strncmp(p
, q
, 8);
557 p
= xstrings
+ xp
->n_offset
;
558 q
= xstrings
+ xq
->n_offset
;
560 compar
= strcmp(p
, q
);
563 compar
= xp
->n_sclass
- xq
->n_sclass
;
569 * dump_xsym - print to XCOFF symbol
578 ("nptr <%-8.8s %8.8s> val %8.8x sc# %4.4x type %4.4x sclass %2.2x naux %2.2x\n",
579 xsp
->n_name
, "", xsp
->n_value
, xsp
->n_scnum
& 0xffff,
580 xsp
->n_type
, xsp
->n_sclass
, xsp
->n_numaux
);
584 ("nptr <%-17.17s> val %8.8x sc# %4.4x type %4.4x sclass %2.2x naux %2.2x\n"
586 , xstrings
+ xsp
->n_offset
590 , xsp
->n_value
, xsp
->n_scnum
& 0xffff, xsp
->n_type
,
591 xsp
->n_sclass
, xsp
->n_numaux
);
594 dump_ksym(ksp
, strings
)
601 printf("%8.8x %-8.8s\n", ksp
->n_value
, ksp
->n_name
);
604 printf("%8.8x %s\n", ksp
->n_value
, ksp
->n_offset
+ strings
);
607 error(p
, a
, b
, c
, d
, e
)
611 fprintf(stderr
, p
, a
, b
, c
, d
, e
);
612 fprintf(stderr
, "\n");
616 sys_error(p
, a
, b
, c
, d
, e
)
620 fprintf(stderr
, p
, a
, b
, c
, d
, e
);
625 warn(p
, a
, b
, c
, d
, e
)
629 fprintf(stderr
, p
, a
, b
, c
, d
, e
);
630 fprintf(stderr
, "\n");