]> granicus.if.org Git - yasm/commitdiff
* gas-bison.y: Add support for .value alias for .2byte (GAS-x86/amd64).
authorPeter Johnson <peter@tortall.net>
Wed, 19 Oct 2005 07:44:59 +0000 (07:44 -0000)
committerPeter Johnson <peter@tortall.net>
Wed, 19 Oct 2005 07:44:59 +0000 (07:44 -0000)
This is generated by GCC in debug sections.
* gas-token.re: Likewise.

* gas-bison.y: Add support for 4th parameter on .section directive, for use
with M (SHF_MERGE) ELF section flag.
* elf-objfmt.c: Add support for M, S (SHF_STRINGS), G (SHF_GROUP), and T
(SHF_TLS) section flags.
* elf.h: Declare additional SHF_* flags.

With these changes, debug information generated by GCC in GAS format is
passed through successfully.  Should just need line number generation to
have full debugging for ELF-DWARF2 coming from GCC.

Only remaining thing to handle that I see at the moment for full GCC output
support is multiple instructions on one line (separated by semicolons).

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

modules/objfmts/elf/elf-objfmt.c
modules/objfmts/elf/elf.h
modules/parsers/gas/gas-bison.y
modules/parsers/gas/gas-token.re

index bb42a32c0b2fd2292bd3f9a3f9f11342b7b11866..f082d4773d0480e7884ecc5fa17076ed62ef30ce 100644 (file)
@@ -715,8 +715,7 @@ elf_objfmt_destroy(yasm_objfmt *objfmt)
 
 static /*@observer@*/ /*@null@*/ yasm_section *
 elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
-                         /*@unused@*/ /*@null@*/
-                         yasm_valparamhead *objext_valparams,
+                         /*@null@*/ yasm_valparamhead *objext_valparams,
                          unsigned long line)
 {
     yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt;
@@ -800,6 +799,22 @@ elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
                    case 'x':
                        flags |= SHF_EXECINSTR;
                        break;
+                   case 'M':
+                       flags |= SHF_MERGE;
+                       break;
+                   case 'S':
+                       flags |= SHF_STRINGS;
+                       break;
+                   case 'G':
+                       flags |= SHF_GROUP;
+                       break;
+                   case 'T':
+                       flags |= SHF_TLS;
+                       break;
+                   default:
+                       yasm__warning(YASM_WARN_GENERAL, line,
+                                     N_("unrecognized section attribute: `%c'"),
+                                     vp->val[i]);
                }
            }
        } else if (yasm__strcasecmp(vp->val, "progbits") == 0) {
@@ -857,6 +872,26 @@ elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
            yasm_section_bcs_first(retval), 1, line);
 
        elf_secthead_set_sym(esd, sym);
+
+       /* Handle merge entity size */
+       if (flags & SHF_MERGE) {
+           if (objext_valparams && (vp = yasm_vps_first(objext_valparams))
+               && vp->param) {
+               /*@dependent@*/ /*@null@*/ const yasm_intnum *merge_intn;
+
+               merge_intn = yasm_expr_get_intnum(&vp->param, NULL);
+               if (merge_intn)
+                   elf_secthead_set_entsize(esd,
+                                            yasm_intnum_get_uint(merge_intn));
+               else
+                   yasm__warning(YASM_WARN_GENERAL, line,
+                                 N_("invalid merge entity size"));
+           } else {
+               yasm__warning(YASM_WARN_GENERAL, line,
+                             N_("entity size for SHF_MERGE not specified"));
+               flags &= ~SHF_MERGE;
+           }
+       }
     } else if (flags_override)
        yasm__warning(YASM_WARN_GENERAL, line,
                      N_("section flags ignored on section redeclaration"));
index a78d345f9df5deab7d69cb01dbb4eb8c09e56f5f..5a7fb159ead0013b73eeb24cff283d2374da29a2 100644 (file)
@@ -151,6 +151,10 @@ typedef enum {
     SHF_WRITE = 0x1,           /* data should be writable at runtime */
     SHF_ALLOC = 0x2,           /* occupies memory at runtime */
     SHF_EXECINSTR = 0x4,       /* contains machine instructions */
+    SHF_MERGE = 0x10,          /* data can be merged */
+    SHF_STRINGS = 0x20,                /* contains 0-terminated strings */
+    SHF_GROUP = 0x200,         /* member of a section group */
+    SHF_TLS = 0x400,           /* thread local storage */
     SHF_MASKOS = 0x0f000000/*,*//* environment specific use */
     /*SHF_MASKPROC = 0xf0000000*/      /* bits reserved for processor specific needs */
 } elf_section_flags;
