dlltool.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,503 行 · 第 1/5 页
C
2,503 行
q->functail->name = xstrdup (symbol_name); q->functail->ord = func_ordinal; q->functail->next = NULL; *pq = q;}/* def_import is called from within defparse.y when an IMPORT declaration is encountered. Depending on the form of the declaration, the module name may or may not need ".dll" to be appended to it, the name of the function may be stored in internal or entry, and there may or may not be an ordinal value associated with it. *//* A note regarding the parse modes: In defparse.y we have to accept import declarations which follow any one of the following forms: <func_name_in_app> = <dll_name>.<func_name_in_dll> <func_name_in_app> = <dll_name>.<number> <dll_name>.<func_name_in_dll> <dll_name>.<number> Furthermore, the dll's name may or may not end with ".dll", which complicates the parsing a little. Normally the dll's name is passed to def_import() in the "module" parameter, but when it ends with ".dll" it gets passed in "module" sans ".dll" and that needs to be reappended. def_import gets five parameters: APP_NAME - the name of the function in the application, if present, or NULL if not present. MODULE - the name of the dll, possibly sans extension (ie, '.dll'). DLLEXT - the extension of the dll, if present, NULL if not present. ENTRY - the name of the function in the dll, if present, or NULL. ORD_VAL - the numerical tag of the function in the dll, if present, or NULL. Exactly one of <entry> or <ord_val> must be present (i.e., not NULL). */voiddef_import (app_name, module, dllext, entry, ord_val) const char *app_name; const char *module; const char *dllext; const char *entry; int ord_val;{ const char *application_name; char *buf; if (entry != NULL) application_name = entry; else { if (app_name != NULL) application_name = app_name; else application_name = ""; } if (dllext != NULL) { buf = (char *) alloca (strlen (module) + strlen (dllext) + 2); sprintf (buf, "%s.%s", module, dllext); module = buf; } append_import (application_name, module, ord_val);}voiddef_version (major, minor) int major; int minor;{ printf ("VERSION %d.%d\n", major, minor);}voiddef_section (name, attr) const char *name; int attr;{ char buf[200]; char atts[5]; char *d = atts; if (attr & 1) *d++ = 'R'; if (attr & 2) *d++ = 'W'; if (attr & 4) *d++ = 'X'; if (attr & 8) *d++ = 'S'; *d++ = 0; sprintf (buf, "-attr %s %s", name, atts); new_directive (xstrdup (buf));}voiddef_code (attr) int attr;{ def_section ("CODE", attr);}voiddef_data (attr) int attr;{ def_section ("DATA", attr);}/**********************************************************************/static voidrun (what, args) const char *what; char *args;{ char *s; int pid, wait_status; int i; const char **argv; char *errmsg_fmt, *errmsg_arg; char *temp_base = choose_temp_base (); inform ("run: %s %s", what, args); /* Count the args */ i = 0; for (s = args; *s; s++) if (*s == ' ') i++; i++; argv = alloca (sizeof (char *) * (i + 3)); i = 0; argv[i++] = what; s = args; while (1) { while (*s == ' ') ++s; argv[i++] = s; while (*s != ' ' && *s != 0) s++; if (*s == 0) break; *s++ = 0; } argv[i++] = NULL; pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base, &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH); if (pid == -1) { inform (strerror (errno)); fatal (errmsg_fmt, errmsg_arg); } pid = pwait (pid, & wait_status, 0); if (pid == -1) { /* xgettext:c-format */ fatal (_("wait: %s"), strerror (errno)); } else if (WIFSIGNALED (wait_status)) { /* xgettext:c-format */ fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status)); } else if (WIFEXITED (wait_status)) { if (WEXITSTATUS (wait_status) != 0) /* xgettext:c-format */ non_fatal (_("%s exited with status %d"), what, WEXITSTATUS (wait_status)); } else abort ();}/* Look for a list of symbols to export in the .drectve section of ABFD. Pass each one to def_exports. */static voidscan_drectve_symbols (abfd) bfd *abfd;{ asection * s; int size; char * buf; char * p; char * e; /* Look for .drectve's */ s = bfd_get_section_by_name (abfd, DRECTVE_SECTION_NAME); if (s == NULL) return; size = bfd_get_section_size_before_reloc (s); buf = xmalloc (size); bfd_get_section_contents (abfd, s, buf, 0, size); /* xgettext:c-format */ inform (_("Sucking in info from %s section in %s"), DRECTVE_SECTION_NAME, bfd_get_filename (abfd)); /* Search for -export: strings. The exported symbols can optionally have type tags (eg., -export:foo,data), so handle those as well. Currently only data tag is supported. */ p = buf; e = buf + size; while (p < e) { if (p[0] == '-' && strncmp (p, "-export:", 8) == 0) { char * name; char * c; flagword flags = BSF_FUNCTION; p += 8; name = p; while (p < e && *p != ',' && *p != ' ' && *p != '-') p++; c = xmalloc (p - name + 1); memcpy (c, name, p - name); c[p - name] = 0; if (p < e && *p == ',') /* found type tag. */ { char *tag_start = ++p; while (p < e && *p != ' ' && *p != '-') p++; if (strncmp (tag_start, "data", 4) == 0) flags &= ~BSF_FUNCTION; } /* FIXME: The 5th arg is for the `constant' field. What should it be? Not that it matters since it's not currently useful. */ def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION)); if (add_stdcall_alias && strchr (c, '@')) { char *exported_name = xstrdup (c); char *atsym = strchr (exported_name, '@'); *atsym = '\0'; /* Note: stdcall alias symbols can never be data. */ def_exports (exported_name, xstrdup (c), -1, 0, 0, 0); } } else p++; } free (buf);}/* Look through the symbols in MINISYMS, and add each one to list of symbols to export. */static voidscan_filtered_symbols (abfd, minisyms, symcount, size) bfd *abfd; PTR minisyms; long symcount; unsigned int size;{ asymbol *store; bfd_byte *from, *fromend; store = bfd_make_empty_symbol (abfd); if (store == NULL) bfd_fatal (bfd_get_filename (abfd)); from = (bfd_byte *) minisyms; fromend = from + symcount * size; for (; from < fromend; from += size) { asymbol *sym; const char *symbol_name; sym = bfd_minisymbol_to_symbol (abfd, false, from, store); if (sym == NULL) bfd_fatal (bfd_get_filename (abfd)); symbol_name = bfd_asymbol_name (sym); if (bfd_get_symbol_leading_char (abfd) == symbol_name[0]) ++symbol_name; def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, ! (sym->flags & BSF_FUNCTION)); if (add_stdcall_alias && strchr (symbol_name, '@')) { char *exported_name = xstrdup (symbol_name); char *atsym = strchr (exported_name, '@'); *atsym = '\0'; /* Note: stdcall alias symbols can never be data. */ def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0); } }}/* Add a list of symbols to exclude. */static voidadd_excludes (new_excludes) const char *new_excludes;{ char *local_copy; char *exclude_string; local_copy = xstrdup (new_excludes); exclude_string = strtok (local_copy, ",:"); for (; exclude_string; exclude_string = strtok (NULL, ",:")) { struct string_list *new_exclude; new_exclude = ((struct string_list *) xmalloc (sizeof (struct string_list))); new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 2); /* FIXME: Is it always right to add a leading underscore? */ sprintf (new_exclude->string, "_%s", exclude_string); new_exclude->next = excludes; excludes = new_exclude; /* xgettext:c-format */ inform (_("Excluding symbol: %s"), exclude_string); } free (local_copy);}/* See if STRING is on the list of symbols to exclude. */static booleanmatch_exclude (string) const char *string;{ struct string_list *excl_item; for (excl_item = excludes; excl_item; excl_item = excl_item->next) if (strcmp (string, excl_item->string) == 0) return true; return false;}/* Add the default list of symbols to exclude. */static voidset_default_excludes (void){ add_excludes (default_excludes);}/* Choose which symbols to export. */static longfilter_symbols (abfd, minisyms, symcount, size) bfd *abfd; PTR minisyms; long symcount; unsigned int size;{ bfd_byte *from, *fromend, *to; asymbol *store; store = bfd_make_empty_symbol (abfd); if (store == NULL) bfd_fatal (bfd_get_filename (abfd)); from = (bfd_byte *) minisyms; fromend = from + symcount * size; to = (bfd_byte *) minisyms; for (; from < fromend; from += size) { int keep = 0; asymbol *sym; sym = bfd_minisymbol_to_symbol (abfd, false, (const PTR) from, store); if (sym == NULL) bfd_fatal (bfd_get_filename (abfd)); /* Check for external and defined only symbols. */ keep = (((sym->flags & BSF_GLOBAL) != 0 || (sym->flags & BSF_WEAK) != 0 || bfd_is_com_section (sym->section)) && ! bfd_is_und_section (sym->section)); keep = keep && ! match_exclude (sym->name); if (keep) { memcpy (to, from, size); to += size; } } return (to - (bfd_byte *) minisyms) / size;}/* Export all symbols in ABFD, except for ones we were told not to export. */static voidscan_all_symbols (abfd) bfd *abfd;{ long symcount; PTR minisyms; unsigned int size; /* Ignore bfds with an import descriptor table. We assume that any such BFD contains symbols which are exported from another DLL, and we don't want to reexport them from here. */ if (bfd_get_section_by_name (abfd, ".idata$4")) return; if (! (bfd_get_file_flags (abfd) & HAS_SYMS)) { /* xgettext:c-format */ non_fatal (_("%s: no symbols"), bfd_get_filename (abfd)); return; } symcount = bfd_read_minisymbols (abfd, false, &minisyms, &size); if (symcount < 0) bfd_fatal (bfd_get_filename (abfd)); if (symcount == 0) { /* xgettext:c-format */ non_fatal (_("%s: no symbols"), bfd_get_filename (abfd)); return; } /* Discard the symbols we don't want to export. It's OK to do this in place; we'll free the storage anyway. */ symcount = filter_symbols (abfd, minisyms, symcount, size); scan_filtered_symbols (abfd, minisyms, symcount, size); free (minisyms);}/* Look at the object file to decide which symbols to export. */static voidscan_open_obj_file (abfd) bfd *abfd;{ if (export_all_symbols) scan_all_symbols (abfd); else scan_drectve_symbols (abfd); /* FIXME: we ought to read in and block out the base relocations */ /* xgettext:c-format */ inform (_("Done reading %s"), bfd_get_filename (abfd));}static voidscan_obj_file (filename) const char *filename;{ bfd * f = bfd_openr (filename, 0); if (!f) /* xgettext:c-format */ fatal (_("Unable to open object file: %s"), filename); /* xgettext:c-format */ inform (_("Scanning object file %s"), filename); if (bfd_check_format (f, bfd_archive)) { bfd *arfile = bfd_openr_next_archived_file (f, 0); while (arfile) { if (bfd_check_format (arfile, bfd_object)) scan_open_obj_file (arfile); bfd_close (arfile); arfile = bfd_openr_next_archived_file (f, arfile); } #ifdef DLLTOOL_MCORE_ELF if (mcore_elf_out_file) inform (_("Cannot produce mcore-elf dll from archive file: %s"), filename);#endif } else if (bfd_check_format (f, bfd_object)) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?