build: remove unused linux related code

- Modules are not a feature of the Zephyr kernel.
- genksyms removed, not used by zephyr
- bin2c remove, not used in zephyr

Change-Id: Ic8f0e786530dcf410b07d6c5cc47f1087000d528
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
Anas Nashif 2015-12-06 19:38:53 -05:00
commit 3bdae61cac
18 changed files with 3 additions and 7264 deletions

View file

@ -301,7 +301,6 @@ STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
AWK = awk
GENKSYMS = scripts/genksyms/genksyms
GENIDT = scripts/gen_idt/gen_idt
GENOFFSET_H = scripts/gen_offset_header/gen_offset_header
PERL = perl
@ -377,7 +376,7 @@ export VERSION_MAJOR VERSION_MINOR PATCHLEVEL VERSION_RESERVED EXTRAVERSION
export KERNELRELEASE KERNELVERSION
export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
export CPP AR NM STRIP OBJCOPY OBJDUMP
export MAKE AWK GENKSYMS INSTALLKERNEL PERL PYTHON GENIDT GENOFFSET_H
export MAKE AWK INSTALLKERNEL PERL PYTHON GENIDT GENOFFSET_H
export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
export KBUILD_CPPFLAGS NOSTDINC_FLAGS ZEPHYRINCLUDE OBJCOPYFLAGS LDFLAGS
@ -421,14 +420,6 @@ ifneq ($(KBUILD_SRC),)
$(srctree) $(objtree) $(VERSION_MAJOR) $(VERSION_MINOR)
endif
# Support for using generic headers in asm-generic
PHONY += asm-generic
asm-generic:
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.asm-generic \
src=asm obj=arch/$(ARCH)/include/generated/asm
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.asm-generic \
src=uapi/asm obj=arch/$(ARCH)/include/generated/uapi/asm
# To make sure we do not include .config for any of the *config targets
# catch them early, and hand them over to scripts/kconfig/Makefile
# It is allowed to specify more targets when calling make, including
@ -757,8 +748,6 @@ libs-y := $(libs-y1) $(libs-y2)
# Externally visible symbols (used by link-zephyr.sh)
export KBUILD_ZEPHYR_MAIN := $(drivers-y) $(core-y) $(libs-y) $(app-y)
export LDFLAGS_zephyr
# used by scripts/pacmage/Makefile
export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(zephyr-alldirs)) arch include samples scripts)
zephyr-deps := $(KBUILD_LDS) $(KBUILD_ZEPHYR_MAIN)
@ -1012,8 +1001,8 @@ clean: $(clean-dirs)
@find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \
\( -name '*.[oas]' -o -name '.*.cmd' \
-o -name '*.dwo' -o -name '.*.d' -o -name '.*.tmp' \
-o -name '*.symtypes' -o -name '.tmp_*.o.*' \
-o -name '*.gcno' \) -type f -print | xargs rm -f
-o -name '.tmp_*.o.*' -o -name '*.gcno' \) -type f \
-print | xargs rm -f
# Generate tags for editors
# ---------------------------------------------------------------------------

View file

@ -184,12 +184,6 @@ build := -f $(srctree)/scripts/Makefile.build obj
# $(Q)$(MAKE) $(modbuiltin)=dir
modbuiltin := -f $(srctree)/scripts/Makefile.modbuiltin obj
###
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.dtbinst obj=
# Usage:
# $(Q)$(MAKE) $(dtbinst)=dir
dtbinst := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.dtbinst obj
###
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=
# Usage:

View file

@ -18,7 +18,5 @@ build_unifdef: $(obj)/unifdef
build_docproc: $(obj)/docproc
@:
subdir-$(CONFIG_MODVERSIONS) += genksyms
# Let clean descend into subdirs
subdir- += basic kconfig gen_idt

View file

@ -1,23 +0,0 @@
# include/asm-generic contains a lot of files that are used
# verbatim by several architectures.
#
# This Makefile reads the file arch/$(SRCARCH)/include/asm/Kbuild
# and for each file listed in this file with generic-y creates
# a small wrapper file in $(obj) (arch/$(SRCARCH)/include/generated/asm)
kbuild-file := $(srctree)/arch/$(SRCARCH)/include/$(src)/Kbuild
-include $(kbuild-file)
include scripts/Kbuild.include
# Create output directory if not already present
_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
quiet_cmd_wrap = WRAP $@
cmd_wrap = echo "\#include <asm-generic/$*.h>" >$@
all: $(patsubst %, $(obj)/%, $(generic-y))
@:
$(obj)/%.h:
$(call cmd,wrap)

View file

