]> granicus.if.org Git - yasm/commitdiff
Push down GAS .ident directive handling into objfmts. Note this makes it
authorPeter Johnson <peter@tortall.net>
Thu, 14 Dec 2006 07:39:01 +0000 (07:39 -0000)
committerPeter Johnson <peter@tortall.net>
Thu, 14 Dec 2006 07:39:01 +0000 (07:39 -0000)
such that only ELF and COFF actually handle .ident; all other object
formats silently ignore it.

In Win32/Win64, the .ident contents are dumped into the .rdata$zzz section
rather than the .comment section as in COFF and ELF; this is due to the
fact the GNU linker for Win32 is broken and puts .comment in the output
executable as a separate section, breaking the executable.  The .rdata$zzz
name matches that used by GAS to work around this same linker bug.

Reported and tracked down by: Peter Tanski <p.tanski@gmail.com>

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

modules/dbgfmts/dwarf2/tests/passwin64/dwarfwin64_testhd.hex
modules/objfmts/coff/coff-objfmt.c
modules/objfmts/elf/elf-objfmt.c
modules/parsers/gas/gas-bison.y

index 41ed7bcb88e87a0920c627582ed59e88ead17e42..dd90b3aa7e4c539421b8595255fed41130ee789d 100644 (file)
@@ -458,14 +458,14 @@ aa
 00 
 10 
 42 
-2e 
-63 
-6f 
-6d 
-6d 
-65 
-6e 
-74 
+2f 
+31 
+33 
+33 
+00 
+00 
+00 
+00 
 54 
 0b 
 00 
@@ -494,14 +494,14 @@ f4
 00 
 00 
 00 
+40 
 00 
-02 
-00 
-42 
+40 
+40 
 2f 
 31 
-33 
-33 
+34 
+34 
 00 
 00 
 00 
@@ -4449,7 +4449,7 @@ ff
 00 
 00 
 00 
-95 
+a0 
 00 
 00 
 00 
@@ -4485,7 +4485,7 @@ e8
 00 
 00 
 00 
-a3 
+ae 
 00 
 00 
 00 
@@ -4503,7 +4503,7 @@ a3
 00 
 00 
 00 
-b3 
+be 
 00 
 00 
 00 
@@ -4539,7 +4539,7 @@ b3
 00 
 00 
 00 
-bf 
+ca 
 00 
 00 
 00 
@@ -4557,7 +4557,7 @@ bf
 00 
 00 
 00 
-cd 
+d8 
 00 
 00 
 00 
@@ -4593,7 +4593,7 @@ cd
 00 
 00 
 00 
-d9 
+e4 
 00 
 00 
 00 
@@ -4629,7 +4629,7 @@ d9
 00 
 00 
 00 
-e7 
+f2 
 00 
 00 
 00 
@@ -5583,8 +5583,8 @@ e3
 00 
 00 
 00 
-f6 
-00 
+01 
+01 
 00 
 00 
 00 
@@ -5727,7 +5727,7 @@ f6
 00 
 00 
 00 
-03 
+0e 
 01 
 00 
 00 
@@ -5889,7 +5889,7 @@ f6
 00 
 00 
 00 
-0d 
+18 
 01 
 00 
 00 
@@ -5925,7 +5925,7 @@ f6
 00 
 00 
 00 
-18 
+23 
 01 
 00 
 00 
@@ -7023,7 +7023,7 @@ c0
 00 
 00 
 00 
-25 
+30 
 01 
 00 
 00 
@@ -7059,7 +7059,7 @@ c0
 00 
 00 
 00 
-35 
+40 
 01 
 00 
 00 
@@ -7095,7 +7095,7 @@ c0
 00 
 00 
 00 
-44 
+4f 
 01 
 00 
 00 
@@ -7127,14 +7127,14 @@ c0
 00 
 00 
 00 
-2e 
-63 
-6f 
-6d 
-6d 
-65 
-6e 
-74 
+00 
+00 
+00 
+00 
+5a 
+01 
+00 
+00 
 00 
 00 
 00 
@@ -7167,7 +7167,7 @@ c0
 00 
 00 
 00 
-4f 
+65 
 01 
 00 
 00 
