| Index: gdb/coffread.c
|
| diff --git a/gdb/coffread.c b/gdb/coffread.c
|
| index b0a8b8202995186f5a99c737612fe7d56b70c96d..b49e30c4ff4c37ccb5055f97f064257aa6bdfcd3 100644
|
| --- a/gdb/coffread.c
|
| +++ b/gdb/coffread.c
|
| @@ -1,5 +1,5 @@
|
| /* Read coff symbol tables and convert to internal format, for GDB.
|
| - Copyright (C) 1987-2005, 2007-2012 Free Software Foundation, Inc.
|
| + Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
| Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
|
|
|
| This file is part of GDB.
|
| @@ -26,7 +26,7 @@
|
| #include "bfd.h"
|
| #include "gdb_obstack.h"
|
|
|
| -#include "gdb_string.h"
|
| +#include <string.h>
|
| #include <ctype.h>
|
|
|
| #include "coff/internal.h" /* Internal format of COFF symbols in BFD */
|
| @@ -47,6 +47,10 @@
|
|
|
| extern void _initialize_coffread (void);
|
|
|
| +/* Key for COFF-associated data. */
|
| +
|
| +static const struct objfile_data *coff_objfile_data_key;
|
| +
|
| /* The objfile we are currently reading. */
|
|
|
| static struct objfile *coffread_objfile;
|
| @@ -142,6 +146,19 @@ struct coff_symbol
|
| unsigned int c_type;
|
| };
|
|
|
| +/* Vector of types defined so far, indexed by their type numbers. */
|
| +
|
| +static struct type **type_vector;
|
| +
|
| +/* Number of elements allocated for type_vector currently. */
|
| +
|
| +static int type_vector_length;
|
| +
|
| +/* Initial size of type vector. Is realloc'd larger if needed, and
|
| + realloc'd down to the size actually used, when completed. */
|
| +
|
| +#define INITIAL_TYPE_VECTOR_LENGTH 160
|
| +
|
| extern void stabsread_clear_cache (void);
|
|
|
| static struct type *coff_read_struct_type (int, int, int,
|
| @@ -293,7 +310,7 @@ cs_to_section (struct coff_symbol *cs, struct objfile *objfile)
|
|
|
| if (sect == NULL)
|
| return SECT_OFF_TEXT (objfile);
|
| - return sect->index;
|
| + return gdb_bfd_section_index (objfile->obfd, sect);
|
| }
|
|
|
| /* Return the address of the section of a COFF symbol. */
|
| @@ -392,9 +409,7 @@ coff_start_symtab (const char *name)
|
| static void
|
| complete_symtab (const char *name, CORE_ADDR start_addr, unsigned int size)
|
| {
|
| - if (last_source_file != NULL)
|
| - xfree (last_source_file);
|
| - last_source_file = xstrdup (name);
|
| + set_last_source_file (name);
|
| current_source_start_addr = start_addr;
|
| current_source_end_addr = start_addr + size;
|
| }
|
| @@ -413,24 +428,63 @@ coff_end_symtab (struct objfile *objfile)
|
| SECT_OFF_TEXT (objfile));
|
|
|
| /* Reinitialize for beginning of new file. */
|
| - last_source_file = NULL;
|
| + set_last_source_file (NULL);
|
| }
|
|
|
| +/* The linker sometimes generates some non-function symbols inside
|
| + functions referencing variables imported from another DLL.
|
| + Return nonzero if the given symbol corresponds to one of them. */
|
| +
|
| +static int
|
| +is_import_fixup_symbol (struct coff_symbol *cs,
|
| + enum minimal_symbol_type type)
|
| +{
|
| + /* The following is a bit of a heuristic using the characterictics
|
| + of these fixup symbols, but should work well in practice... */
|
| + int i;
|
| +
|
| + /* Must be a non-static text symbol. */
|
| + if (type != mst_text)
|
| + return 0;
|
| +
|
| + /* Must be a non-function symbol. */
|
| + if (ISFCN (cs->c_type))
|
| + return 0;
|
| +
|
| + /* The name must start with "__fu<digits>__". */
|
| + if (strncmp (cs->c_name, "__fu", 4) != 0)
|
| + return 0;
|
| + if (! isdigit (cs->c_name[4]))
|
| + return 0;
|
| + for (i = 5; cs->c_name[i] != '\0' && isdigit (cs->c_name[i]); i++)
|
| + /* Nothing, just incrementing index past all digits. */;
|
| + if (cs->c_name[i] != '_' || cs->c_name[i + 1] != '_')
|
| + return 0;
|
| +
|
| + return 1;
|
| +}
|
| +
|
| static struct minimal_symbol *
|
| record_minimal_symbol (struct coff_symbol *cs, CORE_ADDR address,
|
| enum minimal_symbol_type type, int section,
|
| struct objfile *objfile)
|
| {
|
| - struct bfd_section *bfd_section;
|
| -
|
| /* We don't want TDESC entry points in the minimal symbol table. */
|
| if (cs->c_name[0] == '@')
|
| return NULL;
|
|
|
| - bfd_section = cs_to_bfd_section (cs, objfile);
|
| + if (is_import_fixup_symbol (cs, type))
|
| + {
|
| + /* Because the value of these symbols is within a function code
|
| + range, these symbols interfere with the symbol-from-address
|
| + reverse lookup; this manifests itselfs in backtraces, or any
|
| + other commands that prints symbolic addresses. Just pretend
|
| + these symbols do not exist. */
|
| + return NULL;
|
| + }
|
| +
|
| return prim_record_minimal_symbol_and_info (cs->c_name, address,
|
| - type, section,
|
| - bfd_section, objfile);
|
| + type, section, objfile);
|
| }
|
|
|
| /* coff_symfile_init ()
|
| @@ -450,26 +504,21 @@ record_minimal_symbol (struct coff_symbol *cs, CORE_ADDR address,
|
| static void
|
| coff_symfile_init (struct objfile *objfile)
|
| {
|
| - /* Allocate struct to keep track of stab reading. */
|
| - objfile->deprecated_sym_stab_info = (struct dbx_symfile_info *)
|
| - xmalloc (sizeof (struct dbx_symfile_info));
|
| + struct dbx_symfile_info *dbx;
|
| + struct coff_symfile_info *coff;
|
|
|
| - memset (objfile->deprecated_sym_stab_info, 0,
|
| - sizeof (struct dbx_symfile_info));
|
| + /* Allocate struct to keep track of stab reading. */
|
| + dbx = XCNEW (struct dbx_symfile_info);
|
| + set_objfile_data (objfile, dbx_objfile_data_key, dbx);
|
|
|
| /* Allocate struct to keep track of the symfile. */
|
| - objfile->deprecated_sym_private
|
| - = xmalloc (sizeof (struct coff_symfile_info));
|
| -
|
| - memset (objfile->deprecated_sym_private, 0,
|
| - sizeof (struct coff_symfile_info));
|
| + coff = XCNEW (struct coff_symfile_info);
|
| + set_objfile_data (objfile, coff_objfile_data_key, coff);
|
|
|
| /* COFF objects may be reordered, so set OBJF_REORDERED. If we
|
| find this causes a significant slowdown in gdb then we could
|
| set it in the debug symbol readers only when necessary. */
|
| objfile->flags |= OBJF_REORDERED;
|
| -
|
| - init_entry_point_info (objfile);
|
| }
|
|
|
| /* This function is called for every section; it finds the outer
|
| @@ -527,8 +576,8 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags)
|
| struct cleanup *back_to, *cleanup_minimal_symbols;
|
| int stabstrsize;
|
|
|
| - info = (struct coff_symfile_info *) objfile->deprecated_sym_private;
|
| - dbxinfo = objfile->deprecated_sym_stab_info;
|
| + info = objfile_data (objfile, coff_objfile_data_key);
|
| + dbxinfo = DBX_SYMFILE_INFO (objfile);
|
| symfile_bfd = abfd; /* Kludge for swap routines. */
|
|
|
| /* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
|
| @@ -614,6 +663,35 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags)
|
|
|
| install_minimal_symbols (objfile);
|
|
|
| + if (pe_file)
|
| + {
|
| + struct minimal_symbol *msym;
|
| +
|
| + ALL_OBJFILE_MSYMBOLS (objfile, msym)
|
| + {
|
| + const char *name = SYMBOL_LINKAGE_NAME (msym);
|
| +
|
| + /* If the minimal symbols whose name are prefixed by "__imp_"
|
| + or "_imp_", get rid of the prefix, and search the minimal
|
| + symbol in OBJFILE. Note that 'maintenance print msymbols'
|
| + shows that type of these "_imp_XXXX" symbols is mst_data. */
|
| + if (MSYMBOL_TYPE (msym) == mst_data
|
| + && (strncmp (name, "__imp_", 6) == 0
|
| + || strncmp (name, "_imp_", 5) == 0))
|
| + {
|
| + const char *name1 = (name[1] == '_' ? &name[7] : &name[6]);
|
| + struct minimal_symbol *found;
|
| +
|
| + found = lookup_minimal_symbol (name1, NULL, objfile);
|
| + /* If found, there are symbols named "_imp_foo" and "foo"
|
| + respectively in OBJFILE. Set the type of symbol "foo"
|
| + as 'mst_solib_trampoline'. */
|
| + if (found != NULL && MSYMBOL_TYPE (found) == mst_text)
|
| + MSYMBOL_TYPE (found) = mst_solib_trampoline;
|
| + }
|
| + }
|
| + }
|
| +
|
| /* Free the installed minimal symbol data. */
|
| do_cleanups (cleanup_minimal_symbols);
|
|
|
| @@ -653,13 +731,14 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags)
|
| char *debugfile;
|
|
|
| debugfile = find_separate_debug_file_by_debuglink (objfile);
|
| + make_cleanup (xfree, debugfile);
|
|
|
| if (debugfile)
|
| {
|
| bfd *abfd = symfile_bfd_open (debugfile);
|
|
|
| - symbol_file_add_separate (abfd, symfile_flags, objfile);
|
| - xfree (debugfile);
|
| + make_cleanup_bfd_unref (abfd);
|
| + symbol_file_add_separate (abfd, debugfile, symfile_flags, objfile);
|
| }
|
| }
|
|
|
| @@ -680,11 +759,6 @@ coff_new_init (struct objfile *ignore)
|
| static void
|
| coff_symfile_finish (struct objfile *objfile)
|
| {
|
| - if (objfile->deprecated_sym_private != NULL)
|
| - {
|
| - xfree (objfile->deprecated_sym_private);
|
| - }
|
| -
|
| /* Let stabs reader clean up. */
|
| stabsread_clear_cache ();
|
|
|
| @@ -745,17 +819,17 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
| /* Position to read the symbol table. */
|
| val = bfd_seek (objfile->obfd, (long) symtab_offset, 0);
|
| if (val < 0)
|
| - perror_with_name (objfile->name);
|
| + perror_with_name (objfile_name (objfile));
|
|
|
| coffread_objfile = objfile;
|
| nlist_bfd_global = objfile->obfd;
|
| nlist_nsyms_global = nsyms;
|
| - last_source_file = NULL;
|
| + set_last_source_file (NULL);
|
| memset (opaque_type_chain, 0, sizeof opaque_type_chain);
|
|
|
| if (type_vector) /* Get rid of previous one. */
|
| xfree (type_vector);
|
| - type_vector_length = 160;
|
| + type_vector_length = INITIAL_TYPE_VECTOR_LENGTH;
|
| type_vector = (struct type **)
|
| xmalloc (type_vector_length * sizeof (struct type *));
|
| memset (type_vector, 0, type_vector_length * sizeof (struct type *));
|
| @@ -771,7 +845,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|
|
| if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
|
| {
|
| - if (last_source_file)
|
| + if (get_last_source_file ())
|
| coff_end_symtab (objfile);
|
|
|
| coff_start_symtab ("_globals_");
|
| @@ -787,7 +861,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|
|
| /* Special case for file with type declarations only, no
|
| text. */
|
| - if (!last_source_file && SDB_TYPE (cs->c_type)
|
| + if (!get_last_source_file () && SDB_TYPE (cs->c_type)
|
| && cs->c_secnum == N_DEBUG)
|
| complete_symtab (filestring, 0, 0);
|
|
|
| @@ -836,7 +910,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|
|
| /* Complete symbol table for last object file
|
| containing debugging information. */
|
| - if (last_source_file)
|
| + if (get_last_source_file ())
|
| {
|
| coff_end_symtab (objfile);
|
| coff_start_symtab (filestring);
|
| @@ -940,7 +1014,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
| cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
|
| || cs->c_sclass == C_THUMBEXT ?
|
| mst_text : mst_file_text;
|
| - tmpaddr = gdbarch_smash_text_address (gdbarch, tmpaddr);
|
| + tmpaddr = gdbarch_addr_bits_remove (gdbarch, tmpaddr);
|
| }
|
| else if (bfd_section->flags & SEC_ALLOC
|
| && bfd_section->flags & SEC_LOAD)
|
| @@ -1126,7 +1200,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
| read_pe_exported_syms (objfile);
|
| }
|
|
|
| - if (last_source_file)
|
| + if (get_last_source_file ())
|
| coff_end_symtab (objfile);
|
|
|
| /* Patch up any opaque types (references to types that are not defined
|
| @@ -1155,14 +1229,14 @@ read_one_sym (struct coff_symbol *cs,
|
| cs->c_symnum = symnum;
|
| bytes = bfd_bread (temp_sym, local_symesz, nlist_bfd_global);
|
| if (bytes != local_symesz)
|
| - error (_("%s: error reading symbols"), coffread_objfile->name);
|
| + error (_("%s: error reading symbols"), objfile_name (coffread_objfile));
|
| bfd_coff_swap_sym_in (symfile_bfd, temp_sym, (char *) sym);
|
| cs->c_naux = sym->n_numaux & 0xff;
|
| if (cs->c_naux >= 1)
|
| {
|
| bytes = bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
|
| if (bytes != local_auxesz)
|
| - error (_("%s: error reading symbols"), coffread_objfile->name);
|
| + error (_("%s: error reading symbols"), objfile_name (coffread_objfile));
|
| bfd_coff_swap_aux_in (symfile_bfd, temp_aux,
|
| sym->n_type, sym->n_sclass,
|
| 0, cs->c_naux, (char *) aux);
|
| @@ -1172,7 +1246,8 @@ read_one_sym (struct coff_symbol *cs,
|
| {
|
| bytes = bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
|
| if (bytes != local_auxesz)
|
| - error (_("%s: error reading symbols"), coffread_objfile->name);
|
| + error (_("%s: error reading symbols"),
|
| + objfile_name (coffread_objfile));
|
| }
|
| }
|
| cs->c_name = getsymname (sym);
|
| @@ -1536,20 +1611,22 @@ static const struct symbol_register_ops coff_register_funcs = {
|
| coff_reg_to_regnum
|
| };
|
|
|
| +/* The "aclass" index for computed COFF symbols. */
|
| +
|
| +static int coff_register_index;
|
| +
|
| static struct symbol *
|
| process_coff_symbol (struct coff_symbol *cs,
|
| union internal_auxent *aux,
|
| struct objfile *objfile)
|
| {
|
| - struct symbol *sym
|
| - = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
|
| - sizeof (struct symbol));
|
| + struct symbol *sym = allocate_symbol (objfile);
|
| char *name;
|
|
|
| - memset (sym, 0, sizeof (struct symbol));
|
| name = cs->c_name;
|
| name = EXTERNAL_NAME (name, objfile->obfd);
|
| - SYMBOL_SET_LANGUAGE (sym, current_subfile->language);
|
| + SYMBOL_SET_LANGUAGE (sym, current_subfile->language,
|
| + &objfile->objfile_obstack);
|
| SYMBOL_SET_NAMES (sym, name, strlen (name), 1, objfile);
|
|
|
| /* default assumptions */
|
| @@ -1565,7 +1642,7 @@ process_coff_symbol (struct coff_symbol *cs,
|
| lookup_function_type (decode_function_type (cs, cs->c_type,
|
| aux, objfile));
|
|
|
| - SYMBOL_CLASS (sym) = LOC_BLOCK;
|
| + SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
|
| if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
|
| || cs->c_sclass == C_THUMBSTATFUNC)
|
| add_symbol_to_list (sym, &file_symbols);
|
| @@ -1582,14 +1659,14 @@ process_coff_symbol (struct coff_symbol *cs,
|
| break;
|
|
|
| case C_AUTO:
|
| - SYMBOL_CLASS (sym) = LOC_LOCAL;
|
| + SYMBOL_ACLASS_INDEX (sym) = LOC_LOCAL;
|
| add_symbol_to_list (sym, &local_symbols);
|
| break;
|
|
|
| case C_THUMBEXT:
|
| case C_THUMBEXTFUNC:
|
| case C_EXT:
|
| - SYMBOL_CLASS (sym) = LOC_STATIC;
|
| + SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
|
| SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
|
| SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
|
| SECT_OFF_TEXT (objfile));
|
| @@ -1599,7 +1676,7 @@ process_coff_symbol (struct coff_symbol *cs,
|
| case C_THUMBSTAT:
|
| case C_THUMBSTATFUNC:
|
| case C_STAT:
|
| - SYMBOL_CLASS (sym) = LOC_STATIC;
|
| + SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
|
| SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
|
| SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
|
| SECT_OFF_TEXT (objfile));
|
| @@ -1619,8 +1696,7 @@ process_coff_symbol (struct coff_symbol *cs,
|
| case C_GLBLREG:
|
| #endif
|
| case C_REG:
|
| - SYMBOL_CLASS (sym) = LOC_REGISTER;
|
| - SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs;
|
| + SYMBOL_ACLASS_INDEX (sym) = coff_register_index;
|
| SYMBOL_VALUE (sym) = cs->c_value;
|
| add_symbol_to_list (sym, &local_symbols);
|
| break;
|
| @@ -1630,21 +1706,20 @@ process_coff_symbol (struct coff_symbol *cs,
|
| break;
|
|
|
| case C_ARG:
|
| - SYMBOL_CLASS (sym) = LOC_ARG;
|
| + SYMBOL_ACLASS_INDEX (sym) = LOC_ARG;
|
| SYMBOL_IS_ARGUMENT (sym) = 1;
|
| add_symbol_to_list (sym, &local_symbols);
|
| break;
|
|
|
| case C_REGPARM:
|
| - SYMBOL_CLASS (sym) = LOC_REGISTER;
|
| - SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs;
|
| + SYMBOL_ACLASS_INDEX (sym) = coff_register_index;
|
| SYMBOL_IS_ARGUMENT (sym) = 1;
|
| SYMBOL_VALUE (sym) = cs->c_value;
|
| add_symbol_to_list (sym, &local_symbols);
|
| break;
|
|
|
| case C_TPDEF:
|
| - SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
| + SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
|
| SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
|
|
|
| /* If type has no name, give it one. */
|
| @@ -1700,7 +1775,7 @@ process_coff_symbol (struct coff_symbol *cs,
|
| case C_STRTAG:
|
| case C_UNTAG:
|
| case C_ENTAG:
|
| - SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
| + SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
|
| SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
|
|
|
| /* Some compilers try to be helpful by inventing "fake"
|
| @@ -2018,8 +2093,8 @@ coff_read_struct_type (int index, int length, int lastsym,
|
| list = new;
|
|
|
| /* Save the data. */
|
| - list->field.name = obsavestring (name, strlen (name),
|
| - &objfile->objfile_obstack);
|
| + list->field.name = obstack_copy0 (&objfile->objfile_obstack,
|
| + name, strlen (name));
|
| FIELD_TYPE (list->field) = decode_type (ms, ms->c_type,
|
| &sub_aux, objfile);
|
| SET_FIELD_BITPOS (list->field, 8 * ms->c_value);
|
| @@ -2035,8 +2110,8 @@ coff_read_struct_type (int index, int length, int lastsym,
|
| list = new;
|
|
|
| /* Save the data. */
|
| - list->field.name = obsavestring (name, strlen (name),
|
| - &objfile->objfile_obstack);
|
| + list->field.name = obstack_copy0 (&objfile->objfile_obstack,
|
| + name, strlen (name));
|
| FIELD_TYPE (list->field) = decode_type (ms, ms->c_type,
|
| &sub_aux, objfile);
|
| SET_FIELD_BITPOS (list->field, ms->c_value);
|
| @@ -2104,14 +2179,12 @@ coff_read_enum_type (int index, int length, int lastsym,
|
| switch (ms->c_sclass)
|
| {
|
| case C_MOE:
|
| - sym = (struct symbol *) obstack_alloc
|
| - (&objfile->objfile_obstack, sizeof (struct symbol));
|
| - memset (sym, 0, sizeof (struct symbol));
|
| + sym = allocate_symbol (objfile);
|
|
|
| SYMBOL_SET_LINKAGE_NAME (sym,
|
| - obsavestring (name, strlen (name),
|
| - &objfile->objfile_obstack));
|
| - SYMBOL_CLASS (sym) = LOC_CONST;
|
| + obstack_copy0 (&objfile->objfile_obstack,
|
| + name, strlen (name)));
|
| + SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
|
| SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
|
| SYMBOL_VALUE (sym) = ms->c_value;
|
| add_symbol_to_list (sym, symlist);
|
| @@ -2177,7 +2250,6 @@ coff_read_enum_type (int index, int length, int lastsym,
|
|
|
| static const struct sym_fns coff_sym_fns =
|
| {
|
| - bfd_target_coff_flavour,
|
| coff_new_init, /* sym_new_init: init anything gbl to
|
| entire symtab */
|
| coff_symfile_init, /* sym_init: read initial info, setup
|
| @@ -2199,8 +2271,22 @@ static const struct sym_fns coff_sym_fns =
|
| &psym_functions
|
| };
|
|
|
| +/* Free the per-objfile COFF data. */
|
| +
|
| +static void
|
| +coff_free_info (struct objfile *objfile, void *arg)
|
| +{
|
| + xfree (arg);
|
| +}
|
| +
|
| void
|
| _initialize_coffread (void)
|
| {
|
| - add_symtab_fns (&coff_sym_fns);
|
| + add_symtab_fns (bfd_target_coff_flavour, &coff_sym_fns);
|
| +
|
| + coff_objfile_data_key = register_objfile_data_with_cleanup (NULL,
|
| + coff_free_info);
|
| +
|
| + coff_register_index
|
| + = register_symbol_register_impl (LOC_REGISTER, &coff_register_funcs);
|
| }
|
|
|