index af6a8dd18367f39ca2077f011b4674a928b89a74..3a883335d093a3819ffd871e64becaedae7ffdf6 100644 (file)
@@ -43,11 +43,12 @@ RCSID("$Id$");
 #include "modules/parsers/gas/gas-defs.h"
 
 static void define_label(yasm_parser_gas *parser_gas, char *name, int local);
-static yasm_section *gas_get_section(yasm_parser_gas *parser_gas, char *name,
-                                    /*@null@*/ char *flags,
-                                    /*@null@*/ char *type);
+static yasm_section *gas_get_section
+    (yasm_parser_gas *parser_gas, char *name, /*@null@*/ char *flags,
+     /*@null@*/ char *type, /*@null@*/ yasm_valparamhead *objext_valparams);
 static void gas_switch_section(yasm_parser_gas *parser_gas, char *name,
-                              /*@null@*/ char *flags, /*@null@*/ char *type);
+                              /*@null@*/ char *flags, /*@null@*/ char *type,
+                              /*@null@*/ yasm_valparamhead *objext_valparams);
 static yasm_bytecode *gas_parser_align(yasm_parser_gas *parser_gas,
                                       yasm_valparamhead *valparams,
                                       int power2);
@@ -107,8 +108,8 @@ static void gas_parser_directive
 %token DIR_BSS DIR_BYTE DIR_COMM DIR_DATA DIR_DOUBLE DIR_ENDR DIR_EXTERN
 %token DIR_EQU DIR_FILE DIR_FLOAT DIR_GLOBAL DIR_IDENT DIR_INT DIR_LOC
 %token DIR_LCOMM DIR_OCTA DIR_ORG DIR_P2ALIGN DIR_REPT DIR_SECTION
-%token DIR_SHORT DIR_SIZE DIR_SKIP DIR_SLEB128 DIR_STRING
-%token DIR_TEXT DIR_TFLOAT DIR_TYPE DIR_QUAD DIR_ULEB128 DIR_WEAK DIR_WORD
+%token DIR_SHORT DIR_SIZE DIR_SKIP DIR_SLEB128 DIR_STRING DIR_TEXT
+%token DIR_TFLOAT DIR_TYPE DIR_QUAD DIR_ULEB128 DIR_VALUE DIR_WEAK DIR_WORD
 %token DIR_ZERO
 
 %type <bc> line lineexp instr
@@ -226,7 +227,8 @@ lineexp: instr
     | DIR_LCOMM label_id ',' expr {
        /* Put into .bss section. */
        /*@dependent@*/ yasm_section *bss =
-           gas_get_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL);
+           gas_get_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL,
+                           NULL);
        /* TODO: default alignment */
        yasm_symtab_define_label(p_symtab, $2, yasm_section_bcs_last(bss), 1,
                                 cur_line);
@@ -237,7 +239,8 @@ lineexp: instr
     | DIR_LCOMM label_id ',' expr ',' expr {
        /* Put into .bss section. */
        /*@dependent@*/ yasm_section *bss =
-           gas_get_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL);
+           gas_get_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL,
+                           NULL);
        /* TODO: force alignment */
        yasm_symtab_define_label(p_symtab, $2, yasm_section_bcs_last(bss), 1,
                                 cur_line);
@@ -273,6 +276,11 @@ lineexp: instr
        $$ = gas_define_data(parser_gas, &$2, 4);
        yasm_vps_delete(&$2);
     }
