]> granicus.if.org Git - yasm/commitdiff
Enable use of sym@FOO constructs in GAS parser.
authorPeter Johnson <peter@tortall.net>
Sat, 9 Feb 2008 03:35:07 +0000 (03:35 -0000)
committerPeter Johnson <peter@tortall.net>
Sat, 9 Feb 2008 03:35:07 +0000 (03:35 -0000)
To do this, restructure how special symbols are handled between the parser
and object format.  Instead of creating special symbols with the right
names, instead have the parser call the object format to see if a match
is found into the special symbols, which are no longer stored in the
symbol table.

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

13 files changed:
libyasm/objfmt.h
modules/objfmts/bin/bin-objfmt.c
modules/objfmts/coff/coff-objfmt.c
modules/objfmts/dbg/dbg-objfmt.c
modules/objfmts/elf/elf-objfmt.c
modules/objfmts/elf/elf.c
modules/objfmts/elf/elf.h
modules/objfmts/macho/macho-objfmt.c
modules/objfmts/rdf/rdf-objfmt.c
modules/objfmts/xdf/xdf-objfmt.c
modules/parsers/gas/gas-parse.c
modules/parsers/nasm/nasm-parse.c
modules/parsers/nasm/nasm-token.re

index afde85ebaa57ef75aca5ed9be61cf57d2a1f7482..0c40c4a3cfcd01738e53b695ae97f4d8cf31e0d3 100644 (file)
@@ -109,6 +109,13 @@ 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_get_special_sym().
+     * Call yasm_objfmt_get_special_sym() instead of calling this function.
+     */
+    /*@observer@*/ /*@null@*/ yasm_symrec *
+        (*get_special_sym)(yasm_object *object, const char *name,
+                           const char *parser);
 };
 
 /** Create object format.
@@ -156,6 +163,16 @@ yasm_section *yasm_objfmt_add_default_section(yasm_object *object);
     (yasm_object *object, yasm_valparamhead *valparams,
      /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line);
 
+/** Get a special symbol.  Special symbols are generally used to generate
+ * special relocation types via the WRT mechanism.
+ * \param object        object
+ * \param name          symbol name (not including any parser-specific prefix)
+ * \param parser        parser keyword
+ * \return NULL if unrecognized, otherwise special symbol.
+ */
+/*@observer@*/ /*@null@*/ yasm_symrec *yasm_objfmt_get_special_sym
+    (yasm_object *object, const char *name, const char *parser);
+
 #ifndef YASM_DOXYGEN
 
 /* Inline macro implementations for objfmt functions */
@@ -173,6 +190,9 @@ yasm_section *yasm_objfmt_add_default_section(yasm_object *object);
 #define yasm_objfmt_add_default_section(object) \
     ((yasm_objfmt_base *)((object)->objfmt))->module->add_default_section \
         (object)
+#define yasm_objfmt_get_special_sym(object, name, parser) \
+    ((yasm_objfmt_base *)((object)->objfmt))->module->get_special_sym \
+        (object, name, parser)
 
 #endif
 
index cb3c5b13dcfbc2c14a2947ec675fce9914e3dd10..e108076081c39b0d99efb41aa8ad8f0f567fd763 100644 (file)
@@ -1568,6 +1568,13 @@ bin_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
     return retval;
 }
 
+static /*@observer@*/ /*@null@*/ yasm_symrec *
+bin_objfmt_get_special_sym(yasm_object *object, const char *name,
+                           const char *parser)
+{
+    return NULL;
+}
+
 static void
 bin_objfmt_dir_org(yasm_object *object,
                    /*@null@*/ yasm_valparamhead *valparams,
@@ -1777,5 +1784,6 @@ yasm_objfmt_module yasm_bin_LTX_objfmt = {
     bin_objfmt_output,
     bin_objfmt_destroy,
     bin_objfmt_add_default_section,
-    bin_objfmt_section_switch
+    bin_objfmt_section_switch,
+    bin_objfmt_get_special_sym
 };
index 64805610c9343cb1b71cdb344c0595bdbb1734d4..300b37691341b44ae526a88a33ed3fb661c65bf2 100644 (file)
@@ -1579,6 +1579,13 @@ coff_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
     return retval;
 }
 
