mirror of
https://github.com/yasm/yasm
synced 2026-08-26 22:26:05 -04:00
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:
parent
ee10323d3a
commit
decb27eaa2
45 changed files with 13019 additions and 13423 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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, \
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
139
libyasm/symrec.c
139
libyasm/symrec.c
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -4,3 +4,8 @@ global ghidden:hidden
|
|||
global ginternal:internal
|
||||
global gprotected:protected
|
||||
global gtoomany:hidden internal
|
||||
|
||||
ghidden:
|
||||
ginternal:
|
||||
gprotected:
|
||||
gtoomany:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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_$.]* {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue