]> granicus.if.org Git - yasm/commitdiff
Merge [2109] from trunk (Fix #132, --prefix and --suffix options).
authorPeter Johnson <peter@tortall.net>
Wed, 8 Oct 2008 07:29:43 +0000 (07:29 -0000)
committerPeter Johnson <peter@tortall.net>
Wed, 8 Oct 2008 07:29:43 +0000 (07:29 -0000)
svn path=/branches/yasm-0.7.x/; revision=2143

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 8c24d285aad1be29a40d08a738f14cc8895f6741..3920afbe343a3e76151d43b7e2dd08be810a5e3e 100644 (file)
@@ -44,6 +44,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;
@@ -102,6 +103,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);
 
 static /*@only@*/ char *replace_extension(const char *orig, /*@null@*/
                                           const char *ext, const char *def);
@@ -188,6 +191,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") },
 };
 
 /* version message */
@@ -425,6 +434,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);
 
@@ -1111,6 +1125,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;
+}
+
 static void
 apply_preproc_builtins()
 {
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 d42040a6f1e32521e6094c8138a16235638fbb81..b1d1e518556bdb8b30bb8afa4671b4794a9ab652 100644 (file)
@@ -67,6 +67,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.
@@ -163,6 +169,18 @@ int yasm_object_sections_traverse
  */
 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
+ */
+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
+ */
+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 349dcce5642639c0d3e2400a0d7608f3e6e6afa6..531fb018a09f0ed6b5bb8bdc0168949b641e1e74 100644 (file)
@@ -231,6 +231,13 @@ void yasm_symtab_print(yasm_symtab *symtab, FILE *f, int indent_level);
  */
 /*@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).
+ */
+/*@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 e108076081c39b0d99efb41aa8ad8f0f567fd763..c0d28191195369ed98bc2ce80422a20ff2a4c729 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 300b37691341b44ae526a88a33ed3fb661c65bf2..28aec157f41f42561fd0a46bb1ab0e2d114e6d7f 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 142275eadb58a5d6f2ff5d3f1c777d344e8c28d0..3756df304b8f38b89146aeeeb4e78f45ef20c844 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 0dc74e94a6c287b0605a329451a7349cdcd5c830..70e09ec2e240ac4db7ad2e793e327c07f20ea735 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 22e2a1c7cd20f68bc2a34eb755567730c900f776..41e95cae5054e82eec2a601c0ea103ab934d7ea9 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 d7cb453b1ed7553261c274402be32e08f1b4e9f5..693c31cfa60591dc965ff3cf98af3709e40d380f 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;
 }