Massive update of directive handling, including handling of extern, global,

and common declare.  The latter no longer passes through objfmt at parse time;
instead the objfmt must handle them at output time (objfmt-specific
extensions are parsed & stored by the parser).  Directives are now handled
using a list (with function pointers) rather than a single function entry
point.

svn path=/trunk/yasm/; revision=1819
This commit is contained in:
Peter Johnson 2007-03-21 04:23:59 +00:00
parent ee10323d3a
commit decb27eaa2
45 changed files with 13019 additions and 13423 deletions

View file

@ -453,7 +453,7 @@ do_assemble(FILE *in)
yasm_symtab_parser_finalize(object->symtab,
strcmp(cur_parser_module->keyword, "gas")==0 ||
strcmp(cur_parser_module->keyword, "gnu")==0,
object, errwarns);
errwarns);
check_errors(errwarns, object, linemap);
/* Finalize parse */
@ -604,7 +604,7 @@ main(int argc, char *argv[])
/* Check for arch help */
if (machine_name && strcmp(machine_name, "help") == 0) {
yasm_arch_machine *m = cur_arch_module->machines;
const yasm_arch_machine *m = cur_arch_module->machines;
printf(_("Available %s for %s `%s':\n"), _("machines"),
_("architecture"), cur_arch_module->keyword);
while (m->keyword && m->name) {

View file

@ -106,6 +106,9 @@ typedef struct yasm_arch_module {
*/
const char *keyword;
/** NULL-terminated list of directives. NULL if none. */
/*@null@*/ const yasm_directive *directives;
/** Create architecture.
* Module-level implementation of yasm_arch_create().
* Call yasm_arch_create() instead of calling this function.
@ -133,11 +136,6 @@ typedef struct yasm_arch_module {
*/
int (*set_var) (yasm_arch *arch, const char *var, unsigned long val);
/** Module-level implementation of yasm_arch_parse_cpu().
* Call yasm_arch_parse_cpu() instead of calling this function.
*/
void (*parse_cpu) (yasm_arch *arch, const char *cpuid, size_t cpuid_len);
/** Module-level implementation of yasm_arch_parse_check_insnprefix().
* Call yasm_arch_parse_check_insnprefix() instead of calling this function.
*/
@ -152,14 +150,6 @@ typedef struct yasm_arch_module {
(yasm_arch *arch, /*@out@*/ uintptr_t *data, const char *id,
size_t id_len);
/** Module-level implementation of yasm_arch_parse_directive().
* Call yasm_arch_parse_directive() instead of calling this function.
*/
int (*parse_directive) (yasm_arch *arch, const char *name,
/*@null@*/ yasm_valparamhead *valparams,
/*@null@*/ yasm_valparamhead *objext_valparams,
yasm_object *object, unsigned long line);
/** Module-level implementation of yasm_arch_get_fill().
* Call yasm_arch_get_fill() instead of calling this function.
*/
@ -219,7 +209,7 @@ typedef struct yasm_arch_module {
* Call yasm_arch_get_machine() to get the active machine of a particular
* #yasm_arch.
*/
yasm_arch_machine *machines;
const yasm_arch_machine *machines;
/** Default machine keyword.
* Call yasm_arch_get_machine() to get the active machine of a particular
@ -352,15 +342,6 @@ unsigned int yasm_arch_get_address_size(const yasm_arch *arch);
*/
int yasm_arch_set_var(yasm_arch *arch, const char *var, unsigned long val);
/** Switch available instructions/registers/etc based on a user-specified
* CPU identifier. Should modify behavior ONLY of parse_* functions! The
* bytecode and output functions should be able to handle any CPU.
* \param arch architecture
* \param cpuid cpu identifier as in the input file
* \param cpuid_len length of cpu identifier string
*/
void yasm_arch_parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len);
/** Check an generic identifier to see if it matches architecture specific
* names for instructions or instruction prefixes. Unrecognized identifiers
* should return #YASM_ARCH_NOTINSNPREFIX so they can be treated as normal
@ -393,23 +374,6 @@ yasm_arch_regtmod yasm_arch_parse_check_regtmod
(yasm_arch *arch, /*@out@*/ uintptr_t *data, const char *id,
size_t id_len);
/** Handle architecture-specific directives.
* Should modify behavior ONLY of parse functions, much like parse_cpu().
* \param arch architecture
* \param name directive name
* \param valparams value/parameters
* \param objext_valparams object format extensions
* value/parameters
* \param object object
* \param line virtual line (as from yasm_linemap)
* \return Nonzero if directive was not recognized; 0 if directive was
* recognized, even if it wasn't valid.
*/
int yasm_arch_parse_directive(yasm_arch *arch, const char *name,
/*@null@*/ yasm_valparamhead *valparams,
/*@null@*/ yasm_valparamhead *objext_valparams,
yasm_object *object, unsigned long line);
/** Get NOP fill patterns for 1-15 bytes of fill.
* \param arch architecture
* \return 16-entry array of arrays; [0] is unused, [1] - [15] point to arrays
@ -542,18 +506,12 @@ yasm_effaddr *yasm_arch_ea_create(yasm_arch *arch, /*@keep@*/ yasm_expr *e);
((yasm_arch_base *)arch)->module->get_address_size(arch)
#define yasm_arch_set_var(arch, var, val) \
((yasm_arch_base *)arch)->module->set_var(arch, var, val)
#define yasm_arch_parse_cpu(arch, cpuid, cpuid_len) \
((yasm_arch_base *)arch)->module->parse_cpu(arch, cpuid, cpuid_len)
#define yasm_arch_parse_check_insnprefix(arch, data, id, id_len) \
((yasm_arch_base *)arch)->module->parse_check_insnprefix(arch, data, id, \
id_len)
#define yasm_arch_parse_check_regtmod(arch, data, id, id_len) \
((yasm_arch_base *)arch)->module->parse_check_regtmod(arch, data, id, \
id_len)
#define yasm_arch_parse_directive(arch, name, valparams, objext_valparams, \
object, line) \
((yasm_arch_base *)arch)->module->parse_directive \
(arch, name, valparams, objext_valparams, object, line)
#define yasm_arch_get_fill(arch) \
((yasm_arch_base *)arch)->module->get_fill(arch)
#define yasm_arch_finalize_insn(arch, bc, prev_bc, data, num_operands, \

View file

@ -187,6 +187,10 @@ typedef struct yasm_valparam yasm_valparam;
* \see valparam.h for related functions.
*/
typedef struct yasm_valparamhead yasm_valparamhead;
/** Directive list entry.
* \see valparam.h for details and related functions.
*/
typedef struct yasm_directive yasm_directive;
/** A list of instruction operands (opaque type).
* The list goes from left-to-right as parsed.
@ -232,18 +236,6 @@ typedef enum yasm_expr_op {
YASM_EXPR_SEGOFF /**< The ':' in segment:offset. */
} yasm_expr_op;
/** Symbol record visibility.
* \see symrec.h for related functions.
* \note YASM_SYM_EXTERN and YASM_SYM_COMMON are mutually exclusive.
*/
typedef enum yasm_sym_vis {
YASM_SYM_LOCAL = 0, /**< Default, local only */
YASM_SYM_GLOBAL = 1 << 0, /**< If symbol is declared GLOBAL */
YASM_SYM_COMMON = 1 << 1, /**< If symbol is declared COMMON */
YASM_SYM_EXTERN = 1 << 2, /**< If symbol is declared EXTERN */
YASM_SYM_DLOCAL = 1 << 3 /**< If symbol is explicitly declared LOCAL */
} yasm_sym_vis;
/** Convert yasm_value to its byte representation. Usually implemented by
* object formats to keep track of relocations and verify legal expressions.
* Must put the value into the least significant bits of the destination,

View file

@ -52,6 +52,9 @@ struct yasm_dbgfmt_module {
/** Keyword used to select debug format. */
const char *keyword;
/** NULL-terminated list of directives. NULL if none. */
/*@null@*/ const yasm_directive *directives;
/** Create debug format.
* Module-level implementation of yasm_dbgfmt_create().
* The filenames are provided solely for informational purposes.
@ -65,13 +68,6 @@ struct yasm_dbgfmt_module {
*/
void (*destroy) (/*@only@*/ yasm_dbgfmt *dbgfmt);
/** Module-level implementation of yasm_dbgfmt_directive().
* Call yasm_dbgfmt_directive() instead of calling this function.
*/
int (*directive) (yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *valparams,
unsigned long line);
/** Module-level implementation of yasm_dbgfmt_generate().
* Call yasm_dbgfmt_generate() instead of calling this function.
*/
@ -100,18 +96,6 @@ const char *yasm_dbgfmt_keyword(const yasm_dbgfmt *dbgfmt);
*/
void yasm_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt);
/** DEBUG directive support.
* \param object object
* \param name directive name
* \param valparams value/parameters
* \param line virtual line (from yasm_linemap)
* \return Nonzero if directive was not recognized; 0 if directive was
* recognized even if it wasn't valid.
*/
int yasm_dbgfmt_directive(yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *valparams,
unsigned long line);
/** Generate debugging information bytecodes.
* \param object object
* \param linemap virtual/physical line mapping
@ -133,9 +117,6 @@ void yasm_dbgfmt_generate(yasm_object *object, yasm_linemap *linemap,
#define yasm_dbgfmt_destroy(dbgfmt) \
((yasm_dbgfmt_base *)dbgfmt)->module->destroy(dbgfmt)
#define yasm_dbgfmt_directive(object, name, valparams, line) \
((yasm_dbgfmt_base *)((object)->dbgfmt))->module->directive \
(object, name, valparams, line)
#define yasm_dbgfmt_generate(object, linemap, ews) \
((yasm_dbgfmt_base *)((object)->dbgfmt))->module->generate \
(object, linemap, ews)

View file

@ -33,6 +33,8 @@
#include "util.h"
/*@unused@*/ RCSID("$Id$");
#include <ctype.h>
#include "libyasm-stdint.h"
#include "coretype.h"
#include "hamt.h"
@ -53,6 +55,8 @@ struct HAMT {
HAMTNode *root;
/*@exits@*/ void (*error_func) (const char *file, unsigned int line,
const char *message);
unsigned long (*HashKey) (const char *key);
unsigned long (*ReHashKey) (const char *key, int Level);
};
/* XXX make a portable version of this. This depends on the pointer being
@ -92,8 +96,26 @@ ReHashKey(const char *key, int Level)
return vHash;
}
static unsigned long
HashKey_nocase(const char *key)
{
unsigned long a=31415, b=27183, vHash;
for (vHash=0; *key; key++, a*=b)
vHash = a*vHash + tolower(*key);
return vHash;
}
static unsigned long
ReHashKey_nocase(const char *key, int Level)
{
unsigned long a=31415, b=27183, vHash;
for (vHash=0; *key; key++, a*=b)
vHash = a*vHash*(unsigned long)Level + tolower(*key);
return vHash;
}
HAMT *
HAMT_create(/*@exits@*/ void (*error_func)
HAMT_create(int nocase, /*@exits@*/ void (*error_func)
(const char *file, unsigned int line, const char *message))
{
/*@out@*/ HAMT *hamt = yasm_xmalloc(sizeof(HAMT));
@ -108,6 +130,13 @@ HAMT_create(/*@exits@*/ void (*error_func)
}
hamt->error_func = error_func;
if (nocase) {
hamt->HashKey = HashKey_nocase;
hamt->ReHashKey = ReHashKey_nocase;
} else {
hamt->HashKey = HashKey;
hamt->ReHashKey = ReHashKey;
}
return hamt;
}
@ -195,7 +224,7 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
int keypartbits = 0;
int level = 0;
key = HashKey(str);
key = hamt->HashKey(str);
keypart = key & 0x1F;
node = &hamt->root[keypart];
@ -236,9 +265,9 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
keypartbits += 5;
if (keypartbits > 30) {
/* Exceeded 32 bits: rehash */
key = ReHashKey(str, level);
key2 = ReHashKey(((HAMTEntry *)(node->BaseValue))->str,
level);
key = hamt->ReHashKey(str, level);
key2 = hamt->ReHashKey(
((HAMTEntry *)(node->BaseValue))->str, level);
keypartbits = 0;
}
keypart = (key >> keypartbits) & 0x1F;
@ -288,7 +317,7 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
keypartbits += 5;
if (keypartbits > 30) {
/* Exceeded 32 bits of current key: rehash */
key = ReHashKey(str, level);
key = hamt->ReHashKey(str, level);
keypartbits = 0;
}
keypart = (key >> keypartbits) & 0x1F;
@ -347,7 +376,7 @@ HAMT_search(HAMT *hamt, const char *str)
int keypartbits = 0;
int level = 0;
key = HashKey(str);
key = hamt->HashKey(str);
keypart = key & 0x1F;
node = &hamt->root[keypart];
@ -366,7 +395,7 @@ HAMT_search(HAMT *hamt, const char *str)
keypartbits += 5;
if (keypartbits > 30) {
/* Exceeded 32 bits of current key: rehash */
key = ReHashKey(str, level);
key = hamt->ReHashKey(str, level);
keypartbits = 0;
}
keypart = (key >> keypartbits) & 0x1F;

View file