@ -110,11 +110,6 @@ ifneq ($(KBUILD_CHECKSRC),0)
endif
endif
# Do section mismatch analysis for each module/built-in.o
ifdef CONFIG_DEBUG_SECTION_MISMATCH
cmd_secanalysis = ; scripts/mod/modpost $@
endif
# Compile C sources (.c)
# ---------------------------------------------------------------------------
@ -161,88 +156,14 @@ cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $<
$(obj)/%.i: $(src)/%.c FORCE
$(call if_changed_dep,cc_i_c)
cmd_gensymtypes = \
$(CPP) -D__GENKSYMS__ $(c_flags) $< | \
$(GENKSYMS) $(if $(1), -T $(2)) \
$(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX)) \
$(if $(KBUILD_PRESERVE),-p) \
-r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
cmd_cc_symtypes_c = \
set -e; \
$(call cmd_gensymtypes,true,$@) >/dev/null; \
test -s $@ || rm -f $@
$(obj)/%.symtypes : $(src)/%.c FORCE
$(call cmd,cc_symtypes_c)
# C (.c) files
# The C file is compiled and updated dependency information is generated.
# (See cmd_cc_o_c + relevant part of rule_cc_o_c)
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
ifndef CONFIG_MODVERSIONS
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
else
# When module versioning is enabled the following steps are executed:
# o compile a .tmp_<file>.o from <file>.c
# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does
# not export symbols, we just rename .tmp_<file>.o to <file>.o and
# are done.
# o otherwise, we calculate symbol versions using the good old
# genksyms on the preprocessed source and postprocess them in a way
# that they are usable as a linker script
# o generate <file>.o from .tmp_<file>.o using the linker to
# replace the unresolved symbols __crc_exported_symbol with
# the actual value of the checksum generated by genksyms
cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
cmd_modversions = \
if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
$(call cmd_gensymtypes,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
> $(@D)/.tmp_$(@F:.o=.ver); \
\
$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
-T $(@D)/.tmp_$(@F:.o=.ver); \
rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
else \
mv -f $(@D)/.tmp_$(@F) $@; \
fi;
endif
ifdef CONFIG_FTRACE_MCOUNT_RECORD
ifdef BUILD_C_RECORDMCOUNT
ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")
RECORDMCOUNT_FLAGS = -w
endif
# Due to recursion, we must skip empty.o.
# The empty.o file is created in the make process in order to determine
# the target endianness and word size. It is made before all other C
# files, including recordmcount.
sub_cmd_record_mcount = \
if [ $(@) != "scripts/mod/empty.o" ]; then \
$(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; \
fi;
recordmcount_source := $(srctree)/scripts/recordmcount.c \
$(srctree)/scripts/recordmcount.h
else
sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
"$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
"$(if $(CONFIG_64BIT),64,32)" \
"$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CFLAGS)" \
"$(LD)" "$(NM)" "$(RM)" "$(MV)" \
"$(if $(part-of-module),1,0)" "$(@)";
recordmcount_source := $(srctree)/scripts/recordmcount.pl
endif
cmd_record_mcount = \
if [ "$(findstring -pg,$(_c_flags))" = "-pg" ]; then \
$(sub_cmd_record_mcount) \
fi;
endif
define rule_cc_o_c
$(call echo-cmd,checksrc) $(cmd_checksrc) \
$(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \

View file

@ -1,51 +0,0 @@
# ==========================================================================
# Installing dtb files
#
# Installs all dtb files listed in $(dtb-y) either in the
# INSTALL_DTBS_PATH directory or the default location:
#
# $INSTALL_PATH/dtbs/$KERNELRELEASE
#
# Traverse through subdirectories listed in $(dts-dirs).
# ==========================================================================
src := $(obj)
PHONY := __dtbs_install
__dtbs_install:
export dtbinst-root ?= $(obj)
include include/config/auto.conf
include scripts/Kbuild.include
include $(srctree)/$(obj)/Makefile
PHONY += __dtbs_install_prep
__dtbs_install_prep:
ifeq ("$(dtbinst-root)", "$(obj)")
$(Q)if [ -d $(INSTALL_DTBS_PATH).old ]; then rm -rf $(INSTALL_DTBS_PATH).old; fi
$(Q)if [ -d $(INSTALL_DTBS_PATH) ]; then mv $(INSTALL_DTBS_PATH) $(INSTALL_DTBS_PATH).old; fi
$(Q)mkdir -p $(INSTALL_DTBS_PATH)
endif
dtbinst-files := $(dtb-y)
dtbinst-dirs := $(dts-dirs)
# Helper targets for Installing DTBs into the boot directory
quiet_cmd_dtb_install = INSTALL $<
cmd_dtb_install = mkdir -p $(2); cp $< $(2)
install-dir = $(patsubst $(dtbinst-root)%,$(INSTALL_DTBS_PATH)%,$(obj))
$(dtbinst-files) $(dtbinst-dirs): | __dtbs_install_prep
$(dtbinst-files): %.dtb: $(obj)/%.dtb
$(call cmd,dtb_install,$(install-dir))
$(dtbinst-dirs):
$(Q)$(MAKE) $(dtbinst)=$(obj)/$@
PHONY += $(dtbinst-files) $(dtbinst-dirs)
__dtbs_install: $(dtbinst-files) $(dtbinst-dirs)
.PHONY: $(PHONY)

View file

@ -9,7 +9,6 @@
# fixdep: Used to generate dependency information during build process
hostprogs-y := fixdep
hostprogs-$(CONFIG_BUILD_BIN2C) += bin2c
always := $(hostprogs-y)
# fixdep is needed to compile other host programs

View file

@ -1,35 +0,0 @@
/*
* Unloved program to convert a binary on stdin to a C include on stdout
*
* Jan 1999 Matt Mackall <mpm@selenic.com>
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*/
#include <stdio.h>
int main(int argc, char *argv[])
{
int ch, total = 0;
if (argc > 1)
printf("const char %s[] %s=\n",
argv[1], argc > 2 ? argv[2] : "");
do {
printf("\t\"");
while ((ch = getchar()) != EOF) {
total++;
printf("\\x%02x", ch);
if (total % 16 == 0)
break;
}
printf("\"\n");
} while (ch != EOF);
if (argc > 1)
printf("\t;\n\nconst int %s_size = %d;\n", argv[1], total);
return 0;
}

View file

@ -1,14 +0,0 @@
hostprogs-y := genksyms
always := $(hostprogs-y)
genksyms-objs := genksyms.o parse.tab.o lex.lex.o
# -I needed for generated C source (shipped source)
HOSTCFLAGS_parse.tab.o := -I$(src)
HOSTCFLAGS_lex.lex.o := -I$(src)
# dependencies on generated files need to be listed explicitly
$(obj)/lex.lex.o: $(obj)/keywords.hash.c $(obj)/parse.tab.h
clean-files := keywords.hash.c lex.lex.c parse.tab.c parse.tab.h

View file

@ -1,875 +0,0 @@
/* Generate kernel symbol version hashes.
Copyright 1996, 1997 Linux International.
New implementation contributed by Richard Henderson <rth@tamu.edu>
Based on original work by Bjorn Ekwall <bj0rn@blox.se>
This file was part of the Linux modutils 2.4.22: moved back into the
kernel sources by Rusty Russell/Kai Germaschewski.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <stdarg.h>
#ifdef __GNU_LIBRARY__
#include <getopt.h>
#endif /* __GNU_LIBRARY__ */
#include "genksyms.h"
/*----------------------------------------------------------------------*/
#define HASH_BUCKETS 4096
static struct symbol *symtab[HASH_BUCKETS];
static FILE *debugfile;
int cur_line = 1;
char *cur_filename, *source_file;
int in_source_file;
static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,
flag_preserve, flag_warnings;
static const char *mod_prefix = "";
static int errors;
static int nsyms;
static struct symbol *expansion_trail;
static struct symbol *visited_symbols;
static const struct {
int n;
const char *name;
} symbol_types[] = {
[SYM_NORMAL] = { 0, NULL},
[SYM_TYPEDEF] = {'t', "typedef"},
[SYM_ENUM] = {'e', "enum"},
[SYM_STRUCT] = {'s', "struct"},
[SYM_UNION] = {'u', "union"},
[SYM_ENUM_CONST] = {'E', "enum constant"},
};
static int equal_list(struct string_list *a, struct string_list *b);
static void print_list(FILE * f, struct string_list *list);
static struct string_list *concat_list(struct string_list *start, ...);
static struct string_list *mk_node(const char *string);
static void print_location(void);
static void print_type_name(enum symbol_type type, const char *name);
/*----------------------------------------------------------------------*/
static const unsigned int crctab32[] = {
0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U,
0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U,
0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U,
0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU,
0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U,
0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U,
0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U,
0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU,
0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U,
0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU,
0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U,
0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U,
0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U,
0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU,
0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU,
0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U,
0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU,
0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U,
0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U,
0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U,
0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU,
0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U,
0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U,
0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU,
0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U,
0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U,
0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U,
0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U,
0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U,
0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU,
0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU,
0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U,
0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U,
0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU,
0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU,
0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U,
0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU,
0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U,
0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU,
0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U,
0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU,
0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U,
0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U,
0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU,
0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U,
0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U,
0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U,
0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U,
0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U,
0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U,
0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU,
0x2d02ef8dU
};
static unsigned long partial_crc32_one(unsigned char c, unsigned long crc)
{
return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
}
static unsigned long partial_crc32(const char *s, unsigned long crc)
{
while (*s)
crc = partial_crc32_one(*s++, crc);
return crc;
}
static unsigned long crc32(const char *s)
{
return partial_crc32(s, 0xffffffff) ^ 0xffffffff;
}
/*----------------------------------------------------------------------*/
static enum symbol_type map_to_ns(enum symbol_type t)
{
switch (t) {
case SYM_ENUM_CONST:
case SYM_NORMAL:
case SYM_TYPEDEF:
return SYM_NORMAL;
case SYM_ENUM:
case SYM_STRUCT:
case SYM_UNION:
return SYM_STRUCT;
}
return t;
}
struct symbol *find_symbol(const char *name, enum symbol_type ns, int exact)
{
unsigned long h = crc32(name) % HASH_BUCKETS;
struct symbol *sym;
for (sym = symtab[h]; sym; sym = sym->hash_next)
if (map_to_ns(sym->type) == map_to_ns(ns) &&
strcmp(name, sym->name) == 0 &&
sym->is_declared)
break;
if (exact && sym && sym->type != ns)
return NULL;
return sym;
}
static int is_unknown_symbol(struct symbol *sym)
{
struct string_list *defn;
return ((sym->type == SYM_STRUCT ||
sym->type == SYM_UNION ||
sym->type == SYM_ENUM) &&
(defn = sym->defn) && defn->tag == SYM_NORMAL &&
strcmp(defn->string, "}") == 0 &&
(defn = defn->next) && defn->tag == SYM_NORMAL &&
strcmp(defn->string, "UNKNOWN") == 0 &&
(defn = defn->next) && defn->tag == SYM_NORMAL &&
strcmp(defn->string, "{") == 0);
}
static struct symbol *__add_symbol(const char *name, enum symbol_type type,
struct string_list *defn, int is_extern,
int is_reference)
{
unsigned long h;
struct symbol *sym;
enum symbol_status status = STATUS_UNCHANGED;
/* The parser adds symbols in the order their declaration completes,
* so it is safe to store the value of the previous enum constant in
* a static variable.
*/
static int enum_counter;
static struct string_list *last_enum_expr;
if (type == SYM_ENUM_CONST) {
if (defn) {
free_list(last_enum_expr, NULL);
last_enum_expr = copy_list_range(defn, NULL);
enum_counter = 1;
} else {
struct string_list *expr;
char buf[20];
snprintf(buf, sizeof(buf), "%d", enum_counter++);
if (last_enum_expr) {
expr = copy_list_range(last_enum_expr, NULL);
defn = concat_list(mk_node("("),
expr,
mk_node(")"),
mk_node("+"),
mk_node(buf), NULL);
} else {
defn = mk_node(buf);
}
}
} else if (type == SYM_ENUM) {
free_list(last_enum_expr, NULL);
last_enum_expr = NULL;
enum_counter = 0;
if (!name)
/* Anonymous enum definition, nothing more to do */
return NULL;
}
h = crc32(name) % HASH_BUCKETS;
for (sym = symtab[h]; sym; sym = sym->hash_next) {
if (map_to_ns(sym->type) == map_to_ns(type) &&
strcmp(name, sym->name) == 0) {
if (is_reference)
/* fall through */ ;
else if (sym->type == type &&
equal_list(sym->defn, defn)) {
if (!sym->is_declared && sym->is_override) {
print_location();
print_type_name(type, name);
fprintf(stderr, " modversion is "
"unchanged\n");
}
sym->is_declared = 1;
return sym;
} else if (!sym->is_declared) {
if (sym->is_override && flag_preserve) {
print_location();
fprintf(stderr, "ignoring ");
print_type_name(type, name);
fprintf(stderr, " modversion change\n");
sym->is_declared = 1;
return sym;
} else {
status = is_unknown_symbol(sym) ?
STATUS_DEFINED : STATUS_MODIFIED;
}
} else {
error_with_pos("redefinition of %s", name);
return sym;
}
break;
}
}
if (sym) {
struct symbol **psym;
for (psym = &symtab[h]; *psym; psym = &(*psym)->hash_next) {
if (*psym == sym) {
*psym = sym->hash_next;
break;
}
}
--nsyms;
}
sym = xmalloc(sizeof(*sym));
sym->name = name;
sym->type = type;
sym->defn = defn;
sym->expansion_trail = NULL;
sym->visited = NULL;
sym->is_extern = is_extern;
sym->hash_next = symtab[h];
symtab[h] = sym;
sym->is_declared = !is_reference;
sym->status = status;
sym->is_override = 0;
if (flag_debug) {
if (symbol_types[type].name)
fprintf(debugfile, "Defn for %s %s == <",
symbol_types[type].name, name);
else
fprintf(debugfile, "Defn for type%d %s == <",
type, name);
if (is_extern)
fputs("extern ", debugfile);
print_list(debugfile, defn);
fputs(">\n", debugfile);
}
++nsyms;
return sym;
}
struct symbol *add_symbol(const char *name, enum symbol_type type,
struct string_list *defn, int is_extern)
{
return __add_symbol(name, type, defn, is_extern, 0);
}
static struct symbol *add_reference_symbol(const char *name, enum symbol_type type,
struct string_list *defn, int is_extern)
{
return __add_symbol(name, type, defn, is_extern, 1);
}
/*----------------------------------------------------------------------*/
void free_node(struct string_list *node)
{
free(node->string);
free(node);
}
void free_list(struct string_list *s, struct string_list *e)
{
while (s != e) {
struct string_list *next = s->next;
free_node(s);
s = next;
}
}
static struct string_list *mk_node(const char *string)
{
struct string_list *newnode;
newnode = xmalloc(sizeof(*newnode));
newnode->string = xstrdup(string);
newnode->tag = SYM_NORMAL;
newnode->next = NULL;
return newnode;
}
static struct string_list *concat_list(struct string_list *start, ...)
{
va_list ap;
struct string_list *n, *n2;
if (!start)
return NULL;
for (va_start(ap, start); (n = va_arg(ap, struct string_list *));) {
for (n2 = n; n2->next; n2 = n2->next)
;
n2->next = start;
start = n;
}
va_end(ap);
return start;
}
struct string_list *copy_node(struct string_list *node)
{
struct string_list *newnode;
newnode = xmalloc(sizeof(*newnode));
newnode->string = xstrdup(node->string);
newnode->tag = node->tag;
return newnode;
}
struct string_list *copy_list_range(struct string_list *start,
struct string_list *end)
{
struct string_list *res, *n;
if (start == end)
return NULL;
n = res = copy_node(start);
for (start = start->next; start != end; start = start->next) {
n->next = copy_node(start);
n = n->next;
}
n->next = NULL;
return res;
}
static int equal_list(struct string_list *a, struct string_list *b)
{
while (a && b) {
if (a->tag != b->tag || strcmp(a->string, b->string))
return 0;
a = a->next;
b = b->next;
}
return !a && !b;
}
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
static struct string_list *read_node(FILE *f)
{
char buffer[256];
struct string_list node = {
.string = buffer,
.tag = SYM_NORMAL };
int c;
while ((c = fgetc(f)) != EOF) {
if (c == ' ') {
if (node.string == buffer)
continue;
break;
} else if (c == '\n') {
if (node.string == buffer)
return NULL;
ungetc(c, f);
break;
}
if (node.string >= buffer + sizeof(buffer) - 1) {
fprintf(stderr, "Token too long\n");
exit(1);
}
*node.string++ = c;
}
if (node.string == buffer)
return NULL;
*node.string = 0;
node.string = buffer;
if (node.string[1] == '#') {
size_t n;
for (n = 0; n < ARRAY_SIZE(symbol_types); n++) {
if (node.string[0] == symbol_types[n].n) {
node.tag = n;
node.string += 2;
return copy_node(&node);
}
}
fprintf(stderr, "Unknown type %c\n", node.string[0]);
exit(1);
}
return copy_node(&node);
}
static void read_reference(FILE *f)
{
while (!feof(f)) {
struct string_list *defn = NULL;
struct string_list *sym, *def;
int is_extern = 0, is_override = 0;
struct symbol *subsym;
sym = read_node(f);
if (sym && sym->tag == SYM_NORMAL &&
!strcmp(sym->string, "override")) {
is_override = 1;
free_node(sym);
sym = read_node(f);
}
if (!sym)
continue;
def = read_node(f);
if (def && def->tag == SYM_NORMAL &&
!strcmp(def->string, "extern")) {
is_extern = 1;
free_node(def);
def = read_node(f);
}
while (def) {
def->next = defn;
defn = def;
def = read_node(f);
}
subsym = add_reference_symbol(xstrdup(sym->string), sym->tag,
defn, is_extern);
subsym->is_override = is_override;
free_node(sym);
}
}
static void print_node(FILE * f, struct string_list *list)
{
if (symbol_types[list->tag].n) {
putc(symbol_types[list->tag].n, f);
putc('#', f);
}
fputs(list->string, f);
}
static void print_list(FILE * f, struct string_list *list)
{
struct string_list **e, **b;
struct string_list *tmp, **tmp2;
int elem = 1;
if (list == NULL) {
fputs("(nil)", f);
return;
}
tmp = list;
while ((tmp = tmp->next) != NULL)
elem++;
b = alloca(elem * sizeof(*e));
e = b + elem;
tmp2 = e - 1;
(*tmp2--) = list;
while ((list = list->next) != NULL)
*(tmp2--) = list;
while (b != e) {
print_node(f, *b++);
putc(' ', f);
}
}
static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
{
struct string_list *list = sym->defn;
struct string_list **e, **b;
struct string_list *tmp, **tmp2;
int elem = 1;
if (!list)
return crc;
tmp = list;
while ((tmp = tmp->next) != NULL)
elem++;
b = alloca(elem * sizeof(*e));
e = b + elem;
tmp2 = e - 1;
*(tmp2--) = list;
while ((list = list->next) != NULL)
*(tmp2--) = list;
while (b != e) {
struct string_list *cur;
struct symbol *subsym;
cur = *(b++);
switch (cur->tag) {
case SYM_NORMAL:
if (flag_dump_defs)
fprintf(debugfile, "%s ", cur->string);
crc = partial_crc32(cur->string, crc);
crc = partial_crc32_one(' ', crc);
break;
case SYM_ENUM_CONST:
case SYM_TYPEDEF:
subsym = find_symbol(cur->string, cur->tag, 0);
/* FIXME: Bad reference files can segfault here. */
if (subsym->expansion_trail) {
if (flag_dump_defs)
fprintf(debugfile, "%s ", cur->string);
crc = partial_crc32(cur->string, crc);
crc = partial_crc32_one(' ', crc);
} else {
subsym->expansion_trail = expansion_trail;
expansion_trail = subsym;
crc = expand_and_crc_sym(subsym, crc);
}
break;
case SYM_STRUCT:
case SYM_UNION:
case SYM_ENUM:
subsym = find_symbol(cur->string, cur->tag, 0);
if (!subsym) {
struct string_list *n;
error_with_pos("expand undefined %s %s",
symbol_types[cur->tag].name,
cur->string);
n = concat_list(mk_node
(symbol_types[cur->tag].name),
mk_node(cur->string),
mk_node("{"),
mk_node("UNKNOWN"),
mk_node("}"), NULL);
subsym =
add_symbol(cur->string, cur->tag, n, 0);
}
if (subsym->expansion_trail) {
if (flag_dump_defs) {
fprintf(debugfile, "%s %s ",
symbol_types[cur->tag].name,
cur->string);
}
crc = partial_crc32(symbol_types[cur->tag].name,
crc);
crc = partial_crc32_one(' ', crc);
crc = partial_crc32(cur->string, crc);
crc = partial_crc32_one(' ', crc);
} else {
subsym->expansion_trail = expansion_trail;
expansion_trail = subsym;
crc = expand_and_crc_sym(subsym, crc);
}
break;
}
}
{
static struct symbol **end = &visited_symbols;
if (!sym->visited) {
*end = sym;
end = &sym->visited;
sym->visited = (struct symbol *)-1L;
}
}
return crc;
}
void export_symbol(const char *name)
{
struct symbol *sym;
sym = find_symbol(name, SYM_NORMAL, 0);
if (!sym)
error_with_pos("export undefined symbol %s", name);
else {
unsigned long crc;
int has_changed = 0;
if (flag_dump_defs)
fprintf(debugfile, "Export %s == <", name);
expansion_trail = (struct symbol *)-1L;
sym->expansion_trail = expansion_trail;
expansion_trail = sym;
crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
sym = expansion_trail;
while (sym != (struct symbol *)-1L) {
struct symbol *n = sym->expansion_trail;
if (sym->status != STATUS_UNCHANGED) {
if (!has_changed) {
print_location();
fprintf(stderr, "%s: %s: modversion "
"changed because of changes "
"in ", flag_preserve ? "error" :
"warning", name);
} else
fprintf(stderr, ", ");
print_type_name(sym->type, sym->name);
if (sym->status == STATUS_DEFINED)
fprintf(stderr, " (became defined)");
has_changed = 1;
if (flag_preserve)
errors++;
}
sym->expansion_trail = 0;
sym = n;
}
if (has_changed)
fprintf(stderr, "\n");
if (flag_dump_defs)
fputs(">\n", debugfile);
/* Used as a linker script. */
printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc);
}
}
/*----------------------------------------------------------------------*/
static void print_location(void)
{
fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line);
}
static void print_type_name(enum symbol_type type, const char *name)
{
if (symbol_types[type].name)
fprintf(stderr, "%s %s", symbol_types[type].name, name);
else
fprintf(stderr, "%s", name);
}
void error_with_pos(const char *fmt, ...)
{
va_list args;
if (flag_warnings) {
print_location();
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
putc('\n', stderr);
errors++;
}
}
static void genksyms_usage(void)
{
fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n"
#ifdef __GNU_LIBRARY__
" -s, --symbol-prefix Select symbol prefix\n"
" -d, --debug Increment the debug level (repeatable)\n"
" -D, --dump Dump expanded symbol defs (for debugging only)\n"
" -r, --reference file Read reference symbols from a file\n"
" -T, --dump-types file Dump expanded types into file\n"
" -p, --preserve Preserve reference modversions or fail\n"
" -w, --warnings Enable warnings\n"
" -q, --quiet Disable warnings (default)\n"
" -h, --help Print this message\n"
" -V, --version Print the release version\n"
#else /* __GNU_LIBRARY__ */
" -s Select symbol prefix\n"
" -d Increment the debug level (repeatable)\n"
" -D Dump expanded symbol defs (for debugging only)\n"
" -r file Read reference symbols from a file\n"
" -T file Dump expanded types into file\n"
" -p Preserve reference modversions or fail\n"
" -w Enable warnings\n"
" -q Disable warnings (default)\n"
" -h Print this message\n"
" -V Print the release version\n"
#endif /* __GNU_LIBRARY__ */
, stderr);
}
int main(int argc, char **argv)
{
FILE *dumpfile = NULL, *ref_file = NULL;
int o;
#ifdef __GNU_LIBRARY__
struct option long_opts[] = {
{"symbol-prefix", 1, 0, 's'},
{"debug", 0, 0, 'd'},
{"warnings", 0, 0, 'w'},
{"quiet", 0, 0, 'q'},
{"dump", 0, 0, 'D'},
{"reference", 1, 0, 'r'},
{"dump-types", 1, 0, 'T'},
{"preserve", 0, 0, 'p'},
{"version", 0, 0, 'V'},
{"help", 0, 0, 'h'},
{0, 0, 0, 0}
};
while ((o = getopt_long(argc, argv, "s:dwqVDr:T:ph",
&long_opts[0], NULL)) != EOF)
#else /* __GNU_LIBRARY__ */
while ((o = getopt(argc, argv, "s:dwqVDr:T:ph")) != EOF)
#endif /* __GNU_LIBRARY__ */
switch (o) {
case 's':
mod_prefix = optarg;
break;
case 'd':
flag_debug++;
break;
case 'w':
flag_warnings = 1;
break;
case 'q':
flag_warnings = 0;
break;
case 'V':
fputs("genksyms version 2.5.60\n", stderr);
break;
case 'D':
flag_dump_defs = 1;
break;
case 'r':
flag_reference = 1;
ref_file = fopen(optarg, "r");
if (!ref_file) {
perror(optarg);
return 1;
}
break;
case 'T':
flag_dump_types = 1;
dumpfile = fopen(optarg, "w");
if (!dumpfile) {
perror(optarg);
return 1;
}
break;
case 'p':
flag_preserve = 1;
break;
case 'h':
genksyms_usage();
return 0;
default:
genksyms_usage();
return 1;
}
{
extern int yydebug;
extern int yy_flex_debug;
yydebug = (flag_debug > 1);
yy_flex_debug = (flag_debug > 2);
debugfile = stderr;
/* setlinebuf(debugfile); */
}
if (flag_reference) {
read_reference(ref_file);
fclose(ref_file);
}
yyparse();
if (flag_dump_types && visited_symbols) {
while (visited_symbols != (struct symbol *)-1L) {
struct symbol *sym = visited_symbols;
if (sym->is_override)
fputs("override ", dumpfile);
if (symbol_types[sym->type].n) {
putc(symbol_types[sym->type].n, dumpfile);
putc('#', dumpfile);
}
fputs(sym->name, dumpfile);
putc(' ', dumpfile);
if (sym->is_extern)
fputs("extern ", dumpfile);
print_list(dumpfile, sym->defn);
putc('\n', dumpfile);
visited_symbols = sym->visited;
sym->visited = NULL;
}
}
if (flag_debug) {
fprintf(debugfile, "Hash table occupancy %d/%d = %g\n",
nsyms, HASH_BUCKETS,
(double)nsyms / (double)HASH_BUCKETS);
}
return errors != 0;
}