+static /*@observer@*/ /*@null@*/ yasm_symrec *
+coff_objfmt_get_special_sym(yasm_object *object, const char *name,
+                            const char *parser)
+{
+    return NULL;
+}
+
 static void
 coff_section_data_destroy(void *data)
 {
@@ -2189,7 +2196,8 @@ yasm_objfmt_module yasm_coff_LTX_objfmt = {
     coff_objfmt_output,
     coff_objfmt_destroy,
     coff_objfmt_add_default_section,
-    coff_objfmt_section_switch
+    coff_objfmt_section_switch,
+    coff_objfmt_get_special_sym
 };
 
 /* Define valid debug formats to use with this object format */
@@ -2222,7 +2230,8 @@ yasm_objfmt_module yasm_win32_LTX_objfmt = {
     coff_objfmt_output,
     coff_objfmt_destroy,
     coff_objfmt_add_default_section,
-    coff_objfmt_section_switch
+    coff_objfmt_section_switch,
+    coff_objfmt_get_special_sym
 };
 
 static const yasm_directive win64_objfmt_directives[] = {
@@ -2255,7 +2264,8 @@ yasm_objfmt_module yasm_win64_LTX_objfmt = {
     coff_objfmt_output,
     coff_objfmt_destroy,
     coff_objfmt_add_default_section,
-    coff_objfmt_section_switch
+    coff_objfmt_section_switch,
+    coff_objfmt_get_special_sym
 };
 yasm_objfmt_module yasm_x64_LTX_objfmt = {
     "Win64",
@@ -2269,5 +2279,6 @@ yasm_objfmt_module yasm_x64_LTX_objfmt = {
     coff_objfmt_output,
     coff_objfmt_destroy,
     coff_objfmt_add_default_section,
-    coff_objfmt_section_switch
+    coff_objfmt_section_switch,
+    coff_objfmt_get_special_sym
 };
index 998dc4f2358a7596976d89376a73f4a7a6767f73..21a161abfe4bdfc245b5c56b65652a753847ab71 100644 (file)
@@ -140,6 +140,16 @@ dbg_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
     return retval;
 }
 
+static /*@observer@*/ /*@null@*/ yasm_symrec *
+dbg_objfmt_get_special_sym(yasm_object *object, const char *name,
+                           const char *parser)
+{
+    yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)object->objfmt;
+    fprintf(objfmt_dbg->dbgfile, "get_special_sym(object, \"%s\", \"%s\")\n",
+            name, parser);
+    return NULL;
+}
+
 /* Define valid debug formats to use with this object format */
 static const char *dbg_objfmt_dbgfmt_keywords[] = {
     "null",
@@ -159,5 +169,6 @@ yasm_objfmt_module yasm_dbg_LTX_objfmt = {
     dbg_objfmt_output,
     dbg_objfmt_destroy,
     dbg_objfmt_add_default_section,
-    dbg_objfmt_section_switch
+    dbg_objfmt_section_switch,
+    dbg_objfmt_get_special_sym
 };
index 66fb6c56022600fd29b3fa092eb38739aa31c540..c2464d770e410bc34ca63bb26d42b7596a62e334 100644 (file)
@@ -1142,6 +1142,13 @@ elf_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
     return retval;
 }
 
+static /*@observer@*/ /*@null@*/ yasm_symrec *
+elf_objfmt_get_special_sym(yasm_object *object, const char *name,
+                           const char *parser)
+{
+    return elf_get_special_sym(name, parser);
+}
+
 static void
 dir_type(yasm_object *object, yasm_valparamhead *valparams,
          yasm_valparamhead *objext_valparams, unsigned long line)
@@ -1301,7 +1308,8 @@ yasm_objfmt_module yasm_elf_LTX_objfmt = {
     elf_objfmt_output,
     elf_objfmt_destroy,
     elf_objfmt_add_default_section,
-    elf_objfmt_section_switch
+    elf_objfmt_section_switch,
+    elf_objfmt_get_special_sym
 };
 
 yasm_objfmt_module yasm_elf32_LTX_objfmt = {
@@ -1316,7 +1324,8 @@ yasm_objfmt_module yasm_elf32_LTX_objfmt = {
     elf_objfmt_output,
     elf_objfmt_destroy,
     elf_objfmt_add_default_section,
-    elf_objfmt_section_switch
+    elf_objfmt_section_switch,
+    elf_objfmt_get_special_sym
 };
 
 yasm_objfmt_module yasm_elf64_LTX_objfmt = {
@@ -1331,5 +1340,6 @@ yasm_objfmt_module yasm_elf64_LTX_objfmt = {
     elf_objfmt_output,
     elf_objfmt_destroy,
     elf_objfmt_add_default_section,
-    elf_objfmt_section_switch
+    elf_objfmt_section_switch,
+    elf_objfmt_get_special_sym
 };
index 87ee9828959a3a3c9e7e7bc08dd0b1d254e5cc81..807a3afe1267035719373962dbc3361721b4eeed 100644 (file)
@@ -91,13 +91,24 @@ elf_set_arch(yasm_arch *arch, yasm_symtab *symtab, int bits_pref)
             /* FIXME: misuse of NULL bytecode */
             elf_ssyms[i] = yasm_symtab_define_label(symtab,
                                                     elf_march->ssyms[i].name,
-                                                    NULL, 1, 0);
+                                                    NULL, 0, 0);
         }
     }
 
     return elf_march;
 }
 
