]> granicus.if.org Git - yasm/commitdiff
Fix #132: Add --prefix and --suffix (aka --postfix) options.
authorPeter Johnson <peter@tortall.net>
Sun, 8 Jun 2008 09:06:05 +0000 (09:06 -0000)
committerPeter Johnson <peter@tortall.net>
Sun, 8 Jun 2008 09:06:05 +0000 (09:06 -0000)
These allow arbitrary prefixes and/or suffixes to be added to
externally-visible (GLOBAL, EXTERN, or COMMON) symbol names.

svn path=/trunk/yasm/; revision=2109

frontends/yasm/yasm.c
libyasm/section.c
libyasm/section.h
libyasm/symrec.c
libyasm/symrec.h
modules/objfmts/bin/bin-objfmt.c
modules/objfmts/coff/coff-objfmt.c
modules/objfmts/elf/elf-objfmt.c
modules/objfmts/macho/macho-objfmt.c
modules/objfmts/rdf/rdf-objfmt.c
modules/objfmts/xdf/xdf-objfmt.c

index 832940690012c842ecf2318510d2a78d4cd975e6..b8c1ac5953d3185a40cceec7c03afcfc3703a9c4 100644 (file)
@@ -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,
index a767e3099bc1a659043835a80212f63e6886738f..1f73929b60110601387c8711ba51a7669e0b3b9b 100644 (file)
@@ -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);
index b17f887d9ff1f9e8d235e39937b77a44e6fba3d4..3b3942a9c887b04bd78885bf9c0e6acd852fdafb 100644 (file)
@@ -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
index 91807eb4548f356b649c581a9b4d6ef3ed73fa5b..4ea0ca7e46a80ea7519087ff5e17f25e7a6fa3af 100644 (file)
@@ -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)
 {
index 10706d9dc518e5e28fe1fe6a83c2c9703b593228..65d47755913fd0adb2f6a38e01cd0a0ff5a4f5ed 100644 (file)
@@ -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.
index 478502ec1ae05bb14aa3c2a4e0c7d78f1051f7fc..3d69a2dbbd61f57812fa682f85b92c1c2d7048ed 100644 (file)
@@ -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;
 }
 
index 16cf6ea3d43582cb000bf4f60bee1a53fc38765b..5066acff2938889e3873e96f4828a76d52bd186c 100644 (file)
@@ -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;
 }
index d2083a842ecbe610f437a159d90af3b3ac4c08e7..dd868d91c77479c78692c1dbdb1328f451c60d30 100644 (file)
@@ -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
index 78ba9f0ac05764f31e0d29f76386422dd0b89866..10d5893a9e4179ca878955fbf634d0f14b8188f4 100644 (file)
        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;
index e4173289d29ca9edb18e7f4c4c94a176f2e1bf3c..962f02f6e50ba2782d0877c6d8b8b75fe732a8af 100644 (file)
@@ -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);
 
index 89cb403c0a6eebf4effc5db0ba182fe967fc9c7f..bae4352501c24a2173f066d9594e9a5b931657dd 100644 (file)
@@ -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;
 }