View file

@ -1,94 +0,0 @@
/* Generate kernel symbol version hashes.
Copyright 1996, 1997 Linux International.
New implementation contributed by Richard Henderson <rth@tamu.edu>
Based on original work by Bjorn Ekwall <bj0rn@blox.se>
This file is part of the Linux modutils.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef MODUTILS_GENKSYMS_H
#define MODUTILS_GENKSYMS_H 1
#include <stdio.h>
enum symbol_type {
SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION,
SYM_ENUM_CONST
};
enum symbol_status {
STATUS_UNCHANGED, STATUS_DEFINED, STATUS_MODIFIED
};
struct string_list {
struct string_list *next;
enum symbol_type tag;
int in_source_file;
char *string;
};
struct symbol {
struct symbol *hash_next;
const char *name;
enum symbol_type type;
struct string_list *defn;
struct symbol *expansion_trail;
struct symbol *visited;
int is_extern;
int is_declared;
enum symbol_status status;
int is_override;
};
typedef struct string_list **yystype;
#define YYSTYPE yystype
extern int cur_line;
extern char *cur_filename, *source_file;
extern int in_source_file;
struct symbol *find_symbol(const char *name, enum symbol_type ns, int exact);
struct symbol *add_symbol(const char *name, enum symbol_type type,
struct string_list *defn, int is_extern);
void export_symbol(const char *);
void free_node(struct string_list *list);
void free_list(struct string_list *s, struct string_list *e);
struct string_list *copy_node(struct string_list *);
struct string_list *copy_list_range(struct string_list *start,
struct string_list *end);
int yylex(void);
int yyparse(void);
void error_with_pos(const char *, ...);
/*----------------------------------------------------------------------*/
#define xmalloc(size) ({ void *__ptr = malloc(size); \
if(!__ptr && size != 0) { \
fprintf(stderr, "out of memory\n"); \
exit(1); \
} \
__ptr; })
#define xstrdup(str) ({ char *__str = strdup(str); \
if (!__str) { \
fprintf(stderr, "out of memory\n"); \
exit(1); \
} \
__str; })
#endif /* genksyms.h */