+yasm_symrec *
+elf_get_special_sym(const char *name, const char *parser)
+{
+    int i;
+    for (i=0; (unsigned int)i<elf_march->num_ssyms; i++) {
+        if (yasm__strcasecmp(name, elf_march->ssyms[i].name) == 0)
+            return elf_ssyms[i];
+    }
+    return NULL;
+}
+
 /* reloc functions */
 int elf_ssym_has_flag(yasm_symrec *wrt, int flag);
 
index 954e052e39bdeb4a708f028cc37b3e44d2b80dc8..a10b0b4918bb47948b062a705b0473b7b405e14e 100644 (file)
@@ -410,6 +410,8 @@ const elf_machine_handler *elf_set_arch(struct yasm_arch *arch,
                                         yasm_symtab *symtab,
                                         int bits_pref);
 
+yasm_symrec *elf_get_special_sym(const char *name, const char *parser);
+
 /* reloc functions */
 int elf_is_wrt_sym_relative(yasm_symrec *wrt);
 int elf_is_wrt_pos_adjusted(yasm_symrec *wrt);
index 893ef0db414dcab94c620ff1881035c0d1e68806..4628bf74ad1912d44dac8a619276c01d7fb5755d 100644 (file)
@@ -1485,6 +1485,13 @@ macho_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
     return retval;
 }
 