@ -41,10 +41,11 @@ typedef struct HAMTEntry HAMTEntry;
/** Create new, empty, HAMT. error_func() is called when an internal error is
* encountered--it should NOT return to the calling function.
* \param nocase nonzero if HAMT should be case-insensitive
* \param error_func function called on internal error
* \return New, empty, hash array mapped trie.
*/
HAMT *HAMT_create(/*@exits@*/ void (*error_func)
HAMT *HAMT_create(int nocase, /*@exits@*/ void (*error_func)
(const char *file, unsigned int line, const char *message));
/** Delete HAMT and all data associated with it. Uses deletefunc() to delete

View file

@ -151,7 +151,7 @@ yasm_linemap_create(void)
size_t i;
yasm_linemap *linemap = yasm_xmalloc(sizeof(yasm_linemap));
linemap->filenames = HAMT_create(yasm_internal_error_);
linemap->filenames = HAMT_create(0, yasm_internal_error_);
linemap->current = 1;

View file

@ -74,6 +74,9 @@ struct yasm_objfmt_module {
*/
const char *default_dbgfmt_keyword;
/** NULL-terminated list of directives. NULL if none. */
/*@null@*/ const yasm_directive *directives;
/** Create object format.
* Module-level implementation of yasm_objfmt_create().
* Call yasm_objfmt_create() instead of calling this function.
@ -106,35 +109,6 @@ struct yasm_objfmt_module {
(*section_switch)(yasm_object *object, yasm_valparamhead *valparams,
/*@null@*/ yasm_valparamhead *objext_valparams,
unsigned long line);
/** Module-level implementation of yasm_objfmt_extern_declare().
* Call yasm_objfmt_extern_declare() instead of calling this function.
*/
yasm_symrec * (*extern_declare)
(yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line);
/** Module-level implementation of yasm_objfmt_global_declare().
* Call yasm_objfmt_global_declare() instead of calling this function.
*/
yasm_symrec * (*global_declare)
(yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line);
/** Module-level implementation of yasm_objfmt_common_declare().
* Call yasm_objfmt_common_declare() instead of calling this function.
*/
yasm_symrec * (*common_declare)
(yasm_object *object, const char *name, /*@only@*/ yasm_expr *size,
/*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line);
/** Module-level implementation of yasm_objfmt_directive().
* Call yasm_objfmt_directive() instead of calling this function.
*/
int (*directive) (yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *valparams,
/*@null@*/ yasm_valparamhead *objext_valparams,
unsigned long line);
};
/** Create object format.
@ -182,58 +156,6 @@ yasm_section *yasm_objfmt_add_default_section(yasm_object *object);
(yasm_object *object, yasm_valparamhead *valparams,
/*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line);
/** Declare an "extern" (importing from another module) symbol. Should
* call yasm_symtab_declare().
* \param object object
* \param name symbol name
* \param objext_valparams object format-specific value/paramaters
* \param line virtual line (from yasm_linemap)
* \return Declared symbol.
*/
yasm_symrec *yasm_objfmt_extern_declare
(yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line);
/** Declare a "global" (exporting to other modules) symbol. Should call
* yasm_symtab_declare().
* \param object object
* \param name symbol name
* \param objext_valparams object format-specific value/paramaters
* \param line virtual line (from yasm_linemap)
* \return Declared symbol.
*/
yasm_symrec *yasm_objfmt_global_declare
(yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line);
/** Declare a "common" (shared space with other modules) symbol. Should
* call yasm_symtab_declare().
* declaration.
* \param object object
* \param name symbol name
* \param size common data size
* \param objext_valparams object format-specific value/paramaters
* \param line virtual line (from yasm_linemap)
* \return Declared symbol.
*/
yasm_symrec *yasm_objfmt_common_declare
(yasm_object *object, const char *name, /*@only@*/ yasm_expr *size,
/*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line);
/** Handle object format-specific directives.
* \param object object
* \param name directive name
* \param valparams value/parameters
* \param objext_valparams object format-specific value/parameters
* \param line virtual line (from yasm_linemap)
* \return Nonzero if directive was not recognized; 0 if directive was
* recognized, even if it wasn't valid.
*/
int yasm_objfmt_directive(yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *valparams,
/*@null@*/ yasm_valparamhead *objext_valparams,
unsigned long line);
#ifndef YASM_DOXYGEN
/* Inline macro implementations for objfmt functions */
@ -248,18 +170,6 @@ int yasm_objfmt_directive(yasm_object *object, const char *name,
#define yasm_objfmt_section_switch(object, vpms, oe_vpms, line) \
((yasm_objfmt_base *)((object)->objfmt))->module->section_switch \
(object, vpms, oe_vpms, line)
#define yasm_objfmt_extern_declare(object, name, oe_vpms, line) \
((yasm_objfmt_base *)((object)->objfmt))->module->extern_declare \
(object, name, oe_vpms, line)
#define yasm_objfmt_global_declare(object, name, oe_vpms, line) \
((yasm_objfmt_base *)((object)->objfmt))->module->global_declare \
(object, name, oe_vpms, line)
#define yasm_objfmt_common_declare(object, name, size, oe_vpms, line) \
((yasm_objfmt_base *)((object)->objfmt))->module->common_declare \
(object, name, size, oe_vpms, line)
#define yasm_objfmt_directive(object, name, vpms, oe_vpms, line) \
((yasm_objfmt_base *)((object)->objfmt))->module->directive \
(object, name, vpms, oe_vpms, line)
#define yasm_objfmt_add_default_section(object) \
((yasm_objfmt_base *)((object)->objfmt))->module->add_default_section \
(object)

View file

@ -32,6 +32,7 @@
#include "libyasm-stdint.h"
#include "coretype.h"
#include "hamt.h"
#include "valparam.h"
#include "assocdat.h"
@ -101,6 +102,130 @@ struct yasm_section {
static void yasm_section_destroy(/*@only@*/ yasm_section *sect);
/* Wrapper around directive for HAMT insertion */
typedef struct yasm_directive_wrap {
const yasm_directive *directive;
} yasm_directive_wrap;
/*
* Standard "builtin" object directives.
*/
static void
dir_extern(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_valparam *vp = yasm_vps_first(valparams);
yasm_symrec *sym;
sym = yasm_symtab_declare(object->symtab, vp->val, YASM_SYM_EXTERN, line);
if (objext_valparams) {
yasm_valparamhead *vps = yasm_vps_create();
*vps = *objext_valparams; /* structure copy */
yasm_vps_initialize(objext_valparams); /* don't double-free */
yasm_symrec_set_objext_valparams(sym, vps);
}
}
static void
dir_global(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_valparam *vp = yasm_vps_first(valparams);
yasm_symrec *sym;
sym = yasm_symtab_declare(object->symtab, vp->val, YASM_SYM_GLOBAL, line);
if (objext_valparams) {
yasm_valparamhead *vps = yasm_vps_create();
*vps = *objext_valparams; /* structure copy */
yasm_vps_initialize(objext_valparams); /* don't double-free */
yasm_symrec_set_objext_valparams(sym, vps);
}
}
static void
dir_common(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_valparam *vp = yasm_vps_first(valparams);
yasm_valparam *vp2 = yasm_vps_next(vp);
yasm_expr *size = yasm_vp_expr(vp2, object->symtab, line);
yasm_symrec *sym;
if (!size) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("no size specified in %s declaration"), "COMMON");
return;
}
sym = yasm_symtab_declare(object->symtab, vp->val, YASM_SYM_COMMON, line);
yasm_symrec_set_common_size(sym, size);
if (objext_valparams) {
yasm_valparamhead *vps = yasm_vps_create();
*vps = *objext_valparams; /* structure copy */
yasm_vps_initialize(objext_valparams); /* don't double-free */
yasm_symrec_set_objext_valparams(sym, vps);
}
}
static void
dir_section(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_section *new_section =
yasm_objfmt_section_switch(object, valparams, objext_valparams, line);
if (new_section)
object->cur_section = new_section;
else
yasm_error_set(YASM_ERROR_SYNTAX,
N_("invalid argument to directive `%s'"), "SECTION");
}
static const yasm_directive object_directives[] = {
{ ".extern", "gas", dir_extern, YASM_DIR_ID_REQUIRED },
{ ".global", "gas", dir_global, YASM_DIR_ID_REQUIRED },
{ ".globl", "gas", dir_global, YASM_DIR_ID_REQUIRED },
{ "extern", "nasm", dir_extern, YASM_DIR_ID_REQUIRED },
{ "global", "nasm", dir_global, YASM_DIR_ID_REQUIRED },
{ "common", "nasm", dir_common, YASM_DIR_ID_REQUIRED },
{ "section", "nasm", dir_section, YASM_DIR_ARG_REQUIRED },
{ "segment", "nasm", dir_section, YASM_DIR_ARG_REQUIRED },
{ NULL, NULL, NULL, 0 }
};
static void
directive_level2_delete(/*@only@*/ void *data)
{
yasm_xfree(data);
}
static void
directive_level1_delete(/*@only@*/ void *data)
{
HAMT_destroy(data, directive_level2_delete);
}
static void
directives_add(yasm_object *object, /*@null@*/ const yasm_directive *dir)
{
if (!dir)
return;
while (dir->name) {
HAMT *level2 = HAMT_search(object->directives, dir->parser);
int replace;
yasm_directive_wrap *wrap = yasm_xmalloc(sizeof(yasm_directive_wrap));
if (!level2) {
replace = 0;
level2 = HAMT_insert(object->directives, dir->parser,
HAMT_create(1, yasm_internal_error_),
&replace, directive_level1_delete);
}
replace = 0;
wrap->directive = dir;
HAMT_insert(level2, dir->name, wrap, &replace,
directive_level2_delete);
dir++;
}
}
/*@-compdestroy@*/
yasm_object *
@ -121,6 +246,9 @@ yasm_object_create(const char *src_filename, const char *obj_filename,
/* Initialize sections linked list */
STAILQ_INIT(&object->sections);
/* Create directives HAMT */
object->directives = HAMT_create(1, yasm_internal_error_);
/* Initialize the target architecture */
object->arch = arch;
@ -167,6 +295,15 @@ yasm_object_create(const char *src_filename, const char *obj_filename,
goto error;
}
/* Add directives to HAMT. Note ordering here determines priority. */
directives_add(object,
((yasm_objfmt_base *)object->objfmt)->module->directives);
directives_add(object,
((yasm_dbgfmt_base *)object->dbgfmt)->module->directives);
directives_add(object,
((yasm_arch_base *)object->arch)->module->directives);
directives_add(object, object_directives);
return object;
error:
@ -274,6 +411,28 @@ yasm_object_create_absolute(yasm_object *object, yasm_expr *start,
}
/*@=onlytrans@*/
int
yasm_object_directive(yasm_object *object, const char *name,
const char *parser, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams,
unsigned long line)
{
HAMT *level2;
yasm_directive_wrap *wrap;
level2 = HAMT_search(object->directives, parser);
if (!level2)
return 1;
wrap = HAMT_search(level2, name);
if (!wrap)
return 1;
yasm_call_directive(wrap->directive, object, valparams, objext_valparams,
line);
return 0;
}
void
yasm_object_set_source_fn(yasm_object *object, const char *src_filename)
{
@ -358,6 +517,9 @@ yasm_object_destroy(yasm_object *object)
cur = next;
}
/* Delete directives HAMT */
HAMT_destroy(object->directives, directive_level1_delete);
/* Delete associated filenames */
yasm_xfree(object->src_filename);
yasm_xfree(object->obj_filename);

View file

@ -61,7 +61,13 @@ struct yasm_object {
/*@dependent@*/ yasm_section *cur_section;
#ifdef YASM_LIB_INTERNAL
/** Linked list of sections. */
/*@reldef@*/ STAILQ_HEAD(yasm_sectionhead, yasm_section) sections;
/** Directives, organized as two level HAMT; first level is parser,
* second level is directive name.
*/
/*@owned@*/ struct HAMT *directives;
#endif
};
@ -112,6 +118,21 @@ struct yasm_object {
/*@dependent@*/ yasm_section *yasm_object_create_absolute
(yasm_object *object, /*@keep@*/ yasm_expr *start, unsigned long line);
/** Handle a directive. Passed down to object format, debug format, or
* architecture as appropriate.
* \param object object
* \param name directive name
* \param parser parser keyword
* \param valparams value/parameters
* \param objext_valparams "object format-specific" value/parameters
* \param line virtual line (from yasm_linemap)
* \return 0 if directive recognized, nonzero if unrecognized.
*/
int yasm_object_directive(yasm_object *object, const char *name,
const char *parser, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams,
unsigned long line);
/** Delete (free allocated memory for) an object. All sections in the
* object and all bytecodes within those sections are also deleted.
* \param object object

View file

@ -34,6 +34,7 @@
#include "libyasm-stdint.h"
#include "coretype.h"
#include "valparam.h"
#include "hamt.h"
#include "assocdat.h"
@ -64,7 +65,9 @@ struct yasm_symrec {
sym_type type;
yasm_sym_status status;
yasm_sym_vis visibility;
unsigned long line; /* symbol was first declared or used on */
unsigned long def_line; /* line where symbol was first defined */
unsigned long decl_line; /* line where symbol was first declared */
unsigned long use_line; /* line where symbol was first used */
union {
yasm_expr *expn; /* equ value */
@ -89,12 +92,48 @@ struct yasm_symtab {
SLIST_HEAD(nontablesymhead_s, non_table_symrec_s) non_table_syms;
};
static void
objext_valparams_destroy(void *data)
{
yasm_vps_destroy((yasm_valparamhead *)data);
}
static void
objext_valparams_print(void *data, FILE *f, int indent_level)
{
yasm_vps_print((yasm_valparamhead *)data, f);
}
static yasm_assoc_data_callback objext_valparams_cb = {
objext_valparams_destroy,
objext_valparams_print
};
static void
common_size_destroy(void *data)
{
yasm_expr **e = (yasm_expr **)data;
yasm_expr_destroy(*e);
yasm_xfree(data);
}
static void
common_size_print(void *data, FILE *f, int indent_level)
{
yasm_expr **e = (yasm_expr **)data;
yasm_expr_print(*e, f);
}
static yasm_assoc_data_callback common_size_cb = {
common_size_destroy,
common_size_print
};
yasm_symtab *
yasm_symtab_create(void)
{
yasm_symtab *symtab = yasm_xmalloc(sizeof(yasm_symtab));
symtab->sym_table = HAMT_create(yasm_internal_error_);
symtab->sym_table = HAMT_create(0, yasm_internal_error_);
SLIST_INIT(&symtab->non_table_syms);
return symtab;
}
@ -116,7 +155,9 @@ symrec_new_common(/*@keep@*/ char *name)
yasm_symrec *rec = yasm_xmalloc(sizeof(yasm_symrec));
rec->name = name;
rec->type = SYM_UNKNOWN;
rec->line = 0;
rec->def_line = 0;
rec->decl_line = 0;
rec->use_line = 0;
rec->visibility = YASM_SYM_LOCAL;
rec->assoc_data = NULL;
return rec;
@ -190,7 +231,9 @@ yasm_symrec *
yasm_symtab_abs_sym(yasm_symtab *symtab)
{
yasm_symrec *rec = symtab_get_or_new(symtab, "", 1);
rec->line = 0;
rec->def_line = 0;
rec->decl_line = 0;
rec->use_line = 0;
rec->type = SYM_EQU;
rec->value.expn =
yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)), 0);
@ -202,8 +245,8 @@ yasm_symrec *
yasm_symtab_use(yasm_symtab *symtab, const char *name, unsigned long line)
{
yasm_symrec *rec = symtab_get_or_new(symtab, name, 1);
if (rec->line == 0)
rec->line = line; /* set line number of first use */
if (rec->use_line == 0)
rec->use_line = line; /* set line number of first use */
rec->status |= YASM_SYM_USED;
return rec;
}
@ -222,15 +265,15 @@ symtab_define(yasm_symtab *symtab, const char *name, sym_type type,
/* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
if (rec->status & YASM_SYM_DEFINED) {
yasm_error_set_xref(rec->line, N_("`%s' previously defined here"),
name);
yasm_error_set_xref(rec->def_line!=0 ? rec->def_line : rec->decl_line,
N_("`%s' previously defined here"), name);
yasm_error_set(YASM_ERROR_GENERAL, N_("redefinition of `%s'"),
name);
} else {
if (rec->visibility & YASM_SYM_EXTERN)
yasm_warn_set(YASM_WARN_GENERAL,
N_("`%s' both defined and declared extern"), name);
rec->line = line; /* set line number of definition */
rec->def_line = line; /* set line number of definition */
rec->type = type;
rec->status |= YASM_SYM_DEFINED;
}
@ -313,18 +356,18 @@ yasm_symrec_declare(yasm_symrec *rec, yasm_sym_vis vis, unsigned long line)
(!(rec->status & YASM_SYM_DEFINED) &&
(!(rec->visibility & (YASM_SYM_COMMON | YASM_SYM_EXTERN)) ||
((rec->visibility & YASM_SYM_COMMON) && (vis == YASM_SYM_COMMON)) ||
((rec->visibility & YASM_SYM_EXTERN) && (vis == YASM_SYM_EXTERN)))))
((rec->visibility & YASM_SYM_EXTERN) && (vis == YASM_SYM_EXTERN))))) {
rec->decl_line = line;
rec->visibility |= vis;
else
} else
yasm_error_set(YASM_ERROR_GENERAL,
N_("duplicate definition of `%s'; first defined on line %lu"),
rec->name, rec->line);
rec->name, rec->def_line!=0 ? rec->def_line : rec->decl_line);
}
typedef struct symtab_finalize_info {
unsigned long firstundef_line;
int undef_extern;
/*@null@*/ yasm_object *object;
yasm_errwarns *errwarns;
} symtab_finalize_info;
@ -337,14 +380,14 @@ symtab_parser_finalize_checksym(yasm_symrec *sym, /*@null@*/ void *d)
/* error if a symbol is used but never defined or extern/common declared */
if ((sym->status & YASM_SYM_USED) && !(sym->status & YASM_SYM_DEFINED) &&
!(sym->visibility & (YASM_SYM_EXTERN | YASM_SYM_COMMON))) {
if (info->undef_extern && info->object)
yasm_objfmt_extern_declare(info->object, sym->name, NULL, 1);
if (info->undef_extern)
sym->visibility |= YASM_SYM_EXTERN;
else {
yasm_error_set(YASM_ERROR_GENERAL,
N_("undefined symbol `%s' (first use)"), sym->name);
yasm_errwarn_propagate(info->errwarns, sym->line);
if (sym->line < info->firstundef_line)
info->firstundef_line = sym->line;
yasm_errwarn_propagate(info->errwarns, sym->use_line);
if (sym->use_line < info->firstundef_line)
info->firstundef_line = sym->use_line;
}
}
@ -361,10 +404,10 @@ symtab_parser_finalize_checksym(yasm_symrec *sym, /*@null@*/ void *d)
yasm_expr_create(YASM_EXPR_SUB,
yasm_expr_precbc(sym->value.precbc),
yasm_expr_precbc(yasm_section_bcs_first(sect)),
sym->line),
sym->def_line),
YASM_EXPR_ADD,
yasm_expr_copy(yasm_section_get_start(sect)),
sym->line);
sym->def_line);
sym->status |= YASM_SYM_VALUED;
}
@ -373,12 +416,11 @@ symtab_parser_finalize_checksym(yasm_symrec *sym, /*@null@*/ void *d)
void
yasm_symtab_parser_finalize(yasm_symtab *symtab, int undef_extern,
yasm_object *object, yasm_errwarns *errwarns)
yasm_errwarns *errwarns)
{
symtab_finalize_info info;
info.firstundef_line = ULONG_MAX;
info.undef_extern = undef_extern;
info.object = object;
info.errwarns = errwarns;
yasm_symtab_traverse(symtab, &info, symtab_parser_finalize_checksym);
if (info.firstundef_line < ULONG_MAX) {
@ -448,9 +490,21 @@ yasm_symrec_get_status(const yasm_symrec *sym)
}
unsigned long
yasm_symrec_get_line(const yasm_symrec *sym)
yasm_symrec_get_def_line(const yasm_symrec *sym)
{
return sym->line;
return sym->def_line;
}
unsigned long
yasm_symrec_get_decl_line(const yasm_symrec *sym)
{
return sym->decl_line;
}
unsigned long
yasm_symrec_get_use_line(const yasm_symrec *sym)
{
return sym->use_line;
}
const yasm_expr *
@ -477,7 +531,8 @@ yasm_symrec_get_label(const yasm_symrec *sym,
int
yasm_symrec_is_abs(const yasm_symrec *sym)
{
return (sym->line == 0 && sym->type == SYM_EQU && sym->name[0] == '\0');
return (sym->def_line == 0 && sym->type == SYM_EQU &&
sym->name[0] == '\0');
}
int
@ -492,6 +547,34 @@ yasm_symrec_is_curpos(const yasm_symrec *sym)
return (sym->type == SYM_CURPOS);
}
void
yasm_symrec_set_objext_valparams(yasm_symrec *sym,
/*@only@*/ yasm_valparamhead *objext_valparams)
{
yasm_symrec_add_data(sym, &objext_valparams_cb, objext_valparams);
}
yasm_valparamhead *
yasm_symrec_get_objext_valparams(yasm_symrec *sym)
{
return yasm_symrec_get_data(sym, &objext_valparams_cb);
}
void
yasm_symrec_set_common_size(yasm_symrec *sym,
/*@only@*/ yasm_expr *common_size)
{
yasm_expr **ep = yasm_xmalloc(sizeof(yasm_expr *));
*ep = common_size;
yasm_symrec_add_data(sym, &common_size_cb, ep);
}
yasm_expr **
yasm_symrec_get_common_size(yasm_symrec *sym)
{
return (yasm_expr **)yasm_symrec_get_data(sym, &common_size_cb);
}
void *
yasm_symrec_get_data(yasm_symrec *sym,
const yasm_assoc_data_callback *callback)
@ -570,5 +653,9 @@ yasm_symrec_print(const yasm_symrec *sym, FILE *f, int indent_level)
yasm__assoc_data_print(sym->assoc_data, f, indent_level+1);
}
fprintf(f, "%*sLine Index=%lu\n", indent_level, "", sym->line);
fprintf(f, "%*sLine Index (Defined)=%lu\n", indent_level, "",
sym->def_line);
fprintf(f, "%*sLine Index (Declared)=%lu\n", indent_level, "",
sym->decl_line);
fprintf(f, "%*sLine Index (Used)=%lu\n", indent_level, "", sym->use_line);
}

View file