View file

@ -1,60 +0,0 @@
%language=ANSI-C
%define hash-function-name is_reserved_hash
%define lookup-function-name is_reserved_word
%{
struct resword;
static const struct resword *is_reserved_word(register const char *str, register unsigned int len);
%}
struct resword { const char *name; int token; }
%%
EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW
EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW
EXPORT_UNUSED_SYMBOL, EXPORT_SYMBOL_KEYW
EXPORT_UNUSED_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
__asm, ASM_KEYW
__asm__, ASM_KEYW
__attribute, ATTRIBUTE_KEYW
__attribute__, ATTRIBUTE_KEYW
__const, CONST_KEYW
__const__, CONST_KEYW
__extension__, EXTENSION_KEYW
__inline, INLINE_KEYW
__inline__, INLINE_KEYW
__signed, SIGNED_KEYW
__signed__, SIGNED_KEYW
__typeof, TYPEOF_KEYW
__typeof__, TYPEOF_KEYW
__volatile, VOLATILE_KEYW
__volatile__, VOLATILE_KEYW
# According to rth, c99 defines _Bool, __restrict, __restrict__, restrict. KAO
_Bool, BOOL_KEYW
_restrict, RESTRICT_KEYW
__restrict__, RESTRICT_KEYW
restrict, RESTRICT_KEYW
asm, ASM_KEYW
# attribute commented out in modutils 2.4.2. People are using 'attribute' as a
# field name which breaks the genksyms parser. It is not a gcc keyword anyway.
# KAO.
# attribute, ATTRIBUTE_KEYW
auto, AUTO_KEYW
char, CHAR_KEYW
const, CONST_KEYW
double, DOUBLE_KEYW
enum, ENUM_KEYW
extern, EXTERN_KEYW
float, FLOAT_KEYW
inline, INLINE_KEYW
int, INT_KEYW
long, LONG_KEYW
register, REGISTER_KEYW
short, SHORT_KEYW
signed, SIGNED_KEYW
static, STATIC_KEYW
struct, STRUCT_KEYW
typedef, TYPEDEF_KEYW
typeof, TYPEOF_KEYW
union, UNION_KEYW
unsigned, UNSIGNED_KEYW
void, VOID_KEYW
volatile, VOLATILE_KEYW