@@ -7199,7 +7199,7 @@ c0
 00 
 00 
 00 
-5f 
+75 
 01 
 00 
 00 
@@ -7333,6 +7333,17 @@ c0
 72 
 00 
 2e 
+72 
+64 
+61 
+74 
+61 
+24 
+7a 
+7a 
+7a 
+00 
+2e 
 6e 
 6f 
 74 
@@ -7535,6 +7546,17 @@ c0
 72 
 00 
 2e 
+72 
+64 
+61 
+74 
+61 
+24 
+7a 
+7a 
+7a 
+00 
+2e 
 6e 
 6f 
 74 
index e7ae8611e77d54be6bb98a07aa29113772e435e8..9b0bb5c93be1a1a00d2b1bdef14f7781c6ff46a0 100644 (file)
@@ -1360,7 +1360,8 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
        }
        iscode = 1;
     } else if (strcmp(sectname, ".rdata") == 0
-              || strncmp(sectname, ".rodata", 7) == 0) {
+              || strncmp(sectname, ".rodata", 7) == 0
+              || strncmp(sectname, ".rdata$", 7) == 0) {
        flags = COFF_STYP_DATA;
        if (objfmt_coff->win32) {
            flags |= COFF_STYP_READ;
@@ -1695,9 +1696,9 @@ win32_objfmt_directive(yasm_objfmt *objfmt, const char *name,
                       unsigned long line)
 {
     yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt;
+    yasm_valparam *vp = yasm_vps_first(valparams);
 
     if (yasm__strcasecmp(name, "export") == 0) {
-       yasm_valparam *vp = yasm_vps_first(valparams);
        int isnew;
        yasm_section *sect;
        yasm_datavalhead dvs;
@@ -1736,6 +1737,49 @@ win32_objfmt_directive(yasm_objfmt *objfmt, const char *name,
                                                          line));
 
        return 0;
+    } else if (yasm__strcasecmp(name, "ident") == 0) {
+       yasm_valparamhead sect_vps;
+       yasm_datavalhead dvs;
+       yasm_section *comment;
+       const char *sectname;
+
+       if (objfmt_coff->win32) {
+           /* Put ident data into .comment section for COFF, or .rdata$zzz
+            * to be compatible with the GNU linker, which doesn't ignore
+            * .comment (see binutils/gas/config/obj-coff.c:476-502).
+            */
+           sectname = ".rdata$zzz";
+       } else {
+           sectname = ".comment";
+       }
+       yasm_vps_initialize(&sect_vps);
+       yasm_vps_append(&sect_vps,
+                       yasm_vp_create(yasm__xstrdup(sectname), NULL));
+       comment = coff_objfmt_section_switch(objfmt, &sect_vps, NULL, line);
+       yasm_vps_delete(&sect_vps);
+
+       /* To match GAS output, if the comment section is empty, put an
+        * initial 0 byte in the section.
+        */
+       if (yasm_section_bcs_first(comment)
+           == yasm_section_bcs_last(comment)) {
+           yasm_dvs_initialize(&dvs);
+           yasm_dvs_append(&dvs, yasm_dv_create_expr(
+               yasm_expr_create_ident(
+                   yasm_expr_int(yasm_intnum_create_uint(0)), line)));
+           yasm_section_bcs_append(comment,
+               yasm_bc_create_data(&dvs, 1, 0, objfmt_coff->arch, line));
+       }
+
+       yasm_dvs_initialize(&dvs);
+       do {
+           yasm_dvs_append(&dvs, yasm_dv_create_string(vp->val,
+                                                       strlen(vp->val)));
+           vp->val = NULL;
+       } while ((vp = yasm_vps_next(vp)));
+
+       yasm_section_bcs_append(comment,
+           yasm_bc_create_data(&dvs, 1, 1, objfmt_coff->arch, line));
     } else
        return 1;
 }
index 142e3955aeae79473ecf9f1924fc1a452e87dbe5..782fd624a2cede3954a16925f3c4ff598d83551b 100644 (file)
@@ -1170,6 +1170,40 @@ elf_objfmt_directive(yasm_objfmt *objfmt, const char *name,
                                  line);
        elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_WEAK,
                                 0, STV_DEFAULT, NULL, NULL);