@ -46,6 +46,16 @@ typedef enum yasm_sym_status {
YASM_SYM_NOTINTABLE = 1 << 3 /**< if it's not in sym_table (ex. '$') */
} yasm_sym_status;
/** Symbol record visibility.
* \note YASM_SYM_EXTERN and YASM_SYM_COMMON are mutually exclusive.
*/
typedef enum yasm_sym_vis {
YASM_SYM_LOCAL = 0, /**< Default, local only */
YASM_SYM_GLOBAL = 1 << 0, /**< If symbol is declared GLOBAL */
YASM_SYM_COMMON = 1 << 1, /**< If symbol is declared COMMON */
YASM_SYM_EXTERN = 1 << 2, /**< If symbol is declared EXTERN */
YASM_SYM_DLOCAL = 1 << 3 /**< If symbol is explicitly declared LOCAL */
} yasm_sym_vis;
/** Create a new symbol table. */
yasm_symtab *yasm_symtab_create(void);
@ -202,13 +212,10 @@ yasm_symrec *yasm_symtab_iter_value(const yasm_symtab_iter *cur);
* used but never defined or declared #YASM_SYM_EXTERN or #YASM_SYM_COMMON.
* \param symtab symbol table
* \param undef_extern if nonzero, all undef syms should be declared extern
* \param object object to notify about new extern decls
* (may be NULL if undef_extern is 0)
* \param errwarns error/warning set
* \note Errors/warnings are stored into errwarns.
*/
void yasm_symtab_parser_finalize(yasm_symtab *symtab, int undef_extern,
/*@null@*/ yasm_object *object,
yasm_errwarns *errwarns);
/** Print the symbol table. For debugging purposes.
@ -236,11 +243,23 @@ yasm_sym_vis yasm_symrec_get_visibility(const yasm_symrec *sym);
*/
yasm_sym_status yasm_symrec_get_status(const yasm_symrec *sym);
/** Get the virtual line of a symbol (where it was first declared or used).
/** Get the virtual line of where a symbol was first defined.
* \param sym symbol
* \return line virtual line
*/
unsigned long yasm_symrec_get_line(const yasm_symrec *sym);
unsigned long yasm_symrec_get_def_line(const yasm_symrec *sym);
/** Get the virtual line of where a symbol was first declared.
* \param sym symbol
* \return line virtual line
*/
unsigned long yasm_symrec_get_decl_line(const yasm_symrec *sym);
/** Get the virtual line of where a symbol was first used.
* \param sym symbol
* \return line virtual line
*/
unsigned long yasm_symrec_get_use_line(const yasm_symrec *sym);
/** Get EQU value of a symbol.
* \param sym symbol
@ -280,6 +299,36 @@ int yasm_symrec_is_special(const yasm_symrec *sym);
*/
int yasm_symrec_is_curpos(const yasm_symrec *sym);
/** Set object-extended valparams.
* \param sym symbol
* \param objext_valparams object-extended valparams
*/
void yasm_symrec_set_objext_valparams
(yasm_symrec *sym, /*@only@*/ yasm_valparamhead *objext_valparams);
/** Get object-extended valparams, if any, associated with symbol's
* declaration.
* \param sym symbol
* \return Object-extended valparams (NULL if none).
*/
/*@null@*/ /*@dependent@*/ yasm_valparamhead *yasm_symrec_get_objext_valparams
(yasm_symrec *sym);
/** Set common size of symbol.
* \param sym symbol
* \param common_size common size expression
*/
void yasm_symrec_set_common_size
(yasm_symrec *sym, /*@only@*/ yasm_expr *common_size);
/** Get common size of symbol, if symbol is declared COMMON and a size was set
* for it.
* \param sym symbol
* \return Common size (NULL if none).
*/
/*@dependent@*/ /*@null@*/ yasm_expr **yasm_symrec_get_common_size
(yasm_symrec *sym);
/** Get associated data for a symbol and data callback.
* \param sym symbol
* \param callback callback used when adding data

View file

@ -32,9 +32,37 @@
#include "coretype.h"
#include "valparam.h"
#include "errwarn.h"
#include "expr.h"
#include "symrec.h"
void
yasm_call_directive(const yasm_directive *directive, yasm_object *object,
yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_valparam *vp;
if ((directive->flags & (YASM_DIR_ARG_REQUIRED|YASM_DIR_ID_REQUIRED)) &&
(!valparams || !yasm_vps_first(valparams))) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("directive `%s' requires an argument"),
directive->name);
return;
}
if (valparams) {
vp = yasm_vps_first(valparams);
if ((directive->flags & YASM_DIR_ID_REQUIRED) && !vp->val) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("directive `%s' requires an identifier parameter"),
directive->name);
return;
}
}
directive->handler(object, valparams, objext_valparams, line);
}
yasm_valparam *
yasm_vp_create(/*@keep@*/ char *v, /*@keep@*/ yasm_expr *p)
{
@ -44,6 +72,22 @@ yasm_vp_create(/*@keep@*/ char *v, /*@keep@*/ yasm_expr *p)
return r;
}
/*@null@*/ /*@only@*/ yasm_expr *
yasm_vp_expr(yasm_valparam *vp, yasm_symtab *symtab, unsigned long line)
{
if (!vp)
return NULL;
if (vp->val) {
return yasm_expr_create_ident(yasm_expr_sym(
yasm_symtab_use(symtab, vp->val, line)), line);
} else if (vp->param) {
yasm_expr *e = vp->param;
vp->param = NULL; /* to avoid double-free */
return e;
} else
return NULL;
}
void
yasm_vps_delete(yasm_valparamhead *headp)
{

View file

@ -46,6 +46,47 @@ struct yasm_valparam {
/*@reldef@*/ STAILQ_HEAD(yasm_valparamhead, yasm_valparam);
#endif
/** Directive list entry structure. */
struct yasm_directive {
/** Directive name. GAS directives should include the ".", NASM
* directives should just be the raw name (not including the []).
* NULL entry required to terminate list of directives.
*/
/*@null@*/ const char *name;
const char *parser; /**< Parser keyword */
/** Handler callback function for the directive.
* \param object object
* \param valparams value/parameters
* \param objext_valparams object format-specific value/parameters
* \param line virtual line (from yasm_linemap)
*/
void (*handler) (yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line);
/* Flags for pre-handler parameter checking. */
enum yasm_directive_flags {
YASM_DIR_ANY = 0, /**< Any valparams accepted */
YASM_DIR_ARG_REQUIRED = 1, /**< Require at least 1 valparam */
YASM_DIR_ID_REQUIRED = 2 /**< First valparam must be ID */
} flags;
};
/** Call a directive. Performs any valparam checks asked for by the
* directive prior to call. Note that for a variety of reasons, a directive
* can generate an error.
* \param directive directive
* \param object object
* \param valparams value/parameters
* \param objext_valparams object format-specific value/parameters
* \param line virtual line (from yasm_linemap)
*/
void yasm_call_directive(const yasm_directive *directive, yasm_object *object,
yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams,
unsigned long line);
/** Create a new valparam.
* \param v value
* \param p parameter
@ -53,6 +94,17 @@ struct yasm_valparam {
*/
yasm_valparam *yasm_vp_create(/*@keep@*/ char *v, /*@keep@*/ yasm_expr *p);
/** Get a valparam as an expr. If the valparam is a value, it's treated
* as a symbol (yasm_symtab_use() is called to convert it). The valparam
* is modified as necessary to avoid double-frees.
* \param vp valparam
* \param symtab symbol table
* \param line virtual line
* \return Expression, or NULL if vp is NULL or if val and param are both NULL.
*/
/*@null@*/ /*@only@*/ yasm_expr *yasm_vp_expr
(yasm_valparam *vp, yasm_symtab *symtab, unsigned long line);
/** Create a new linked list of valparams.
* \return Newly allocated valparam list.
*/

View file

@ -118,35 +118,72 @@ x86_set_var(yasm_arch *arch, const char *var, unsigned long val)
return 0;
}
static int
x86_parse_directive(yasm_arch *arch, const char *name,
/*@null@*/ yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
/*@unused@*/ yasm_object *object,
/*@unused@*/ unsigned long line)
static void
x86_dir_cpu(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)object->arch;
yasm_valparam *vp;
yasm_vps_foreach(vp, valparams) {
if (vp->val)
yasm_x86__parse_cpu(arch_x86, vp->val, strlen(vp->val));
else if (vp->param) {
const yasm_intnum *intcpu;
intcpu = yasm_expr_get_intnum(&vp->param, 0);
if (!intcpu)
yasm_error_set(YASM_ERROR_SYNTAX,
N_("invalid argument to [%s]"), "CPU");
else {
char strcpu[16];
sprintf(strcpu, "%lu", yasm_intnum_get_uint(intcpu));
yasm_x86__parse_cpu(arch_x86, strcpu, strlen(strcpu));
}
}
}
}
static void
x86_dir_bits(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)object->arch;
yasm_valparam *vp;
const yasm_intnum *intn;
long lval;
if (yasm__strcasecmp(name, "bits") == 0) {
if (!valparams)
yasm_error_set(YASM_ERROR_VALUE, N_("[%s] requires an argument"),
"BITS");
else if ((vp = yasm_vps_first(valparams)) && !vp->val &&
vp->param != NULL &&
(intn = yasm_expr_get_intnum(&vp->param, 0)) != NULL &&
(lval = yasm_intnum_get_int(intn)) &&
(lval == 16 || lval == 32 || lval == 64))
arch_x86->mode_bits = (unsigned char)lval;
else
yasm_error_set(YASM_ERROR_VALUE, N_("invalid argument to [%s]"),
"BITS");
return 0;
} else
return 1;
if ((vp = yasm_vps_first(valparams)) && !vp->val && vp->param != NULL &&
(intn = yasm_expr_get_intnum(&vp->param, 0)) != NULL &&
(lval = yasm_intnum_get_int(intn)) &&
(lval == 16 || lval == 32 || lval == 64))
arch_x86->mode_bits = (unsigned char)lval;
else
yasm_error_set(YASM_ERROR_VALUE, N_("invalid argument to [%s]"),
"BITS");
}
static void
x86_dir_code16(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)object->arch;
arch_x86->mode_bits = 16;
}
static void
x86_dir_code32(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)object->arch;
arch_x86->mode_bits = 32;
}
static void
x86_dir_code64(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)object->arch;
arch_x86->mode_bits = 64;
}
static const unsigned char **
@ -438,25 +475,33 @@ x86_segreg_print(yasm_arch *arch, uintptr_t segreg, FILE *f)
}
/* Define x86 machines -- see arch.h for details */
static yasm_arch_machine x86_machines[] = {
static const yasm_arch_machine x86_machines[] = {
{ "IA-32 and derivatives", "x86" },
{ "AMD64", "amd64" },
{ NULL, NULL }
};
static const yasm_directive x86_directives[] = {
{ "cpu", "nasm", x86_dir_cpu, YASM_DIR_ARG_REQUIRED },
{ "bits", "nasm", x86_dir_bits, YASM_DIR_ARG_REQUIRED },
{ ".code16", "gas", x86_dir_code16, YASM_DIR_ANY },
{ ".code32", "gas", x86_dir_code32, YASM_DIR_ANY },
{ ".code64", "gas", x86_dir_code64, YASM_DIR_ANY },
{ NULL, NULL, NULL, 0 }
};
/* Define arch structure -- see arch.h for details */
yasm_arch_module yasm_x86_LTX_arch = {
"x86 (IA-32 and derivatives), AMD64",
"x86",
x86_directives,
x86_create,
x86_destroy,
x86_get_machine,
x86_get_address_size,
x86_set_var,
yasm_x86__parse_cpu,
yasm_x86__parse_check_insnprefix,
yasm_x86__parse_check_regtmod,
x86_parse_directive,
x86_get_fill,
yasm_x86__finalize_insn,
yasm_x86__floatnum_tobytes,

View file

@ -259,7 +259,8 @@ int yasm_x86__expr_checkea
(x86_effaddr *x86_ea, unsigned char *addrsize, unsigned int bits,
int address16_op, unsigned char *rex, yasm_bytecode *bc);
void yasm_x86__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len);
void yasm_x86__parse_cpu(yasm_arch_x86 *arch_x86, const char *cpuid,
size_t cpuid_len);
yasm_arch_insnprefix yasm_x86__parse_check_insnprefix
(yasm_arch *arch, /*@out@*/ uintptr_t data[4], const char *id,

View file

@ -3295,9 +3295,9 @@ yasm_x86__parse_check_insnprefix(yasm_arch *arch, uintptr_t data[4],
}
void
yasm_x86__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len)
yasm_x86__parse_cpu(yasm_arch_x86 *arch_x86, const char *cpuid,
size_t cpuid_len)
{
yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
/*@null@*/ const cpu_parse_data *pdata;
size_t i;
static char lcaseid[16];

View file

@ -99,19 +99,12 @@ cv_dbgfmt_generate(yasm_object *object, yasm_linemap *linemap,
yasm_cv__generate_type(object);
}
static int
cv_dbgfmt_directive(yasm_object *object, const char *name,
yasm_valparamhead *valparams, unsigned long line)
{
return 1; /* TODO */
}
/* Define dbgfmt structure -- see dbgfmt.h for details */
yasm_dbgfmt_module yasm_cv8_LTX_dbgfmt = {
"CodeView debugging format for VC8",
"cv8",
NULL, /* no directives */
cv8_dbgfmt_create,
cv_dbgfmt_destroy,
cv_dbgfmt_directive,
cv_dbgfmt_generate
};

View file

@ -330,19 +330,20 @@ dwarf2_section_data_print(void *data, FILE *f, int indent_level)
/* TODO */
}
static int
dwarf2_dbgfmt_directive(yasm_object *object, const char *name,
yasm_valparamhead *valparams, unsigned long line)
{
return yasm_dwarf2__line_directive(object, name, valparams, line);
}
static const yasm_directive dwarf2_directives[] = {
{ ".loc", "gas", yasm_dwarf2__dir_loc, YASM_DIR_ARG_REQUIRED },
{ ".file", "gas", yasm_dwarf2__dir_file, YASM_DIR_ARG_REQUIRED },
{ "loc", "nasm", yasm_dwarf2__dir_loc, YASM_DIR_ARG_REQUIRED },
{ "file", "nasm", yasm_dwarf2__dir_file, YASM_DIR_ARG_REQUIRED },
{ NULL, NULL, NULL, 0 }
};
/* Define dbgfmt structure -- see dbgfmt.h for details */
yasm_dbgfmt_module yasm_dwarf2_LTX_dbgfmt = {
"DWARF2 debugging format",
"dwarf2",
dwarf2_directives,
dwarf2_dbgfmt_create,
dwarf2_dbgfmt_destroy,
dwarf2_dbgfmt_directive,
dwarf2_dbgfmt_generate
};

View file

@ -107,9 +107,12 @@ yasm_section *yasm_dwarf2__generate_line
(yasm_object *object, yasm_linemap *linemap, yasm_errwarns *errwarns,
int asm_source, /*@out@*/ yasm_section **main_code,
/*@out@*/ size_t *num_line_sections);
int yasm_dwarf2__line_directive
(yasm_object *object, const char *name, yasm_valparamhead *valparams,
unsigned long line);
void yasm_dwarf2__dir_loc(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams,
unsigned long line);
void yasm_dwarf2__dir_file(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams,
unsigned long line);
/* Address range table functions */
yasm_section *yasm_dwarf2__generate_aranges(yasm_object *object,

View file

@ -826,188 +826,187 @@ dwarf2_line_op_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
return 0;
}
int
yasm_dwarf2__line_directive(yasm_object *object, const char *name,
yasm_valparamhead *valparams, unsigned long line)
void
yasm_dwarf2__dir_loc(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
yasm_valparam *vp;
if (yasm__strcasecmp(name, "loc") == 0) {
/*@dependent@*/ /*@null@*/ const yasm_intnum *intn;
dwarf2_section_data *dsd;
dwarf2_loc *loc = yasm_xmalloc(sizeof(dwarf2_loc));
/* File number (required) */
if (!valparams || !(vp = yasm_vps_first(valparams)) || !vp->param) {
yasm_error_set(YASM_ERROR_SYNTAX, N_("file number required"));
yasm_xfree(loc);
return 0;
}
/*@dependent@*/ /*@null@*/ const yasm_intnum *intn;
dwarf2_section_data *dsd;
dwarf2_loc *loc = yasm_xmalloc(sizeof(dwarf2_loc));
/* File number (required) */
if (!valparams || !(vp = yasm_vps_first(valparams)) || !vp->param) {
yasm_error_set(YASM_ERROR_SYNTAX, N_("file number required"));
yasm_xfree(loc);
return;
}
intn = yasm_expr_get_intnum(&vp->param, 0);
if (!intn) {
yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("file number is not a constant"));
yasm_xfree(loc);
return;
}
if (yasm_intnum_sign(intn) != 1) {
yasm_error_set(YASM_ERROR_VALUE, N_("file number less than one"));
yasm_xfree(loc);
return;
}
loc->file = yasm_intnum_get_uint(intn);
/* Line number (required) */
vp = yasm_vps_next(vp);
if (!vp || !vp->param) {
yasm_error_set(YASM_ERROR_SYNTAX, N_("line number required"));
yasm_xfree(loc);
return;
}
intn = yasm_expr_get_intnum(&vp->param, 0);
if (!intn) {
yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("file number is not a constant"));
yasm_xfree(loc);
return;
}
loc->line = yasm_intnum_get_uint(intn);
/* Generate new section data if it doesn't already exist */
dsd = yasm_section_get_data(object->cur_section,
&yasm_dwarf2__section_data_cb);
if (!dsd) {
dsd = yasm_xmalloc(sizeof(dwarf2_section_data));
STAILQ_INIT(&dsd->locs);
yasm_section_add_data(object->cur_section,
&yasm_dwarf2__section_data_cb, dsd);
}
/* Defaults for optional settings */
loc->column = 0;
loc->isa_change = 0;
loc->isa = 0;
loc->is_stmt = IS_STMT_NOCHANGE;
loc->basic_block = 0;
loc->prologue_end = 0;
loc->epilogue_begin = 0;
/* Optional column number */
vp = yasm_vps_next(vp);
if (vp && vp->param) {
intn = yasm_expr_get_intnum(&vp->param, 0);
if (!intn) {
yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("file number is not a constant"));
N_("column number is not a constant"));
yasm_xfree(loc);
return 0;
return;
}
if (yasm_intnum_sign(intn) != 1) {
yasm_error_set(YASM_ERROR_VALUE,
N_("file number less than one"));
yasm_xfree(loc);
return 0;
}
loc->file = yasm_intnum_get_uint(intn);
/* Line number (required) */
loc->column = yasm_intnum_get_uint(intn);
vp = yasm_vps_next(vp);
if (!vp || !vp->param) {
yasm_error_set(YASM_ERROR_SYNTAX, N_("line number required"));
yasm_xfree(loc);
return 0;
}
intn = yasm_expr_get_intnum(&vp->param, 0);
if (!intn) {
yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("file number is not a constant"));
yasm_xfree(loc);
return 0;
}
loc->line = yasm_intnum_get_uint(intn);
}
/* Generate new section data if it doesn't already exist */
dsd = yasm_section_get_data(object->cur_section,
&yasm_dwarf2__section_data_cb);
if (!dsd) {
dsd = yasm_xmalloc(sizeof(dwarf2_section_data));
STAILQ_INIT(&dsd->locs);
yasm_section_add_data(object->cur_section,
&yasm_dwarf2__section_data_cb, dsd);
}
/* Defaults for optional settings */
loc->column = 0;
loc->isa_change = 0;
loc->isa = 0;
loc->is_stmt = IS_STMT_NOCHANGE;
loc->basic_block = 0;
loc->prologue_end = 0;
loc->epilogue_begin = 0;
/* Optional column number */
vp = yasm_vps_next(vp);
if (vp && vp->param) {
/* Other options */
while (vp && vp->val) {
if (yasm__strcasecmp(vp->val, "basic_block") == 0)
loc->basic_block = 1;
else if (yasm__strcasecmp(vp->val, "prologue_end") == 0)
loc->prologue_end = 1;
else if (yasm__strcasecmp(vp->val, "epilogue_begin") == 0)
loc->epilogue_begin = 1;
else if (yasm__strcasecmp(vp->val, "is_stmt") == 0) {
if (!vp->param) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("is_stmt requires value"));
yasm_xfree(loc);
return;
}
intn = yasm_expr_get_intnum(&vp->param, 0);
if (!intn) {
yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("column number is not a constant"));
N_("is_stmt value is not a constant"));
yasm_xfree(loc);
return 0;
return;
}
loc->column = yasm_intnum_get_uint(intn);
vp = yasm_vps_next(vp);
}
/* Other options */
while (vp && vp->val) {
if (yasm__strcasecmp(vp->val, "basic_block") == 0)
loc->basic_block = 1;
else if (yasm__strcasecmp(vp->val, "prologue_end") == 0)
loc->prologue_end = 1;
else if (yasm__strcasecmp(vp->val, "epilogue_begin") == 0)
loc->epilogue_begin = 1;
else if (yasm__strcasecmp(vp->val, "is_stmt") == 0) {
if (!vp->param) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("is_stmt requires value"));
yasm_xfree(loc);
return 0;
}
intn = yasm_expr_get_intnum(&vp->param, 0);
if (!intn) {
yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("is_stmt value is not a constant"));
yasm_xfree(loc);
return 0;
}
if (yasm_intnum_is_zero(intn))
loc->is_stmt = IS_STMT_SET;
else if (yasm_intnum_is_pos1(intn))
loc->is_stmt = IS_STMT_CLEAR;
else {
yasm_error_set(YASM_ERROR_VALUE,
N_("is_stmt value not 0 or 1"));
yasm_xfree(loc);
return 0;
}
} else if (yasm__strcasecmp(vp->val, "isa") == 0) {
if (!vp->param) {
yasm_error_set(YASM_ERROR_SYNTAX, N_("isa requires value"));
yasm_xfree(loc);
return 0;
}
intn = yasm_expr_get_intnum(&vp->param, 0);
if (!intn) {
yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("isa value is not a constant"));
yasm_xfree(loc);
return 0;
}
if (yasm_intnum_sign(intn) < 0) {
yasm_error_set(YASM_ERROR_VALUE,
N_("isa value less than zero"));
yasm_xfree(loc);
return 0;
}
loc->isa_change = 1;
loc->isa = yasm_intnum_get_uint(intn);
} else
yasm_warn_set(YASM_WARN_GENERAL,
N_("unrecognized loc option `%s'"), vp->val);
}
/* Append new location */
loc->vline = line;
loc->bc = NULL;
loc->sym = NULL;
STAILQ_INSERT_TAIL(&dsd->locs, loc, link);
return 0;
} else if (yasm__strcasecmp(name, "file") == 0) {
/*@dependent@*/ /*@null@*/ const yasm_intnum *file_intn;
unsigned long filenum;
if (!valparams) {
yasm_error_set(YASM_ERROR_SYNTAX, N_("[%s] requires an argument"),
"FILE");
return 0;
}
vp = yasm_vps_first(valparams);
if (vp->val) {
/* Just a bare filename */
yasm_object_set_source_fn(object, vp->val);
return 0;
}
/* Otherwise.. first vp is the file number */
file_intn = yasm_expr_get_intnum(&vp->param, 0);
if (!file_intn) {
yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("file number is not a constant"));
return 0;
}
filenum = yasm_intnum_get_uint(file_intn);
vp = yasm_vps_next(vp);
if (!vp || !vp->val) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("file number given but no filename"));
return 0;
}
dwarf2_dbgfmt_add_file(dbgfmt_dwarf2, filenum, vp->val);
return 0;
if (yasm_intnum_is_zero(intn))
loc->is_stmt = IS_STMT_SET;
else if (yasm_intnum_is_pos1(intn))
loc->is_stmt = IS_STMT_CLEAR;
else {
yasm_error_set(YASM_ERROR_VALUE,
N_("is_stmt value not 0 or 1"));
yasm_xfree(loc);
return;
}
} else if (yasm__strcasecmp(vp->val, "isa") == 0) {
if (!vp->param) {
yasm_error_set(YASM_ERROR_SYNTAX, N_("isa requires value"));
yasm_xfree(loc);
return;
}
intn = yasm_expr_get_intnum(&vp->param, 0);
if (!intn) {
yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("isa value is not a constant"));
yasm_xfree(loc);
return;
}
if (yasm_intnum_sign(intn) < 0) {
yasm_error_set(YASM_ERROR_VALUE,
N_("isa value less than zero"));
yasm_xfree(loc);
return;
}
loc->isa_change = 1;
loc->isa = yasm_intnum_get_uint(intn);
} else
yasm_warn_set(YASM_WARN_GENERAL,
N_("unrecognized loc option `%s'"), vp->val);
}
return 1;
/* Append new location */
loc->vline = line;
loc->bc = NULL;
loc->sym = NULL;
STAILQ_INSERT_TAIL(&dsd->locs, loc, link);
}
void
yasm_dwarf2__dir_file(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
yasm_valparam *vp;
/*@dependent@*/ /*@null@*/ const yasm_intnum *file_intn;
unsigned long filenum;
if (!valparams) {
yasm_error_set(YASM_ERROR_SYNTAX, N_("[%s] requires an argument"),
"FILE");
return;
}
vp = yasm_vps_first(valparams);
if (vp->val) {
/* Just a bare filename */
yasm_object_set_source_fn(object, vp->val);
return;
}
/* Otherwise.. first vp is the file number */
file_intn = yasm_expr_get_intnum(&vp->param, 0);
if (!file_intn) {
yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("file number is not a constant"));
return;
}
filenum = yasm_intnum_get_uint(file_intn);
vp = yasm_vps_next(vp);
if (!vp || !vp->val) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("file number given but no filename"));
return;
}
dwarf2_dbgfmt_add_file(dbgfmt_dwarf2, filenum, vp->val);
}