View file

@ -1,229 +0,0 @@
/* ANSI-C code produced by gperf version 3.0.4 */
/* Command-line: gperf -t --output-file scripts/genksyms/keywords.hash.c_shipped -a -C -E -g -k '1,3,$' -p -t scripts/genksyms/keywords.gperf */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
/* The character set is not based on ISO-646. */
#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
#endif
#line 4 "scripts/genksyms/keywords.gperf"
struct resword;
static const struct resword *is_reserved_word(register const char *str, register unsigned int len);
#line 8 "scripts/genksyms/keywords.gperf"
struct resword { const char *name; int token; };
/* maximum key range = 98, duplicates = 0 */
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static unsigned int
is_reserved_hash (register const char *str, register unsigned int len)
{
static const unsigned char asso_values[] =
{
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 0,
101, 101, 101, 101, 101, 101, 15, 101, 101, 101,
0, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 0, 101, 0, 101, 5,
25, 20, 55, 30, 101, 15, 101, 101, 10, 0,
10, 40, 10, 101, 10, 5, 0, 10, 15, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
101, 101, 101, 101, 101, 101
};
return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
}
#ifdef __GNUC__
__inline
#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
__attribute__ ((__gnu_inline__))
#endif
#endif
const struct resword *
is_reserved_word (register const char *str, register unsigned int len)
{
enum
{
TOTAL_KEYWORDS = 46,
MIN_WORD_LENGTH = 3,
MAX_WORD_LENGTH = 24,
MIN_HASH_VALUE = 3,
MAX_HASH_VALUE = 100
};
static const struct resword wordlist[] =
{
{""}, {""}, {""},
#line 35 "scripts/genksyms/keywords.gperf"
{"asm", ASM_KEYW},
{""},
#line 15 "scripts/genksyms/keywords.gperf"
{"__asm", ASM_KEYW},
{""},
#line 16 "scripts/genksyms/keywords.gperf"
{"__asm__", ASM_KEYW},
{""}, {""},
#line 27 "scripts/genksyms/keywords.gperf"
{"__typeof__", TYPEOF_KEYW},
{""},
#line 19 "scripts/genksyms/keywords.gperf"
{"__const", CONST_KEYW},
#line 18 "scripts/genksyms/keywords.gperf"
{"__attribute__", ATTRIBUTE_KEYW},
#line 20 "scripts/genksyms/keywords.gperf"
{"__const__", CONST_KEYW},
#line 25 "scripts/genksyms/keywords.gperf"
{"__signed__", SIGNED_KEYW},
#line 53 "scripts/genksyms/keywords.gperf"
{"static", STATIC_KEYW},
{""},
#line 48 "scripts/genksyms/keywords.gperf"
{"int", INT_KEYW},
#line 41 "scripts/genksyms/keywords.gperf"
{"char", CHAR_KEYW},
#line 42 "scripts/genksyms/keywords.gperf"
{"const", CONST_KEYW},
#line 54 "scripts/genksyms/keywords.gperf"
{"struct", STRUCT_KEYW},
#line 33 "scripts/genksyms/keywords.gperf"
{"__restrict__", RESTRICT_KEYW},
#line 34 "scripts/genksyms/keywords.gperf"
{"restrict", RESTRICT_KEYW},
#line 12 "scripts/genksyms/keywords.gperf"
{"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW},
#line 23 "scripts/genksyms/keywords.gperf"
{"__inline__", INLINE_KEYW},
{""},
#line 29 "scripts/genksyms/keywords.gperf"
{"__volatile__", VOLATILE_KEYW},
#line 10 "scripts/genksyms/keywords.gperf"
{"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
#line 32 "scripts/genksyms/keywords.gperf"
{"_restrict", RESTRICT_KEYW},
{""},
#line 17 "scripts/genksyms/keywords.gperf"
{"__attribute", ATTRIBUTE_KEYW},
#line 11 "scripts/genksyms/keywords.gperf"
{"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
#line 21 "scripts/genksyms/keywords.gperf"
{"__extension__", EXTENSION_KEYW},
#line 44 "scripts/genksyms/keywords.gperf"
{"enum", ENUM_KEYW},
#line 13 "scripts/genksyms/keywords.gperf"
{"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW},
#line 45 "scripts/genksyms/keywords.gperf"
{"extern", EXTERN_KEYW},
{""},
#line 24 "scripts/genksyms/keywords.gperf"
{"__signed", SIGNED_KEYW},
#line 14 "scripts/genksyms/keywords.gperf"
{"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
#line 57 "scripts/genksyms/keywords.gperf"
{"union", UNION_KEYW},
{""}, {""},
#line 22 "scripts/genksyms/keywords.gperf"
{"__inline", INLINE_KEYW},
#line 40 "scripts/genksyms/keywords.gperf"
{"auto", AUTO_KEYW},
#line 28 "scripts/genksyms/keywords.gperf"
{"__volatile", VOLATILE_KEYW},
{""}, {""},
#line 58 "scripts/genksyms/keywords.gperf"
{"unsigned", UNSIGNED_KEYW},
{""},
#line 51 "scripts/genksyms/keywords.gperf"
{"short", SHORT_KEYW},
#line 47 "scripts/genksyms/keywords.gperf"
{"inline", INLINE_KEYW},
{""},
#line 60 "scripts/genksyms/keywords.gperf"
{"volatile", VOLATILE_KEYW},
#line 49 "scripts/genksyms/keywords.gperf"
{"long", LONG_KEYW},
#line 31 "scripts/genksyms/keywords.gperf"
{"_Bool", BOOL_KEYW},
{""}, {""},
#line 50 "scripts/genksyms/keywords.gperf"
{"register", REGISTER_KEYW},
#line 59 "scripts/genksyms/keywords.gperf"
{"void", VOID_KEYW},
{""},
#line 43 "scripts/genksyms/keywords.gperf"
{"double", DOUBLE_KEYW},
{""},
#line 26 "scripts/genksyms/keywords.gperf"
{"__typeof", TYPEOF_KEYW},
{""}, {""},
#line 52 "scripts/genksyms/keywords.gperf"
{"signed", SIGNED_KEYW},
{""}, {""}, {""}, {""},
#line 56 "scripts/genksyms/keywords.gperf"
{"typeof", TYPEOF_KEYW},
#line 55 "scripts/genksyms/keywords.gperf"
{"typedef", TYPEDEF_KEYW},
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
#line 46 "scripts/genksyms/keywords.gperf"
{"float", FLOAT_KEYW}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
register int key = is_reserved_hash (str, len);
if (key <= MAX_HASH_VALUE && key >= 0)
{
register const char *s = wordlist[key].name;
if (*str == *s && !strcmp (str + 1, s + 1))
return &wordlist[key];
}
}
return 0;
}

View file

@ -1,482 +0,0 @@
/* Lexical analysis for genksyms.
Copyright 1996, 1997 Linux International.
New implementation contributed by Richard Henderson <rth@tamu.edu>
Based on original work by Bjorn Ekwall <bj0rn@blox.se>
Taken from Linux modutils 2.4.22.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
%{
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "genksyms.h"
#include "parse.tab.h"
/* We've got a two-level lexer here. We let flex do basic tokenization
and then we categorize those basic tokens in the second stage. */
#define YY_DECL static int yylex1(void)
%}
IDENT [A-Za-z_\$][A-Za-z0-9_\$]*
O_INT 0[0-7]*
D_INT [1-9][0-9]*
X_INT 0[Xx][0-9A-Fa-f]+
I_SUF [Uu]|[Ll]|[Uu][Ll]|[Ll][Uu]
INT ({O_INT}|{D_INT}|{X_INT}){I_SUF}?
FRAC ([0-9]*\.[0-9]+)|([0-9]+\.)
EXP [Ee][+-]?[0-9]+
F_SUF [FfLl]
REAL ({FRAC}{EXP}?{F_SUF}?)|([0-9]+{EXP}{F_SUF}?)
STRING L?\"([^\\\"]*\\.)*[^\\\"]*\"
CHAR L?\'([^\\\']*\\.)*[^\\\']*\'
MC_TOKEN ([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>)
/* We don't do multiple input files. */
%option noyywrap
%option noinput
%%
/* Keep track of our location in the original source files. */
^#[ \t]+{INT}[ \t]+\"[^\"\n]+\".*\n return FILENAME;
^#.*\n cur_line++;
\n cur_line++;
/* Ignore all other whitespace. */
[ \t\f\v\r]+ ;
{STRING} return STRING;
{CHAR} return CHAR;
{IDENT} return IDENT;
/* The Pedant requires that the other C multi-character tokens be
recognized as tokens. We don't actually use them since we don't
parse expressions, but we do want whitespace to be arranged
around them properly. */
{MC_TOKEN} return OTHER;
{INT} return INT;
{REAL} return REAL;
"..." return DOTS;
/* All other tokens are single characters. */
. return yytext[0];
%%
/* Bring in the keyword recognizer. */
#include "keywords.hash.c"
/* Macros to append to our phrase collection list. */
/*
* We mark any token, that that equals to a known enumerator, as
* SYM_ENUM_CONST. The parser will change this for struct and union tags later,
* the only problem is struct and union members:
* enum e { a, b }; struct s { int a, b; }
* but in this case, the only effect will be, that the ABI checksums become
* more volatile, which is acceptable. Also, such collisions are quite rare,
* so far it was only observed in include/linux/telephony.h.
*/
#define _APP(T,L) do { \
cur_node = next_node; \
next_node = xmalloc(sizeof(*next_node)); \
next_node->next = cur_node; \
cur_node->string = memcpy(xmalloc(L+1), T, L+1); \
cur_node->tag = \
find_symbol(cur_node->string, SYM_ENUM_CONST, 1)?\
SYM_ENUM_CONST : SYM_NORMAL ; \
cur_node->in_source_file = in_source_file; \
} while (0)
#define APP _APP(yytext, yyleng)
/* The second stage lexer. Here we incorporate knowledge of the state
of the parser to tailor the tokens that are returned. */
int
yylex(void)
{
static enum {
ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_TYPEOF, ST_TYPEOF_1,
ST_BRACKET, ST_BRACE, ST_EXPRESSION,
ST_TABLE_1, ST_TABLE_2, ST_TABLE_3, ST_TABLE_4,
ST_TABLE_5, ST_TABLE_6
} lexstate = ST_NOTSTARTED;
static int suppress_type_lookup, dont_want_brace_phrase;
static struct string_list *next_node;
int token, count = 0;
struct string_list *cur_node;
if (lexstate == ST_NOTSTARTED)
{
next_node = xmalloc(sizeof(*next_node));
next_node->next = NULL;
lexstate = ST_NORMAL;
}
repeat:
token = yylex1();
if (token == 0)
return 0;
else if (token == FILENAME)
{
char *file, *e;
/* Save the filename and line number for later error messages. */
if (cur_filename)
free(cur_filename);
file = strchr(yytext, '\"')+1;
e = strchr(file, '\"');
*e = '\0';
cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
cur_line = atoi(yytext+2);
if (!source_file) {
source_file = xstrdup(cur_filename);
in_source_file = 1;
} else {
in_source_file = (strcmp(cur_filename, source_file) == 0);
}
goto repeat;
}
switch (lexstate)
{
case ST_NORMAL:
switch (token)
{
case IDENT:
APP;
{
const struct resword *r = is_reserved_word(yytext, yyleng);
if (r)
{
switch (token = r->token)
{
case ATTRIBUTE_KEYW:
lexstate = ST_ATTRIBUTE;
count = 0;
goto repeat;
case ASM_KEYW:
lexstate = ST_ASM;
count = 0;
goto repeat;
case TYPEOF_KEYW:
lexstate = ST_TYPEOF;
count = 0;
goto repeat;
case STRUCT_KEYW:
case UNION_KEYW:
case ENUM_KEYW:
dont_want_brace_phrase = 3;
suppress_type_lookup = 2;
goto fini;
case EXPORT_SYMBOL_KEYW:
goto fini;
}
}
if (!suppress_type_lookup)
{
if (find_symbol(yytext, SYM_TYPEDEF, 1))
token = TYPE;
}
}
break;
case '[':
APP;
lexstate = ST_BRACKET;
count = 1;
goto repeat;
case '{':
APP;
if (dont_want_brace_phrase)
break;
lexstate = ST_BRACE;
count = 1;
goto repeat;
case '=': case ':':
APP;
lexstate = ST_EXPRESSION;
break;
case DOTS:
default:
APP;
break;
}
break;
case ST_ATTRIBUTE:
APP;
switch (token)
{
case '(':
++count;
goto repeat;
case ')':
if (--count == 0)
{
lexstate = ST_NORMAL;
token = ATTRIBUTE_PHRASE;
break;
}
goto repeat;
default:
goto repeat;
}
break;
case ST_ASM:
APP;
switch (token)
{
case '(':
++count;
goto repeat;
case ')':
if (--count == 0)
{
lexstate = ST_NORMAL;
token = ASM_PHRASE;
break;
}
goto repeat;
default:
goto repeat;
}
break;
case ST_TYPEOF:
switch (token)
{
case '(':
if ( ++count == 1 )
lexstate = ST_TYPEOF_1;
else
APP;
goto repeat;
case ')':
APP;
if (--count == 0)
{
lexstate = ST_NORMAL;
token = TYPEOF_PHRASE;
break;
}
goto repeat;
default:
APP;
goto repeat;
}
break;
case ST_TYPEOF_1:
if (token == IDENT)
{
if (is_reserved_word(yytext, yyleng)
|| find_symbol(yytext, SYM_TYPEDEF, 1))
{
yyless(0);
unput('(');
lexstate = ST_NORMAL;
token = TYPEOF_KEYW;
break;
}
_APP("(", 1);
}
APP;
lexstate = ST_TYPEOF;
goto repeat;
case ST_BRACKET:
APP;
switch (token)
{
case '[':
++count;
goto repeat;
case ']':
if (--count == 0)
{
lexstate = ST_NORMAL;
token = BRACKET_PHRASE;
break;
}
goto repeat;
default:
goto repeat;
}
break;
case ST_BRACE:
APP;
switch (token)
{
case '{':
++count;
goto repeat;
case '}':
if (--count == 0)
{
lexstate = ST_NORMAL;
token = BRACE_PHRASE;
break;
}
goto repeat;
default:
goto repeat;
}
break;
case ST_EXPRESSION:
switch (token)
{
case '(': case '[': case '{':
++count;
APP;
goto repeat;
case '}':
/* is this the last line of an enum declaration? */
if (count == 0)
{
/* Put back the token we just read so's we can find it again
after registering the expression. */
unput(token);
lexstate = ST_NORMAL;
token = EXPRESSION_PHRASE;
break;
}
/* FALLTHRU */
case ')': case ']':
--count;
APP;
goto repeat;
case ',': case ';':
if (count == 0)
{
/* Put back the token we just read so's we can find it again
after registering the expression. */
unput(token);
lexstate = ST_NORMAL;
token = EXPRESSION_PHRASE;
break;
}
APP;
goto repeat;
default:
APP;
goto repeat;
}
break;
case ST_TABLE_1:
goto repeat;
case ST_TABLE_2:
if (token == IDENT && yyleng == 1 && yytext[0] == 'X')
{
token = EXPORT_SYMBOL_KEYW;
lexstate = ST_TABLE_5;
APP;
break;
}
lexstate = ST_TABLE_6;
/* FALLTHRU */
case ST_TABLE_6:
switch (token)
{
case '{': case '[': case '(':
++count;
break;
case '}': case ']': case ')':
--count;
break;
case ',':
if (count == 0)
lexstate = ST_TABLE_2;
break;
};
goto repeat;
case ST_TABLE_3:
goto repeat;
case ST_TABLE_4:
if (token == ';')
lexstate = ST_NORMAL;
goto repeat;
case ST_TABLE_5:
switch (token)
{
case ',':
token = ';';
lexstate = ST_TABLE_2;
APP;
break;
default:
APP;
break;
}
break;
default:
exit(1);
}
fini:
if (suppress_type_lookup > 0)
--suppress_type_lookup;
if (dont_want_brace_phrase > 0)
--dont_want_brace_phrase;
yylval = &next_node->next;
return token;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,96 +0,0 @@
/* A Bison parser, made by GNU Bison 2.5.1. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
ASM_KEYW = 258,
ATTRIBUTE_KEYW = 259,
AUTO_KEYW = 260,
BOOL_KEYW = 261,
CHAR_KEYW = 262,
CONST_KEYW = 263,
DOUBLE_KEYW = 264,
ENUM_KEYW = 265,
EXTERN_KEYW = 266,
EXTENSION_KEYW = 267,
FLOAT_KEYW = 268,
INLINE_KEYW = 269,
INT_KEYW = 270,
LONG_KEYW = 271,
REGISTER_KEYW = 272,
RESTRICT_KEYW = 273,
SHORT_KEYW = 274,
SIGNED_KEYW = 275,
STATIC_KEYW = 276,
STRUCT_KEYW = 277,
TYPEDEF_KEYW = 278,
UNION_KEYW = 279,
UNSIGNED_KEYW = 280,
VOID_KEYW = 281,
VOLATILE_KEYW = 282,
TYPEOF_KEYW = 283,
EXPORT_SYMBOL_KEYW = 284,
ASM_PHRASE = 285,
ATTRIBUTE_PHRASE = 286,
TYPEOF_PHRASE = 287,
BRACE_PHRASE = 288,
BRACKET_PHRASE = 289,
EXPRESSION_PHRASE = 290,
CHAR = 291,
DOTS = 292,
IDENT = 293,
INT = 294,
REAL = 295,
STRING = 296,
TYPE = 297,
OTHER = 298,
FILENAME = 299
};
#endif
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval;

View file

@ -1,504 +0,0 @@
/* C global declaration parser for genksyms.
Copyright 1996, 1997 Linux International.
New implementation contributed by Richard Henderson <rth@tamu.edu>
Based on original work by Bjorn Ekwall <bj0rn@blox.se>
This file is part of the Linux modutils.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
%{
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "genksyms.h"
static int is_typedef;
static int is_extern;
static char *current_name;
static struct string_list *decl_spec;
static void yyerror(const char *);
static inline void
remove_node(struct string_list **p)
{
struct string_list *node = *p;
*p = node->next;
free_node(node);
}
static inline void
remove_list(struct string_list **pb, struct string_list **pe)
{
struct string_list *b = *pb, *e = *pe;
*pb = e;
free_list(b, e);
}
/* Record definition of a struct/union/enum */
static void record_compound(struct string_list **keyw,
struct string_list **ident,
struct string_list **body,
enum symbol_type type)
{
struct string_list *b = *body, *i = *ident, *r;
if (i->in_source_file) {
remove_node(keyw);
(*ident)->tag = type;
remove_list(body, ident);
return;
}
r = copy_node(i); r->tag = type;
r->next = (*keyw)->next; *body = r; (*keyw)->next = NULL;
add_symbol(i->string, type, b, is_extern);
}
%}
%token ASM_KEYW
%token ATTRIBUTE_KEYW
%token AUTO_KEYW
%token BOOL_KEYW
%token CHAR_KEYW
%token CONST_KEYW
%token DOUBLE_KEYW
%token ENUM_KEYW
%token EXTERN_KEYW
%token EXTENSION_KEYW
%token FLOAT_KEYW
%token INLINE_KEYW
%token INT_KEYW
%token LONG_KEYW
%token REGISTER_KEYW
%token RESTRICT_KEYW
%token SHORT_KEYW
%token SIGNED_KEYW
%token STATIC_KEYW
%token STRUCT_KEYW
%token TYPEDEF_KEYW
%token UNION_KEYW
%token UNSIGNED_KEYW
%token VOID_KEYW
%token VOLATILE_KEYW
%token TYPEOF_KEYW
%token EXPORT_SYMBOL_KEYW
%token ASM_PHRASE
%token ATTRIBUTE_PHRASE
%token TYPEOF_PHRASE
%token BRACE_PHRASE
%token BRACKET_PHRASE
%token EXPRESSION_PHRASE
%token CHAR
%token DOTS
%token IDENT
%token INT
%token REAL
%token STRING
%token TYPE
%token OTHER
%token FILENAME
%%
declaration_seq:
declaration
| declaration_seq declaration
;
declaration:
{ is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; }
declaration1
{ free_list(*$2, NULL); *$2 = NULL; }
;
declaration1:
EXTENSION_KEYW TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
{ $$ = $4; }
| TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
{ $$ = $3; }
| simple_declaration
| function_definition
| asm_definition
| export_definition
| error ';' { $$ = $2; }
| error '}' { $$ = $2; }
;
simple_declaration:
decl_specifier_seq_opt init_declarator_list_opt ';'
{ if (current_name) {
struct string_list *decl = (*$3)->next;
(*$3)->next = NULL;
add_symbol(current_name,
is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
decl, is_extern);
current_name = NULL;
}
$$ = $3;
}
;
init_declarator_list_opt:
/* empty */ { $$ = NULL; }
| init_declarator_list
;
init_declarator_list:
init_declarator
{ struct string_list *decl = *$1;
*$1 = NULL;
add_symbol(current_name,
is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
current_name = NULL;
$$ = $1;
}
| init_declarator_list ',' init_declarator
{ struct string_list *decl = *$3;
*$3 = NULL;
free_list(*$2, NULL);
*$2 = decl_spec;
add_symbol(current_name,
is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
current_name = NULL;
$$ = $3;
}
;
init_declarator:
declarator asm_phrase_opt attribute_opt initializer_opt
{ $$ = $4 ? $4 : $3 ? $3 : $2 ? $2 : $1; }
;
/* Hang on to the specifiers so that we can reuse them. */
decl_specifier_seq_opt:
/* empty */ { decl_spec = NULL; }
| decl_specifier_seq
;
decl_specifier_seq:
decl_specifier { decl_spec = *$1; }
| decl_specifier_seq decl_specifier { decl_spec = *$2; }
;
decl_specifier:
storage_class_specifier
{ /* Version 2 checksumming ignores storage class, as that
is really irrelevant to the linkage. */
remove_node($1);
$$ = $1;
}
| type_specifier
;
storage_class_specifier:
AUTO_KEYW
| REGISTER_KEYW
| STATIC_KEYW
| EXTERN_KEYW { is_extern = 1; $$ = $1; }
| INLINE_KEYW { is_extern = 0; $$ = $1; }
;
type_specifier:
simple_type_specifier
| cvar_qualifier
| TYPEOF_KEYW '(' parameter_declaration ')'
| TYPEOF_PHRASE
/* References to s/u/e's defined elsewhere. Rearrange things
so that it is easier to expand the definition fully later. */
| STRUCT_KEYW IDENT
{ remove_node($1); (*$2)->tag = SYM_STRUCT; $$ = $2; }
| UNION_KEYW IDENT
{ remove_node($1); (*$2)->tag = SYM_UNION; $$ = $2; }
| ENUM_KEYW IDENT
{ remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; }
/* Full definitions of an s/u/e. Record it. */
| STRUCT_KEYW IDENT class_body
{ record_compound($1, $2, $3, SYM_STRUCT); $$ = $3; }
| UNION_KEYW IDENT class_body
{ record_compound($1, $2, $3, SYM_UNION); $$ = $3; }
| ENUM_KEYW IDENT enum_body
{ record_compound($1, $2, $3, SYM_ENUM); $$ = $3; }
/*
* Anonymous enum definition. Tell add_symbol() to restart its counter.
*/
| ENUM_KEYW enum_body
{ add_symbol(NULL, SYM_ENUM, NULL, 0); $$ = $2; }
/* Anonymous s/u definitions. Nothing needs doing. */
| STRUCT_KEYW class_body { $$ = $2; }
| UNION_KEYW class_body { $$ = $2; }
;
simple_type_specifier:
CHAR_KEYW
| SHORT_KEYW
| INT_KEYW
| LONG_KEYW
| SIGNED_KEYW
| UNSIGNED_KEYW
| FLOAT_KEYW
| DOUBLE_KEYW
| VOID_KEYW
| BOOL_KEYW
| TYPE { (*$1)->tag = SYM_TYPEDEF; $$ = $1; }
;
ptr_operator:
'*' cvar_qualifier_seq_opt
{ $$ = $2 ? $2 : $1; }
;
cvar_qualifier_seq_opt:
/* empty */ { $$ = NULL; }
| cvar_qualifier_seq
;
cvar_qualifier_seq:
cvar_qualifier
| cvar_qualifier_seq cvar_qualifier { $$ = $2; }
;
cvar_qualifier:
CONST_KEYW | VOLATILE_KEYW | ATTRIBUTE_PHRASE
| RESTRICT_KEYW
{ /* restrict has no effect in prototypes so ignore it */
remove_node($1);
$$ = $1;
}
;
declarator:
ptr_operator declarator { $$ = $2; }
| direct_declarator
;
direct_declarator:
IDENT
{ if (current_name != NULL) {
error_with_pos("unexpected second declaration name");
YYERROR;
} else {
current_name = (*$1)->string;
$$ = $1;
}
}
| direct_declarator '(' parameter_declaration_clause ')'
{ $$ = $4; }
| direct_declarator '(' error ')'
{ $$ = $4; }
| direct_declarator BRACKET_PHRASE
{ $$ = $2; }
| '(' declarator ')'
{ $$ = $3; }
| '(' error ')'
{ $$ = $3; }
;
/* Nested declarators differ from regular declarators in that they do
not record the symbols they find in the global symbol table. */
nested_declarator:
ptr_operator nested_declarator { $$ = $2; }
| direct_nested_declarator
;
direct_nested_declarator:
IDENT
| TYPE
| direct_nested_declarator '(' parameter_declaration_clause ')'
{ $$ = $4; }
| direct_nested_declarator '(' error ')'
{ $$ = $4; }
| direct_nested_declarator BRACKET_PHRASE
{ $$ = $2; }
| '(' nested_declarator ')'
{ $$ = $3; }
| '(' error ')'
{ $$ = $3; }
;
parameter_declaration_clause:
parameter_declaration_list_opt DOTS { $$ = $2; }
| parameter_declaration_list_opt
| parameter_declaration_list ',' DOTS { $$ = $3; }
;
parameter_declaration_list_opt:
/* empty */ { $$ = NULL; }
| parameter_declaration_list
;
parameter_declaration_list:
parameter_declaration
| parameter_declaration_list ',' parameter_declaration
{ $$ = $3; }
;
parameter_declaration:
decl_specifier_seq m_abstract_declarator
{ $$ = $2 ? $2 : $1; }
;
m_abstract_declarator:
ptr_operator m_abstract_declarator
{ $$ = $2 ? $2 : $1; }
| direct_m_abstract_declarator
;
direct_m_abstract_declarator:
/* empty */ { $$ = NULL; }
| IDENT
{ /* For version 2 checksums, we don't want to remember
private parameter names. */
remove_node($1);
$$ = $1;
}
/* This wasn't really a typedef name but an identifier that
shadows one. */
| TYPE
{ remove_node($1);
$$ = $1;
}
| direct_m_abstract_declarator '(' parameter_declaration_clause ')'
{ $$ = $4; }
| direct_m_abstract_declarator '(' error ')'
{ $$ = $4; }
| direct_m_abstract_declarator BRACKET_PHRASE
{ $$ = $2; }
| '(' m_abstract_declarator ')'
{ $$ = $3; }
| '(' error ')'
{ $$ = $3; }
;
function_definition:
decl_specifier_seq_opt declarator BRACE_PHRASE
{ struct string_list *decl = *$2;
*$2 = NULL;
add_symbol(current_name, SYM_NORMAL, decl, is_extern);
$$ = $3;
}
;
initializer_opt:
/* empty */ { $$ = NULL; }
| initializer
;
/* We never care about the contents of an initializer. */
initializer:
'=' EXPRESSION_PHRASE
{ remove_list($2, &(*$1)->next); $$ = $2; }
;
class_body:
'{' member_specification_opt '}' { $$ = $3; }
| '{' error '}' { $$ = $3; }
;
member_specification_opt:
/* empty */ { $$ = NULL; }
| member_specification
;
member_specification:
member_declaration
| member_specification member_declaration { $$ = $2; }
;
member_declaration:
decl_specifier_seq_opt member_declarator_list_opt ';'
{ $$ = $3; }
| error ';'
{ $$ = $2; }
;
member_declarator_list_opt:
/* empty */ { $$ = NULL; }
| member_declarator_list
;
member_declarator_list:
member_declarator
| member_declarator_list ',' member_declarator { $$ = $3; }
;
member_declarator:
nested_declarator attribute_opt { $$ = $2 ? $2 : $1; }
| IDENT member_bitfield_declarator { $$ = $2; }
| member_bitfield_declarator
;
member_bitfield_declarator:
':' EXPRESSION_PHRASE { $$ = $2; }
;
attribute_opt:
/* empty */ { $$ = NULL; }
| attribute_opt ATTRIBUTE_PHRASE
;
enum_body:
'{' enumerator_list '}' { $$ = $3; }
| '{' enumerator_list ',' '}' { $$ = $4; }
;
enumerator_list:
enumerator
| enumerator_list ',' enumerator
enumerator:
IDENT
{
const char *name = strdup((*$1)->string);
add_symbol(name, SYM_ENUM_CONST, NULL, 0);
}
| IDENT '=' EXPRESSION_PHRASE
{
const char *name = strdup((*$1)->string);
struct string_list *expr = copy_list_range(*$3, *$2);
add_symbol(name, SYM_ENUM_CONST, expr, 0);
}
asm_definition:
ASM_PHRASE ';' { $$ = $2; }
;
asm_phrase_opt:
/* empty */ { $$ = NULL; }
| ASM_PHRASE
;
export_definition:
EXPORT_SYMBOL_KEYW '(' IDENT ')' ';'
{ export_symbol((*$3)->string); $$ = $5; }
;
%%
static void
yyerror(const char *e)
{
error_with_pos("%s", e);
}