+static /*@observer@*/ /*@null@*/ yasm_symrec *
+macho_objfmt_get_special_sym(yasm_object *object, const char *name,
+                             const char *parser)
+{
+    return NULL;
+}
+
 static void
 macho_section_data_destroy(void *data)
 {
@@ -1548,7 +1555,8 @@ yasm_objfmt_module yasm_macho_LTX_objfmt = {
     macho_objfmt_output,
     macho_objfmt_destroy,
     macho_objfmt_add_default_section,
-    macho_objfmt_section_switch
+    macho_objfmt_section_switch,
+    macho_objfmt_get_special_sym
 };
 
 yasm_objfmt_module yasm_macho32_LTX_objfmt = {
@@ -1563,7 +1571,8 @@ yasm_objfmt_module yasm_macho32_LTX_objfmt = {
     macho_objfmt_output,
     macho_objfmt_destroy,
     macho_objfmt_add_default_section,
-    macho_objfmt_section_switch
+    macho_objfmt_section_switch,
+    macho_objfmt_get_special_sym
 };
 
 yasm_objfmt_module yasm_macho64_LTX_objfmt = {
@@ -1578,5 +1587,6 @@ yasm_objfmt_module yasm_macho64_LTX_objfmt = {
     macho_objfmt_output,
     macho_objfmt_destroy,
     macho_objfmt_add_default_section,
-    macho_objfmt_section_switch
+    macho_objfmt_section_switch,
+    macho_objfmt_get_special_sym
 };
index 46a5a8c860e6a64cb1a9ccbde8c583494bb7fae7..22e2a1c7cd20f68bc2a34eb755567730c900f776 100644 (file)
@@ -964,6 +964,13 @@ rdf_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
     return retval;
 }
 
+static /*@observer@*/ /*@null@*/ yasm_symrec *
+rdf_objfmt_get_special_sym(yasm_object *object, const char *name,
+                           const char *parser)
+{
+    return NULL;
+}
+
 static void
 rdf_section_data_destroy(void *data)
 {
@@ -1063,5 +1070,6 @@ yasm_objfmt_module yasm_rdf_LTX_objfmt = {
     rdf_objfmt_output,
     rdf_objfmt_destroy,
     rdf_objfmt_add_default_section,
-    rdf_objfmt_section_switch
+    rdf_objfmt_section_switch,
+    rdf_objfmt_get_special_sym
 };
index a68dc0bff20dc16a5f175259439fab9b372ea3b7..d7cb453b1ed7553261c274402be32e08f1b4e9f5 100644 (file)
@@ -773,6 +773,13 @@ xdf_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
     return retval;
 }
 
+static /*@observer@*/ /*@null@*/ yasm_symrec *
+xdf_objfmt_get_special_sym(yasm_object *object, const char *name,
+                           const char *parser)
+{
+    return NULL;
+}
+
 static void
 xdf_section_data_destroy(void *data)
 {
@@ -836,5 +843,6 @@ yasm_objfmt_module yasm_xdf_LTX_objfmt = {
     xdf_objfmt_output,
     xdf_objfmt_destroy,
     xdf_objfmt_add_default_section,
-    xdf_objfmt_section_switch
+    xdf_objfmt_section_switch,
+    xdf_objfmt_get_special_sym
 };
index 2c402f15b9a734dafde1125f2d41e3a8a591854b..583e39e0a4ab2ec04339edf219d324c3c4577042 100644 (file)
@@ -1347,7 +1347,17 @@ parse_expr2(yasm_parser_gas *parser_gas)
         {
             char *name = ID_val;
             get_next_token(); /* ID */
+
+            /* "." references the current assembly position */
+            if (name[1] == '\0' && name[0] == '.')
+                sym = yasm_symtab_define_curpos(p_symtab, ".",
+                                                parser_gas->prev_bc, cur_line);
+            else
+                sym = yasm_symtab_use(p_symtab, name, cur_line);
+            yasm_xfree(name);
+
             if (curtok == '@') {
+                yasm_symrec *wrt;
                 /* TODO: this is needed for shared objects, e.g. sym@PLT */
                 get_next_token(); /* '@' */
                 if (!expect(ID)) {
@@ -1356,20 +1366,18 @@ parse_expr2(yasm_parser_gas *parser_gas)
                     yasm_xfree(name);
                     return NULL;
                 }
+                wrt = yasm_objfmt_get_special_sym(p_object, ID_val, "gas");
                 yasm_xfree(ID_val);
                 get_next_token(); /* ID */
-                sym = yasm_symtab_use(p_symtab, name, cur_line);
-                yasm_xfree(name);
-                return p_expr_new_ident(yasm_expr_sym(sym));
+                if (!wrt) {
+                    yasm_warn_set(YASM_WARN_GENERAL,
+                                  N_("unrecognized identifier after `@'"));
+                    return p_expr_new_ident(yasm_expr_sym(sym));
+                }
+                return p_expr_new(yasm_expr_sym(sym), YASM_EXPR_WRT,
+                                  yasm_expr_sym(wrt));
             }
 
-            /* "." references the current assembly position */
-            if (name[1] == '\0' && name[0] == '.')
-                sym = yasm_symtab_define_curpos(p_symtab, ".",
-                                                parser_gas->prev_bc, cur_line);
-            else
-                sym = yasm_symtab_use(p_symtab, name, cur_line);
-            yasm_xfree(name);
             return p_expr_new_ident(yasm_expr_sym(sym));
         }
         default:
index 88d2297bba84c383962f9b0c43ceb4d5de1cb41f..02a64121c2d18b2fd7d4761b10136389839f730c 100644 (file)
@@ -1133,8 +1133,15 @@ parse_expr6(yasm_parser_nasm *parser_nasm, expr_type type)
                 yasm_intnum_create_charconst_nasm(STRING_val.contents)));
             yasm_xfree(STRING_val.contents);
             break;
-        case ID:
         case SPECIAL_ID:
+            sym = yasm_objfmt_get_special_sym(p_object, ID_val+2, "nasm");
+            if (sym) {
+                e = p_expr_new_ident(yasm_expr_sym(sym));
+                yasm_xfree(ID_val);
+                break;
+            }
+            /*@fallthrough@*/
+        case ID:
         case LOCAL_ID:
             sym = yasm_symtab_use(p_symtab, ID_val, cur_line);
             e = p_expr_new_ident(yasm_expr_sym(sym));
index 35de7924b6130fc34fdab20a9caa19132059931b..453744be6a283e579af9025f99944ace5644b882 100644 (file)
@@ -286,8 +286,14 @@ scan:
         [-+|^*&/%~$():=,\[]     { RETURN(s->tok[0]); }
         "]"                     { RETURN(s->tok[0]); }
 
-        /* special non-local ..@label and labels like ..start */
-        ".." [a-zA-Z0-9_$#@~.?]+ {
+        /* special non-local ..@label */
+        "..@" [a-zA-Z0-9_$#@~.?]+ {
+            lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
+            RETURN(ID);
+        }
+
+        /* special non-local labels like ..start */
+        ".." [a-zA-Z0-9_$#~.?]+ {
             lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
             RETURN(SPECIAL_ID);
         }