diff options
-rw-r--r-- | frontends/yasm/yasm.c | 38 | ||||
-rw-r--r-- | libyasm/section.c | 22 | ||||
-rw-r--r-- | libyasm/section.h | 20 | ||||
-rw-r--r-- | libyasm/symrec.c | 15 | ||||
-rw-r--r-- | libyasm/symrec.h | 8 | ||||
-rw-r--r-- | modules/objfmts/bin/bin-objfmt.c | 6 | ||||
-rw-r--r-- | modules/objfmts/coff/coff-objfmt.c | 6 | ||||
-rw-r--r-- | modules/objfmts/elf/elf-objfmt.c | 31 | ||||
-rw-r--r-- | modules/objfmts/macho/macho-objfmt.c | 33 | ||||
-rw-r--r-- | modules/objfmts/rdf/rdf-objfmt.c | 5 | ||||
-rw-r--r-- | modules/objfmts/xdf/xdf-objfmt.c | 6 |
11 files changed, 144 insertions, 46 deletions
diff --git a/frontends/yasm/yasm.c b/frontends/yasm/yasm.c index 83294069..b8c1ac59 100644 --- a/frontends/yasm/yasm.c +++ b/frontends/yasm/yasm.c @@ -48,6 +48,7 @@ #define PREPROC_BUF_SIZE 16384 /*@null@*/ /*@only@*/ static char *obj_filename = NULL, *in_filename = NULL; +/*@null@*/ /*@only@*/ static char *global_prefix = NULL, *global_suffix = NULL; /*@null@*/ /*@only@*/ static char *list_filename = NULL, *map_filename = NULL; /*@null@*/ /*@only@*/ static char *machine_name = NULL; static int special_options = 0; @@ -106,6 +107,8 @@ static int opt_include_option(char *cmd, /*@null@*/ char *param, int extra); static int opt_preproc_option(char *cmd, /*@null@*/ char *param, int extra); static int opt_ewmsg_handler(char *cmd, /*@null@*/ char *param, int extra); static int opt_makedep_handler(char *cmd, /*@null@*/ char *param, int extra); +static int opt_prefix_handler(char *cmd, /*@null@*/ char *param, int extra); +static int opt_suffix_handler(char *cmd, /*@null@*/ char *param, int extra); #ifdef CMAKE_BUILD static int opt_plugin_handler(char *cmd, /*@null@*/ char *param, int extra); #endif @@ -196,6 +199,12 @@ static opt_option options[] = N_("undefine a macro"), N_("macro") }, { 'X', NULL, 1, opt_ewmsg_handler, 0, N_("select error/warning message style (`gnu' or `vc')"), N_("style") }, + { 0, "prefix", 1, opt_prefix_handler, 0, + N_("prepend argument to name of all external symbols"), N_("prefix") }, + { 0, "suffix", 1, opt_suffix_handler, 0, + N_("append argument to name of all external symbols"), N_("suffix") }, + { 0, "postfix", 1, opt_suffix_handler, 0, + N_("append argument to name of all external symbols"), N_("suffix") }, #ifdef CMAKE_BUILD { 'N', "plugin", 1, opt_plugin_handler, 0, N_("load plugin module"), N_("plugin") }, @@ -441,6 +450,11 @@ do_assemble(void) return EXIT_FAILURE; } + if (global_prefix) + yasm_object_set_global_prefix(object, global_prefix); + if (global_suffix) + yasm_object_set_global_suffix(object, global_suffix); + cur_preproc = yasm_preproc_create(cur_preproc_module, in_filename, object->symtab, linemap, errwarns); @@ -1140,6 +1154,30 @@ opt_makedep_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, return 0; } +static int +opt_prefix_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) +{ + if (global_prefix) + yasm_xfree(global_prefix); + + assert(param != NULL); + global_prefix = yasm__xstrdup(param); + + return 0; +} + +static int +opt_suffix_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) +{ + if (global_suffix) + yasm_xfree(global_suffix); + + assert(param != NULL); + global_suffix = yasm__xstrdup(param); + + return 0; +} + #ifdef CMAKE_BUILD static int opt_plugin_handler(/*@unused@*/ char *cmd, char *param, diff --git a/libyasm/section.c b/libyasm/section.c index a767e309..1f73929b 100644 --- a/libyasm/section.c +++ b/libyasm/section.c @@ -223,6 +223,10 @@ yasm_object_create(const char *src_filename, const char *obj_filename, object->src_filename = yasm__xstrdup(src_filename); object->obj_filename = yasm__xstrdup(obj_filename); + /* No prefix/suffix */ + object->global_prefix = yasm__xstrdup(""); + object->global_suffix = yasm__xstrdup(""); + /* Create empty symbol table */ object->symtab = yasm_symtab_create(); @@ -376,6 +380,20 @@ yasm_object_set_source_fn(yasm_object *object, const char *src_filename) object->src_filename = yasm__xstrdup(src_filename); } +void +yasm_object_set_global_prefix(yasm_object *object, const char *prefix) +{ + yasm_xfree(object->global_prefix); + object->global_prefix = yasm__xstrdup(prefix); +} + +void +yasm_object_set_global_suffix(yasm_object *object, const char *suffix) +{ + yasm_xfree(object->global_suffix); + object->global_suffix = yasm__xstrdup(suffix); +} + int yasm_section_is_code(yasm_section *sect) { @@ -450,6 +468,10 @@ yasm_object_destroy(yasm_object *object) /* Delete directives HAMT */ HAMT_destroy(object->directives, directive_level1_delete); + /* Delete prefix/suffix */ + yasm_xfree(object->global_prefix); + yasm_xfree(object->global_suffix); + /* Delete associated filenames */ yasm_xfree(object->src_filename); yasm_xfree(object->obj_filename); diff --git a/libyasm/section.h b/libyasm/section.h index b17f887d..3b3942a9 100644 --- a/libyasm/section.h +++ b/libyasm/section.h @@ -71,6 +71,12 @@ struct yasm_object { * second level is directive name. */ /*@owned@*/ struct HAMT *directives; + + /** Prefix prepended to externally-visible symbols (empty string if none) */ + /*@owned@*/ char *global_prefix; + + /** Suffix appended to externally-visible symbols (empty string if none) */ + /*@owned@*/ char *global_suffix; }; /** Create a new object. A default section is created as the first section. @@ -176,6 +182,20 @@ YASM_LIB_DECL YASM_LIB_DECL void yasm_object_set_source_fn(yasm_object *object, const char *src_filename); +/** Change the prefix used for externally-visible symbols. + * \param object object + * \param prefix new prefix + */ +YASM_LIB_DECL +void yasm_object_set_global_prefix(yasm_object *object, const char *prefix); + +/** Change the suffix used for externally-visible symbols. + * \param object object + * \param suffix new suffix + */ +YASM_LIB_DECL +void yasm_object_set_global_suffix(yasm_object *object, const char *suffix); + /** Optimize an object. Takes the unoptimized object and optimizes it. * If successful, the object is ready for output to an object file. * \param object object diff --git a/libyasm/symrec.c b/libyasm/symrec.c index 91807eb4..4ea0ca7e 100644 --- a/libyasm/symrec.c +++ b/libyasm/symrec.c @@ -453,6 +453,21 @@ yasm_symrec_get_name(const yasm_symrec *sym) return sym->name; } +char * +yasm_symrec_get_global_name(const yasm_symrec *sym, const yasm_object *object) +{ + if (sym->visibility & (YASM_SYM_GLOBAL|YASM_SYM_COMMON|YASM_SYM_EXTERN)) { + char *name = yasm_xmalloc(strlen(object->global_prefix) + + strlen(sym->name) + + strlen(object->global_suffix) + 1); + strcpy(name, object->global_prefix); + strcat(name, sym->name); + strcat(name, object->global_suffix); + return name; + } + return yasm__xstrdup(sym->name); +} + yasm_sym_vis yasm_symrec_get_visibility(const yasm_symrec *sym) { diff --git a/libyasm/symrec.h b/libyasm/symrec.h index 10706d9d..65d47755 100644 --- a/libyasm/symrec.h +++ b/libyasm/symrec.h @@ -253,6 +253,14 @@ void yasm_symtab_print(yasm_symtab *symtab, FILE *f, int indent_level); YASM_LIB_DECL /*@observer@*/ const char *yasm_symrec_get_name(const yasm_symrec *sym); +/** Get the externally-visible (global) name of a symbol. + * \param sym symbol + * \return Externally-visible symbol name (allocated, caller must free). + */ +YASM_LIB_DECL +/*@only@*/ char *yasm_symrec_get_global_name(const yasm_symrec *sym, + const yasm_object *object); + /** Get the visibility of a symbol. * \param sym symbol * \return Symbol visibility. diff --git a/modules/objfmts/bin/bin-objfmt.c b/modules/objfmts/bin/bin-objfmt.c index 478502ec..3d69a2db 100644 --- a/modules/objfmts/bin/bin-objfmt.c +++ b/modules/objfmts/bin/bin-objfmt.c @@ -663,6 +663,7 @@ map_symrec_output(yasm_symrec *sym, void *d) map_output_info *info = (map_output_info *)d; const yasm_expr *equ; /*@dependent@*/ yasm_bytecode *precbc; + /*@only@*/ char *name = yasm_symrec_get_global_name(sym, info->object); assert(info != NULL); @@ -673,7 +674,7 @@ map_symrec_output(yasm_symrec *sym, void *d) yasm_intnum_set(info->intn, yasm_expr_get_intnum(&realequ, 0)); yasm_expr_destroy(realequ); map_print_intnum(info->intn, info); - fprintf(info->f, " %s\n", yasm_symrec_get_name(sym)); + fprintf(info->f, " %s\n", name); } else if (yasm_symrec_get_label(sym, &precbc) && yasm_bc_get_section(precbc) == info->section) { bin_section_data *bsd = @@ -691,8 +692,9 @@ map_symrec_output(yasm_symrec *sym, void *d) map_print_intnum(info->intn, info); /* Name */ - fprintf(info->f, " %s\n", yasm_symrec_get_name(sym)); + fprintf(info->f, " %s\n", name); } + yasm_xfree(name); return 0; } diff --git a/modules/objfmts/coff/coff-objfmt.c b/modules/objfmts/coff/coff-objfmt.c index 16cf6ea3..5066acff 100644 --- a/modules/objfmts/coff/coff-objfmt.c +++ b/modules/objfmts/coff/coff-objfmt.c @@ -973,7 +973,7 @@ coff_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d) /* Don't output local syms unless outputting all syms */ if (info->all_syms || vis != YASM_SYM_LOCAL) { - const char *name = yasm_symrec_get_name(sym); + /*@only*/ char *name = yasm_symrec_get_global_name(sym, info->object); const yasm_expr *equ_val; const yasm_intnum *intn; unsigned char *localbuf; @@ -1091,6 +1091,7 @@ coff_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d) } fwrite(info->buf, 18, 1, info->f); } + yasm_xfree(name); } return 0; } @@ -1105,7 +1106,7 @@ coff_objfmt_output_str(yasm_symrec *sym, /*@null@*/ void *d) /* Don't output local syms unless outputting all syms */ if (info->all_syms || vis != YASM_SYM_LOCAL) { - const char *name = yasm_symrec_get_name(sym); + /*@only@*/ char *name = yasm_symrec_get_global_name(sym, info->object); /*@dependent@*/ /*@null@*/ coff_symrec_data *csymd; size_t len = strlen(name); int aux; @@ -1127,6 +1128,7 @@ coff_objfmt_output_str(yasm_symrec *sym, /*@null@*/ void *d) break; } } + yasm_xfree(name); } return 0; } diff --git a/modules/objfmts/elf/elf-objfmt.c b/modules/objfmts/elf/elf-objfmt.c index d2083a84..dd868d91 100644 --- a/modules/objfmts/elf/elf-objfmt.c +++ b/modules/objfmts/elf/elf-objfmt.c @@ -86,14 +86,16 @@ static elf_symtab_entry * elf_objfmt_symtab_append(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym, elf_section_index sectidx, elf_symbol_binding bind, elf_symbol_type type, elf_symbol_vis vis, - yasm_expr *size, elf_address *value) + yasm_expr *size, elf_address *value, + yasm_object *object) { elf_symtab_entry *entry = yasm_symrec_get_data(sym, &elf_symrec_data); if (!entry) { + /*@only@*/ char *symname = yasm_symrec_get_global_name(sym, object); elf_strtab_entry *name = - elf_strtab_append_str(objfmt_elf->strtab, - yasm_symrec_get_name(sym)); + elf_strtab_append_str(objfmt_elf->strtab, symname); + yasm_xfree(symname); entry = elf_symtab_entry_create(name, sym); yasm_symrec_add_data(sym, &elf_symrec_data, entry); } @@ -109,7 +111,7 @@ elf_objfmt_symtab_append(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym, } static elf_symtab_entry * -build_extern(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym) +build_extern(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym, yasm_object *object) { yasm_valparamhead *objext_valparams = yasm_symrec_get_objext_valparams(sym); @@ -125,7 +127,7 @@ build_extern(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym) } return elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_GLOBAL, 0, - STV_DEFAULT, NULL, NULL); + STV_DEFAULT, NULL, NULL, object); } struct elf_build_global_data { @@ -166,7 +168,7 @@ elf_global_helper_vis(void *obj, yasm_valparam *vp, unsigned long line, static elf_symtab_entry * -build_global(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym) +build_global(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym, yasm_object *object) { yasm_valparamhead *objext_valparams = yasm_symrec_get_objext_valparams(sym); @@ -201,7 +203,8 @@ build_global(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym) } return elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_GLOBAL, - data.type, data.vis, data.size, NULL); + data.type, data.vis, data.size, NULL, + object); } static /*@null@*/ elf_symtab_entry * @@ -244,7 +247,7 @@ build_common(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym, yasm_object *object) } return elf_objfmt_symtab_append(objfmt_elf, sym, SHN_COMMON, STB_GLOBAL, - 0, STV_DEFAULT, *size, &addralign); + 0, STV_DEFAULT, *size, &addralign, object); } static int @@ -261,7 +264,7 @@ elf_objfmt_build_symtab(yasm_symrec *sym, /*@null@*/ void *d) assert(info != NULL); if (vis & YASM_SYM_EXTERN) { - entry = build_extern(info->objfmt_elf, sym); + entry = build_extern(info->objfmt_elf, sym, info->object); yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym)); return 0; @@ -292,7 +295,7 @@ elf_objfmt_build_symtab(yasm_symrec *sym, /*@null@*/ void *d) if (entry && elf_sym_in_table(entry)) ; else if (vis & YASM_SYM_GLOBAL) { - entry = build_global(info->objfmt_elf, sym); + entry = build_global(info->objfmt_elf, sym, info->object); yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym)); } else { int is_sect = 0; @@ -315,9 +318,11 @@ elf_objfmt_build_symtab(yasm_symrec *sym, /*@null@*/ void *d) #endif entry = yasm_symrec_get_data(sym, &elf_symrec_data); if (!entry) { + /*@only@*/ char *symname = + yasm_symrec_get_global_name(sym, info->object); elf_strtab_entry *name = !info->local_names || is_sect ? NULL : - elf_strtab_append_str(info->objfmt_elf->strtab, - yasm_symrec_get_name(sym)); + elf_strtab_append_str(info->objfmt_elf->strtab, symname); + yasm_xfree(symname); entry = elf_symtab_entry_create(name, sym); yasm_symrec_add_data(sym, &elf_symrec_data, entry); } @@ -1234,7 +1239,7 @@ dir_weak(yasm_object *object, yasm_valparamhead *valparams, yasm_symrec *sym = yasm_symtab_declare(object->symtab, symname, YASM_SYM_GLOBAL, line); elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_WEAK, 0, - STV_DEFAULT, NULL, NULL); + STV_DEFAULT, NULL, NULL, object); } static void diff --git a/modules/objfmts/macho/macho-objfmt.c b/modules/objfmts/macho/macho-objfmt.c index 78ba9f0a..10d5893a 100644 --- a/modules/objfmts/macho/macho-objfmt.c +++ b/modules/objfmts/macho/macho-objfmt.c @@ -88,21 +88,11 @@ Will currently produce an error though the necessary means are provided by the Mach-O specification. - 3) symbol naming for global and external symbols - BSD, Windows and MacOS-X use underscores for global symbols, - where ELF/Linux does not. This file contains simple means of adding - underscores to symbols by defining "AUTO_UNDERSCORE" but that - can be considered not more than a hack. For cross-platform coding, - use two symbols for your routines and referenced data. - */ #include <util.h> /*@unused@*/ RCSID("$Id$"); -/* optional: automatically prefix underscores to global exported symbols */ -/*#define AUTO_UNDERSCORE*/ - #include <libyasm.h> /* MACH-O DEFINES */ @@ -288,7 +278,6 @@ typedef struct macho_symrec_data { unsigned long index; /* index in output order */ yasm_intnum *value; /* valid after writing symtable to file */ unsigned long length; /* length + 1 (plus auto underscore) */ - int add_uscore; /* add underscore (0/1) */ } macho_symrec_data; @@ -808,7 +797,7 @@ static int macho_objfmt_count_sym(yasm_symrec *sym, /*@null@*/ void *d) { /*@null@*/ macho_objfmt_output_info *info = (macho_objfmt_output_info *)d; - const char *name; + /*@only@*/ char *name; yasm_sym_vis vis = yasm_symrec_get_visibility(sym); assert(info != NULL); @@ -825,19 +814,13 @@ macho_objfmt_count_sym(yasm_symrec *sym, /*@null@*/ void *d) sym_data->index = info->symindex; info->symindex++; - name = yasm_symrec_get_name(sym); /*printf("%s\n",name); */ - sym_data->add_uscore = 0; -#ifdef AUTO_UNDERSCORE - if (vis & (YASM_SYM_EXTERN | YASM_SYM_COMMON | YASM_SYM_GLOBAL)) { - if (name[0] != '_') - sym_data->add_uscore = 1; - } -#endif + name = yasm_symrec_get_global_name(sym, info->object); + /*printf("%s\n",name); */ /* name length + delimiter */ - sym_data->length = - (unsigned long)strlen(name) + sym_data->add_uscore + 1; + sym_data->length = (unsigned long)strlen(name) + 1; info->strlength += sym_data->length; info->indx++; + yasm_xfree(name); } } return 0; @@ -977,13 +960,13 @@ macho_objfmt_output_str(yasm_symrec *sym, /*@null@*/ void *d) if (info->all_syms || vis & (YASM_SYM_GLOBAL | YASM_SYM_COMMON | YASM_SYM_EXTERN)) { if (0 == macho_objfmt_is_section_label(sym)) { - const char *name = yasm_symrec_get_name(sym); + /*@only@*/ char *name = + yasm_symrec_get_global_name(sym, info->object); size_t len = strlen(name); xsymd = yasm_symrec_get_data(sym, &macho_symrec_data_cb); - if (xsymd->add_uscore) - fputc('_', info->f); fwrite(name, len + 1, 1, info->f); + yasm_xfree(name); } } return 0; diff --git a/modules/objfmts/rdf/rdf-objfmt.c b/modules/objfmts/rdf/rdf-objfmt.c index e4173289..962f02f6 100644 --- a/modules/objfmts/rdf/rdf-objfmt.c +++ b/modules/objfmts/rdf/rdf-objfmt.c @@ -520,7 +520,7 @@ rdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d) { /*@null@*/ rdf_objfmt_output_info *info = (rdf_objfmt_output_info *)d; yasm_sym_vis vis = yasm_symrec_get_visibility(sym); - const char *name; + /*@only@*/ char *name; size_t len; unsigned long value = 0; unsigned int scnum = 0; @@ -558,7 +558,7 @@ rdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d) return 0; } - name = yasm_symrec_get_name(sym); + name = yasm_symrec_get_global_name(sym, info->object); len = strlen(name); if (len > EXIM_LABEL_MAX-1) { @@ -655,6 +655,7 @@ rdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d) memcpy(localbuf, name, len); localbuf += len; YASM_WRITE_8(localbuf, 0); /* 0-terminated name */ + yasm_xfree(name); fwrite(info->buf, (unsigned long)(localbuf-info->buf), 1, info->f); diff --git a/modules/objfmts/xdf/xdf-objfmt.c b/modules/objfmts/xdf/xdf-objfmt.c index 89cb403c..bae43525 100644 --- a/modules/objfmts/xdf/xdf-objfmt.c +++ b/modules/objfmts/xdf/xdf-objfmt.c @@ -452,7 +452,7 @@ xdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d) assert(info != NULL); if (info->all_syms || vis != YASM_SYM_LOCAL) { - const char *name = yasm_symrec_get_name(sym); + /*@only@*/ char *name = yasm_symrec_get_global_name(sym, info->object); const yasm_expr *equ_val; const yasm_intnum *intn; size_t len = strlen(name); @@ -514,6 +514,7 @@ xdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d) info->strtab_offset += (unsigned long)(len+1); YASM_WRITE_32_L(localbuf, flags); /* flags */ fwrite(info->buf, 16, 1, info->f); + yasm_xfree(name); } return 0; } @@ -527,9 +528,10 @@ xdf_objfmt_output_str(yasm_symrec *sym, /*@null@*/ void *d) assert(info != NULL); if (info->all_syms || vis != YASM_SYM_LOCAL) { - const char *name = yasm_symrec_get_name(sym); + /*@only@*/ char *name = yasm_symrec_get_global_name(sym, info->object); size_t len = strlen(name); fwrite(name, len+1, 1, info->f); + yasm_xfree(name); } return 0; } |