+    | DIR_VALUE datavals {
+       /* XXX: At least on x86, this is two bytes */
+       $$ = gas_define_data(parser_gas, &$2, 2);
+       yasm_vps_delete(&$2);
+    }
     | DIR_2BYTE datavals {
        $$ = gas_define_data(parser_gas, &$2, 2);
        yasm_vps_delete(&$2);
@@ -335,34 +343,41 @@ lineexp: instr
     }
     /* Section directives */
     | DIR_TEXT {
-       gas_switch_section(parser_gas, yasm__xstrdup(".text"), NULL, NULL);
+       gas_switch_section(parser_gas, yasm__xstrdup(".text"), NULL, NULL,
+                          NULL);
        $$ = NULL;
     }
     | DIR_DATA {
-       gas_switch_section(parser_gas, yasm__xstrdup(".data"), NULL, NULL);
+       gas_switch_section(parser_gas, yasm__xstrdup(".data"), NULL, NULL,
+                          NULL);
        $$ = NULL;
     }
     | DIR_BSS {
-       gas_switch_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL);
+       gas_switch_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL, NULL);
        $$ = NULL;
     }
     | DIR_SECTION label_id {
-       gas_switch_section(parser_gas, $2, NULL, NULL);
+       gas_switch_section(parser_gas, $2, NULL, NULL, NULL);
        $$ = NULL;
     }
     | DIR_SECTION label_id ',' STRING {
-       gas_switch_section(parser_gas, $2, $4, NULL);
+       gas_switch_section(parser_gas, $2, $4, NULL, NULL);
        $$ = NULL;
     }
     | DIR_SECTION label_id ',' STRING ',' '@' label_id {
-       gas_switch_section(parser_gas, $2, $4, $7);
+       gas_switch_section(parser_gas, $2, $4, $7, NULL);
+       $$ = NULL;
+    }
+    | DIR_SECTION label_id ',' STRING ',' '@' label_id ',' datavals {
+       gas_switch_section(parser_gas, $2, $4, $7, &$9);
        $$ = NULL;
     }
     /* Other directives */
     | DIR_IDENT strvals {
        /* Put text into .comment section. */
        /*@dependent@*/ yasm_section *comment =
-           gas_get_section(parser_gas, yasm__xstrdup(".comment"), NULL, NULL);
+           gas_get_section(parser_gas, yasm__xstrdup(".comment"), NULL, NULL,
+                           NULL);
        /* To match GAS output, if the comment section is empty, put an
         * initial 0 byte in the section.
         */
@@ -688,7 +703,8 @@ define_label(yasm_parser_gas *parser_gas, char *name, int local)
 
 static yasm_section *
 gas_get_section(yasm_parser_gas *parser_gas, char *name,
-               /*@null@*/ char *flags, /*@null@*/ char *type)
+               /*@null@*/ char *flags, /*@null@*/ char *type,
+               /*@null@*/ yasm_valparamhead *objext_valparams)
 {
     yasm_valparamhead vps;
     yasm_valparam *vp;
@@ -713,8 +729,8 @@ gas_get_section(yasm_parser_gas *parser_gas, char *name,
        yasm_vps_append(&vps, vp);
     }
 
-    new_section = yasm_objfmt_section_switch(parser_gas->objfmt, &vps, NULL,
-                                            cur_line);
+    new_section = yasm_objfmt_section_switch(parser_gas->objfmt, &vps,
+                                            objext_valparams, cur_line);
 
     yasm_vps_delete(&vps);
     return new_section;
@@ -722,11 +738,13 @@ gas_get_section(yasm_parser_gas *parser_gas, char *name,
 
 static void
 gas_switch_section(yasm_parser_gas *parser_gas, char *name,
-                  /*@null@*/ char *flags, /*@null@*/ char *type)
+                  /*@null@*/ char *flags, /*@null@*/ char *type,
+                  /*@null@*/ yasm_valparamhead *objext_valparams)
 {
     yasm_section *new_section;
 
-    new_section = gas_get_section(parser_gas, name, flags, type);
+    new_section = gas_get_section(parser_gas, name, flags, type,
+                                 objext_valparams);
     if (new_section) {
        parser_gas->cur_section = new_section;
        parser_gas->prev_bc = yasm_section_bcs_last(new_section);
index 61edb0ed5caa6852a55a3478ed44cc945020dc91..2f5974f030c1a40df50e0ea80267546522d80a7d 100644 (file)
@@ -299,6 +299,7 @@ scan:
        '.type'         { RETURN(DIR_TYPE); }
        '.quad'         { RETURN(DIR_QUAD); }
        '.uleb128'      { RETURN(DIR_ULEB128); }
+       '.value'        { RETURN(DIR_VALUE); }
        '.weak'         { RETURN(DIR_WEAK); }
        '.word'         { RETURN(DIR_WORD); }
        '.zero'         { RETURN(DIR_ZERO); }