From: Keith Marshall Date: Mon, 7 Sep 2015 20:19:27 +0000 (+0100) Subject: Eliminate Microsoft inspired obfuscated typedef insanity. X-Git-Tag: v0_47~2 X-Git-Url: http://git.osdn.net/view?p=mingw%2Fpexports.git;a=commitdiff_plain;h=76ec49ceffda4ba129c0616dfbdf2b28063116bf Eliminate Microsoft inspired obfuscated typedef insanity. --- diff --git a/.hgsub b/.hgsub deleted file mode 100644 index 92c6100..0000000 --- a/.hgsub +++ /dev/null @@ -1 +0,0 @@ -build-aux = ../build-aux diff --git a/.hgsubstate b/.hgsubstate deleted file mode 100644 index 541d184..0000000 --- a/.hgsubstate +++ /dev/null @@ -1 +0,0 @@ -92c883f2daa845b9fa1f0e739e23cd50887082b5 build-aux diff --git a/ChangeLog b/ChangeLog index a508e55..8a195ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2015-09-07 Keith Marshall + + Eliminate Microsoft inspired obfuscated typedef insanity. + + * pexports.c pexports.h (BYTE, WORD, DWORD): Delete typedefs; + respectively replace all corresponding usage instances with... + (uint8_t, uint16_t, uint32_t): ...these ISO-C standard types. + (PVOID, PIMAGE_DOS_HEADER, PIMAGE_FILE_HEADER, PIMAGE_SECTION_HEADER) + (PIMAGE_DATA_DIRECTORY, PIMAGE_EXPORT_DIRECTORY, PIMAGE_NT_HEADERS32) + (PIMAGE_NT_HEADERS64, PIMAGE_OPTIONAL_HEADER32) + (PIMAGE_OPTIONAL_HEADER64): Delete these non-standard style pointer + reference typedefs; replace with conventional pointer references to + the underlying data type; where these are structural types, delete + initial underscores from the corresponding structure tag names. + (HMODULE): Likewise; replace with pointer to void. + 2013-05-30 Keith Marshall Prepare, tag, and publish 0.46 release. diff --git a/pexports.c b/pexports.c index 310f48a..cb6dc42 100644 --- a/pexports.c +++ b/pexports.c @@ -18,13 +18,14 @@ #endif /* get pointer to section header n */ -#define IMAGE_SECTION_HDR(n) ((PIMAGE_SECTION_HEADER) ((char *) nt_hdr32 + \ - 4 + sizeof(IMAGE_FILE_HEADER) + \ - nt_hdr32->FileHeader.SizeOfOptionalHeader + \ - n * sizeof(IMAGE_SECTION_HEADER))) +#define IMAGE_SECTION_HDR(n) \ + ((IMAGE_SECTION_HEADER *)((char *) nt_hdr32 \ + + 4 + sizeof(IMAGE_FILE_HEADER) + nt_hdr32->FileHeader.SizeOfOptionalHeader \ + + n * sizeof(IMAGE_SECTION_HEADER)) \ + ) /* convert relative virtual address to a useable pointer */ -#define RVA_TO_PTR(rva,type) ((type) rva_to_ptr((DWORD) rva)) +#define RVA_TO_PTR(rva,type) ((type)(rva_to_ptr((uint32_t)(rva)))) typedef struct str_list { char *s; @@ -38,15 +39,15 @@ static void add_path_list(char *path); static const char *find_file(const char *name); static void str_list_add(str_list **head, const char *s); static void parse_headers(); -static void dump_symbol(char *name, int ord, DWORD rva); +static void dump_symbol(char *name, int ord, uint32_t rva); static const char mz_sign[2] = {'M','Z'}; static const char pe_sign[4] = {'P','E','\0','\0'}; static const char exp_sign[6] = {'.','e','d','a','t','a'}; -static PIMAGE_DOS_HEADER dos_hdr; -static PIMAGE_NT_HEADERS32 nt_hdr32; -static PIMAGE_NT_HEADERS64 nt_hdr64; +static IMAGE_DOS_HEADER *dos_hdr; +static IMAGE_NT_HEADERS32 *nt_hdr32; +static IMAGE_NT_HEADERS64 *nt_hdr64; static char *filename = NULL; static char *program_name; @@ -64,31 +65,30 @@ extern FILE *yyin; int main(int argc, char *argv[]) { - PIMAGE_SECTION_HEADER section; - DWORD exp_rva, exp_size; + IMAGE_SECTION_HEADER *section; + uint32_t exp_rva, exp_size; int i; -#if defined(_WIN32) && !defined(_WIN64) - /* If running on 64-bit Windows and built as a 32-bit process, try +# if defined(_WIN32) && !defined(_WIN64) + /* + * If running on 64-bit Windows and built as a 32-bit process, try * disable Wow64 file system redirection, so that we can open DLLs * in the real system32 folder if requested. */ + void *old_redirection; + void *kernel32; - PVOID old_redirection; + extern __declspec(dllimport) void __stdcall *GetModuleHandleA(char *name); + extern __declspec(dllimport) void __stdcall *GetProcAddress(void *module, char *name); - HMODULE kernel32; - - extern __declspec(dllimport) HMODULE __stdcall GetModuleHandleA(char *name); - extern __declspec(dllimport) PVOID __stdcall GetProcAddress(HMODULE module, char *name); - - BOOL (__stdcall *pWow64DisableWow64FsRedirection) (PVOID *old_value); + int32_t (__stdcall *pWow64DisableWow64FsRedirection) (void **old_value); kernel32 = GetModuleHandleA("kernel32.dll"); pWow64DisableWow64FsRedirection = GetProcAddress(kernel32, "Wow64DisableWow64FsRedirection"); if (pWow64DisableWow64FsRedirection) pWow64DisableWow64FsRedirection(&old_redirection); -#endif +# endif program_name = argv[0]; @@ -161,17 +161,16 @@ main(int argc, char *argv[]) parse_headers(); /* load file */ - dos_hdr = load_pe_image(filename); - if (dos_hdr == NULL) + if( (dos_hdr = load_pe_image(filename)) == NULL ) { fprintf(stderr, "%s: %s: could not load PE image\n", program_name, filename); return 1; } - nt_hdr32 = (PIMAGE_NT_HEADERS32) ((char *) dos_hdr + dos_hdr->e_lfanew); - nt_hdr64 = (PIMAGE_NT_HEADERS64) nt_hdr32; - + nt_hdr32 = (IMAGE_NT_HEADERS32 *) ((char *) dos_hdr + dos_hdr->e_lfanew); + nt_hdr64 = (IMAGE_NT_HEADERS64 *) nt_hdr32; + if (nt_hdr32->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) { exp_rva = nt_hdr32->OptionalHeader.DataDirectory[0].VirtualAddress; exp_size = nt_hdr32->OptionalHeader.DataDirectory[0].Size; @@ -198,7 +197,7 @@ main(int argc, char *argv[]) section = IMAGE_SECTION_HDR(i); if (memcmp(section->Name, exp_sign, sizeof(exp_sign)) == 0) dump_exports(section->VirtualAddress, exp_size); - else if ((exp_rva >= section->VirtualAddress) && + else if ((exp_rva >= section->VirtualAddress) && (exp_rva < (section->VirtualAddress + section->SizeOfRawData))) dump_exports(exp_rva, exp_size); } @@ -209,14 +208,14 @@ main(int argc, char *argv[]) /* dump exported symbols on stdout */ void -dump_exports(DWORD exports_rva, DWORD exports_size) +dump_exports(uint32_t exports_rva, uint32_t exports_size) { - PIMAGE_SECTION_HEADER section; - PIMAGE_EXPORT_DIRECTORY exports; + IMAGE_SECTION_HEADER *section; + IMAGE_EXPORT_DIRECTORY *exports; char *export_name; - WORD *ordinal_table; - DWORD *name_table; - DWORD *function_table; + uint16_t *ordinal_table; + uint32_t *name_table; + uint32_t *function_table; int i; static int first = 1; @@ -226,12 +225,12 @@ dump_exports(DWORD exports_rva, DWORD exports_size) printf("; Reading exports from section: %s\n", section->Name); - exports = RVA_TO_PTR(exports_rva, PIMAGE_EXPORT_DIRECTORY); + exports = RVA_TO_PTR(exports_rva, IMAGE_EXPORT_DIRECTORY *); /* set up various pointers */ export_name = RVA_TO_PTR(exports->Name,char*); - ordinal_table = RVA_TO_PTR(exports->AddressOfNameOrdinals,WORD*); - name_table = RVA_TO_PTR(exports->AddressOfNames,DWORD*); + ordinal_table = RVA_TO_PTR(exports->AddressOfNameOrdinals, uint16_t *); + name_table = RVA_TO_PTR(exports->AddressOfNames, uint32_t *); function_table = RVA_TO_PTR(exports->AddressOfFunctions,void*); if (verbose) @@ -260,33 +259,33 @@ dump_exports(DWORD exports_rva, DWORD exports_size) dump_symbol(RVA_TO_PTR(name_table[i],char*), ordinal_table[i] + exports->Base, function_table[ordinal_table[i]]); - + int f_off = ordinal_table[i]; - + if(function_table[f_off] >= exports_rva && function_table[f_off] < (exports_rva + exports_size) && verbose) { printf(" ; Forwarder (%s)", RVA_TO_PTR(function_table[f_off], char*)); } - + printf("\n"); } for (i = 0; i < exports->NumberOfFunctions; i++) { - if ( (function_table[i] >= exports_rva) && + if ( (function_table[i] >= exports_rva) && (function_table[i] < (exports_rva + exports_size))) { int name_present = 0, n; - + for(n = 0; n < exports->NumberOfNames; n++) { if(ordinal_table[n] == i) { name_present = 1; break; } } - + if(!name_present) { dump_symbol(strchr(RVA_TO_PTR(function_table[i],char*), '.')+1, i + exports->Base, function_table[i]); - + printf(" ; WARNING: Symbol name guessed from forwarder (%s)\n", RVA_TO_PTR(function_table[i], char*)); } } @@ -294,7 +293,7 @@ dump_exports(DWORD exports_rva, DWORD exports_size) } static void -dump_symbol(char *name, int ord, DWORD rva) +dump_symbol(char *name, int ord, uint32_t rva) { char s[256]; str_tree *symbol = str_tree_find(symbols, name); @@ -303,7 +302,7 @@ dump_symbol(char *name, int ord, DWORD rva) sprintf(s, "%s@%"PRIdPTR, name, (intptr_t)(symbol->extra)); else sprintf(s, "%s", name); - + /* output ordinal */ if (ordinal_flag) printf("%-24s\t@%d", s, ord); @@ -311,7 +310,7 @@ dump_symbol(char *name, int ord, DWORD rva) printf("%s", s); { - PIMAGE_SECTION_HEADER s=find_section(rva); + IMAGE_SECTION_HEADER *s = find_section(rva); /* Stupid msvc doesn't have .bss section, it spews uninitilized data * to no section @@ -329,23 +328,22 @@ dump_symbol(char *name, int ord, DWORD rva) } /* get section to which rva points */ -PIMAGE_SECTION_HEADER -find_section(DWORD rva) +IMAGE_SECTION_HEADER *find_section(uint32_t rva) { int i; - PIMAGE_SECTION_HEADER section = IMAGE_SECTION_HDR(0); + IMAGE_SECTION_HEADER *section = IMAGE_SECTION_HDR(0); for (i = 0; i < nt_hdr32->FileHeader.NumberOfSections; i++, section++) - if ((rva >= section->VirtualAddress) && + if ((rva >= section->VirtualAddress) && (rva <= (section->VirtualAddress + section->SizeOfRawData))) return section; - return NULL; + return NULL; } /* convert rva to pointer into loaded file */ void * -rva_to_ptr(DWORD rva) +rva_to_ptr(uint32_t rva) { - PIMAGE_SECTION_HEADER section = find_section(rva); + IMAGE_SECTION_HEADER *section = find_section(rva); if (section->PointerToRawData == 0) return NULL; else @@ -353,25 +351,24 @@ rva_to_ptr(DWORD rva) } /* Load a portable executable into memory */ -PIMAGE_DOS_HEADER -load_pe_image(const char *filename) +IMAGE_DOS_HEADER *load_pe_image(const char *filename) { #ifdef _MSC_VER struct _stat32 st; #else struct stat st; #endif - PIMAGE_DOS_HEADER phdr; + IMAGE_DOS_HEADER *phdr; FILE *f; - + if (stat(filename, &st) == -1) { perror("stat"); return NULL; } - phdr = (PIMAGE_DOS_HEADER) xmalloc(st.st_size); - + phdr = (IMAGE_DOS_HEADER *) xmalloc(st.st_size); + f = fopen(filename, "rb"); if (f == NULL) @@ -479,8 +476,7 @@ parse_headers() } /* allocate memory; abort on failure */ -static void -*xmalloc(size_t count) +static void *xmalloc(size_t count) { void *p = malloc(count); if (p == NULL) diff --git a/pexports.h b/pexports.h index 7f7e5d9..24db504 100644 --- a/pexports.h +++ b/pexports.h @@ -9,7 +9,6 @@ pexports will work only on intel machines. */ - #ifndef _pexports_h #define _pexports_h @@ -18,187 +17,167 @@ #include "str_tree.h" -/* These are needed: - * FIXME: However, I'd really much prefer to see ISO-C99 standard - * types used throughout, in preference to these Micrsoft-inspired - * obfuscated typedefs. - */ -typedef uint8_t BYTE; -typedef uint16_t WORD; -typedef uint32_t DWORD; -typedef void* PVOID; -typedef int32_t LONG; -typedef uint64_t ULONGLONG; -typedef int BOOL; -typedef void* HMODULE; - -#define FALSE 0 -#define TRUE 1 +#define FALSE (int32_t)(0) +#define TRUE (int32_t)(1) /* PE structures */ -typedef struct _IMAGE_DATA_DIRECTORY { - DWORD VirtualAddress; - DWORD Size; -} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; - -typedef struct _IMAGE_FILE_HEADER { - WORD Machine; - WORD NumberOfSections; - DWORD TimeDateStamp; - DWORD PointerToSymbolTable; - DWORD NumberOfSymbols; - WORD SizeOfOptionalHeader; - WORD Characteristics; -} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; +typedef struct IMAGE_DATA_DIRECTORY { + uint32_t VirtualAddress; + uint32_t Size; +} IMAGE_DATA_DIRECTORY; + +typedef struct IMAGE_FILE_HEADER { + uint16_t Machine; + uint16_t NumberOfSections; + uint32_t TimeDateStamp; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + uint16_t SizeOfOptionalHeader; + uint16_t Characteristics; +} IMAGE_FILE_HEADER; #define IMAGE_FILE_MACHINE_I386 0x014c #define IMAGE_FILE_MACHINE_IA64 0x0200 #define IMAGE_FILE_MACHINE_AMD64 0x8664 -typedef struct _IMAGE_OPTIONAL_HEADER32 { - WORD Magic; - BYTE MajorLinkerVersion; - BYTE MinorLinkerVersion; - DWORD SizeOfCode; - DWORD SizeOfInitializedData; - DWORD SizeOfUninitializedData; - DWORD AddressOfEntryPoint; - DWORD BaseOfCode; - DWORD BaseOfData; - DWORD ImageBase; - DWORD SectionAlignment; - DWORD FileAlignment; - WORD MajorOperatingSystemVersion; - WORD MinorOperatingSystemVersion; - WORD MajorImageVersion; - WORD MinorImageVersion; - WORD MajorSubsystemVersion; - WORD MinorSubsystemVersion; - DWORD Reserved1; - DWORD SizeOfImage; - DWORD SizeOfHeaders; - DWORD CheckSum; - WORD Subsystem; - WORD DllCharacteristics; - DWORD SizeOfStackReserve; - DWORD SizeOfStackCommit; - DWORD SizeOfHeapReserve; - DWORD SizeOfHeapCommit; - DWORD LoaderFlags; - DWORD NumberOfRvaAndSizes; +typedef struct IMAGE_OPTIONAL_HEADER32 { + uint16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint32_t BaseOfData; + uint32_t ImageBase; + uint32_t SectionAlignment; + uint32_t FileAlignment; + uint16_t MajorOperatingSystemVersion; + uint16_t MinorOperatingSystemVersion; + uint16_t MajorImageVersion; + uint16_t MinorImageVersion; + uint16_t MajorSubsystemVersion; + uint16_t MinorSubsystemVersion; + uint32_t Reserved1; + uint32_t SizeOfImage; + uint32_t SizeOfHeaders; + uint32_t CheckSum; + uint16_t Subsystem; + uint16_t DllCharacteristics; + uint32_t SizeOfStackReserve; + uint32_t SizeOfStackCommit; + uint32_t SizeOfHeapReserve; + uint32_t SizeOfHeapCommit; + uint32_t LoaderFlags; + uint32_t NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[16]; -} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; - -typedef struct _IMAGE_OPTIONAL_HEADER64 { - WORD Magic; - BYTE MajorLinkerVersion; - BYTE MinorLinkerVersion; - DWORD SizeOfCode; - DWORD SizeOfInitializedData; - DWORD SizeOfUninitializedData; - DWORD AddressOfEntryPoint; - DWORD BaseOfCode; - ULONGLONG ImageBase; - DWORD SectionAlignment; - DWORD FileAlignment; - WORD MajorOperatingSystemVersion; - WORD MinorOperatingSystemVersion; - WORD MajorImageVersion; - WORD MinorImageVersion; - WORD MajorSubsystemVersion; - WORD MinorSubsystemVersion; - DWORD Win32VersionValue; - DWORD SizeOfImage; - DWORD SizeOfHeaders; - DWORD CheckSum; - WORD Subsystem; - WORD DllCharacteristics; - ULONGLONG SizeOfStackReserve; - ULONGLONG SizeOfStackCommit; - ULONGLONG SizeOfHeapReserve; - ULONGLONG SizeOfHeapCommit; - DWORD LoaderFlags; - DWORD NumberOfRvaAndSizes; +} IMAGE_OPTIONAL_HEADER32; + +typedef struct IMAGE_OPTIONAL_HEADER64 { + uint16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint64_t ImageBase; + uint32_t SectionAlignment; + uint32_t FileAlignment; + uint16_t MajorOperatingSystemVersion; + uint16_t MinorOperatingSystemVersion; + uint16_t MajorImageVersion; + uint16_t MinorImageVersion; + uint16_t MajorSubsystemVersion; + uint16_t MinorSubsystemVersion; + uint32_t Win32VersionValue; + uint32_t SizeOfImage; + uint32_t SizeOfHeaders; + uint32_t CheckSum; + uint16_t Subsystem; + uint16_t DllCharacteristics; + uint64_t SizeOfStackReserve; + uint64_t SizeOfStackCommit; + uint64_t SizeOfHeapReserve; + uint64_t SizeOfHeapCommit; + uint32_t LoaderFlags; + uint32_t NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[16]; -} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; +} IMAGE_OPTIONAL_HEADER64; typedef struct IMAGE_NT_HEADERS32 { char Signature[4]; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER32 OptionalHeader; -} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; +} IMAGE_NT_HEADERS32; -typedef struct _IMAGE_NT_HEADERS64 { +typedef struct IMAGE_NT_HEADERS64 { char Signature[4]; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER64 OptionalHeader; -} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; +} IMAGE_NT_HEADERS64; -typedef struct _IMAGE_SECTION_HEADER { - BYTE Name[8]; +typedef struct IMAGE_SECTION_HEADER { + uint8_t Name[8]; union { - DWORD PhysicalAddress; - DWORD VirtualSize; + uint32_t PhysicalAddress; + uint32_t VirtualSize; } Misc; - DWORD VirtualAddress; - DWORD SizeOfRawData; - DWORD PointerToRawData; - DWORD PointerToRelocations; - DWORD PointerToLinenumbers; - WORD NumberOfRelocations; - WORD NumberOfLinenumbers; - DWORD Characteristics; -} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + uint32_t VirtualAddress; + uint32_t SizeOfRawData; + uint32_t PointerToRawData; + uint32_t PointerToRelocations; + uint32_t PointerToLinenumbers; + uint16_t NumberOfRelocations; + uint16_t NumberOfLinenumbers; + uint32_t Characteristics; +} IMAGE_SECTION_HEADER; #define IMAGE_SCN_CNT_CODE 0x00000020 -typedef struct _IMAGE_EXPORT_DIRECTORY { - DWORD Characteristics; - DWORD TimeDateStamp; - WORD MajorVersion; - WORD MinorVersion; - DWORD Name; - DWORD Base; - DWORD NumberOfFunctions; - DWORD NumberOfNames; - DWORD AddressOfFunctions; - DWORD AddressOfNames; - DWORD AddressOfNameOrdinals; -} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; - -typedef struct _IMAGE_DOS_HEADER { - WORD e_magic; - WORD e_cblp; - WORD e_cp; - WORD e_crlc; - WORD e_cparhdr; - WORD e_minalloc; - WORD e_maxalloc; - WORD e_ss; - WORD e_sp; - WORD e_csum; - WORD e_ip; - WORD e_cs; - WORD e_lfarlc; - WORD e_ovno; - WORD e_res[4]; - WORD e_oemid; - WORD e_oeminfo; - WORD e_res2[10]; - LONG e_lfanew; -} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; - -PIMAGE_SECTION_HEADER -find_section(DWORD rva); - -PIMAGE_DOS_HEADER -load_pe_image(const char *filename); - -void * -rva_to_ptr(DWORD rva); - -void -dump_exports(DWORD exports_rva, DWORD exports_size); +typedef struct IMAGE_EXPORT_DIRECTORY { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Name; + uint32_t Base; + uint32_t NumberOfFunctions; + uint32_t NumberOfNames; + uint32_t AddressOfFunctions; + uint32_t AddressOfNames; + uint32_t AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY; + +typedef struct IMAGE_DOS_HEADER { + uint16_t e_magic; + uint16_t e_cblp; + uint16_t e_cp; + uint16_t e_crlc; + uint16_t e_cparhdr; + uint16_t e_minalloc; + uint16_t e_maxalloc; + uint16_t e_ss; + uint16_t e_sp; + uint16_t e_csum; + uint16_t e_ip; + uint16_t e_cs; + uint16_t e_lfarlc; + uint16_t e_ovno; + uint16_t e_res[4]; + uint16_t e_oemid; + uint16_t e_oeminfo; + uint16_t e_res2[10]; + int32_t e_lfanew; +} IMAGE_DOS_HEADER; + +IMAGE_SECTION_HEADER *find_section( uint32_t ); +IMAGE_DOS_HEADER *load_pe_image( const char * ); + +void *rva_to_ptr( uint32_t ); +void dump_exports( uint32_t, uint32_t ); #define ADD_FUNCTION(nm,n) str_tree_add(&symbols, nm, (void*)(intptr_t)(n)) extern str_tree *symbols;