View file

@ -3038,70 +3038,6 @@ e3
69
6e
00
5f
5f
73
74
64
65
72
72
70
00
66
70
72
69
6e
74
66
00
66
6f
70
65
6e
00
70
72
69
6e
74
66
00
66
67
65
74
63
00
5f
5f
69
73
74
68
72
65
61
64
65
64
00
66
65
72
72
6f
72
00
66
63
6c
6f
73
65
00
2e
4c
64
@ -3217,6 +3153,16 @@ e3
4c
32
00
5f
5f
73
74
64
65
72
72
70
00
2e
4c
43
@ -3224,10 +3170,24 @@ e3
49
34
00
66
70
72
69
6e
74
66
00
2e
4c
31
00
66
6f
70
65
6e
00
2e
4c
34
@ -3236,6 +3196,32 @@ e3
4c
36
00
70
72
69
6e
74
66
00
66
67
65
74
63
00
5f
5f
69
73
74
68
72
65
61
64
65
64
00
2e
4c
38
@ -3248,6 +3234,20 @@ e3
4c
37
00
66
65
72
72
6f
72
00
66
63
6c
6f
73
65
00
2e
4c
46
@ -4554,7 +4554,7 @@ e3
00
04
00
de
d0
00
00
00
@ -4570,7 +4570,7 @@ cc
00
04
00
da
cc
00
00
00
@ -4586,7 +4586,7 @@ af
00
04
00
d6
c8
00
00
00
@ -4602,7 +4602,7 @@ d6
00
04
00
d2
aa
00
00
00
@ -4618,7 +4618,7 @@ d2
00
04
00
ce
a6
00
00
00
@ -4634,7 +4634,7 @@ ce
00
04
00
ca
9c
00
00
00
@ -4650,7 +4650,7 @@ dc
00
04
00
c3
8d
00
00
00
@ -4666,7 +4666,7 @@ c3
00
04
00
bf
7f
00
00
00
@ -4682,7 +4682,7 @@ bf
00
04
00
b8
78
00
00
00
@ -4698,7 +4698,7 @@ b8
00
04
00
b1
71
00
00
00
@ -4714,7 +4714,7 @@ b1
00
04
00
aa
6a
00
00
00
@ -4730,7 +4730,7 @@ aa
00
04
00
a3
63
00
00
00
@ -4746,7 +4746,7 @@ a3
00
04
00
9d
5d
00
00
00
@ -4762,7 +4762,7 @@ a3
00
04
00
98
58
00
00
00
@ -4778,7 +4778,7 @@ a3
00
0b
00
93
53
00
00
00
@ -4794,7 +4794,7 @@ a3
00
0b
00
8e
4e
00
00
00
@ -4810,7 +4810,7 @@ a3
00
0b
00
89
49
00
00
00
@ -4826,7 +4826,7 @@ a3
00
0b
00
84
44
00
00
00
@ -4858,7 +4858,7 @@ a3
00
0b
00
7c
3c
00
00
00
@ -4874,7 +4874,7 @@ a3
00
04
00
6e
2e
00
00
00
@ -4906,7 +4906,7 @@ a3
00
09
00
60
20
00
00
00
@ -4938,7 +4938,7 @@ a3
00
07
00
50
10
00
00
00
@ -5002,7 +5002,7 @@ e3
00
04
00
10
83
00
00
00
@ -5018,7 +5018,7 @@ e3
00
00
00
1a
94
00
00
00
@ -5034,7 +5034,7 @@ e3
00
00
00
22
a0
00
00
00
@ -5050,7 +5050,7 @@ e3
00
00
00
28
ae
00
00
00
@ -5066,7 +5066,7 @@ e3
00
00
00
2f
b5
00
00
00
@ -5082,7 +5082,7 @@ e3
00
00
00
35
bb
00
00
00
@ -5098,7 +5098,7 @@ e3
00
00
00
42
d4
00
00
00
@ -5114,7 +5114,7 @@ e3
00
00
00
49
db
00
00
00

File diff suppressed because it is too large Load diff

View file

@ -4,6 +4,8 @@
-:10: warning: unrecognized section attribute: `M'
-:10: warning: unrecognized section attribute: `S'
-:10: warning: Unrecognized qualifier `progbits'
-:24: warning: directive `.type' not recognized
-:152: warning: directive `.size' not recognized
-:153: warning: Unrecognized qualifier `progbits'
-:190: warning: Unrecognized qualifier `progbits'
-:232: warning: Unrecognized qualifier `progbits'

View file

@ -48,13 +48,6 @@ null_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt)
yasm_xfree(dbgfmt);
}
static int
null_dbgfmt_directive(yasm_object *object, const char *name,
yasm_valparamhead *valparams, unsigned long line)
{
return 1;
}
static void
null_dbgfmt_generate(yasm_object *object, yasm_linemap *linemap,
yasm_errwarns *errwarns)
@ -66,8 +59,8 @@ null_dbgfmt_generate(yasm_object *object, yasm_linemap *linemap,
yasm_dbgfmt_module yasm_null_LTX_dbgfmt = {
"No debugging info",
"null",
NULL, /* no directives */
null_dbgfmt_create,
null_dbgfmt_destroy,
null_dbgfmt_directive,
null_dbgfmt_generate
};

View file

@ -499,19 +499,12 @@ stabs_bc_str_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
return 0;
}
static int
stabs_dbgfmt_directive(yasm_object *object, const char *name,
yasm_valparamhead *valparams, unsigned long line)
{
return 1;
}
/* Define dbgfmt structure -- see dbgfmt.h for details */
yasm_dbgfmt_module yasm_stabs_LTX_dbgfmt = {
"Stabs debugging format",
"stabs",
NULL, /* no directives */
stabs_dbgfmt_create,
stabs_dbgfmt_destroy,
stabs_dbgfmt_directive,
stabs_dbgfmt_generate
};

View file

