#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;
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
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") },
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);
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,
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();
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)
{
/* 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);
* 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.
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
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)
{
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.
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);
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 =
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;
}
/* 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;
}
fwrite(info->buf, 18, 1, info->f);
}
+ yasm_xfree(name);
}
return 0;
}
/* 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;
break;
}
}
+ yasm_xfree(name);
}
return 0;
}
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);
}
}
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);
}
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 {
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);
}
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 *
}
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
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;
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;
#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);
}
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
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 */
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;
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);
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;
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;
{
/*@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;
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) {
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);
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);
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;
}
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;
}