summaryrefslogtreecommitdiff
path: root/usr/src/cmd/sgs
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/sgs')
-rw-r--r--usr/src/cmd/sgs/elfdump/Makefile.targ2
-rw-r--r--usr/src/cmd/sgs/elfdump/amd64/Makefile2
-rw-r--r--usr/src/cmd/sgs/elfdump/i386/Makefile2
-rw-r--r--usr/src/cmd/sgs/include/conv.h2
-rw-r--r--usr/src/cmd/sgs/lex/common/main.c45
-rw-r--r--usr/src/cmd/sgs/lex/common/once.h12
-rw-r--r--usr/src/cmd/sgs/libconv/common/corenote.c13
-rw-r--r--usr/src/cmd/sgs/libconv/common/corenote.msg5
-rw-r--r--usr/src/cmd/sgs/libconv/common/phdr.c46
-rw-r--r--usr/src/cmd/sgs/libconv/common/phdr.msg30
-rw-r--r--usr/src/cmd/sgs/librtld_db/common/librtld_db.msg6
-rw-r--r--usr/src/cmd/sgs/librtld_db/common/rd_elf.c28
-rw-r--r--usr/src/cmd/sgs/rtld/common/_rtld.h4
-rw-r--r--usr/src/cmd/sgs/rtld/common/analyze.c63
-rw-r--r--usr/src/cmd/sgs/rtld/common/external.c24
-rw-r--r--usr/src/cmd/sgs/rtld/common/globals.c3
-rw-r--r--usr/src/cmd/sgs/rtld/common/rtld.msg7
-rw-r--r--usr/src/cmd/sgs/rtld/common/setup.c10
-rw-r--r--usr/src/cmd/sgs/rtld/common/util.c16
-rw-r--r--usr/src/cmd/sgs/yacc/common/dextern.h19
-rw-r--r--usr/src/cmd/sgs/yacc/common/y1.c36
-rw-r--r--usr/src/cmd/sgs/yacc/common/y2.c7
22 files changed, 347 insertions, 35 deletions
diff --git a/usr/src/cmd/sgs/elfdump/Makefile.targ b/usr/src/cmd/sgs/elfdump/Makefile.targ
index 4cbbec6bff..bef356bb28 100644
--- a/usr/src/cmd/sgs/elfdump/Makefile.targ
+++ b/usr/src/cmd/sgs/elfdump/Makefile.targ
@@ -79,6 +79,8 @@ delete:
package \
install: all $(VAR_SGSBINPROG) $(VAR_SGSCCSLINK)
+ -$(RM) $(ROOTPROG)
+ -$(LN) $(ISAEXEC) $(ROOTPROG)
include $(SRC)/cmd/Makefile.targ
include $(SRC)/cmd/sgs/Makefile.targ
diff --git a/usr/src/cmd/sgs/elfdump/amd64/Makefile b/usr/src/cmd/sgs/elfdump/amd64/Makefile
index ec8341a69b..7c3f1eb876 100644
--- a/usr/src/cmd/sgs/elfdump/amd64/Makefile
+++ b/usr/src/cmd/sgs/elfdump/amd64/Makefile
@@ -39,6 +39,8 @@ CONVLIBDIR = $(CONVLIBDIR64)
VAR_SGSBINPROG= $(VAR_SGSBINPROG64)
VAR_SGSCCSLINK= $(VAR_SGSCCSLINK64)
+install: all $(ROOTPROG64)
+
include ../Makefile.targ
include ../../Makefile.sub.64
diff --git a/usr/src/cmd/sgs/elfdump/i386/Makefile b/usr/src/cmd/sgs/elfdump/i386/Makefile
index d3cb302ac1..95390a2899 100644
--- a/usr/src/cmd/sgs/elfdump/i386/Makefile
+++ b/usr/src/cmd/sgs/elfdump/i386/Makefile
@@ -30,4 +30,6 @@ include ../Makefile.com
ARCH = i386
+install: all $(ROOTPROG32)
+
include ../Makefile.targ
diff --git a/usr/src/cmd/sgs/include/conv.h b/usr/src/cmd/sgs/include/conv.h
index 066e215bc4..7fc4c026d5 100644
--- a/usr/src/cmd/sgs/include/conv.h
+++ b/usr/src/cmd/sgs/include/conv.h
@@ -283,7 +283,7 @@ typedef union {
} Conv_bnd_obj_buf_t;
/* conv_phdr_flags() */
-#define CONV_PHDR_FLAGS_BUFSIZE 88
+#define CONV_PHDR_FLAGS_BUFSIZE 244
typedef union {
Conv_inv_buf_t inv_buf;
char buf[CONV_PHDR_FLAGS_BUFSIZE];
diff --git a/usr/src/cmd/sgs/lex/common/main.c b/usr/src/cmd/sgs/lex/common/main.c
index 17ba4808a4..a1fd526cf9 100644
--- a/usr/src/cmd/sgs/lex/common/main.c
+++ b/usr/src/cmd/sgs/lex/common/main.c
@@ -30,11 +30,15 @@
/* Copyright 1976, Bell Telephone Laboratories, Inc. */
+/* Copyright (c) 2013, joyent, Inc. All rights reserved. */
+
#include <string.h>
#include "once.h"
#include "sgs.h"
#include <locale.h>
#include <limits.h>
+#include <unistd.h>
+#include <libgen.h>
static wchar_t L_INITIAL[] = {'I', 'N', 'I', 'T', 'I', 'A', 'L', 0};
static void get1core(void);
@@ -46,6 +50,25 @@ static void get3core(void);
static void free3core(void);
#endif
+static int
+lex_construct_path(char *buf, size_t size, const char *file, int type)
+{
+ int ret;
+ char origin[PATH_MAX];
+
+ if (type != 0) {
+ ret = readlink("/proc/self/path/a.out", origin, PATH_MAX - 1);
+ if (ret < 0)
+ error(
+ "lex: failed to read origin from /proc\n");
+ origin[ret] = '\0';
+ return (snprintf(buf, size, "%s/../%s/%s", dirname(origin),
+ NBASE, file));
+ }
+
+ return (snprintf(buf, size, "%s/%s/%s", NPREFIX, NBASE, file));
+}
+
int
main(int argc, char **argv)
{
@@ -53,6 +76,7 @@ main(int argc, char **argv)
int c;
char *apath = NULL;
char *ypath;
+ char pathbuf[PATH_MAX];
Boolean eoption = 0, woption = 0;
sargv = argv;
@@ -224,6 +248,11 @@ main(int argc, char **argv)
free3core();
#endif
+ /*
+ * Try to find the file relative to $ORIGIN. Note that we don't touch
+ * antyhing related to -Y. In fact, unfortunately it's always been
+ * ignored it seems.
+ */
if (handleeuc) {
if (ratfor)
error("Ratfor is not supported by -w or -e option.");
@@ -232,9 +261,19 @@ main(int argc, char **argv)
else
ypath = ratfor ? RATNAME : CNAME;
- if (apath != NULL)
- ypath = strcat(apath, strrchr(ypath, '/'));
- fother = fopen(ypath, "r");
+ if (apath == NULL) {
+ (void) lex_construct_path(pathbuf, sizeof (pathbuf), ypath, 1);
+ fother = fopen(pathbuf, "r");
+ if (fother == NULL) {
+ (void) lex_construct_path(pathbuf, sizeof (pathbuf),
+ ypath, 0);
+ fother = fopen(pathbuf, "r");
+ }
+ } else {
+ apath = strcat(apath, "/");
+ ypath = strcat(apath, ypath);
+ fother = fopen(ypath, "r");
+ }
if (fother == NULL)
error("Lex driver missing, file %s", ypath);
while ((i = getc(fother)) != EOF)
diff --git a/usr/src/cmd/sgs/lex/common/once.h b/usr/src/cmd/sgs/lex/common/once.h
index 014ca00b17..9e4b0e5e00 100644
--- a/usr/src/cmd/sgs/lex/common/once.h
+++ b/usr/src/cmd/sgs/lex/common/once.h
@@ -26,11 +26,11 @@
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
+/* Copyright (c) 2013, joyent, Inc. All rights reserved. */
+
#ifndef _ONCE_H
#define _ONCE_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ldefs.h"
/* once.c */
@@ -73,9 +73,11 @@ int peek = '\n'; /* next input character */
CHR *pushptr = pushc;
CHR *slptr = slist;
-#define CNAME "/usr/share/lib/ccs/ncform"
-#define RATNAME "/usr/share/lib/ccs/nrform"
-#define EUCNAME "/usr/share/lib/ccs/nceucform"
+#define NPREFIX "/usr"
+#define NBASE "/share/lib/ccs/"
+#define CNAME "ncform"
+#define RATNAME "nrform"
+#define EUCNAME "nceucform"
int ccount = 1;
int casecount = 1;
diff --git a/usr/src/cmd/sgs/libconv/common/corenote.c b/usr/src/cmd/sgs/libconv/common/corenote.c
index dc9b8022f3..ce923bb039 100644
--- a/usr/src/cmd/sgs/libconv/common/corenote.c
+++ b/usr/src/cmd/sgs/libconv/common/corenote.c
@@ -78,7 +78,7 @@ const char *
conv_cnote_auxv_type(Word type, Conv_fmt_flags_t fmt_flags,
Conv_inv_buf_t *inv_buf)
{
- static const Msg types_0_22[] = {
+ static const Msg types_0_25[] = {
MSG_AUXV_AT_NULL, MSG_AUXV_AT_IGNORE,
MSG_AUXV_AT_EXECFD, MSG_AUXV_AT_PHDR,
MSG_AUXV_AT_PHENT, MSG_AUXV_AT_PHNUM,
@@ -90,10 +90,11 @@ conv_cnote_auxv_type(Word type, Conv_fmt_flags_t fmt_flags,
MSG_AUXV_AT_HWCAP, MSG_AUXV_AT_CLKTCK,
MSG_AUXV_AT_FPUCW, MSG_AUXV_AT_DCACHEBSIZE,
MSG_AUXV_AT_ICACHEBSIZE, MSG_AUXV_AT_UCACHEBSIZE,
- MSG_AUXV_AT_IGNOREPPC
+ MSG_AUXV_AT_IGNOREPPC, MSG_AUXV_AT_SECURE,
+ MSG_AUXV_AT_BASE_PLATFORM, MSG_AUXV_AT_RANDOM
};
- static const conv_ds_msg_t ds_types_0_22 = {
- CONV_DS_MSG_INIT(0, types_0_22) };
+ static const conv_ds_msg_t ds_types_0_25 = {
+ CONV_DS_MSG_INIT(0, types_0_25) };
static const Msg types_2000_2011[] = {
MSG_AUXV_AT_SUN_UID, MSG_AUXV_AT_SUN_RUID,
@@ -112,7 +113,7 @@ conv_cnote_auxv_type(Word type, Conv_fmt_flags_t fmt_flags,
MSG_AUXV_AT_SUN_EMULATOR, MSG_AUXV_AT_SUN_BRANDNAME,
MSG_AUXV_AT_SUN_BRAND_AUX1, MSG_AUXV_AT_SUN_BRAND_AUX2,
MSG_AUXV_AT_SUN_BRAND_AUX3, MSG_AUXV_AT_SUN_HWCAP2,
- NULL, NULL,
+ MSG_AUXV_AT_SUN_BRAND_NROOT, MSG_AUXV_AT_SUN_BRAND_AUX4,
MSG_AUXV_AT_SUN_COMMPAGE, MSG_AUXV_AT_SUN_FPTYPE,
MSG_AUXV_AT_SUN_FPSIZE
};
@@ -120,7 +121,7 @@ conv_cnote_auxv_type(Word type, Conv_fmt_flags_t fmt_flags,
CONV_DS_MSG_INIT(2014, types_2014_2028) };
static const conv_ds_t *ds[] = {
- CONV_DS_ADDR(ds_types_0_22), CONV_DS_ADDR(ds_types_2000_2011),
+ CONV_DS_ADDR(ds_types_0_25), CONV_DS_ADDR(ds_types_2000_2011),
CONV_DS_ADDR(ds_types_2014_2028), NULL };
return (conv_map_ds(ELFOSABI_NONE, EM_NONE, type, ds, fmt_flags,
diff --git a/usr/src/cmd/sgs/libconv/common/corenote.msg b/usr/src/cmd/sgs/libconv/common/corenote.msg
index a36f2bddf7..78951cfb1d 100644
--- a/usr/src/cmd/sgs/libconv/common/corenote.msg
+++ b/usr/src/cmd/sgs/libconv/common/corenote.msg
@@ -80,6 +80,9 @@
@ MSG_AUXV_AT_ICACHEBSIZE "ICACHEBSIZE"
@ MSG_AUXV_AT_UCACHEBSIZE "UCACHEBSIZE"
@ MSG_AUXV_AT_IGNOREPPC "IGNOREPPC"
+@ MSG_AUXV_AT_SECURE "SECURE"
+@ MSG_AUXV_AT_BASE_PLATFORM "BASE_PLATFORM"
+@ MSG_AUXV_AT_RANDOM "RANDOM"
@ MSG_AUXV_AT_SUN_UID "SUN_UID"
@ MSG_AUXV_AT_SUN_RUID "SUN_RUID"
@ MSG_AUXV_AT_SUN_GID "SUN_GID"
@@ -102,6 +105,8 @@
@ MSG_AUXV_AT_SUN_BRAND_AUX2 "SUN_BRAND_AUX2"
@ MSG_AUXV_AT_SUN_BRAND_AUX3 "SUN_BRAND_AUX3"
@ MSG_AUXV_AT_SUN_HWCAP2 "SUN_HWCAP2"
+@ MSG_AUXV_AT_SUN_BRAND_NROOT "SUN_BRAND_NROOT"
+@ MSG_AUXV_AT_SUN_BRAND_AUX4 "SUN_BRAND_AUX4"
@ MSG_AUXV_AT_SUN_COMMPAGE "SUN_COMMPAGE"
@ MSG_AUXV_AT_SUN_FPTYPE "SUN_FPTYPE"
@ MSG_AUXV_AT_SUN_FPSIZE "SUN_FPSIZE"
diff --git a/usr/src/cmd/sgs/libconv/common/phdr.c b/usr/src/cmd/sgs/libconv/common/phdr.c
index d2b29a201f..382a1bf9f1 100644
--- a/usr/src/cmd/sgs/libconv/common/phdr.c
+++ b/usr/src/cmd/sgs/libconv/common/phdr.c
@@ -25,6 +25,10 @@
*/
/*
+ * Copyright (c) 2015, Joyent, Inc. All rights reserved.
+ */
+
+/*
* String conversion routines for program header attributes.
*/
#include <stdio.h>
@@ -95,6 +99,7 @@ error "PT_NUM has grown. Update phdrs[]"
{ PT_GNU_EH_FRAME, LIN, MSG_PT_GNU_EH_FRAME },
{ PT_GNU_STACK, LIN, MSG_PT_GNU_STACK },
{ PT_GNU_RELRO, LIN, MSG_PT_GNU_RELRO },
+ { PT_PAX_FLAGS, LIN, MSG_PT_PAX_FLAGS },
{ 0 }
};
@@ -109,6 +114,7 @@ error "PT_NUM has grown. Update phdrs[]"
{ PT_GNU_EH_FRAME, LIN, MSG_PT_GNU_EH_FRAME_CF },
{ PT_GNU_STACK, LIN, MSG_PT_GNU_STACK_CF },
{ PT_GNU_RELRO, LIN, MSG_PT_GNU_RELRO_CF },
+ { PT_PAX_FLAGS, LIN, MSG_PT_PAX_FLAGS_CF },
{ 0 }
};
@@ -123,6 +129,7 @@ error "PT_NUM has grown. Update phdrs[]"
{ PT_GNU_EH_FRAME, LIN, MSG_PT_GNU_EH_FRAME_CFNP },
{ PT_GNU_STACK, LIN, MSG_PT_GNU_STACK_CFNP },
{ PT_GNU_RELRO, LIN, MSG_PT_GNU_RELRO_CFNP },
+ { PT_PAX_FLAGS, LIN, MSG_PT_PAX_FLAGS_CFNP },
{ 0 }
};
@@ -137,6 +144,7 @@ error "PT_NUM has grown. Update phdrs[]"
{ PT_GNU_EH_FRAME, LIN, MSG_PT_GNU_EH_FRAME_NF },
{ PT_GNU_STACK, LIN, MSG_PT_GNU_STACK_NF },
{ PT_GNU_RELRO, LIN, MSG_PT_GNU_RELRO_NF },
+ { PT_PAX_FLAGS, LIN, MSG_PT_PAX_FLAGS_NF },
{ 0 }
};
@@ -214,6 +222,18 @@ conv_phdr_flags_strings(Conv_fmt_flags_t fmt_flags)
MSG_PF_X_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
MSG_PF_W_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
MSG_PF_R_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_PF_PAGEEXEC_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_PF_NOPAGEEXEC_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_PF_SEGMEXEC_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_PF_NOSEGMEXEC_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_PF_MPROTECT_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_PF_NOMPROTECT_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_PF_RANDEXEC_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_PF_NORANDEXEC_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_PF_EMUTRAMP_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_PF_NOEMUTRAMP_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_PF_RANDMMAP_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_PF_NORANDMMAP_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
MSG_PF_SUNW_FAILURE_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
MSG_PF_SUNW_KILLED_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
MSG_PF_SUNW_SIGINFO_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
@@ -237,11 +257,24 @@ conv_phdr_flags_strings(Conv_fmt_flags_t fmt_flags)
#define ALL ELFOSABI_NONE, EM_NONE
#define SOL ELFOSABI_SOLARIS, EM_NONE
+#define LIN ELFOSABI_LINUX, EM_NONE
static const Val_desc2 vda_cf[] = {
{ PF_X, ALL, MSG_PF_X_CF },
{ PF_W, ALL, MSG_PF_W_CF },
{ PF_R, ALL, MSG_PF_R_CF },
+ { PF_PAGEEXEC, LIN, MSG_PF_PAGEEXEC_CF },
+ { PF_NOPAGEEXEC, LIN, MSG_PF_NOPAGEEXEC_CF },
+ { PF_SEGMEXEC, LIN, MSG_PF_SEGMEXEC_CF },
+ { PF_NOSEGMEXEC, LIN, MSG_PF_NOSEGMEXEC_CF },
+ { PF_MPROTECT, LIN, MSG_PF_MPROTECT_CF },
+ { PF_NOMPROTECT, LIN, MSG_PF_NOMPROTECT_CF },
+ { PF_RANDEXEC, LIN, MSG_PF_RANDEXEC_CF },
+ { PF_NORANDEXEC, LIN, MSG_PF_NORANDEXEC_CF },
+ { PF_EMUTRAMP, LIN, MSG_PF_EMUTRAMP_CF },
+ { PF_NOEMUTRAMP, LIN, MSG_PF_NOEMUTRAMP_CF },
+ { PF_RANDMMAP, LIN, MSG_PF_RANDMMAP_CF },
+ { PF_NORANDMMAP, LIN, MSG_PF_NORANDMMAP_CF },
{ PF_SUNW_FAILURE, SOL, MSG_PF_SUNW_FAILURE_CF },
{ PF_SUNW_KILLED, SOL, MSG_PF_SUNW_KILLED_CF },
{ PF_SUNW_SIGINFO, SOL, MSG_PF_SUNW_SIGINFO_CF },
@@ -251,6 +284,18 @@ conv_phdr_flags_strings(Conv_fmt_flags_t fmt_flags)
{ PF_X, ALL, MSG_PF_X_NF },
{ PF_W, ALL, MSG_PF_W_NF },
{ PF_R, ALL, MSG_PF_R_NF },
+ { PF_PAGEEXEC, LIN, MSG_PF_PAGEEXEC_NF },
+ { PF_NOPAGEEXEC, LIN, MSG_PF_NOPAGEEXEC_NF },
+ { PF_SEGMEXEC, LIN, MSG_PF_SEGMEXEC_NF },
+ { PF_NOSEGMEXEC, LIN, MSG_PF_NOSEGMEXEC_NF },
+ { PF_MPROTECT, LIN, MSG_PF_MPROTECT_NF },
+ { PF_NOMPROTECT, LIN, MSG_PF_NOMPROTECT_NF },
+ { PF_RANDEXEC, LIN, MSG_PF_RANDEXEC_NF },
+ { PF_NORANDEXEC, LIN, MSG_PF_NORANDEXEC_NF },
+ { PF_EMUTRAMP, LIN, MSG_PF_EMUTRAMP_NF },
+ { PF_NOEMUTRAMP, LIN, MSG_PF_NOEMUTRAMP_NF },
+ { PF_RANDMMAP, LIN, MSG_PF_RANDMMAP_NF },
+ { PF_NORANDMMAP, LIN, MSG_PF_NORANDMMAP_NF },
{ PF_SUNW_FAILURE, SOL, MSG_PF_SUNW_FAILURE_NF },
{ PF_SUNW_KILLED, SOL, MSG_PF_SUNW_KILLED_NF },
{ PF_SUNW_SIGINFO, SOL, MSG_PF_SUNW_SIGINFO_NF },
@@ -262,6 +307,7 @@ conv_phdr_flags_strings(Conv_fmt_flags_t fmt_flags)
#undef ALL
#undef SOL
+#undef LIN
}
const char *
diff --git a/usr/src/cmd/sgs/libconv/common/phdr.msg b/usr/src/cmd/sgs/libconv/common/phdr.msg
index 789832a16a..e84182277b 100644
--- a/usr/src/cmd/sgs/libconv/common/phdr.msg
+++ b/usr/src/cmd/sgs/libconv/common/phdr.msg
@@ -24,6 +24,8 @@
# Use is subject to license terms.
#
+# Copyright (c) 2015, Joyent, Inc. All rights reserved.
+
@ MSG_PT_NULL "[ PT_NULL ]" # 0
@ MSG_PT_NULL_CF "PT_NULL"
@ MSG_PT_NULL_CFNP "NULL"
@@ -79,6 +81,10 @@
@ MSG_PT_GNU_RELRO_CF "PT_GNU_RELRO"
@ MSG_PT_GNU_RELRO_CFNP "GNU_RELRO"
@ MSG_PT_GNU_RELRO_NF "gnu_relro"
+@ MSG_PT_PAX_FLAGS "[ PT_PAX_FLAGS ]" # 0x65041580
+@ MSG_PT_PAX_FLAGS_CF "PT_PAX_FLAGS"
+@ MSG_PT_PAX_FLAGS_CFNP "PAX_FLAGS"
+@ MSG_PT_PAX_FLAGS_NF "pax_flags"
@ MSG_PT_SUNWBSS "[ PT_SUNWBSS ]" # 0x6ffffffa
@ MSG_PT_SUNWBSS_CF "PT_SUNWBSS"
@@ -103,6 +109,30 @@
@ MSG_PF_W_NF "w"
@ MSG_PF_R_CF "PF_R" # 0x4
@ MSG_PF_R_NF "r"
+@ MSG_PF_PAGEEXEC_CF "PF_PAGEEXEC" # 0x00000010
+@ MSG_PF_PAGEEXEC_NF "pageexec"
+@ MSG_PF_NOPAGEEXEC_CF "PF_NOPAGEEXEC" # 0x00000020
+@ MSG_PF_NOPAGEEXEC_NF "nopageexec"
+@ MSG_PF_SEGMEXEC_CF "PF_SEGMEXEC" # 0x00000040
+@ MSG_PF_SEGMEXEC_NF "segmexec"
+@ MSG_PF_NOSEGMEXEC_CF "PF_NOSEGMEXEC" # 0x00000080
+@ MSG_PF_NOSEGMEXEC_NF "nosegmexec"
+@ MSG_PF_MPROTECT_CF "PF_MPROTECT" # 0x00000100
+@ MSG_PF_MPROTECT_NF "mprotect"
+@ MSG_PF_NOMPROTECT_CF "PF_NOMPROTECT" # 0x00000200
+@ MSG_PF_NOMPROTECT_NF "nomprotect"
+@ MSG_PF_RANDEXEC_CF "PF_RANDEXEC" # 0x00000400
+@ MSG_PF_RANDEXEC_NF "randexec"
+@ MSG_PF_NORANDEXEC_CF "PF_NORANDEXEC" # 0x00000800
+@ MSG_PF_NORANDEXEC_NF "norandexec"
+@ MSG_PF_EMUTRAMP_CF "PF_EMUTRAMP" # 0x00001000
+@ MSG_PF_EMUTRAMP_NF "emutramp"
+@ MSG_PF_NOEMUTRAMP_CF "PF_NOEMUTRAMP" # 0x00002000
+@ MSG_PF_NOEMUTRAMP_NF "noemutramp"
+@ MSG_PF_RANDMMAP_CF "PF_RANDMMAP" # 0x00004000
+@ MSG_PF_RANDMMAP_NF "randmmap"
+@ MSG_PF_NORANDMMAP_CF "PF_NORANDMMAP" # 0x00008000
+@ MSG_PF_NORANDMMAP_NF "norandmmap"
@ MSG_PF_SUNW_FAILURE_CF "PF_SUNW_FAILURE" # 0x00100000
@ MSG_PF_SUNW_FAILURE_NF "sunw_failure"
@ MSG_PF_SUNW_KILLED_CF "PF_SUNW_KILLED" # 0x00200000
diff --git a/usr/src/cmd/sgs/librtld_db/common/librtld_db.msg b/usr/src/cmd/sgs/librtld_db/common/librtld_db.msg
index fbc595f5f4..5b0ad9533a 100644
--- a/usr/src/cmd/sgs/librtld_db/common/librtld_db.msg
+++ b/usr/src/cmd/sgs/librtld_db/common/librtld_db.msg
@@ -24,6 +24,10 @@
# Use is subject to license terms.
#
+#
+# Copyright (c) 2014 Joyent, Inc. All rights reserved.
+#
+
# Message file for cmd/sgs/librtld_db.
@ MSG_ID_LIBRTLD_DB
@@ -104,7 +108,7 @@
@ MSG_DB_RDOBJPADE "rtld_db: rd_objpad_enable(padsize=0x%llx)"
@ MSG_DB_64BIT_PREFIX "64/"
@ MSG_DB_BRAND_HELPERPATH_PREFIX "%s/%s/%s/%s%s_librtld_db.so.1"
-@ MSG_DB_BRAND_HELPERPATH "%s/%s/%s%s_librtld_db.so.1"
+@ MSG_DB_BRAND_HELPERPATH "%s/%s/%s/%s%s_librtld_db.so.1"
@ MSG_DB_HELPERNOOPS "rtld_db: helper lib loaded but ops not preset"
@ MSG_DB_HELPERLOADED "rtld_db: helper library loaded for brand \"%s\""
@ MSG_DB_HELPERLOADFAILED "rtld_db: couldn't load brand helper library %s"
diff --git a/usr/src/cmd/sgs/librtld_db/common/rd_elf.c b/usr/src/cmd/sgs/librtld_db/common/rd_elf.c
index 410b819b30..b3de685b81 100644
--- a/usr/src/cmd/sgs/librtld_db/common/rd_elf.c
+++ b/usr/src/cmd/sgs/librtld_db/common/rd_elf.c
@@ -23,6 +23,10 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2014 Joyent, Inc. All rights reserved.
+ */
+
#include <stdlib.h>
#include <stdio.h>
#include <proc_service.h>
@@ -38,6 +42,14 @@
#include <sys/param.h>
/*
+ * We want to include zone.h to pull in the prototype for zone_get_nroot(),
+ * but we need to avoid pulling in <sys/stream.h>, which has a definition
+ * of M_DATA that conflicts with the ELF-related definition in machdep_*.h.
+ */
+#define _SYS_STREAM_H
+#include <zone.h>
+
+/*
* 64-bit builds are going to compile this module twice, the
* second time with _ELF64 defined. These defines should make
* all the necessary adjustments to the code.
@@ -283,7 +295,9 @@ _rd_reset32(struct rd_agent *rap)
* If we are debugging a branded executable, load the appropriate
* helper library, and call its initialization routine. Being unable
* to load the helper library is not a critical error. (Hopefully
- * we'll still be able to access some objects in the target.)
+ * we'll still be able to access some objects in the target.) Note
+ * that we pull in the native root here to allow for helper libraries
+ * to be properly found from within the branded zone.
*/
ps_pbrandname = (ps_pbrandname_fp_t)dlsym(RTLD_PROBE, "ps_pbrandname");
while ((ps_pbrandname != NULL) &&
@@ -294,17 +308,23 @@ _rd_reset32(struct rd_agent *rap)
isa = MSG_ORIG(MSG_DB_64BIT_PREFIX);
#endif /* _LP64 */
- if (rtld_db_helper_path[0] != '\0')
+ if (rtld_db_helper_path[0] != '\0') {
(void) snprintf(brandlib, MAXPATHLEN,
MSG_ORIG(MSG_DB_BRAND_HELPERPATH_PREFIX),
rtld_db_helper_path,
MSG_ORIG(MSG_DB_HELPER_PREFIX), brandname, isa,
brandname);
- else
+ } else {
+ const char *nroot = zone_get_nroot();
+
+ if (nroot == NULL)
+ nroot = "";
+
(void) snprintf(brandlib, MAXPATHLEN,
- MSG_ORIG(MSG_DB_BRAND_HELPERPATH),
+ MSG_ORIG(MSG_DB_BRAND_HELPERPATH), nroot,
MSG_ORIG(MSG_DB_HELPER_PREFIX), brandname, isa,
brandname);
+ }
rap->rd_helper.rh_dlhandle = dlopen(brandlib,
RTLD_LAZY | RTLD_LOCAL);
diff --git a/usr/src/cmd/sgs/rtld/common/_rtld.h b/usr/src/cmd/sgs/rtld/common/_rtld.h
index ece14a855e..83b7071471 100644
--- a/usr/src/cmd/sgs/rtld/common/_rtld.h
+++ b/usr/src/cmd/sgs/rtld/common/_rtld.h
@@ -26,7 +26,7 @@
* Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
*/
#ifndef __RTLD_H
#define __RTLD_H
@@ -589,6 +589,8 @@ extern const char *rpl_ldflags; /* replaceable LD_FLAGS string */
extern const char *rpl_libpath; /* replaceable LD_LIBRARY string */
extern Alist *rpl_libdirs; /* and its associated Pdesc list */
extern const char *rpl_preload; /* replaceable LD_PRELOAD string */
+extern const char *rpl_ldtoxic; /* replaceable LD_TOXIC_PATH string */
+extern Alist *rpl_toxdirs; /* and associated Pdesc list */
extern const char *prm_audit; /* permanent LD_AUDIT string */
extern const char *prm_debug; /* permanent LD_DEBUG string */
diff --git a/usr/src/cmd/sgs/rtld/common/analyze.c b/usr/src/cmd/sgs/rtld/common/analyze.c
index e14c121f07..3cae1036ae 100644
--- a/usr/src/cmd/sgs/rtld/common/analyze.c
+++ b/usr/src/cmd/sgs/rtld/common/analyze.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2015, Joyent, Inc.
*/
/*
@@ -834,6 +835,57 @@ is_so_loaded(Lm_list *lml, const char *name, int *in_nfavl)
}
/*
+ * Walk the toxic path list and determine if the object in question has violated
+ * the toxic path. When evaluating the toxic path we need to ensure that we
+ * match any path that's a subdirectory of a listed entry. In other words if
+ * /foo/bar is toxic, something in /foo/bar/baz/ is no good. However, we need to
+ * ensure that we don't mark /foo/barbaz/ as bad.
+ */
+static int
+is_load_toxic(Lm_list *lml, Rt_map *nlmp)
+{
+ const char *fpath;
+ size_t flen;
+ Pdesc *pdp;
+ Aliste idx;
+
+ fpath = PATHNAME(nlmp);
+
+ /*
+ * If we have a NULL path name, that indicates that rtld is processing
+ * an in-memory shared object. For example, trying to run ldd or doing
+ * an LD_PRELOAD on an object file. In those cases, we'll always allow
+ * it.
+ */
+ if (fpath == NULL)
+ return (0);
+
+ flen = strlen(fpath);
+
+ for (ALIST_TRAVERSE(rpl_toxdirs, idx, pdp)) {
+ if (pdp->pd_plen == 0)
+ continue;
+
+ if (strncmp(pdp->pd_pname, fpath, pdp->pd_plen) == 0) {
+ if (pdp->pd_pname[pdp->pd_plen-1] != '/') {
+ /*
+ * Path didn't end in a /, make sure
+ * we're at a directory boundary
+ * nonetheless.
+ */
+ if (flen > pdp->pd_plen &&
+ fpath[pdp->pd_plen] == '/')
+ return (1);
+ continue;
+ }
+ return (1);
+ }
+ }
+
+ return (0);
+}
+
+/*
* Tracing is enabled by the LD_TRACE_LOADED_OPTIONS environment variable which
* is normally set from ldd(1). For each link map we load, print the load name
* and the full pathname of the associated object.
@@ -2169,6 +2221,17 @@ load_finish(Lm_list *lml, const char *name, Rt_map *clmp, int nmode,
uint_t rdflags;
/*
+ * If this dependency is associated with a toxic path, then we must
+ * honor the user's request to die.
+ */
+ if (is_load_toxic(lml, nlmp) != 0) {
+ eprintf(lml, ERR_FATAL, MSG_INTL(MSG_TOXIC_FILE),
+ PATHNAME(nlmp));
+ rtldexit(lml, 1);
+
+ }
+
+ /*
* If this dependency is associated with a required version ensure that
* the version is present in the loaded file.
*/
diff --git a/usr/src/cmd/sgs/rtld/common/external.c b/usr/src/cmd/sgs/rtld/common/external.c
index 67429ac171..2476a6dbbc 100644
--- a/usr/src/cmd/sgs/rtld/common/external.c
+++ b/usr/src/cmd/sgs/rtld/common/external.c
@@ -22,7 +22,7 @@
/*
* Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2014 Garrett D'Amore <garrett@damore.org>
- * Copyright 2016 Joyent, Inc.
+ * Copyright (c) 2017, Joyent, Inc.
*/
/*
@@ -722,9 +722,9 @@ isalnum(int c)
#if defined(__i386) || defined(__amd64)
/*
- * Instead of utilizing the comm page for clock_gettime, rtld uses the raw
- * syscall instead. Doing so decreases the surface of symbols needed from libc
- * for a modest performance cost.
+ * Instead of utilizing the comm page for clock_gettime and gettimeofday, rtld
+ * uses the raw syscall instead. Doing so decreases the surface of symbols
+ * needed from libc for a modest performance cost.
*/
extern int __clock_gettime_sys(clockid_t, struct timespec *);
@@ -733,6 +733,22 @@ __clock_gettime(clockid_t clock_id, struct timespec *tp)
{
return (__clock_gettime_sys(clock_id, tp));
}
+
+int
+gettimeofday(struct timeval *tv, void *tz)
+{
+ if (tv != NULL) {
+ /*
+ * Perform the same logic as the libc gettimeofday() when it
+ * lacks comm page support: Make the clock_gettime syscall and
+ * divide out the tv_usec field as required.
+ */
+ __clock_gettime_sys(CLOCK_REALTIME, (timespec_t *)tv);
+ tv->tv_usec /= 1000;
+ }
+
+ return (0);
+}
#endif /* defined(__i386) || defined(__amd64) */
/*
diff --git a/usr/src/cmd/sgs/rtld/common/globals.c b/usr/src/cmd/sgs/rtld/common/globals.c
index 5f48fafc5f..2e98768551 100644
--- a/usr/src/cmd/sgs/rtld/common/globals.c
+++ b/usr/src/cmd/sgs/rtld/common/globals.c
@@ -24,6 +24,7 @@
* All Rights Reserved
*
* Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
*/
#include <sys/types.h>
@@ -132,6 +133,8 @@ const char *rpl_ldflags = NULL; /* replaceable LD_FLAGS string */
const char *rpl_libpath = NULL; /* replaceable LD_LIBRARY_PATH string */
Alist *rpl_libdirs = NULL; /* and associated Pdesc list */
const char *rpl_preload = NULL; /* replaceable LD_PRELOAD string */
+const char *rpl_ldtoxic = NULL; /* replaceable LD_TOXIC string */
+Alist *rpl_toxdirs = NULL; /* and associated Pdesc list */
const char *prm_audit = NULL; /* permanent LD_AUDIT string */
const char *prm_debug = NULL; /* permanent LD_DEBUG string */
diff --git a/usr/src/cmd/sgs/rtld/common/rtld.msg b/usr/src/cmd/sgs/rtld/common/rtld.msg
index 97e2841b8f..9309d0c62e 100644
--- a/usr/src/cmd/sgs/rtld/common/rtld.msg
+++ b/usr/src/cmd/sgs/rtld/common/rtld.msg
@@ -21,6 +21,7 @@
#
# Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, Joyent, Inc. All rights reserved.
#
@ _START_
@@ -99,9 +100,14 @@
@ MSG_SYS_MPROT "%s: mprotect failed: %s"
@ MSG_SYS_MMAPANON "mmap anon failed: %s"
+# Secure path failures
+
@ MSG_SEC_OPEN "%s: open failed: No such file in secure directories"
@ MSG_SEC_ILLEGAL "%s: open failed: illegal insecure pathname"
+# Toxic failures
+
+@ MSG_TOXIC_FILE "%s: dependency marked as toxic"
# Configuration failures
@@ -395,6 +401,7 @@
@ MSG_LD_PROFILE_OUTPUT "PROFILE_OUTPUT"
@ MSG_LD_SFCAP "SFCAP"
@ MSG_LD_SIGNAL "SIGNAL"
+@ MSG_LD_TOXICPATH "TOXIC_PATH"
@ MSG_LD_TRACE_OBJS "TRACE_LOADED_OBJECTS"
@ MSG_LD_TRACE_OBJS_E "TRACE_LOADED_OBJECTS_E"
@ MSG_LD_TRACE_OBJS_A "TRACE_LOADED_OBJECTS_A"
diff --git a/usr/src/cmd/sgs/rtld/common/setup.c b/usr/src/cmd/sgs/rtld/common/setup.c
index 862bb7d61f..98e3ba5d33 100644
--- a/usr/src/cmd/sgs/rtld/common/setup.c
+++ b/usr/src/cmd/sgs/rtld/common/setup.c
@@ -28,7 +28,7 @@
* All Rights Reserved
*/
/*
- * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
*/
/*
@@ -819,6 +819,14 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
return (0);
}
+ /*
+ * Initialize our toxic paths
+ */
+ if (rpl_ldtoxic != NULL) {
+ (void) expand_paths(mlmp, rpl_ldtoxic, &rpl_toxdirs,
+ AL_CNT_SEARCH, 0, PD_TKN_CAP);
+ }
+
#if defined(_ELF64)
/*
* If this is a 64-bit process, determine whether this process has
diff --git a/usr/src/cmd/sgs/rtld/common/util.c b/usr/src/cmd/sgs/rtld/common/util.c
index 046c8297a0..f10f7a4aed 100644
--- a/usr/src/cmd/sgs/rtld/common/util.c
+++ b/usr/src/cmd/sgs/rtld/common/util.c
@@ -24,6 +24,7 @@
* All Rights Reserved
*
* Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
*/
/*
@@ -1428,6 +1429,7 @@ static u_longlong_t cmdisa = 0; /* command line (-e) ISA */
#define ENV_FLG_CAP_FILES 0x0080000000000ULL
#define ENV_FLG_DEFERRED 0x0100000000000ULL
#define ENV_FLG_NOENVIRON 0x0200000000000ULL
+#define ENV_FLG_TOXICPATH 0x0400000000000ULL
#define SEL_REPLACE 0x0001
#define SEL_PERMANT 0x0002
@@ -1601,8 +1603,7 @@ ld_generic_env(const char *s1, size_t len, const char *s2, Word *lmflags,
if ((len == MSG_LD_FLAGS_SIZE) && (strncmp(s1,
MSG_ORIG(MSG_LD_FLAGS), MSG_LD_FLAGS_SIZE) == 0)) {
select |= SEL_ACT_SPEC_1;
- str = (select & SEL_REPLACE) ? &rpl_ldflags :
- &prm_ldflags;
+ str = &rpl_ldflags;
variable = ENV_FLG_FLAGS;
}
}
@@ -1813,6 +1814,8 @@ ld_generic_env(const char *s1, size_t len, const char *s2, Word *lmflags,
* In case an auditor is called, which in turn might exec(2) a
* subprocess, this variable is disabled, so that any subprocess
* escapes ldd(1) processing.
+ *
+ * Also, look for LD_TOXIC_PATH
*/
else if (*s1 == 'T') {
if (((len == MSG_LD_TRACE_OBJS_SIZE) &&
@@ -1850,7 +1853,13 @@ ld_generic_env(const char *s1, size_t len, const char *s2, Word *lmflags,
select |= SEL_ACT_LML;
val = LML_FLG_TRC_SEARCH;
variable = ENV_FLG_TRACE_PTHS;
+ } else if ((len == MSG_LD_TOXICPATH_SIZE) && (strncmp(s1,
+ MSG_ORIG(MSG_LD_TOXICPATH), MSG_LD_TOXICPATH_SIZE) == 0)) {
+ select |= SEL_ACT_SPEC_1;
+ str = &rpl_ldtoxic;
+ variable = ENV_FLG_TOXICPATH;
}
+
}
/*
* LD_UNREF and LD_UNUSED (internal, used by ldd(1)).
@@ -1974,7 +1983,8 @@ ld_generic_env(const char *s1, size_t len, const char *s2, Word *lmflags,
*lmtflags &= ~val;
} else if (select & SEL_ACT_SPEC_1) {
/*
- * variable is either ENV_FLG_FLAGS or ENV_FLG_LIBPATH
+ * variable is either ENV_FLG_FLAGS, ENV_FLG_LIBPATH, or
+ * ENV_FLG_TOXICPATH
*/
if (env_flags & ENV_TYP_NULL)
*str = NULL;
diff --git a/usr/src/cmd/sgs/yacc/common/dextern.h b/usr/src/cmd/sgs/yacc/common/dextern.h
index e90aa60468..54b441cac4 100644
--- a/usr/src/cmd/sgs/yacc/common/dextern.h
+++ b/usr/src/cmd/sgs/yacc/common/dextern.h
@@ -26,11 +26,13 @@
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
+
#ifndef _DEXTERN_H
#define _DEXTERN_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdio.h>
#include <inttypes.h>
#include <ctype.h>
@@ -42,6 +44,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <wctype.h>
+#include <limits.h>
#ifdef __cplusplus
extern "C" {
@@ -301,6 +304,12 @@ extern int wscmp(const wchar_t *, const wchar_t *);
extern char *parser;
+#ifndef PBUFSIZE
+#define PBUFSIZE PATH_MAX
+#endif
+
+extern char pbuf[PBUFSIZE];
+
/* default settings for a number of macros */
/* name of yacc tempfiles */
@@ -324,7 +333,11 @@ extern char *parser;
#endif
#ifndef PARSER
-#define PARSER "/usr/share/lib/ccs/yaccpar"
+#define PARSER "/share/lib/ccs/yaccpar"
+#endif
+
+#ifndef PARSERPREFIX
+#define PARSERPREFIX "/usr"
#endif
/*
diff --git a/usr/src/cmd/sgs/yacc/common/y1.c b/usr/src/cmd/sgs/yacc/common/y1.c
index 845f82d367..0e67d9047b 100644
--- a/usr/src/cmd/sgs/yacc/common/y1.c
+++ b/usr/src/cmd/sgs/yacc/common/y1.c
@@ -26,7 +26,9 @@
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
#include "dextern.h"
#include <sys/param.h>
@@ -34,6 +36,7 @@
#include <unistd.h>
#include <locale.h>
#include <stdarg.h> /* For error() */
+#include <libgen.h>
static void mktbls(void);
static void others(void);
@@ -236,6 +239,25 @@ mktbls()
lsetsize = INIT_LSIZE + 1;
}
+static int
+yacc_assemble_path(char *buf, size_t size, const char *file, int type)
+{
+ int ret;
+ char origin[PATH_MAX];
+
+ if (type != 0) {
+ ret = readlink("/proc/self/path/a.out", origin, PATH_MAX - 1);
+ if (ret < 0)
+ error(gettext(
+ "yacc: failed to read origin from /proc\n"));
+ origin[ret] = '\0';
+ return (snprintf(buf, size, "%s/../%s", dirname(origin),
+ file));
+ }
+
+ return (snprintf(buf, size, "%s/%s", PARSERPREFIX, file));
+}
+
/* put out other arrays, copy the parsers */
static void
others()
@@ -244,7 +266,17 @@ others()
int c, i, j;
int tmpline;
- finput = fopen(parser, "r");
+ if (parser == NULL) {
+ parser = pbuf;
+ (void) yacc_assemble_path(pbuf, PBUFSIZE, PARSER, 1);
+ finput = fopen(parser, "r");
+ if (finput == NULL) {
+ (void) yacc_assemble_path(pbuf, PBUFSIZE, PARSER, 0);
+ finput = fopen(parser, "r");
+ }
+ } else {
+ finput = fopen(parser, "r");
+ }
if (finput == NULL)
/*
* TRANSLATION_NOTE -- This is a message from yacc.
diff --git a/usr/src/cmd/sgs/yacc/common/y2.c b/usr/src/cmd/sgs/yacc/common/y2.c
index fbdaf19445..0d97f4260f 100644
--- a/usr/src/cmd/sgs/yacc/common/y2.c
+++ b/usr/src/cmd/sgs/yacc/common/y2.c
@@ -26,6 +26,10 @@
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
+
#include "dextern.h"
#include "sgs.h"
#include <stdio.h>
@@ -58,7 +62,8 @@ char *infile; /* input file name */
static int numbval; /* value of an input number */
static int toksize = NAMESIZE;
static wchar_t *tokname; /* input token name */
-char *parser = PARSER; /* location of common parser */
+char *parser = NULL; /* location of common parser */
+char pbuf[PBUFSIZE];
static void finact(void);
static wchar_t *cstash(wchar_t *);