@ -85,6 +85,7 @@ bin_objfmt_align_section(yasm_section *sect, yasm_section *prevsect,
typedef struct bin_objfmt_output_info {
yasm_object *object;
yasm_errwarns *errwarns;
/*@dependent@*/ FILE *f;
/*@only@*/ unsigned char *buf;
/*@observer@*/ const yasm_section *sect;
@ -252,6 +253,29 @@ bin_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d)
return 0;
}
static int
bin_objfmt_check_sym(yasm_symrec *sym, /*@null@*/ void *d)
{
/*@null@*/ bin_objfmt_output_info *info = (bin_objfmt_output_info *)d;
yasm_sym_vis vis = yasm_symrec_get_visibility(sym);
assert(info != NULL);
if (vis & YASM_SYM_EXTERN) {
yasm_warn_set(YASM_WARN_GENERAL,
N_("binary object format does not support extern variables"));
yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym));
} else if (vis & YASM_SYM_GLOBAL) {
yasm_warn_set(YASM_WARN_GENERAL,
N_("binary object format does not support global variables"));
yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym));
} else if (vis & YASM_SYM_COMMON) {
yasm_error_set(YASM_ERROR_TYPE,
N_("binary object format does not support common variables"));
yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym));
}
return 0;
}
static void
bin_objfmt_output(yasm_object *object, FILE *f, /*@unused@*/ int all_syms,
yasm_errwarns *errwarns)
@ -266,9 +290,13 @@ bin_objfmt_output(yasm_object *object, FILE *f, /*@unused@*/ int all_syms,
bin_objfmt_output_info info;
info.object = object;
info.errwarns = errwarns;
info.f = f;
info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE);
/* Check symbol table */
yasm_symtab_traverse(object->symtab, &info, bin_objfmt_check_sym);
text = yasm_object_find_general(object, ".text");
data = yasm_object_find_general(object, ".data");
bss = yasm_object_find_general(object, ".bss");
@ -467,96 +495,45 @@ bin_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
return NULL;
}
static yasm_symrec *
bin_objfmt_extern_declare(yasm_object *object, const char *name,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_symrec *sym;
yasm_warn_set(YASM_WARN_GENERAL,
N_("binary object format does not support extern variables"));
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_EXTERN, line);
return sym;
}
static yasm_symrec *
bin_objfmt_global_declare(yasm_object *object, const char *name,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_symrec *sym;
yasm_warn_set(YASM_WARN_GENERAL,
N_("binary object format does not support global variables"));
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_GLOBAL, line);
return sym;
}
static yasm_symrec *
bin_objfmt_common_declare(yasm_object *object, const char *name,
/*@only@*/ yasm_expr *size, /*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_symrec *sym;
yasm_expr_destroy(size);
yasm_error_set(YASM_ERROR_TYPE,
N_("binary object format does not support common variables"));
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_COMMON, line);
return sym;
}
static int
bin_objfmt_directive(yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams, unsigned long line)
static void
bin_objfmt_dir_org(yasm_object *object,
/*@null@*/ yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_section *sect;
yasm_valparam *vp;
if (yasm__strcasecmp(name, "org") == 0) {
/*@null@*/ yasm_expr *start = NULL;
/*@null@*/ yasm_expr *start = NULL;
if (!valparams) {
yasm_error_set(YASM_ERROR_SYNTAX, N_("[%s] requires an argument"),
"ORG");
return 0;
}
if (!valparams) {
yasm_error_set(YASM_ERROR_SYNTAX, N_("[%s] requires an argument"),
"ORG");
return;
}
/* ORG takes just a simple integer as param */
vp = yasm_vps_first(valparams);
if (vp->val)
start = yasm_expr_create_ident(yasm_expr_sym(yasm_symtab_use(
object->symtab, vp->val, line)), line);
else if (vp->param) {
start = vp->param;
vp->param = NULL; /* Don't let valparams delete it */
}
/* ORG takes just a simple integer as param */
vp = yasm_vps_first(valparams);
if (vp->val)
start = yasm_expr_create_ident(yasm_expr_sym(yasm_symtab_use(
object->symtab, vp->val, line)), line);
else if (vp->param) {
start = vp->param;
vp->param = NULL; /* Don't let valparams delete it */
}
if (!start) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("argument to ORG must be expression"));
return 0;
}
if (!start) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("argument to ORG must be expression"));
return;
}
/* ORG changes the start of the .text section */
sect = yasm_object_find_general(object, ".text");
if (!sect)
yasm_internal_error(
N_("bin objfmt: .text section does not exist before ORG is called?"));
yasm_section_set_start(sect, start, line);
return 0; /* directive recognized */
} else
return 1; /* directive unrecognized */
/* ORG changes the start of the .text section */
sect = yasm_object_find_general(object, ".text");
if (!sect)
yasm_internal_error(
N_("bin objfmt: .text section does not exist before ORG is called?"));
yasm_section_set_start(sect, start, line);
}
@ -566,6 +543,11 @@ static const char *bin_objfmt_dbgfmt_keywords[] = {
NULL
};
static const yasm_directive bin_objfmt_directives[] = {
{ "org", "nasm", bin_objfmt_dir_org, YASM_DIR_ARG_REQUIRED },
{ NULL, NULL, NULL, 0 }
};
/* Define objfmt structure -- see objfmt.h for details */
yasm_objfmt_module yasm_bin_LTX_objfmt = {
"Flat format binary",
@ -574,13 +556,10 @@ yasm_objfmt_module yasm_bin_LTX_objfmt = {
16,
bin_objfmt_dbgfmt_keywords,
"null",
bin_objfmt_directives,
bin_objfmt_create,
bin_objfmt_output,
bin_objfmt_destroy,
bin_objfmt_add_default_section,
bin_objfmt_section_switch,
bin_objfmt_extern_declare,
bin_objfmt_global_declare,
bin_objfmt_common_declare,
bin_objfmt_directive
bin_objfmt_section_switch
};

View file

@ -168,8 +168,6 @@ typedef struct coff_symrec_data {
unsigned long index; /* assigned COFF symbol table index */
coff_symrec_sclass sclass; /* storage class */
/*@owned@*/ /*@null@*/ yasm_expr *size; /* size if COMMON declaration */
int numaux; /* number of auxiliary entries */
coff_symtab_auxtype auxtype; /* type of aux entries */
coff_symtab_auxent aux[1]; /* actually may be any size (including 0) */
@ -230,8 +228,7 @@ yasm_objfmt_module yasm_win64_LTX_objfmt;
static /*@dependent@*/ coff_symrec_data *
coff_objfmt_sym_set_data(yasm_symrec *sym, coff_symrec_sclass sclass,
/*@only@*/ /*@null@*/ yasm_expr *size, int numaux,
coff_symtab_auxtype auxtype)
int numaux, coff_symtab_auxtype auxtype)
{
coff_symrec_data *sym_data;
@ -239,7 +236,6 @@ coff_objfmt_sym_set_data(yasm_symrec *sym, coff_symrec_sclass sclass,
(numaux-1)*sizeof(coff_symtab_auxent));
sym_data->index = 0;
sym_data->sclass = sclass;
sym_data->size = size;
sym_data->numaux = numaux;
sym_data->auxtype = auxtype;
@ -266,7 +262,7 @@ coff_common_create(yasm_object *object)
filesym = yasm_symtab_define_special(object->symtab, ".file",
YASM_SYM_GLOBAL);
objfmt_coff->filesym_data =
coff_objfmt_sym_set_data(filesym, COFF_SCL_FILE, NULL, 1,
coff_objfmt_sym_set_data(filesym, COFF_SCL_FILE, 1,
COFF_SYMTAB_AUX_FILE);
/* Filename is set in coff_objfmt_output */
objfmt_coff->filesym_data->aux[0].fname = NULL;
@ -376,8 +372,7 @@ coff_objfmt_init_new_section(yasm_object *object, yasm_section *sect,
sym = yasm_symtab_define_label(object->symtab, sectname,
yasm_section_bcs_first(sect), 1, line);
yasm_symrec_declare(sym, YASM_SYM_GLOBAL, line);
coff_objfmt_sym_set_data(sym, COFF_SCL_STAT, NULL, 1,
COFF_SYMTAB_AUX_SECT);
coff_objfmt_sym_set_data(sym, COFF_SCL_STAT, 1, COFF_SYMTAB_AUX_SECT);
data->sym = sym;
return data;
}
@ -506,11 +501,14 @@ coff_objfmt_output_value(yasm_value *value, unsigned char *buf,
/* In standard COFF, COMMON symbols have their length added in */
if (!objfmt_coff->win32) {
/*@dependent@*/ /*@null@*/ coff_symrec_data *csymd;
/*@dependent@*/ /*@null@*/ yasm_expr **csize_expr;
/*@dependent@*/ /*@null@*/ yasm_intnum *common_size;
csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
assert(csymd != NULL);
common_size = yasm_expr_get_intnum(&csymd->size, 1);
csize_expr = yasm_symrec_get_common_size(sym);
assert(csize_expr != NULL);
common_size = yasm_expr_get_intnum(csize_expr, 1);
if (!common_size) {
yasm_error_set(YASM_ERROR_TOO_COMPLEX,
N_("coff: common size too complex"));
@ -942,13 +940,20 @@ static int
coff_objfmt_count_sym(yasm_symrec *sym, /*@null@*/ void *d)
{
/*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
yasm_sym_vis vis = yasm_symrec_get_visibility(sym);
coff_symrec_data *sym_data;
assert(info != NULL);
if (info->all_syms || yasm_symrec_get_visibility(sym) != YASM_SYM_LOCAL) {
sym_data = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
if ((vis & (YASM_SYM_EXTERN|YASM_SYM_GLOBAL|YASM_SYM_COMMON)) && !sym_data)
sym_data = coff_objfmt_sym_set_data(sym, COFF_SCL_EXT, 0,
COFF_SYMTAB_AUX_NONE);
if (info->all_syms || vis != YASM_SYM_LOCAL) {
/* Save index in symrec data */
coff_symrec_data *sym_data =
yasm_symrec_get_data(sym, &coff_symrec_data_cb);
if (!sym_data) {
sym_data = coff_objfmt_sym_set_data(sym, COFF_SCL_STAT, NULL, 0,
sym_data = coff_objfmt_sym_set_data(sym, COFF_SCL_STAT, 0,
COFF_SYMTAB_AUX_NONE);
}
sym_data->index = info->indx;
@ -1042,11 +1047,15 @@ coff_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
scnum = 0xffff; /* -1 = absolute symbol */
} else {
if (vis & YASM_SYM_COMMON) {
intn = yasm_expr_get_intnum(&csymd->size, 1);
/*@dependent@*/ /*@null@*/ yasm_expr **csize_expr;
csize_expr = yasm_symrec_get_common_size(sym);
assert(csize_expr != NULL);
intn = yasm_expr_get_intnum(csize_expr, 1);
if (!intn) {
yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("COMMON data size not an integer expression"));
yasm_errwarn_propagate(info->errwarns, csymd->size->line);
yasm_errwarn_propagate(info->errwarns,
(*csize_expr)->line);
} else
value = yasm_intnum_get_uint(intn);
scnum = 0;
@ -1630,55 +1639,9 @@ coff_section_data_print(void *data, FILE *f, int indent_level)
fprintf(f, "%*srelocs:\n", indent_level, "");
}
static yasm_symrec *
coff_objfmt_extern_declare(yasm_object *object, const char *name, /*@unused@*/
/*@null@*/ yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_symrec *sym;
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_EXTERN, line);
coff_objfmt_sym_set_data(sym, COFF_SCL_EXT, NULL, 0,
COFF_SYMTAB_AUX_NONE);
return sym;
}
static yasm_symrec *
coff_objfmt_global_declare(yasm_object *object, const char *name, /*@unused@*/
/*@null@*/ yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_symrec *sym;
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_GLOBAL, line);
coff_objfmt_sym_set_data(sym, COFF_SCL_EXT, NULL, 0,
COFF_SYMTAB_AUX_NONE);
return sym;
}
static yasm_symrec *
coff_objfmt_common_declare(yasm_object *object, const char *name,
/*@only@*/ yasm_expr *size, /*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_symrec *sym;
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_COMMON, line);
coff_objfmt_sym_set_data(sym, COFF_SCL_EXT, size, 0,
COFF_SYMTAB_AUX_NONE);
return sym;
}
static void
coff_symrec_data_destroy(void *data)
{
coff_symrec_data *csymd = (coff_symrec_data *)data;
if (csymd->size)
yasm_expr_destroy(csymd->size);
yasm_xfree(data);
}
@ -1689,17 +1652,11 @@ coff_symrec_data_print(void *data, FILE *f, int indent_level)
fprintf(f, "%*ssymtab index=%lu\n", indent_level, "", csd->index);
fprintf(f, "%*ssclass=%d\n", indent_level, "", csd->sclass);
fprintf(f, "%*ssize=", indent_level, "");
if (csd->size)
yasm_expr_print(csd->size, f);
else
fprintf(f, "nil");
fprintf(f, "\n");
}
static void
dir_export(yasm_object *object, yasm_valparamhead *valparams,
unsigned long line)
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_valparam *vp;
int isnew;
@ -1740,7 +1697,7 @@ dir_export(yasm_object *object, yasm_valparamhead *valparams,
static void
dir_ident(yasm_object *object, yasm_valparamhead *valparams,
unsigned long line)
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
yasm_valparamhead sect_vps;
@ -1749,7 +1706,13 @@ dir_ident(yasm_object *object, yasm_valparamhead *valparams,
const char *sectname;
yasm_valparam *vp, *vp2;
/* Accept, but do nothing with empty ident */
if (!valparams)
return;
vp = yasm_vps_first(valparams);
if (!vp)
return;
if (objfmt_coff->win32) {
/* Put ident data into .comment section for COFF, or .rdata$zzz
@ -1788,59 +1751,9 @@ dir_ident(yasm_object *object, yasm_valparamhead *valparams,
yasm_bc_create_data(&dvs, 1, 1, object->arch, line));
}
static int
coff_objfmt_directive(yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
unsigned long line)
{
if (yasm__strcasecmp(name, "IDENT") == 0) {
if (!valparams) {
yasm_error_set(YASM_ERROR_SYNTAX, N_("[%s] requires an argument"),
"IDENT");
return 0;
}
dir_ident(object, valparams, line);
return 0;
}
return 1;
}
static int
win32_objfmt_directive(yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
unsigned long line)
{
static const struct {
const char *name;
int required_arg;
void (*func) (yasm_object *, yasm_valparamhead *, unsigned long);
} dirs[] = {
{"EXPORT", 1, dir_export},
{"IDENT", 1, dir_ident}
};
size_t i;
for (i=0; i<NELEMS(dirs); i++) {
if (yasm__strcasecmp(name, dirs[i].name) == 0) {
if (dirs[i].required_arg && !valparams) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("[%s] requires an argument"), dirs[i].name);
return 0;
}
dirs[i].func(object, valparams, line);
return 0;
}
}
return 1;
}
static void
dir_proc_frame(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
unsigned long line)
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
yasm_valparam *vp = yasm_vps_first(valparams);
@ -1902,7 +1815,7 @@ get_curpos(yasm_object *object, unsigned long line)
static void
dir_pushreg(yasm_object *object, yasm_valparamhead *valparams,
unsigned long line)
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
yasm_valparam *vp = yasm_vps_first(valparams);
@ -1931,7 +1844,7 @@ dir_pushreg(yasm_object *object, yasm_valparamhead *valparams,
static void
dir_setframe(yasm_object *object, yasm_valparamhead *valparams,
unsigned long line)
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
yasm_valparam *vp = yasm_vps_first(valparams);
@ -1971,7 +1884,7 @@ dir_setframe(yasm_object *object, yasm_valparamhead *valparams,
static void
dir_allocstack(yasm_object *object, yasm_valparamhead *valparams,
unsigned long line)
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
yasm_valparam *vp = yasm_vps_first(valparams);
@ -2054,21 +1967,21 @@ dir_save_common(yasm_object *object, yasm_valparamhead *valparams,
static void
dir_savereg(yasm_object *object, yasm_valparamhead *valparams,
unsigned long line)
yasm_valparamhead *objext_valparams, unsigned long line)
{
dir_save_common(object, valparams, line, "SAVEREG", UWOP_SAVE_NONVOL);
}
static void
dir_savexmm128(yasm_object *object, yasm_valparamhead *valparams,
unsigned long line)
yasm_valparamhead *objext_valparams, unsigned long line)
{
dir_save_common(object, valparams, line, "SAVEXMM128", UWOP_SAVE_XMM128);
}
static void
dir_pushframe(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
unsigned long line)
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
yasm_valparam *vp = yasm_vps_first(valparams);
@ -2091,7 +2004,7 @@ dir_pushframe(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
static void
dir_endprolog(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
unsigned long line)
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
if (!procframe_checkstate(objfmt_coff, "ENDPROLOG"))
@ -2103,7 +2016,7 @@ dir_endprolog(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
static void
dir_endproc_frame(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
unsigned long line)
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
yasm_section *sect;
@ -2191,47 +2104,6 @@ dir_endproc_frame(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
objfmt_coff->done_prolog = 0;
}
static int
win64_objfmt_directive(yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
unsigned long line)
{
static const struct {
const char *name;
int required_arg;
void (*func) (yasm_object *, yasm_valparamhead *, unsigned long);
} dirs[] = {
{"EXPORT", 1, dir_export},
{"IDENT", 1, dir_ident},
{"PROC_FRAME", 0, dir_proc_frame},
{"PUSHREG", 1, dir_pushreg},
{"SETFRAME", 1, dir_setframe},
{"ALLOCSTACK", 1, dir_allocstack},
{"SAVEREG", 1, dir_savereg},
{"SAVEXMM128", 1, dir_savexmm128},
{"PUSHFRAME", 0, dir_pushframe},
{"ENDPROLOG", 0, dir_endprolog},
{"ENDPROC_FRAME", 0, dir_endproc_frame}
};
size_t i;
for (i=0; i<NELEMS(dirs); i++) {
if (yasm__strcasecmp(name, dirs[i].name) == 0) {
if (dirs[i].required_arg && !valparams) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("[%s] requires an argument"), dirs[i].name);
return 0;
}
dirs[i].func(object, valparams, line);
return 0;
}
}
return 1;
}
/* Define valid debug formats to use with this object format */
static const char *coff_objfmt_dbgfmt_keywords[] = {
"null",
@ -2239,6 +2111,12 @@ static const char *coff_objfmt_dbgfmt_keywords[] = {
NULL
};
static const yasm_directive coff_objfmt_directives[] = {
{ ".ident", "gas", dir_ident, YASM_DIR_ANY },
{ "ident", "nasm", dir_ident, YASM_DIR_ANY },
{ NULL, NULL, NULL, 0 }
};
/* Define objfmt structure -- see objfmt.h for details */
yasm_objfmt_module yasm_coff_LTX_objfmt = {
"COFF (DJGPP)",
@ -2247,15 +2125,12 @@ yasm_objfmt_module yasm_coff_LTX_objfmt = {
32,
coff_objfmt_dbgfmt_keywords,
"null",
coff_objfmt_directives,
coff_objfmt_create,
coff_objfmt_output,
coff_objfmt_destroy,
coff_objfmt_add_default_section,
coff_objfmt_section_switch,
coff_objfmt_extern_declare,
coff_objfmt_global_declare,
coff_objfmt_common_declare,
coff_objfmt_directive
coff_objfmt_section_switch
};
/* Define valid debug formats to use with this object format */
@ -2266,6 +2141,14 @@ static const char *winXX_objfmt_dbgfmt_keywords[] = {
NULL
};
static const yasm_directive win32_objfmt_directives[] = {
{ ".ident", "gas", dir_ident, YASM_DIR_ANY },
{ ".export", "gas", dir_export, YASM_DIR_ID_REQUIRED },
{ "ident", "nasm", dir_ident, YASM_DIR_ANY },
{ "export", "nasm", dir_export, YASM_DIR_ID_REQUIRED },
{ NULL, NULL, NULL, 0 }
};
/* Define objfmt structure -- see objfmt.h for details */
yasm_objfmt_module yasm_win32_LTX_objfmt = {
"Win32",
@ -2274,15 +2157,29 @@ yasm_objfmt_module yasm_win32_LTX_objfmt = {
32,
winXX_objfmt_dbgfmt_keywords,
"null",
win32_objfmt_directives,
win32_objfmt_create,
coff_objfmt_output,
coff_objfmt_destroy,
coff_objfmt_add_default_section,
coff_objfmt_section_switch,
coff_objfmt_extern_declare,
coff_objfmt_global_declare,
coff_objfmt_common_declare,
win32_objfmt_directive
coff_objfmt_section_switch
};
static const yasm_directive win64_objfmt_directives[] = {
{ ".ident", "gas", dir_ident, YASM_DIR_ANY },
{ "ident", "nasm", dir_ident, YASM_DIR_ANY },
{ ".export", "gas", dir_export, YASM_DIR_ID_REQUIRED },
{ "export", "nasm", dir_export, YASM_DIR_ID_REQUIRED },
{ "proc_frame", "nasm", dir_proc_frame, YASM_DIR_ANY },
{ "pushreg", "nasm", dir_pushreg, YASM_DIR_ARG_REQUIRED },
{ "setframe", "nasm", dir_setframe, YASM_DIR_ARG_REQUIRED },
{ "allocstack", "nasm", dir_allocstack, YASM_DIR_ARG_REQUIRED },
{ "savereg", "nasm", dir_savereg, YASM_DIR_ARG_REQUIRED },
{ "savexmm128", "nasm", dir_savexmm128, YASM_DIR_ARG_REQUIRED },
{ "pushframe", "nasm", dir_pushframe, YASM_DIR_ANY },
{ "endprolog", "nasm", dir_endprolog, YASM_DIR_ANY },
{ "endproc_frame", "nasm", dir_endproc_frame, YASM_DIR_ANY },
{ NULL, NULL, NULL, 0 }
};
/* Define objfmt structure -- see objfmt.h for details */
@ -2293,15 +2190,12 @@ yasm_objfmt_module yasm_win64_LTX_objfmt = {
64,
winXX_objfmt_dbgfmt_keywords,
"null",
win64_objfmt_directives,
win64_objfmt_create,
coff_objfmt_output,
coff_objfmt_destroy,
coff_objfmt_add_default_section,
coff_objfmt_section_switch,
coff_objfmt_extern_declare,
coff_objfmt_global_declare,
coff_objfmt_common_declare,
win64_objfmt_directive
coff_objfmt_section_switch
};
yasm_objfmt_module yasm_x64_LTX_objfmt = {
"Win64",
@ -2310,13 +2204,10 @@ yasm_objfmt_module yasm_x64_LTX_objfmt = {
64,
winXX_objfmt_dbgfmt_keywords,
"null",
win64_objfmt_directives,
win64_objfmt_create,
coff_objfmt_output,
coff_objfmt_destroy,
coff_objfmt_add_default_section,
coff_objfmt_section_switch,
coff_objfmt_extern_declare,
coff_objfmt_global_declare,
coff_objfmt_common_declare,
win64_objfmt_directive
coff_objfmt_section_switch
};

View file

@ -152,7 +152,7 @@ yasm_win64__unwind_generate(yasm_section *xdata, coff_unwind_info *info,
/* Code array */
SLIST_FOREACH(code, &info->codes, link) {
codebc = yasm_bc_create_common(&win64_uwcode_bc_callback, code,
yasm_symrec_get_line(code->loc));
yasm_symrec_get_def_line(code->loc));
yasm_section_bcs_append(xdata, codebc);
}
@ -259,7 +259,7 @@ win64_uwinfo_bc_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
coff_unwind_info *info = (coff_unwind_info *)bc->contents;
switch (span) {
case 1:
yasm_error_set_xref(yasm_symrec_get_line(info->prolog),
yasm_error_set_xref(yasm_symrec_get_def_line(info->prolog),
N_("prologue ended here"));
yasm_error_set(YASM_ERROR_VALUE,
N_("prologue %ld bytes, must be <256"), new_val);

View file

@ -144,79 +144,6 @@ dbg_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
}
}
static yasm_symrec *
dbg_objfmt_extern_declare(yasm_object *object, const char *name,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)object->objfmt;
yasm_symrec *sym;
fprintf(objfmt_dbg->dbgfile, "extern_declare(\"%s\", ", name);
yasm_vps_print(objext_valparams, objfmt_dbg->dbgfile);
fprintf(objfmt_dbg->dbgfile, ", %lu), returning sym\n", line);
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_EXTERN, line);
return sym;
}
static yasm_symrec *
dbg_objfmt_global_declare(yasm_object *object, const char *name,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)object->objfmt;
yasm_symrec *sym;
fprintf(objfmt_dbg->dbgfile, "global_declare(\"%s\", ", name);
yasm_vps_print(objext_valparams, objfmt_dbg->dbgfile);
fprintf(objfmt_dbg->dbgfile, ", %lu), returning sym\n", line);
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_GLOBAL, line);
return sym;
}
static yasm_symrec *
dbg_objfmt_common_declare(yasm_object *object, const char *name,
/*@only@*/ yasm_expr *size,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)object->objfmt;
yasm_symrec *sym;
assert(objfmt_dbg->dbgfile != NULL);
fprintf(objfmt_dbg->dbgfile, "common_declare(\"%s\", ", name);
yasm_expr_print(size, objfmt_dbg->dbgfile);
fprintf(objfmt_dbg->dbgfile, ", ");
yasm_vps_print(objext_valparams, objfmt_dbg->dbgfile);
fprintf(objfmt_dbg->dbgfile, ", %lu), returning sym\n", line);
yasm_expr_destroy(size);
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_COMMON, line);
return sym;
}
static int
dbg_objfmt_directive(yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *valparams,
/*@null@*/ yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)object->objfmt;
fprintf(objfmt_dbg->dbgfile, "directive(\"%s\", ", name);
yasm_vps_print(valparams, objfmt_dbg->dbgfile);
fprintf(objfmt_dbg->dbgfile, ", ");
yasm_vps_print(objext_valparams, objfmt_dbg->dbgfile);
fprintf(objfmt_dbg->dbgfile, ", %lu), returning 0 (recognized)\n", line);
return 0; /* dbg format "recognizes" all directives */
}
/* Define valid debug formats to use with this object format */
static const char *dbg_objfmt_dbgfmt_keywords[] = {
"null",
@ -231,13 +158,10 @@ yasm_objfmt_module yasm_dbg_LTX_objfmt = {
32,
dbg_objfmt_dbgfmt_keywords,
"null",
NULL, /* no directives */
dbg_objfmt_create,
dbg_objfmt_output,
dbg_objfmt_destroy,
dbg_objfmt_add_default_section,
dbg_objfmt_section_switch,
dbg_objfmt_extern_declare,
dbg_objfmt_global_declare,
dbg_objfmt_common_declare,
dbg_objfmt_directive
dbg_objfmt_section_switch
};

View file

@ -75,8 +75,9 @@ typedef struct {
typedef struct {
yasm_objfmt_elf *objfmt_elf;
yasm_errwarns *errwarns;
int local_names;
} append_local_sym_info;
} build_symtab_info;
yasm_objfmt_module yasm_elf_LTX_objfmt;
yasm_objfmt_module yasm_elf32_LTX_objfmt;
@ -89,38 +90,170 @@ elf_objfmt_symtab_append(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym,
elf_symbol_type type, elf_symbol_vis vis,
yasm_expr *size, elf_address *value)
{
/* Only append to table if not already appended */
elf_symtab_entry *entry = yasm_symrec_get_data(sym, &elf_symrec_data);
if (!entry || !elf_sym_in_table(entry)) {
if (!entry) {
elf_strtab_entry *name =
elf_strtab_append_str(objfmt_elf->strtab,
yasm_symrec_get_name(sym));
entry = elf_symtab_entry_create(name, sym);
}
elf_symtab_append_entry(objfmt_elf->elf_symtab, entry);
if (!entry) {
elf_strtab_entry *name =
elf_strtab_append_str(objfmt_elf->strtab,
yasm_symrec_get_name(sym));
entry = elf_symtab_entry_create(name, sym);
yasm_symrec_add_data(sym, &elf_symrec_data, entry);
}
/* Only append to table if not already appended */
if (!elf_sym_in_table(entry))
elf_symtab_append_entry(objfmt_elf->elf_symtab, entry);
elf_symtab_set_nonzero(entry, NULL, sectidx, bind, type, size, value);
elf_sym_set_visibility(entry, vis);
return entry;
}
static int
elf_objfmt_append_local_sym(yasm_symrec *sym, /*@null@*/ void *d)
static elf_symtab_entry *
build_extern(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym)
{
append_local_sym_info *info = (append_local_sym_info *)d;
elf_symtab_entry *entry;
yasm_valparamhead *objext_valparams =
yasm_symrec_get_objext_valparams(sym);
if (objext_valparams) {
yasm_valparam *vp = yasm_vps_first(objext_valparams);
for (; vp; vp = yasm_vps_next(vp)) {
if (vp->val)
yasm_error_set(YASM_ERROR_TYPE,
N_("unrecognized symbol type `%s'"), vp->val);
}
}
return elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_GLOBAL, 0,
STV_DEFAULT, NULL, NULL);
}
static elf_symtab_entry *
build_global(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym)
{
yasm_valparamhead *objext_valparams =
yasm_symrec_get_objext_valparams(sym);
elf_symbol_type type = 0;
yasm_expr *size = NULL;
elf_symbol_vis vis = STV_DEFAULT;
unsigned int vis_overrides = 0;
if (objext_valparams) {
yasm_valparam *vp = yasm_vps_first(objext_valparams);
for (; vp; vp = yasm_vps_next(vp))
{
if (vp->val) {
if (yasm__strcasecmp(vp->val, "function") == 0)
type = STT_FUNC;
else if (yasm__strcasecmp(vp->val, "data") == 0 ||
yasm__strcasecmp(vp->val, "object") == 0)
type = STT_OBJECT;
else if (yasm__strcasecmp(vp->val, "internal") == 0) {
vis = STV_INTERNAL;
vis_overrides++;
}
else if (yasm__strcasecmp(vp->val, "hidden") == 0) {
vis = STV_HIDDEN;
vis_overrides++;
}
else if (yasm__strcasecmp(vp->val, "protected") == 0) {
vis = STV_PROTECTED;
vis_overrides++;
}
else
yasm_error_set(YASM_ERROR_TYPE,
N_("unrecognized symbol type `%s'"),
vp->val);
}
else if (vp->param && !size) {
size = vp->param;
vp->param = NULL; /* to avoid double-free of expr */
}
}
if (vis_overrides > 1) {
yasm_warn_set(YASM_WARN_GENERAL,
N_("More than one symbol visibility provided; using last"));
}
}
return elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_GLOBAL,
type, vis, size, NULL);
}
static /*@null@*/ elf_symtab_entry *
build_common(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym)
{
yasm_expr **size = yasm_symrec_get_common_size(sym);
yasm_valparamhead *objext_valparams =
yasm_symrec_get_objext_valparams(sym);
unsigned long addralign = 0;
if (objext_valparams) {
yasm_valparam *vp = yasm_vps_first(objext_valparams);
for (; vp; vp = yasm_vps_next(vp)) {
if (!vp->val && vp->param) {
/*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;
align_expr = yasm_expr_get_intnum(&vp->param, 0);
if (!align_expr) {
yasm_error_set(YASM_ERROR_VALUE,
N_("alignment constraint is not an integer"));
return NULL;
}
addralign = yasm_intnum_get_uint(align_expr);
/* Alignments must be a power of two. */
if (!is_exp2(addralign)) {
yasm_error_set(YASM_ERROR_VALUE,
N_("alignment constraint is not a power of two"));
return NULL;
}
} else if (vp->val)
yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized qualifier `%s'"), vp->val);
}
}
return elf_objfmt_symtab_append(objfmt_elf, sym, SHN_COMMON, STB_GLOBAL,
0, STV_DEFAULT, *size, &addralign);
}
static int
elf_objfmt_build_symtab(yasm_symrec *sym, /*@null@*/ void *d)
{
build_symtab_info *info = (build_symtab_info *)d;
yasm_sym_vis vis = yasm_symrec_get_visibility(sym);
yasm_sym_status status = yasm_symrec_get_status(sym);
elf_symtab_entry *entry = yasm_symrec_get_data(sym, &elf_symrec_data);
elf_address value=0;
yasm_section *sect=NULL;
yasm_bytecode *precbc=NULL;
assert(info != NULL);
if (vis & YASM_SYM_EXTERN) {
entry = build_extern(info->objfmt_elf, sym);
yasm_errwarn_propagate(info->errwarns,
yasm_symrec_get_decl_line(sym));
return 0;
}
if (vis & YASM_SYM_COMMON) {
entry = build_common(info->objfmt_elf, sym);
yasm_errwarn_propagate(info->errwarns,
yasm_symrec_get_decl_line(sym));
/* If the COMMON variable was actually defined, fall through. */
if (!(status & YASM_SYM_DEFINED))
return 0;
}
/* Ignore any undefined at this point. */
if (!(status & YASM_SYM_DEFINED))
return 0;
if (!yasm_symrec_get_label(sym, &precbc)) {
if (!yasm_symrec_is_abs(sym)) /* let absolute symbol into output */
if (!yasm_symrec_get_equ(sym) && !yasm_symrec_is_abs(sym))
return 0;
precbc = NULL;
}
@ -128,25 +261,44 @@ elf_objfmt_append_local_sym(yasm_symrec *sym, /*@null@*/ void *d)
if (precbc)
sect = yasm_bc_get_section(precbc);
entry = yasm_symrec_get_data(sym, &elf_symrec_data);
if (!entry || !elf_sym_in_table(entry)) {
if (entry && elf_sym_in_table(entry))
;
else if (vis & YASM_SYM_GLOBAL) {
entry = build_global(info->objfmt_elf, sym);
yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym));
} else {
int is_sect = 0;
/* Locals (except when debugging) do not need to be
* in the symbol table, unless they're a section.
*/
if (sect && !yasm_section_is_absolute(sect) &&
strcmp(yasm_symrec_get_name(sym), yasm_section_get_name(sect))==0)
is_sect = 1;
/* neither sections nor locals (except when debugging) need names */
#if 0
/* FIXME: to enable this we must have handling in place for special
* symbols.
*/
if (!info->local_names && !is_sect)
return 0;
#else
if (yasm_symrec_get_equ(sym) && !yasm_symrec_is_abs(sym))
return 0;
#endif
entry = yasm_symrec_get_data(sym, &elf_symrec_data);
if (!entry) {
elf_strtab_entry *name = info->local_names && !is_sect
? elf_strtab_append_str(info->objfmt_elf->strtab,
yasm_symrec_get_name(sym))
: NULL;
elf_strtab_entry *name = !info->local_names || is_sect ? NULL :
elf_strtab_append_str(info->objfmt_elf->strtab,
yasm_symrec_get_name(sym));
entry = elf_symtab_entry_create(name, sym);
yasm_symrec_add_data(sym, &elf_symrec_data, entry);
}
elf_symtab_insert_local_sym(info->objfmt_elf->elf_symtab, entry);
if (!elf_sym_in_table(entry))
elf_symtab_insert_local_sym(info->objfmt_elf->elf_symtab, entry);
elf_symtab_set_nonzero(entry, sect, 0, STB_LOCAL,
is_sect ? STT_SECTION : 0, NULL, 0);
yasm_symrec_add_data(sym, &elf_symrec_data, entry);
if (is_sect)
return 0;
@ -588,7 +740,7 @@ elf_objfmt_output(yasm_object *object, FILE *f, int all_syms,
{
yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt;
elf_objfmt_output_info info;
append_local_sym_info localsym_info;
build_symtab_info buildsym_info;
long pos;
unsigned long elf_shead_addr;
elf_secthead *esdn;
@ -614,16 +766,17 @@ elf_objfmt_output(yasm_object *object, FILE *f, int all_syms,
}
/* Create missing section headers */
localsym_info.objfmt_elf = objfmt_elf;
if (yasm_object_sections_traverse(object, &info,
elf_objfmt_create_dbg_secthead))
return;
/* add all (local) syms to symtab because relocation needs a symtab index
* if all_syms, register them by name. if not, use strtab entry 0 */
localsym_info.local_names = all_syms;
yasm_symtab_traverse(object->symtab, &localsym_info,
elf_objfmt_append_local_sym);
buildsym_info.objfmt_elf = objfmt_elf;
buildsym_info.errwarns = errwarns;
buildsym_info.local_names = all_syms;
yasm_symtab_traverse(object->symtab, &buildsym_info,
elf_objfmt_build_symtab);
elf_symtab_nlocal = elf_symtab_assign_indices(objfmt_elf->elf_symtab);
/* output known sections - includes reloc sections which aren't in yasm's
@ -959,135 +1112,11 @@ elf_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
return retval;
}
static yasm_symrec *
elf_objfmt_extern_declare(yasm_object *object, const char *name, /*@unused@*/
/*@null@*/ yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt;
yasm_symrec *sym;
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_EXTERN, line);
elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_GLOBAL,
0, STV_DEFAULT, NULL, NULL);
if (objext_valparams) {
yasm_valparam *vp = yasm_vps_first(objext_valparams);
for (; vp; vp = yasm_vps_next(vp))
{
if (vp->val)
yasm_error_set(YASM_ERROR_TYPE,
N_("unrecognized symbol type `%s'"), vp->val);
}
}
return sym;
}
static yasm_symrec *
elf_objfmt_global_declare(yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt;
yasm_symrec *sym;
elf_symbol_type type = 0;
yasm_expr *size = NULL;
elf_symbol_vis vis = STV_DEFAULT;
unsigned int vis_overrides = 0;
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_GLOBAL, line);
if (objext_valparams) {
yasm_valparam *vp = yasm_vps_first(objext_valparams);
for (; vp; vp = yasm_vps_next(vp))
{
if (vp->val) {
if (yasm__strcasecmp(vp->val, "function") == 0)
type = STT_FUNC;
else if (yasm__strcasecmp(vp->val, "data") == 0 ||
yasm__strcasecmp(vp->val, "object") == 0)
type = STT_OBJECT;
else if (yasm__strcasecmp(vp->val, "internal") == 0) {
vis = STV_INTERNAL;
vis_overrides++;
}
else if (yasm__strcasecmp(vp->val, "hidden") == 0) {
vis = STV_HIDDEN;
vis_overrides++;
}
else if (yasm__strcasecmp(vp->val, "protected") == 0) {
vis = STV_PROTECTED;
vis_overrides++;
}
else
yasm_error_set(YASM_ERROR_TYPE,
N_("unrecognized symbol type `%s'"),
vp->val);
}
else if (vp->param && !size) {
size = vp->param;
vp->param = NULL; /* to avoid deleting the expr */
}
}
if (vis_overrides > 1) {
yasm_warn_set(YASM_WARN_GENERAL,
N_("More than one symbol visibility provided; using last"));
}
}
elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_GLOBAL,
type, vis, size, NULL);
return sym;
}
static yasm_symrec *
elf_objfmt_common_declare(yasm_object *object, const char *name,
/*@only@*/ yasm_expr *size, /*@null@*/
yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt;
yasm_symrec *sym;
unsigned long addralign = 0;
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_COMMON, line);
if (objext_valparams) {
yasm_valparam *vp = yasm_vps_first(objext_valparams);
for (; vp; vp = yasm_vps_next(vp)) {
if (!vp->val && vp->param) {
/*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;
align_expr = yasm_expr_get_intnum(&vp->param, 0);
if (!align_expr) {
yasm_error_set(YASM_ERROR_VALUE,
N_("alignment constraint is not an integer"));
return sym;
}
addralign = yasm_intnum_get_uint(align_expr);
/* Alignments must be a power of two. */
if (!is_exp2(addralign)) {
yasm_error_set(YASM_ERROR_VALUE,
N_("alignment constraint is not a power of two"));
return sym;
}
} else if (vp->val)
yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized qualifier `%s'"), vp->val);
}
}
elf_objfmt_symtab_append(objfmt_elf, sym, SHN_COMMON, STB_GLOBAL,
0, STV_DEFAULT, size, &addralign);
return sym;
}
static void
dir_type(yasm_object *object, yasm_valparam *vp, unsigned long line)
dir_type(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_valparam *vp = yasm_vps_first(valparams);
yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt;
char *symname = vp->val;
/* Get symbol elf data */
@ -1116,8 +1145,10 @@ dir_type(yasm_object *object, yasm_valparam *vp, unsigned long line)
}
static void
dir_size(yasm_object *object, yasm_valparam *vp, unsigned long line)
dir_size(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_valparam *vp = yasm_vps_first(valparams);
yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt;
char *symname = vp->val;
/* Get symbol elf data */
@ -1144,8 +1175,10 @@ dir_size(yasm_object *object, yasm_valparam *vp, unsigned long line)
}
static void
dir_weak(yasm_object *object, yasm_valparam *vp, unsigned long line)
dir_weak(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_valparam *vp = yasm_vps_first(valparams);
yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt;
char *symname = vp->val;
yasm_symrec *sym = yasm_symtab_declare(object->symtab, symname,
@ -1155,11 +1188,13 @@ dir_weak(yasm_object *object, yasm_valparam *vp, unsigned long line)
}
static void
dir_ident(yasm_object *object, yasm_valparam *vp, unsigned long line)
dir_ident(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_valparamhead sect_vps;
yasm_datavalhead dvs;
yasm_section *comment;
yasm_valparam *vp = yasm_vps_first(valparams);
yasm_valparam *vp2;
/* Put ident data into .comment section */
@ -1191,40 +1226,6 @@ dir_ident(yasm_object *object, yasm_valparam *vp, unsigned long line)
yasm_bc_create_data(&dvs, 1, 1, object->arch, line));
}
static int
elf_objfmt_directive(yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
unsigned long line)
{
static const struct {
const char *name;
void (*func) (yasm_object *, yasm_valparam *, unsigned long);
} dirs[] = {
{"TYPE", dir_type},
{"SIZE", dir_size},
{"WEAK", dir_weak},
{"IDENT", dir_ident}
};
size_t i;
for (i=0; i<NELEMS(dirs); i++) {
if (yasm__strcasecmp(name, dirs[i].name) == 0) {
yasm_valparam *vp;
if (!valparams || !(vp = yasm_vps_first(valparams)) || !vp->val) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("Symbol name not specified"));
return 0;
}
dirs[i].func(object, vp, line);
return 0;
}
}
return 1; /* unrecognized */
}
/* Define valid debug formats to use with this object format */
static const char *elf_objfmt_dbgfmt_keywords[] = {
"null",
@ -1233,6 +1234,18 @@ static const char *elf_objfmt_dbgfmt_keywords[] = {
NULL
};
static const yasm_directive elf_objfmt_directives[] = {
{ ".type", "gas", dir_type, YASM_DIR_ID_REQUIRED },
{ ".size", "gas", dir_size, YASM_DIR_ID_REQUIRED },
{ ".weak", "gas", dir_weak, YASM_DIR_ID_REQUIRED },
{ ".ident", "gas", dir_ident, YASM_DIR_ARG_REQUIRED },
{ "type", "nasm", dir_type, YASM_DIR_ID_REQUIRED },
{ "size", "nasm", dir_size, YASM_DIR_ID_REQUIRED },
{ "weak", "nasm", dir_weak, YASM_DIR_ID_REQUIRED },
{ "ident", "nasm", dir_ident, YASM_DIR_ARG_REQUIRED },
{ NULL, NULL, NULL, 0 }
};
/* Define objfmt structure -- see objfmt.h for details */
yasm_objfmt_module yasm_elf_LTX_objfmt = {
"ELF",
@ -1241,15 +1254,12 @@ yasm_objfmt_module yasm_elf_LTX_objfmt = {
32,
elf_objfmt_dbgfmt_keywords,
"null",
elf_objfmt_directives,
elf_objfmt_create,
elf_objfmt_output,
elf_objfmt_destroy,
elf_objfmt_add_default_section,
elf_objfmt_section_switch,
elf_objfmt_extern_declare,
elf_objfmt_global_declare,
elf_objfmt_common_declare,
elf_objfmt_directive
elf_objfmt_section_switch
};
yasm_objfmt_module yasm_elf32_LTX_objfmt = {
@ -1259,15 +1269,12 @@ yasm_objfmt_module yasm_elf32_LTX_objfmt = {
32,
elf_objfmt_dbgfmt_keywords,
"null",
elf_objfmt_directives,
elf32_objfmt_create,
elf_objfmt_output,
elf_objfmt_destroy,
elf_objfmt_add_default_section,
elf_objfmt_section_switch,
elf_objfmt_extern_declare,
elf_objfmt_global_declare,
elf_objfmt_common_declare,
elf_objfmt_directive
elf_objfmt_section_switch
};
yasm_objfmt_module yasm_elf64_LTX_objfmt = {
@ -1277,13 +1284,10 @@ yasm_objfmt_module yasm_elf64_LTX_objfmt = {
64,
elf_objfmt_dbgfmt_keywords,
"null",
elf_objfmt_directives,
elf64_objfmt_create,
elf_objfmt_output,
elf_objfmt_destroy,
elf_objfmt_add_default_section,
elf_objfmt_section_switch,
elf_objfmt_extern_declare,
elf_objfmt_global_declare,
elf_objfmt_common_declare,
elf_objfmt_directive
elf_objfmt_section_switch
};

View file

@ -283,8 +283,6 @@ elf_symtab_entry_destroy(elf_symtab_entry *entry)
if (entry == NULL)
yasm_internal_error("symtab entry is null");
if (entry->xsize)
yasm_expr_destroy(entry->xsize);
yasm_xfree(entry);
}

View file

@ -391,7 +391,7 @@ struct elf_symtab_entry {
yasm_section *sect;
elf_strtab_entry *name;
elf_address value;
yasm_expr *xsize;
/*@dependent@*/ yasm_expr *xsize;
elf_size size;
elf_section_index index;
elf_symbol_binding bind;

View file

@ -30,7 +30,7 @@
00
00
00
b0
80
10
00
00
@ -445,37 +445,6 @@ aa
70
63
5f
65
66
66
65
63
74
69
76
65
5f
74
6f
5f
70
68
79
73
69
63
61
6c
5f
64
61
74
61
00
70
70
63
5f
77
72
69
@ -993,7 +962,6 @@ aa
00
00
00
00
01
00
00
@ -3958,7 +3926,7 @@ e9
01
00
00
00
05
00
00
00
@ -3968,9 +3936,9 @@ e9
00
10
00
04
00
00
5e
5c
01
00
00
@ -3986,7 +3954,7 @@ e9
00
04
00
7b
79
01
00
00
@ -4002,7 +3970,7 @@ e9
00
04
00
98
96
01
00
00
@ -4018,7 +3986,7 @@ e9
00
04
00
b5
b4
01
00
00
@ -4034,7 +4002,7 @@ b5
00
04
00
d3
d2
01
00
00
@ -4050,7 +4018,7 @@ d3
00
04
00
f1
f4
01
00
00
@ -4066,7 +4034,7 @@ f1
00
04
00
13
10
02
00
00
@ -4082,7 +4050,7 @@ f1
00
04
00
2f
2e
02
00
00
@ -4098,7 +4066,7 @@ f1
00
04
00
4d
4c
02
00
00
@ -4114,7 +4082,7 @@ f1
00
04
00
6b
68
02
00
00
@ -4130,7 +4098,7 @@ f1
00
04
00
87
85
02
00
00
@ -4146,7 +4114,7 @@ f1
00
04
00
a4
a2
02
00
00
@ -4162,11 +4130,11 @@ a4
00
04
00
c1
c3
02
00
00
05
00
00
00
00
@ -4182,7 +4150,7 @@ e2
02
00
00
00
05
00
00
00
@ -4194,7 +4162,7 @@ e2
00
04
00
01
03
03
00
00
@ -4210,7 +4178,7 @@ e2
00
04
00
22
14
03
00
00
@ -4226,23 +4194,7 @@ e2
00
04
00
33
03
00
00
05
00
00
00
00
00
00
00
10
00
04
00
45
26
03
00
00
@ -4370,7 +4322,7 @@ e2
00
00
00
56
37
03
00
00
@ -4406,11 +4358,11 @@ e2
00
00
00
d4
b4
03
00
00
d0
c0
0c
00
00

View file

@ -4,3 +4,8 @@ global ghidden:hidden
global ginternal:internal
global gprotected:protected
global gtoomany:hidden internal
ghidden:
ginternal:
gprotected:
gtoomany:

View file

@ -204,7 +204,7 @@ ff
00
10
02
00
04
00
0b
00
@ -220,7 +220,7 @@ ff
00
10
01
00
04
00
15
00
@ -236,7 +236,7 @@ ff
00
10
03
00
04
00
20
00
@ -252,7 +252,7 @@ ff
00
10
01
00
04
00
00
00

View file

@ -730,15 +730,15 @@ ff
2d
00
5f
5a
45
52
4f
56
41
52
00
5f
5a
45
52
4f
56
41
52
@ -870,7 +870,7 @@ c0
00
00
00
03
08
00
00
00
@ -894,7 +894,7 @@ c0
00
00
00
0c
03
00
00
00

View file

@ -293,7 +293,6 @@ typedef struct macho_section_data {
typedef struct macho_symrec_data {
/*@owned@*/ /*@null@*/ yasm_expr *size; /* size if COMMON declaration */
unsigned long index; /* index in output order */
yasm_intnum *value; /* valid after writing symtable to file */
unsigned long length; /* length + 1 (plus auto underscore) */
@ -948,13 +947,14 @@ macho_objfmt_output_symtable(yasm_symrec *sym, /*@null@*/ void *d)
scnum = -1;
/*n_desc = REFERENCE_FLAG_UNDEFINED_LAZY; * FIXME: see definition of REFERENCE_FLAG_* above */
} else if (vis & YASM_SYM_COMMON) {
yasm_expr **csize = yasm_symrec_get_common_size(sym);
n_type = N_UNDF | N_EXT;
if (symd) {
intn = yasm_expr_get_intnum(&symd->size, 1);
if (csize) {
intn = yasm_expr_get_intnum(csize, 1);
if (!intn) {
yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("COMMON data size not an integer expression"));
yasm_errwarn_propagate(info->errwarns, symd->size->line);
yasm_errwarn_propagate(info->errwarns, (*csize)->line);
} else
yasm_intnum_set_uint(val, yasm_intnum_get_uint(intn));
}
@ -1500,48 +1500,9 @@ macho_section_data_print(void *data, FILE *f, int indent_level)
fprintf(f, "%*soffset=%ld\n", indent_level, "", msd->offset);
}
static yasm_symrec *
macho_objfmt_extern_declare(yasm_object *object, const char *name, /*@unused@*/
/*@null@*/ yasm_valparamhead *objext_valparams,
unsigned long line)
{
return yasm_symtab_declare(object->symtab, name, YASM_SYM_EXTERN, line);
}
static yasm_symrec *
macho_objfmt_global_declare(yasm_object *object, const char *name, /*@unused@*/
/*@null@*/ yasm_valparamhead *objext_valparams,
unsigned long line)
{
return yasm_symtab_declare(object->symtab, name, YASM_SYM_GLOBAL, line);
}
static yasm_symrec *
macho_objfmt_common_declare(yasm_object *object, const char *name,
/*@only@*/ yasm_expr *size,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_symrec *sym;
macho_symrec_data *sym_data;
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_COMMON, line);
sym_data = yasm_xmalloc(sizeof(macho_symrec_data));
sym_data->size = size;
yasm_symrec_add_data(sym, &macho_symrec_data_cb, sym_data);
return sym;
}
static void
macho_symrec_data_destroy(void *data)
{
macho_symrec_data *csymd = (macho_symrec_data *)data;
if (csymd->size)
yasm_expr_destroy(csymd->size);
yasm_xfree(data);
}
@ -1550,12 +1511,6 @@ macho_symrec_data_print(void *data, FILE *f, int indent_level)
{
macho_symrec_data *msd = (macho_symrec_data *)data;
fprintf(f, "%*ssize=", indent_level, "");
if (msd->size)
yasm_expr_print(msd->size, f);
else
fprintf(f, "nil");
fprintf(f, "\n");
fprintf(f, "%*sindex=%ld\n", indent_level, "", msd->index);
fprintf(f, "%*svalue=", indent_level, "");
if (msd->value)
@ -1565,18 +1520,6 @@ macho_symrec_data_print(void *data, FILE *f, int indent_level)
}
static int
macho_objfmt_directive(/*@unused@*/ yasm_object *object,
/*@unused@*/ const char *name,
/*@unused@*/ /*@null@*/ yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
/*@unused@*/ unsigned long line)
{
return 1; /* no objfmt directives */
}
/* Define valid debug formats to use with this object format */
static const char *macho_objfmt_dbgfmt_keywords[] = {
"null",
@ -1591,15 +1534,12 @@ yasm_objfmt_module yasm_macho_LTX_objfmt = {
32,
macho_objfmt_dbgfmt_keywords,
"null",
NULL, /* no directives */
macho_objfmt_create,
macho_objfmt_output,
macho_objfmt_destroy,
macho_objfmt_add_default_section,
macho_objfmt_section_switch,
macho_objfmt_extern_declare,
macho_objfmt_global_declare,
macho_objfmt_common_declare,
macho_objfmt_directive
macho_objfmt_section_switch
};
yasm_objfmt_module yasm_macho32_LTX_objfmt = {
@ -1609,15 +1549,12 @@ yasm_objfmt_module yasm_macho32_LTX_objfmt = {
32,
macho_objfmt_dbgfmt_keywords,
"null",
NULL, /* no directives */
macho32_objfmt_create,
macho_objfmt_output,
macho_objfmt_destroy,
macho_objfmt_add_default_section,
macho_objfmt_section_switch,
macho_objfmt_extern_declare,
macho_objfmt_global_declare,
macho_objfmt_common_declare,
macho_objfmt_directive
macho_objfmt_section_switch
};
yasm_objfmt_module yasm_macho64_LTX_objfmt = {
@ -1627,13 +1564,10 @@ yasm_objfmt_module yasm_macho64_LTX_objfmt = {
64,
macho_objfmt_dbgfmt_keywords,
"null",
NULL, /* no directives */
macho64_objfmt_create,
macho_objfmt_output,
macho_objfmt_destroy,
macho_objfmt_add_default_section,
macho_objfmt_section_switch,
macho_objfmt_extern_declare,
macho_objfmt_global_declare,
macho_objfmt_common_declare,
macho_objfmt_directive
macho_objfmt_section_switch
};

View file

@ -100,10 +100,6 @@ typedef struct rdf_section_data {
} rdf_section_data;
typedef struct rdf_symrec_data {
/*@owned@*/ /*@null@*/ yasm_expr *size; /* size if COMMON declaration */
unsigned long align; /* alignment if COMMON declaration */
unsigned int flags; /* import/export/type flags */
unsigned int segment; /* assigned RDF "segment" index */
} rdf_symrec_data;
@ -156,16 +152,11 @@ yasm_objfmt_module yasm_rdf_LTX_objfmt;
static /*@dependent@*/ rdf_symrec_data *
rdf_objfmt_sym_set_data(yasm_symrec *sym,
/*@only@*/ /*@null@*/ yasm_expr *size,
unsigned long align, unsigned int flags)
rdf_objfmt_sym_set_data(yasm_symrec *sym, unsigned int segment)
{
rdf_symrec_data *rsymd = yasm_xmalloc(sizeof(rdf_symrec_data));
rsymd->size = size;
rsymd->align = align;
rsymd->flags = flags;
rsymd->segment = 0;
rsymd->segment = segment;
yasm_symrec_add_data(sym, &rdf_symrec_data_cb, rsymd);
return rsymd;
@ -484,6 +475,72 @@ rdf_objfmt_output_section_file(yasm_section *sect, /*@null@*/ void *d)
return 0;
}
static unsigned int
rdf_parse_flags(yasm_symrec *sym)
{
yasm_sym_vis vis = yasm_symrec_get_visibility(sym);
/*@dependent@*/ /*@null@*/ yasm_valparamhead *objext_valparams =
yasm_symrec_get_objext_valparams(sym);
yasm_valparam *vp;
unsigned int flags = 0;
static const struct {
enum {
FLAG_EXT = 1,
FLAG_GLOB = 2
} type;
enum {
FLAG_SET = 1,
FLAG_CLR = 2
} action;
const char *name;
unsigned int flags;
} flagtbl[] = {
{ FLAG_EXT|FLAG_GLOB, FLAG_SET, "data", SYM_DATA },
{ FLAG_EXT|FLAG_GLOB, FLAG_SET, "object", SYM_DATA },
{ FLAG_EXT|FLAG_GLOB, FLAG_SET, "proc", SYM_FUNCTION },
{ FLAG_EXT|FLAG_GLOB, FLAG_SET, "function", SYM_FUNCTION },
{ FLAG_EXT, FLAG_SET, "import", SYM_IMPORT },
{ FLAG_GLOB, FLAG_SET, "export", SYM_GLOBAL },
{ FLAG_EXT, FLAG_SET, "far", SYM_FAR },
{ FLAG_EXT, FLAG_CLR, "near", SYM_FAR },
};
if (!objext_valparams)
return 0;
vp = yasm_vps_first(objext_valparams);
for (; vp; vp = yasm_vps_next(vp)) {
size_t i;
int match;
if (!vp->val) {
yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized numeric qualifier"));
continue;
}
match = 0;
for (i=0; i<NELEMS(flagtbl) && !match; i++) {
if ((((vis & YASM_SYM_GLOBAL) && (flagtbl[i].type & FLAG_GLOB)) ||
((vis & YASM_SYM_EXTERN) && (flagtbl[i].type & FLAG_EXT))) &&
yasm__strcasecmp(vp->val, flagtbl[i].name) == 0) {
if (flagtbl[i].action == FLAG_SET)
flags |= flagtbl[i].flags;
else if (flagtbl[i].action == FLAG_CLR)
flags &= ~flagtbl[i].flags;
match = 1;
}
}
if (!match)
yasm_warn_set(YASM_WARN_GENERAL, N_("Unrecognized qualifier `%s'"),
vp->val);
}
return flags;
}
static int
rdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
{
@ -496,7 +553,6 @@ rdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
/*@dependent@*/ /*@null@*/ yasm_section *sect;
/*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
unsigned char *localbuf;
rdf_symrec_data *rsymd;
assert(info != NULL);
@ -521,15 +577,16 @@ rdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
} else if (yasm_section_is_absolute(sect)) {
yasm_warn_set(YASM_WARN_GENERAL,
N_("rdf does not support exporting absolutes"));
yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_line(sym));
yasm_errwarn_propagate(info->errwarns,
yasm_symrec_get_decl_line(sym));
return 0;
} else
yasm_internal_error(N_("didn't understand section"));
value = yasm_bc_next_offset(precbc);
} else if (yasm_symrec_get_equ(sym)) {
yasm_warn_set(YASM_WARN_GENERAL,
N_("rdf does not support exporting EQU/absolute values"));
yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_line(sym));
N_("rdf does not support exporting EQU/absolute values"));
yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym));
return 0;
}
@ -540,50 +597,72 @@ rdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
yasm_warn_set(YASM_WARN_GENERAL,
N_("label name too long, truncating to %d bytes"),
EXIM_LABEL_MAX);
yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_line(sym));
len = EXIM_LABEL_MAX-1;
}
localbuf = info->buf;
if (vis & YASM_SYM_GLOBAL) {
rsymd = yasm_symrec_get_data(sym, &rdf_symrec_data_cb);
if (!rsymd)
yasm_internal_error(N_("rdf: no symbol data for global symbol"));
YASM_WRITE_8(localbuf, RDFREC_GLOBAL);
YASM_WRITE_8(localbuf, 6+len+1); /* record length */
YASM_WRITE_8(localbuf, rsymd->flags); /* flags */
YASM_WRITE_8(localbuf, rdf_parse_flags(sym)); /* flags */
YASM_WRITE_8(localbuf, scnum); /* segment referred to */
YASM_WRITE_32_L(localbuf, value); /* offset */
} else {
/* Create new symrec data if it doesn't already exist */
rsymd = yasm_symrec_get_data(sym, &rdf_symrec_data_cb);
if (!rsymd)
rsymd = rdf_objfmt_sym_set_data(sym, NULL, 0, 0);
/* Save symbol segment in symrec data (for later reloc gen) */
rsymd->segment = info->indx++;
scnum = rsymd->segment;
scnum = info->indx++;
rdf_objfmt_sym_set_data(sym, scnum);
if (vis & YASM_SYM_COMMON) {
/*@dependent@*/ /*@null@*/ yasm_expr **csize_expr;
const yasm_intnum *intn;
/*@dependent@*/ /*@null@*/ yasm_valparamhead *objext_valparams =
yasm_symrec_get_objext_valparams(sym);
unsigned long addralign = 0;
YASM_WRITE_8(localbuf, RDFREC_COMMON);
YASM_WRITE_8(localbuf, 8+len+1); /* record length */
YASM_WRITE_16_L(localbuf, scnum); /* segment allocated */
/* size */
intn = yasm_expr_get_intnum(&rsymd->size, 1);
csize_expr = yasm_symrec_get_common_size(sym);
assert(csize_expr != NULL);
intn = yasm_expr_get_intnum(csize_expr, 1);
if (!intn) {
yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("COMMON data size not an integer expression"));
yasm_errwarn_propagate(info->errwarns,
yasm_symrec_get_line(sym));
} else
value = yasm_intnum_get_uint(intn);
YASM_WRITE_32_L(localbuf, value);
YASM_WRITE_16_L(localbuf, rsymd->align); /* alignment */
/* alignment */
if (objext_valparams) {
yasm_valparam *vp = yasm_vps_first(objext_valparams);
for (; vp; vp = yasm_vps_next(vp)) {
if (!vp->val && vp->param) {
/*@null@*/ const yasm_intnum *align_expr;
align_expr = yasm_expr_get_intnum(&vp->param, 0);
if (!align_expr) {
yasm_error_set(YASM_ERROR_VALUE,
N_("alignment constraint is not an integer"));
continue;
}
addralign = yasm_intnum_get_uint(align_expr);
/* Alignments must be a power of two. */
if (!is_exp2(addralign)) {
yasm_error_set(YASM_ERROR_VALUE,
N_("alignment constraint is not a power of two"));
continue;
}
} else if (vp->val)
yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized qualifier `%s'"), vp->val);
}
}
YASM_WRITE_16_L(localbuf, addralign);
} else if (vis & YASM_SYM_EXTERN) {
unsigned int flags = rsymd->flags;
unsigned int flags = rdf_parse_flags(sym);
if (flags & SYM_FAR) {
YASM_WRITE_8(localbuf, RDFREC_FARIMPORT);
flags &= ~SYM_FAR;
@ -601,6 +680,8 @@ rdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
YASM_WRITE_8(localbuf, 0); /* 0-terminated name */
fwrite(info->buf, (unsigned long)(localbuf-info->buf), 1, info->f);
yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym));
return 0;
}
@ -917,163 +998,9 @@ rdf_section_data_print(void *data, FILE *f, int indent_level)
fprintf(f, "%*ssize=%ld\n", indent_level, "", rsd->size);
}
static yasm_symrec *
rdf_objfmt_extern_declare(yasm_object *object, const char *name, /*@unused@*/
/*@null@*/ yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_symrec *sym;
unsigned int flags = 0;
static const struct {
const char *name;
unsigned int flags;
} flagnames[] = {
{ "data", SYM_DATA },
{ "object", SYM_DATA },
{ "proc", SYM_FUNCTION },
{ "function", SYM_FUNCTION },
{ "import", SYM_IMPORT },
{ "far", SYM_FAR },
};
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_EXTERN, line);
if (objext_valparams) {
yasm_valparam *vp = yasm_vps_first(objext_valparams);
for (; vp; vp = yasm_vps_next(vp)) {
size_t i;
int match;
if (!vp->val) {
yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized numeric qualifier"));
continue;
}
match = 0;
for (i=0; i<NELEMS(flagnames) && !match; i++) {
if (yasm__strcasecmp(vp->val, flagnames[i].name) == 0) {
flags |= flagnames[i].flags;
match = 1;
}
}
if (yasm__strcasecmp(vp->val, "near") == 0) {
flags &= ~SYM_FAR;
match = 1;
}
if (!match)
yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized qualifier `%s'"), vp->val);
}
}
/* Remember flags */
rdf_objfmt_sym_set_data(sym, NULL, 0, flags);
return sym;
}
static yasm_symrec *
rdf_objfmt_global_declare(yasm_object *object, const char *name, /*@unused@*/
/*@null@*/ yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_symrec *sym;
unsigned int flags = 0;
static const struct {
const char *name;
unsigned int flags;
} flagnames[] = {
{ "data", SYM_DATA },
{ "object", SYM_DATA },
{ "proc", SYM_FUNCTION },
{ "function", SYM_FUNCTION },
{ "export", SYM_GLOBAL },
};
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_GLOBAL, line);
if (objext_valparams) {
yasm_valparam *vp = yasm_vps_first(objext_valparams);
for (; vp; vp = yasm_vps_next(vp)) {
size_t i;
int match;
if (!vp->val) {
yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized numeric qualifier"));
continue;
}
match = 0;
for (i=0; i<NELEMS(flagnames) && !match; i++) {
if (yasm__strcasecmp(vp->val, flagnames[i].name) == 0) {
flags |= flagnames[i].flags;
match = 1;
}
}
if (!match)
yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized qualifier `%s'"), vp->val);
}
}
/* Remember flags */
rdf_objfmt_sym_set_data(sym, NULL, 0, flags);
return sym;
}
static yasm_symrec *
rdf_objfmt_common_declare(yasm_object *object, const char *name,
/*@only@*/ yasm_expr *size,
yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_symrec *sym;
unsigned long addralign = 0;
sym = yasm_symtab_declare(object->symtab, name, YASM_SYM_COMMON, line);
if (objext_valparams) {
yasm_valparam *vp = yasm_vps_first(objext_valparams);
for (; vp; vp = yasm_vps_next(vp)) {
if (!vp->val && vp->param) {
/*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;
align_expr = yasm_expr_get_intnum(&vp->param, 0);
if (!align_expr) {
yasm_error_set(YASM_ERROR_VALUE,
N_("alignment constraint is not an integer"));
return sym;
}
addralign = yasm_intnum_get_uint(align_expr);
/* Alignments must be a power of two. */
if (!is_exp2(addralign)) {
yasm_error_set(YASM_ERROR_VALUE,
N_("alignment constraint is not a power of two"));
return sym;
}
} else if (vp->val)
yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized qualifier `%s'"), vp->val);
}
}
/* Remember size and alignment */
rdf_objfmt_sym_set_data(sym, size, addralign, 0);
return sym;
}
static void
rdf_symrec_data_destroy(void *data)
{
rdf_symrec_data *rsymd = (rdf_symrec_data *)data;
if (rsymd->size)
yasm_expr_destroy(rsymd->size);
yasm_xfree(data);
}
@ -1083,47 +1010,17 @@ rdf_symrec_data_print(void *data, FILE *f, int indent_level)
rdf_symrec_data *rsymd = (rdf_symrec_data *)data;
fprintf(f, "%*ssymtab segment=%u\n", indent_level, "", rsymd->segment);
fprintf(f, "%*ssize=", indent_level, "");
if (rsymd->size)
yasm_expr_print(rsymd->size, f);
else
fprintf(f, "nil");
fprintf(f, "%*salign=%lu\n", indent_level, "", rsymd->align);
}
static int
rdf_objfmt_directive(yasm_object *object, const char *name,
/*@null@*/ yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams, unsigned long line)
static void
rdf_objfmt_add_libmodule(yasm_object *object, char *name, int lib)
{
yasm_objfmt_rdf *objfmt_rdf = (yasm_objfmt_rdf *)object->objfmt;
int lib;
yasm_valparam *vp;
xdf_str *str;
if (yasm__strcasecmp(name, "library") == 0)
lib = 1;
else if (yasm__strcasecmp(name, "module") == 0)
lib = 0;
else
return 1;
if (!valparams) {
yasm_error_set(YASM_ERROR_SYNTAX, N_("[%s] requires an argument"),
name);
return 0;
}
vp = yasm_vps_first(valparams);
if (!vp->val) {
yasm_error_set(YASM_ERROR_SYNTAX, N_("argument to [%s] must be name"),
name);
return 0;
}
/* Add to list */
str = yasm_xmalloc(sizeof(xdf_str));
str->str = vp->val;
str->str = name;
if (lib)
STAILQ_INSERT_TAIL(&objfmt_rdf->library_names, str, link);
else
@ -1135,11 +1032,25 @@ rdf_objfmt_directive(yasm_object *object, const char *name,
MODLIB_NAME_MAX);
str->str[MODLIB_NAME_MAX-1] = '\0';
}
vp->val = NULL; /* don't free it */
return 0;
}
static void
dir_library(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_valparam *vp = yasm_vps_first(valparams);
rdf_objfmt_add_libmodule(object, vp->val, 1);
vp->val = NULL; /* don't free it */
}
static void
dir_module(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_valparam *vp = yasm_vps_first(valparams);
rdf_objfmt_add_libmodule(object, vp->val, 0);
vp->val = NULL; /* don't free it */
}
/* Define valid debug formats to use with this object format */
static const char *rdf_objfmt_dbgfmt_keywords[] = {
@ -1147,6 +1058,12 @@ static const char *rdf_objfmt_dbgfmt_keywords[] = {
NULL
};
static const yasm_directive rdf_objfmt_directives[] = {
{ "library", "nasm", dir_library, YASM_DIR_ID_REQUIRED },
{ "module", "nasm", dir_module, YASM_DIR_ID_REQUIRED },
{ NULL, NULL, NULL, 0 }
};
/* Define objfmt structure -- see objfmt.h for details */
yasm_objfmt_module yasm_rdf_LTX_objfmt = {
"Relocatable Dynamic Object File Format (RDOFF) v2.0",
@ -1155,13 +1072,10 @@ yasm_objfmt_module yasm_rdf_LTX_objfmt = {
32,
rdf_objfmt_dbgfmt_keywords,
"null",
rdf_objfmt_directives,
rdf_objfmt_create,
rdf_objfmt_output,
rdf_objfmt_destroy,
rdf_objfmt_add_default_section,
rdf_objfmt_section_switch,
rdf_objfmt_extern_declare,
rdf_objfmt_global_declare,
rdf_objfmt_common_declare,
rdf_objfmt_directive
rdf_objfmt_section_switch
};

View file

@ -1,2 +1,2 @@
-:2: warning: rdf does not support exporting EQU/absolute values
-:4: warning: rdf does not support exporting EQU/absolute values
-:6: warning: rdf does not support exporting EQU/absolute values
-:7: warning: rdf does not support exporting EQU/absolute values

View file

@ -434,8 +434,16 @@ static int
xdf_objfmt_count_sym(yasm_symrec *sym, /*@null@*/ void *d)
{
/*@null@*/ xdf_objfmt_output_info *info = (xdf_objfmt_output_info *)d;
yasm_sym_vis vis = yasm_symrec_get_visibility(sym);
assert(info != NULL);
if (info->all_syms || yasm_symrec_get_visibility(sym) != YASM_SYM_LOCAL) {
if (vis & YASM_SYM_COMMON) {
yasm_error_set(YASM_ERROR_GENERAL,
N_("XDF object format does not support common variables"));
yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym));
return 0;
}
if (info->all_syms ||
(vis != YASM_SYM_LOCAL && !(vis & YASM_SYM_DLOCAL))) {
/* Save index in symrec data */
xdf_symrec_data *sym_data = yasm_xmalloc(sizeof(xdf_symrec_data));
sym_data->index = info->indx;
@ -813,35 +821,6 @@ xdf_section_data_print(void *data, FILE *f, int indent_level)
fprintf(f, "%*snreloc=%ld\n", indent_level, "", xsd->nreloc);
}
static yasm_symrec *
xdf_objfmt_extern_declare(yasm_object *object, const char *name, /*@unused@*/
/*@null@*/ yasm_valparamhead *objext_valparams,
unsigned long line)
{
return yasm_symtab_declare(object->symtab, name, YASM_SYM_EXTERN, line);
}
static yasm_symrec *
xdf_objfmt_global_declare(yasm_object *object, const char *name, /*@unused@*/
/*@null@*/ yasm_valparamhead *objext_valparams,
unsigned long line)
{
return yasm_symtab_declare(object->symtab, name, YASM_SYM_GLOBAL, line);
}
static yasm_symrec *
xdf_objfmt_common_declare(yasm_object *object, const char *name,
/*@only@*/ yasm_expr *size, /*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
unsigned long line)
{
yasm_expr_destroy(size);
yasm_error_set(YASM_ERROR_GENERAL,
N_("XDF object format does not support common variables"));
return yasm_symtab_declare(object->symtab, name, YASM_SYM_COMMON, line);
}
static void
xdf_symrec_data_destroy(void *data)
{
@ -856,18 +835,6 @@ xdf_symrec_data_print(void *data, FILE *f, int indent_level)
fprintf(f, "%*ssymtab index=%lu\n", indent_level, "", xsd->index);
}
static int
xdf_objfmt_directive(/*@unused@*/ yasm_object *object,
/*@unused@*/ const char *name,
/*@unused@*/ /*@null@*/ yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
/*@unused@*/ unsigned long line)
{
return 1; /* no objfmt directives */
}
/* Define valid debug formats to use with this object format */
static const char *xdf_objfmt_dbgfmt_keywords[] = {
"null",
@ -882,13 +849,10 @@ yasm_objfmt_module yasm_xdf_LTX_objfmt = {
32,
xdf_objfmt_dbgfmt_keywords,
"null",
NULL, /* no directives */
xdf_objfmt_create,
xdf_objfmt_output,
xdf_objfmt_destroy,
xdf_objfmt_add_default_section,
xdf_objfmt_section_switch,
xdf_objfmt_extern_declare,
xdf_objfmt_global_declare,
xdf_objfmt_common_declare,
xdf_objfmt_directive
xdf_objfmt_section_switch
};

View file

@ -42,8 +42,6 @@ RCSID("$Id$");
static yasm_bytecode *parse_line(yasm_parser_gas *parser_gas);
static yasm_bytecode *parse_instr(yasm_parser_gas *parser_gas);
static int parse_dirvals(yasm_parser_gas *parser_gas, yasm_valparamhead *vps);
static int parse_dirstrvals(yasm_parser_gas *parser_gas,
yasm_valparamhead *vps);
static int parse_datavals(yasm_parser_gas *parser_gas, yasm_datavalhead *dvs);
static int parse_strvals(yasm_parser_gas *parser_gas, yasm_datavalhead *dvs);
static yasm_effaddr *parse_memaddr(yasm_parser_gas *parser_gas);
@ -171,25 +169,18 @@ expect_(yasm_parser_gas *parser_gas, int token)
case DIR_COMM:
case DIR_DATA:
case DIR_ENDR:
case DIR_EXTERN:
case DIR_EQU:
case DIR_FILE:
case DIR_FILL:
case DIR_GLOBAL:
case DIR_IDENT:
case DIR_LEB128:
case DIR_LINE:
case DIR_LOC:
case DIR_LOCAL:
case DIR_LCOMM:
case DIR_ORG:
case DIR_REPT:
case DIR_SECTION:
case DIR_SECTNAME:
case DIR_SIZE:
case DIR_SKIP:
case DIR_TYPE:
case DIR_WEAK:
case DIR_ZERO:
str = "expected directive";
break;
@ -253,14 +244,18 @@ parse_line(yasm_parser_gas *parser_gas)
switch (curtok) {
case ID:
id = ID_val;
parser_gas->state = INSTDIR;
get_next_token(); /* ID */
if (curtok == ':') {
/* Label */
parser_gas->state = INITIAL;
get_next_token(); /* : */
define_label(parser_gas, id, 0);
return parse_line(parser_gas);
} else if (curtok == '=') {
/* EQU */
/* TODO: allow redefinition, assigning to . (same as .org) */
parser_gas->state = INITIAL;
get_next_token(); /* = */
e = parse_expr(parser_gas);
if (e)
@ -271,7 +266,16 @@ parse_line(yasm_parser_gas *parser_gas)
yasm_xfree(id);
return NULL;
}
/* must be an error at this point */
/* possibly a directive; try to parse it */
parse_dirvals(parser_gas, &vps);
if (!yasm_object_directive(p_object, id, "gas", &vps, NULL,
cur_line)) {
yasm_vps_delete(&vps);
yasm_xfree(id);
return NULL;
}
yasm_vps_delete(&vps);
if (id[0] == '.')
yasm_warn_set(YASM_WARN_GENERAL,
N_("directive `%s' not recognized"), id);
@ -399,13 +403,6 @@ parse_line(yasm_parser_gas *parser_gas)
yasm_xfree(ID_val);
get_next_token(); /* ID */
return NULL;
case DIR_GLOBAL:
get_next_token(); /* DIR_GLOBAL */
if (!expect(ID)) return NULL;
yasm_objfmt_global_declare(p_object, ID_val, NULL, cur_line);
yasm_xfree(ID_val);
get_next_token(); /* ID */
return NULL;
case DIR_COMM:
case DIR_LCOMM:
{
@ -441,41 +438,24 @@ parse_line(yasm_parser_gas *parser_gas)
define_lcomm(parser_gas, id, e, align);
} else if (align) {
/* Give third parameter as objext valparam */
yasm_vps_initialize(&vps);
yasm_valparamhead *extvps = yasm_vps_create();
vp = yasm_vp_create(NULL, align);
yasm_vps_append(&vps, vp);
yasm_vps_append(extvps, vp);
yasm_objfmt_common_declare(p_object, id, e, &vps, cur_line);
sym = yasm_symtab_declare(p_symtab, id, YASM_SYM_COMMON,
cur_line);
yasm_symrec_set_common_size(sym, e);
yasm_symrec_set_objext_valparams(sym, extvps);
yasm_vps_delete(&vps);
yasm_xfree(id);
} else {
yasm_objfmt_common_declare(p_object, id, e, NULL, cur_line);
sym = yasm_symtab_declare(p_symtab, id, YASM_SYM_COMMON,
cur_line);
yasm_symrec_set_common_size(sym, e);
yasm_xfree(id);
}
return NULL;
}
case DIR_EXTERN:
get_next_token(); /* DIR_EXTERN */
if (!expect(ID)) return NULL;
/* Go ahead and do it, even though all undef become extern */
yasm_objfmt_extern_declare(p_object, ID_val, NULL, cur_line);
yasm_xfree(ID_val);
get_next_token(); /* ID */
return NULL;
case DIR_WEAK:
get_next_token(); /* DIR_EXTERN */
if (!expect(ID)) return NULL;
yasm_vps_initialize(&vps);
vp = yasm_vp_create(ID_val, NULL);
yasm_vps_append(&vps, vp);
get_next_token(); /* ID */
yasm_objfmt_directive(p_object, "weak", &vps, NULL, cur_line);
yasm_vps_delete(&vps);
return NULL;
/* Integer data definition directives */
case DIR_ASCII:
@ -620,13 +600,6 @@ parse_line(yasm_parser_gas *parser_gas)
}
/* Other directives */
case DIR_IDENT:
get_next_token(); /* DIR_IDENT */
if (!parse_dirstrvals(parser_gas, &vps))
return NULL;
yasm_objfmt_directive(p_object, "ident", &vps, NULL, cur_line);
yasm_vps_delete(&vps);
return NULL;
case DIR_FILE:
get_next_token(); /* DIR_FILE */
if (curtok == STRING) {
@ -662,7 +635,8 @@ parse_line(yasm_parser_gas *parser_gas)
vp = yasm_vp_create(filename, NULL);
yasm_vps_append(&vps, vp);
yasm_dbgfmt_directive(p_object, "file", &vps, cur_line);
yasm_object_directive(p_object, ".file", "gas", &vps, NULL,
cur_line);
yasm_vps_delete(&vps);
return NULL;
@ -685,104 +659,8 @@ parse_line(yasm_parser_gas *parser_gas)
yasm_vps_append(&vps, vp);
get_next_token(); /* STRING */
yasm_dbgfmt_directive(p_object, "file", &vps, cur_line);
yasm_vps_delete(&vps);
return NULL;
case DIR_LOC:
/* INTNUM INTNUM INTNUM */
get_next_token(); /* DIR_LOC */
yasm_vps_initialize(&vps);
if (!expect(INTNUM)) return NULL;
vp = yasm_vp_create(NULL,
p_expr_new_ident(yasm_expr_int(INTNUM_val)));
yasm_vps_append(&vps, vp);
get_next_token(); /* INTNUM */
if (!expect(INTNUM)) {
yasm_vps_delete(&vps);
return NULL;
}
vp = yasm_vp_create(NULL,
p_expr_new_ident(yasm_expr_int(INTNUM_val)));
yasm_vps_append(&vps, vp);
get_next_token(); /* INTNUM */
if (!expect(INTNUM)) {
yasm_vps_delete(&vps);
return NULL;
}
vp = yasm_vp_create(NULL,
p_expr_new_ident(yasm_expr_int(INTNUM_val)));
yasm_vps_append(&vps, vp);
get_next_token(); /* INTNUM */
yasm_dbgfmt_directive(p_object, "loc", &vps, cur_line);
yasm_vps_delete(&vps);
return NULL;
case DIR_TYPE:
/* ID ',' '@' ID */
get_next_token(); /* DIR_TYPE */
yasm_vps_initialize(&vps);
if (!expect(ID)) return NULL;
vp = yasm_vp_create(ID_val, NULL);
yasm_vps_append(&vps, vp);
get_next_token(); /* ID */
if (!expect(',')) {
yasm_vps_delete(&vps);
return NULL;
}
get_next_token(); /* ',' */
if (!expect('@')) {
yasm_vps_delete(&vps);
return NULL;
}
get_next_token(); /* '@' */
if (!expect(ID)) {
yasm_vps_delete(&vps);
return NULL;
}
vp = yasm_vp_create(ID_val, NULL);
yasm_vps_append(&vps, vp);
get_next_token(); /* ID */
yasm_objfmt_directive(p_object, "type", &vps, NULL, cur_line);
yasm_vps_delete(&vps);
return NULL;
case DIR_SIZE:
/* ID ',' expr */
get_next_token(); /* DIR_SIZE */
yasm_vps_initialize(&vps);
if (!expect(ID)) return NULL;
vp = yasm_vp_create(ID_val, NULL);
yasm_vps_append(&vps, vp);
get_next_token(); /* ID */
if (!expect(',')) {
yasm_vps_delete(&vps);
return NULL;
}
get_next_token(); /* ',' */
e = parse_expr(parser_gas);
if (!e) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("expression expected for `.size'"));
yasm_vps_delete(&vps);
return NULL;
}
vp = yasm_vp_create(NULL, e);
yasm_vps_append(&vps, vp);
yasm_objfmt_directive(p_object, "size", &vps, NULL, cur_line);
yasm_object_directive(p_object, ".file", "gas", &vps, NULL,
cur_line);
yasm_vps_delete(&vps);
return NULL;
@ -863,45 +741,45 @@ parse_instr(yasm_parser_gas *parser_gas)
static int
parse_dirvals(yasm_parser_gas *parser_gas, yasm_valparamhead *vps)
{
yasm_valparam *vp;
yasm_expr *e;
yasm_valparam *vp;
int num = 0;
yasm_vps_initialize(vps);
for (;;) {
e = parse_expr(parser_gas);
vp = yasm_vp_create(NULL, e);
yasm_vps_append(vps, vp);
num++;
if (curtok != ',')
break;
get_next_token(); /* ',' */
}
return num;
}
static int
parse_dirstrvals(yasm_parser_gas *parser_gas, yasm_valparamhead *vps)
{
yasm_valparam *vp;
int num = 0;
yasm_vps_initialize(vps);
for (;;) {
if (!expect(STRING)) {
yasm_vps_delete(vps);
yasm_vps_initialize(vps);
return 0;
switch (curtok) {
case ID:
get_peek_token(parser_gas);
if (parser_gas->peek_token == ',' ||
is_eol_tok(parser_gas->peek_token)) {
/* Just an ID */
vp = yasm_vp_create(ID_val, NULL);
get_next_token(); /* ID */
} else {
e = parse_expr(parser_gas);
vp = yasm_vp_create(NULL, e);
}
break;
case STRING:
vp = yasm_vp_create(STRING_val.contents, NULL);
get_next_token(); /* STRING */
break;
case '@':
/* XXX: is throwing it away *really* the right thing? */
get_next_token(); /* @ */
continue;
default:
e = parse_expr(parser_gas);
if (!e)
return num;
vp = yasm_vp_create(NULL, e);
break;
}
vp = yasm_vp_create(STRING_val.contents, NULL);
yasm_vps_append(vps, vp);
get_next_token(); /* STRING */
num++;
if (curtok != ',')
break;
get_next_token(); /* ',' */
if (curtok == ',')
get_next_token(); /* ',' */
}
return num;
}

View file

@ -54,25 +54,18 @@ enum tokentype {
DIR_COMM,
DIR_DATA,
DIR_ENDR,
DIR_EXTERN,
DIR_EQU,
DIR_FILE,
DIR_FILL,
DIR_GLOBAL,
DIR_IDENT,
DIR_LEB128,
DIR_LINE,
DIR_LOC,
DIR_LOCAL,
DIR_LCOMM,
DIR_ORG,
DIR_REPT,
DIR_SECTION,
DIR_SECTNAME,
DIR_SIZE,
DIR_SKIP,
DIR_TYPE,
DIR_WEAK,
DIR_ZERO,
NONE
};

View file

@ -362,12 +362,8 @@ scan:
'.org' { parser_gas->state = INSTDIR; RETURN(DIR_ORG); }
/* data visibility directives */
'.local' { parser_gas->state = INSTDIR; RETURN(DIR_LOCAL); }
'.global' { parser_gas->state = INSTDIR; RETURN(DIR_GLOBAL); }
'.globl' { parser_gas->state = INSTDIR; RETURN(DIR_GLOBAL); }
'.comm' { parser_gas->state = INSTDIR; RETURN(DIR_COMM); }
'.lcomm' { parser_gas->state = INSTDIR; RETURN(DIR_LCOMM); }
'.extern' { parser_gas->state = INSTDIR; RETURN(DIR_EXTERN); }
'.weak' { parser_gas->state = INSTDIR; RETURN(DIR_WEAK); }
/* integer data declaration directives */
'.byte' {
lvalp->int_info = 1;
@ -486,26 +482,10 @@ scan:
'.fill' { parser_gas->state = INSTDIR; RETURN(DIR_FILL); }
'.zero' { parser_gas->state = INSTDIR; RETURN(DIR_ZERO); }
/* other directives */
'.code16' {
yasm_arch_set_var(p_object->arch, "mode_bits", 16);
goto scan;
}
'.code32' {
yasm_arch_set_var(p_object->arch, "mode_bits", 32);
goto scan;
}
'.code64' {
yasm_arch_set_var(p_object->arch, "mode_bits", 64);
goto scan;
}
'.equ' { parser_gas->state = INSTDIR; RETURN(DIR_EQU); }
'.file' { parser_gas->state = INSTDIR; RETURN(DIR_FILE); }
'.ident' { parser_gas->state = INSTDIR; RETURN(DIR_IDENT); }
'.line' { parser_gas->state = INSTDIR; RETURN(DIR_LINE); }
'.loc' { parser_gas->state = INSTDIR; RETURN(DIR_LOC); }
'.set' { parser_gas->state = INSTDIR; RETURN(DIR_EQU); }
'.size' { parser_gas->state = INSTDIR; RETURN(DIR_SIZE); }
'.type' { parser_gas->state = INSTDIR; RETURN(DIR_TYPE); }
/* label or maybe directive */
[_.][a-zA-Z0-9_$.]* {

View file

@ -1074,98 +1074,22 @@ fix_directive_symrec(yasm_expr__item *ei, void *d)
}
static void
dir_extern(yasm_parser_nasm *parser_nasm, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams)
dir_absolute(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_valparam *vp = yasm_vps_first(valparams);
yasm_objfmt_extern_declare(p_object, vp->val, objext_valparams, cur_line);
yasm_expr *start = yasm_vp_expr(vp, object->symtab, line);
object->cur_section = yasm_object_create_absolute(object, start, line);
}
static void
dir_global(yasm_parser_nasm *parser_nasm, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams)
dir_align(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_valparam *vp = yasm_vps_first(valparams);
yasm_objfmt_global_declare(p_object, vp->val, objext_valparams, cur_line);
}
static void
dir_common(yasm_parser_nasm *parser_nasm, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams)
{
yasm_valparam *vp = yasm_vps_first(valparams);
yasm_valparam *vp2 = yasm_vps_next(vp);
unsigned long line = cur_line;
if (!vp2 || (!vp2->val && !vp2->param)) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("no size specified in %s declaration"), "COMMON");
return;
}
if (vp2->val) {
yasm_objfmt_common_declare(p_object, vp->val,
p_expr_new_ident(yasm_expr_sym(
yasm_symtab_use(p_symtab, vp2->val, line))),
objext_valparams, line);
} else if (vp2->param) {
yasm_objfmt_common_declare(p_object, vp->val, vp2->param,
objext_valparams, line);
vp2->param = NULL;
}
}
static void
dir_section(yasm_parser_nasm *parser_nasm, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams)
{
yasm_section *new_section =
yasm_objfmt_section_switch(p_object, valparams, objext_valparams,
cur_line);
if (new_section) {
cursect = new_section;
parser_nasm->prev_bc = yasm_section_bcs_last(new_section);
} else
yasm_error_set(YASM_ERROR_SYNTAX, N_("invalid argument to [%s]"),
"SECTION");
}
static void
dir_absolute(yasm_parser_nasm *parser_nasm, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams)
{
yasm_valparam *vp = yasm_vps_first(valparams);
unsigned long line = cur_line;
/* it can be just an ID or a complete expression, so handle both. */
if (vp->val)
cursect =
yasm_object_create_absolute(p_object,
p_expr_new_ident(yasm_expr_sym(
yasm_symtab_use(p_symtab, vp->val, line))), line);
else if (vp->param) {
cursect =
yasm_object_create_absolute(p_object, vp->param, line);
vp->param = NULL;
}
parser_nasm->prev_bc = yasm_section_bcs_last(cursect);
}
static void
dir_align(yasm_parser_nasm *parser_nasm, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams)
{
/*@only@*/ yasm_expr *boundval;
yasm_expr *boundval = yasm_vp_expr(vp, object->symtab, line);
/*@depedent@*/ yasm_intnum *boundintn;
yasm_valparam *vp = yasm_vps_first(valparams);
/* it can be just an ID or a complete expression, so handle both. */
vp = yasm_vps_first(valparams);
if (vp->val)
boundval = p_expr_new_ident(yasm_expr_sym(
yasm_symtab_use(p_symtab, vp->val, cur_line)));
else if (vp->param) {
boundval = vp->param;
vp->param = NULL;
}
/* Largest .align in the section specifies section alignment.
* Note: this doesn't match NASM behavior, but is a lot more
@ -1177,43 +1101,19 @@ dir_align(yasm_parser_nasm *parser_nasm, yasm_valparamhead *valparams,
/* Alignments must be a power of two. */
if (is_exp2(boundint)) {
if (boundint > yasm_section_get_align(cursect))
yasm_section_set_align(cursect, boundint, cur_line);
if (boundint > yasm_section_get_align(object->cur_section))
yasm_section_set_align(object->cur_section, boundint, line);
}
}
/* As this directive is called only when nop is used as fill, always
* use arch (nop) fill.
*/
parser_nasm->prev_bc =
yasm_section_bcs_append(cursect,
yasm_bc_create_align(boundval, NULL, NULL,
/*yasm_section_is_code(cursect) ?*/
yasm_arch_get_fill(p_object->arch)/* : NULL*/,
cur_line));
}
static void
dir_cpu(yasm_parser_nasm *parser_nasm, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams)
{
yasm_valparam *vp;
yasm_vps_foreach(vp, valparams) {
if (vp->val)
yasm_arch_parse_cpu(p_object->arch, vp->val, strlen(vp->val));
else if (vp->param) {
const yasm_intnum *intcpu;
intcpu = yasm_expr_get_intnum(&vp->param, 0);
if (!intcpu)
yasm_error_set(YASM_ERROR_SYNTAX,
N_("invalid argument to [%s]"), "CPU");
else {
char strcpu[16];
sprintf(strcpu, "%lu", yasm_intnum_get_uint(intcpu));
yasm_arch_parse_cpu(p_object->arch, strcpu, strlen(strcpu));
}
}
}
yasm_section_bcs_append(object->cur_section,
yasm_bc_create_align(boundval, NULL, NULL,
/*yasm_section_is_code(object->cur_section) ?*/
yasm_arch_get_fill(object->arch)/* : NULL*/,
line));
}
static void
@ -1221,57 +1121,21 @@ nasm_parser_directive(yasm_parser_nasm *parser_nasm, const char *name,
yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams)
{
yasm_valparam *vp;
unsigned long line = cur_line;
static const struct {
const char *name;
unsigned int required_arg:1;
unsigned int id_only:1;
void (*func) (yasm_parser_nasm *, yasm_valparamhead *,
yasm_valparamhead *);
} dirs[] = {
{"EXTERN", 1, 1, dir_extern},
{"GLOBAL", 1, 1, dir_global},
{"COMMON", 1, 1, dir_common},
{"SECTION", 1, 0, dir_section},
{"SEGMENT", 1, 0, dir_section},
{"ABSOLUTE", 1, 0, dir_absolute},
{"ALIGN", 1, 0, dir_align},
{"CPU", 1, 0, dir_cpu}
};
size_t i;
/* Handle (mostly) output-format independent directives here */
for (i=0; i<NELEMS(dirs); i++) {
if (yasm__strcasecmp(name, dirs[i].name) == 0) {
if (dirs[i].required_arg && !valparams) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("[%s] requires an argument"), dirs[i].name);
break;
}
if (dirs[i].id_only && (vp = yasm_vps_first(valparams))
&& !vp->val) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("invalid argument to [%s]"), dirs[i].name);
break;
}
dirs[i].func(parser_nasm, valparams, objext_valparams);
break;
}
}
if (i != NELEMS(dirs)) {
if (!yasm_object_directive(p_object, name, "nasm", valparams,
objext_valparams, line))
;
} else if (!yasm_arch_parse_directive(p_object->arch, name, valparams,
objext_valparams, p_object, line)) {
;
} else if (!yasm_dbgfmt_directive(p_object, name, valparams, line)) {
;
} else if (yasm_objfmt_directive(p_object, name, valparams,
objext_valparams, line)) {
yasm_error_set(YASM_ERROR_SYNTAX, N_("unrecognized directive [%s]"),
else if (strcasecmp(name, "absolute") == 0)
dir_absolute(p_object, valparams, objext_valparams, line);
else if (strcasecmp(name, "align") == 0)
dir_align(p_object, valparams, objext_valparams, line);
else
yasm_error_set(YASM_ERROR_SYNTAX, N_("unrecognized directive `%s'"),
name);
}
/* In case cursect changed or a bytecode was added, update prev_bc. */
parser_nasm->prev_bc = yasm_section_bcs_last(cursect);
if (valparams)
yasm_vps_delete(valparams);