+    } else if (yasm__strcasecmp(name, "ident") == 0) {
+       yasm_valparamhead sect_vps;
+       yasm_datavalhead dvs;
+       yasm_section *comment;
+
+       /* Put ident data into .comment section */
+       yasm_vps_initialize(&sect_vps);
+       yasm_vps_append(&sect_vps,
+                       yasm_vp_create(yasm__xstrdup(".comment"), NULL));
+       comment = elf_objfmt_section_switch(objfmt, &sect_vps, NULL, line);
+       yasm_vps_delete(&sect_vps);
+
+       /* To match GAS output, if the comment section is empty, put an
+        * initial 0 byte in the section.
+        */
+       if (yasm_section_bcs_first(comment)
+           == yasm_section_bcs_last(comment)) {
+           yasm_dvs_initialize(&dvs);
+           yasm_dvs_append(&dvs, yasm_dv_create_expr(
+               yasm_expr_create_ident(
+                   yasm_expr_int(yasm_intnum_create_uint(0)), line)));
+           yasm_section_bcs_append(comment,
+               yasm_bc_create_data(&dvs, 1, 0, objfmt_elf->arch, line));
+       }
+
+       yasm_dvs_initialize(&dvs);
+       do {
+           yasm_dvs_append(&dvs, yasm_dv_create_string(vp->val,
+                                                       strlen(vp->val)));
+           vp->val = NULL;
+       } while ((vp = yasm_vps_next(vp)));
+
+       yasm_section_bcs_append(comment,
+           yasm_bc_create_data(&dvs, 1, 1, objfmt_elf->arch, line));
     } else
        return 1;       /* unrecognized */
 
index 0f63627025736e72e5b962b7e46e0a91f7d48f61..d9bfc4c3a7b1c6493c464f1aac4291736897cf05 100644 (file)
@@ -129,7 +129,7 @@ static void gas_parser_directive
 %type <ea> memaddr
 %type <exp> expr regmemexpr
 %type <sym> explabel
-%type <valparams> dirvals dirvals2
+%type <valparams> dirvals dirvals2 dirstrvals dirstrvals2
 %type <datavals> strvals datavals strvals2 datavals2
 %type <insn_operands> operands
 %type <insn_operand> operand
@@ -460,30 +460,10 @@ lineexp: instr
        $$ = 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,
-                           NULL, 1);
-       if (comment) {
-           /* To match GAS output, if the comment section is empty, put an
-            * initial 0 byte in the section.
-            */
-           if (yasm_section_bcs_first(comment)
-               == yasm_section_bcs_last(comment)) {
-               yasm_datavalhead dvs;
-
-               yasm_dvs_initialize(&dvs);
-               yasm_dvs_append(&dvs, yasm_dv_create_expr(
-                   p_expr_new_ident(yasm_expr_int(
-                       yasm_intnum_create_uint(0)))));
-               yasm_section_bcs_append(comment,
-                   yasm_bc_create_data(&dvs, 1, 0, parser_gas->arch,
-                                       cur_line));
-           }
-           yasm_section_bcs_append(comment,
-               yasm_bc_create_data(&$2, 1, 1, parser_gas->arch, cur_line));
-       }
+    | DIR_IDENT dirstrvals {
+       yasm_objfmt_directive(parser_gas->objfmt, "ident", &$2, NULL,
+                             cur_line);
+       yasm_vps_delete(&$2);
        $$ = NULL;
     }
     | DIR_FILE INTNUM STRING {
@@ -693,6 +673,22 @@ dirvals2: expr                     {
     }
 ;
 
+dirstrvals: /* empty */        { yasm_vps_initialize(&$$); }
+    | dirstrvals2
+;
+
+dirstrvals2: STRING    {
+       yasm_valparam *vp = yasm_vp_create($1.contents, NULL);
+       yasm_vps_initialize(&$$);
+       yasm_vps_append(&$$, vp);
+    }
+    | dirstrvals2 ',' STRING   {
+       yasm_valparam *vp = yasm_vp_create($3.contents, NULL);
+       yasm_vps_append(&$1, vp);
+       $$ = $1;
+    }
+;
+
 strvals: /* empty */   { yasm_dvs_initialize(&$$); }
     | strvals2
 ;