]> granicus.if.org Git - yasm/commitdiff
Fix #102: Permit non-standard macho section names.
authorPeter Johnson <peter@tortall.net>
Mon, 28 May 2007 08:52:18 +0000 (08:52 -0000)
committerPeter Johnson <peter@tortall.net>
Mon, 28 May 2007 08:52:18 +0000 (08:52 -0000)
Two forms are legal ({} are replaceables):
SECTION {segname} {sectname}
SECTION {sectname} segname={segname}
Also,
SECTION {sectname}
where sectname is unrecognized is also legal, defaults segname to __TEXT,
and generates a warning.

Contributed by: bird-yasm@anduin.net

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

libyasm/valparam.c
libyasm/valparam.h
modules/objfmts/macho/macho-objfmt.c
modules/objfmts/macho/tests/nasm32/Makefile.inc
modules/objfmts/macho/tests/nasm32/macho32-sect.asm [new file with mode: 0644]
modules/objfmts/macho/tests/nasm32/macho32-sect.errwarn [new file with mode: 0644]
modules/objfmts/macho/tests/nasm32/macho32-sect.hex [new file with mode: 0644]

index 84cf984dd4c8542b7569d6d7c3d1ae394ccea2f9..752ab7e3b2c955402b590f85d59a44964c0dbf72 100644 (file)
@@ -353,6 +353,25 @@ yasm_dir_helper_intn(void *obj, yasm_valparam *vp, unsigned long line,
     return 0;
 }
 
+int
+yasm_dir_helper_string(void *obj, yasm_valparam *vp, unsigned long line,
+                       void *data, uintptr_t arg)
+{
+    /*@dependent@*/ /*@null@*/ const char *local;
+    char **s = (char **)data;
+
+    if (*s)
+        yasm_xfree(*s);
+    if (!(local = yasm_vp_string(vp))) {
+        yasm_error_set(YASM_ERROR_VALUE,
+                       N_("argument to `%s' is not a string or identifier"),
+                       vp->val);
+        return -1;
+    }
+    *s = yasm__xstrdup(local);
+    return 0;
+}
+
 int
 yasm_dir_helper_valparam_warn(void *obj, yasm_valparam *vp,
                               unsigned long line, void *data)
index 9a2a1303b5ed5a993719c9cd2cf8007fef0f5c77..4a64a66fd819d0c0b06c086db47f97bb97f2e488 100644 (file)
@@ -340,6 +340,22 @@ int yasm_dir_helper_flag_and(void *obj, yasm_valparam *vp, unsigned long line,
 int yasm_dir_helper_intn(void *obj, yasm_valparam *vp, unsigned long line,
                          void *data, uintptr_t arg);
 
+/** Standard helper for yasm_dir_helper() that parses an string (or
+ * standalone identifier) parameter.
+ * The #yasm_dir_help structure that uses this function should have
+ * needsparam=1.  The data parameter that is ultimately passed to this
+ * function (e.g. yasm_dir_helper() data parameter plus #yasm_dir_help.off)
+ * must point to a char * initialized to NULL.
+ * \param obj   unused
+ * \param vp    valparam
+ * \param line  unused
+ * \param data  pointer to char *
+ * \param arg   unused
+ * \return -1 on error, 0 otherwise.
+ */
+int yasm_dir_helper_string(void *obj, yasm_valparam *vp, unsigned long line,
+                           void *data, uintptr_t arg);
+
 /** Standard catch-all callback fro yasm_dir_helper().  Generates standard
  * warning for all valparams.
  * \param obj   unused
index 109c3f912a80d005b30390ec577659aca011eddc..830fe5d139598db9e925f114a2b1f3da1a0ec9a3 100644 (file)
@@ -281,8 +281,8 @@ typedef struct macho_reloc {
 typedef struct macho_section_data {
     /*@dependent@*/ yasm_symrec *sym; /* symbol created for this section */
     long scnum;                 /* section number (0=first section) */
-    const char *segname;        /* segment name in file */
-    const char *sectname;       /* section name in file */
+    /*@only@*/ char *segname;   /* segment name in file */
+    /*@only@*/ char *sectname;  /* section name in file */
     unsigned long flags;        /* S_* flags */
     unsigned long size;         /* size of raw data (section data) in bytes */
     unsigned long offset;       /* offset in raw data within file in bytes */
@@ -720,9 +720,13 @@ macho_objfmt_is_section_label(yasm_symrec *sym)
          * If there is not a section, leave as debugging symbol.
          */
         if (sect) {
-            if (strcmp(yasm_symrec_get_name(sym),
-                       yasm_section_get_name(sect)) == 0)
-                return 1;       /* don't store section names */
+            /*@dependent@*/ /*@null@*/ macho_section_data *msd;
+
+            msd = yasm_section_get_data(sect, &macho_section_data_cb);
+            if (msd) {
+                if (msd->sym == sym)
+                    return 1;   /* don't store section names */
+            }
         }
     }
     return 0;
@@ -872,14 +876,13 @@ macho_objfmt_output_symtable(yasm_symrec *sym, /*@null@*/ void *d)
             if (sect) {
                 /*@dependent@*/ /*@null@*/ macho_section_data *msd;
 
-                if (strcmp(yasm_symrec_get_name(sym),
-                           yasm_section_get_name(sect)) == 0) {
-                    /* don't store section names */
-                    yasm_intnum_destroy(val);
-                    return 0;
-                }
                 msd = yasm_section_get_data(sect, &macho_section_data_cb);
                 if (msd) {
+                    if (msd->sym == sym) {
+                        /* don't store section names */
+                        yasm_intnum_destroy(val);
+                        return 0;
+                    }
                     scnum = msd->scnum;
                     n_type = N_SECT;
                 } else
@@ -1249,8 +1252,8 @@ macho_objfmt_init_new_section(yasm_object *object, yasm_section *sect,
 
     data = yasm_xmalloc(sizeof(macho_section_data));
     data->scnum = objfmt_macho->parse_scnum++;
-    data->segname = "";
-    data->sectname = "";
+    data->segname = yasm__xstrdup("");
+    data->sectname = yasm__xstrdup("");
     data->flags = S_REGULAR;
     data->size = 0;
     data->nreloc = 0;
@@ -1270,11 +1273,12 @@ macho_objfmt_add_default_section(yasm_object *object)
     macho_section_data *msd;
     int isnew;
 
-    retval = yasm_object_get_general(object, ".text", 0, 0, 1, 0, &isnew, 0);
+    retval = yasm_object_get_general(object, "LC_SEGMENT.__TEXT.__text", 0, 0, 1, 0,
+                                     &isnew, 0);
     if (isnew) {
         msd = macho_objfmt_init_new_section(object, retval, ".text", 0);
-        msd->segname = "__TEXT";
-        msd->sectname = "__text";
+        msd->segname = yasm__xstrdup("__TEXT");
+        msd->sectname = yasm__xstrdup("__text");
         msd->flags = S_ATTR_PURE_INSTRUCTIONS;
         yasm_section_set_align(retval, 0, 0);
         yasm_section_set_default(retval, 1);
@@ -1291,11 +1295,12 @@ macho_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
     yasm_valparam *vp;
     yasm_section *retval;
     int isnew;
-    const char *f_segname, *f_sectname;
+    /*@only@*/ char *f_sectname;
     unsigned long flags;
     unsigned long align;
     int flags_override = 0;
     const char *sectname;
+    char *realname;
     int resonly = 0;
     macho_section_data *msd;
     size_t i;
@@ -1366,14 +1371,18 @@ macho_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
     };
 
     struct macho_section_switch_data {
+        /*@only@*/ /*@null@*/ char *f_segname;
         /*@only@*/ /*@null@*/ yasm_intnum *align_intn;
     } data;
 
     static const yasm_dir_help help[] = {
+        { "segname", 1, yasm_dir_helper_string,
+          offsetof(struct macho_section_switch_data, f_segname), 0 },
         { "align", 1, yasm_dir_helper_intn,
           offsetof(struct macho_section_switch_data, align_intn), 0 }
     };
 
+    data.f_segname = NULL;
     data.align_intn = NULL;
 
     vp = yasm_vps_first(valparams);
@@ -1389,16 +1398,38 @@ macho_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
     }
 
     if (i == NELEMS(section_name_translation)) {
-        yasm_warn_set(YASM_WARN_GENERAL,
-                      N_("Unknown section type, defaulting to .text"));
-        i = 0;
+        const char *s;
+        if (vp && !vp->val && (s = yasm_vp_string(vp))) {
+            /* Treat as SEGNAME, SECTNAME */
+            if (strlen(sectname) > 16)
+                yasm_warn_set(YASM_WARN_GENERAL,
+                    N_("segment name is too long, max 16 chars; truncating"));
+            data.f_segname = yasm__xstrndup(sectname, 16);
+            if (strlen(s) > 16)
+                yasm_warn_set(YASM_WARN_GENERAL,
+                    N_("section name is too long, max 16 chars; truncating"));
+            f_sectname = yasm__xstrndup(s, 16);
+            flags = S_REGULAR;
+            align = 0;
+
+            sectname = s;
+            vp = yasm_vps_next(vp);
+        } else {
+            data.f_segname = NULL;
+            if (strlen(sectname) > 16)
+                yasm_warn_set(YASM_WARN_GENERAL,
+                    N_("section name is too long, max 16 chars; truncating"));
+            f_sectname = yasm__xstrndup(sectname, 16);
+            flags = S_ATTR_SOME_INSTRUCTIONS;
+            align = 0;
+        }
+    } else {
+        data.f_segname = yasm__xstrdup(section_name_translation[i].seg);
+        f_sectname = yasm__xstrdup(section_name_translation[i].sect);
+        flags = section_name_translation[i].flags;
+        align = section_name_translation[i].align;
     }
 
-    f_segname = section_name_translation[i].seg;
-    f_sectname = section_name_translation[i].sect;
-    flags = section_name_translation[i].flags;
-    align = section_name_translation[i].align;
-
     flags_override = yasm_dir_helper(object, vp, line, help, NELEMS(help),
                                      &data, yasm_dir_helper_valparam_warn);
     if (flags_override < 0)
@@ -1424,8 +1455,19 @@ macho_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
         }
     }
 
-    retval = yasm_object_get_general(object, sectname, 0, align, 1, resonly,
+    if (!data.f_segname) {
+        yasm_warn_set(YASM_WARN_GENERAL,
+                      N_("Unknown section name, defaulting to __TEXT segment"));
+        data.f_segname = yasm__xstrdup("__TEXT");
+    }
+
+    /* Build a unique sectname from f_segname and f_sectname. */
+    realname = yasm_xmalloc(strlen("LC_SEGMENT") + 1 + strlen(data.f_segname) + 1 +
+                            strlen(f_sectname) + 1);
+    sprintf(realname, "LC_SEGMENT.%s.%s", data.f_segname, f_sectname);
+    retval = yasm_object_get_general(object, realname, 0, align, 1, resonly,
                                      &isnew, line);
+    yasm_xfree(realname);
 
     if (isnew)
         msd = macho_objfmt_init_new_section(object, retval, sectname, line);
@@ -1434,7 +1476,7 @@ macho_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
 
     if (isnew || yasm_section_is_default(retval)) {
         yasm_section_set_default(retval, 0);
-        msd->segname = f_segname;
+        msd->segname = data.f_segname;
         msd->sectname = f_sectname;
         msd->flags = flags;
         yasm_section_set_align(retval, align, line);
@@ -1447,6 +1489,9 @@ macho_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
 static void
 macho_section_data_destroy(void *data)
 {
+    macho_section_data *msd = (macho_section_data *) data;
+    yasm_xfree(msd->segname);
+    yasm_xfree(msd->sectname);
     yasm_xfree(data);
 }
 
index 695208fd839c4e50848a2f7030720660230fdc25..0b3a3c5b8c75bb14190122da6bdef8c4bb2b6bf7 100644 (file)
@@ -8,3 +8,6 @@ EXTRA_DIST += modules/objfmts/macho/tests/nasm32/machotest.asm
 EXTRA_DIST += modules/objfmts/macho/tests/nasm32/machotest.hex
 EXTRA_DIST += modules/objfmts/macho/tests/nasm32/macho-reloc.asm
 EXTRA_DIST += modules/objfmts/macho/tests/nasm32/macho-reloc.hex
+EXTRA_DIST += modules/objfmts/macho/tests/nasm32/macho-sect.asm
+EXTRA_DIST += modules/objfmts/macho/tests/nasm32/macho-sect.errwarn
+EXTRA_DIST += modules/objfmts/macho/tests/nasm32/macho-sect.hex
diff --git a/modules/objfmts/macho/tests/nasm32/macho32-sect.asm b/modules/objfmts/macho/tests/nasm32/macho32-sect.asm
new file mode 100644 (file)
index 0000000..b02f02a
--- /dev/null
@@ -0,0 +1,9 @@
+section .data
+section __x
+section __y segname=__Y
+section __Z, __z
+section __Y __bar
+section __reallylongname12345
+section __REALLYLONGSEGNAME __1
+section __2 __reallylongsectname
+section __2REALLYLONGSEGNAME __2reallylongsectname
diff --git a/modules/objfmts/macho/tests/nasm32/macho32-sect.errwarn b/modules/objfmts/macho/tests/nasm32/macho32-sect.errwarn
new file mode 100644 (file)
index 0000000..620e878
--- /dev/null
@@ -0,0 +1,7 @@
+-:2: warning: Unknown section name, defaulting to __TEXT segment
+-:6: warning: section name is too long, max 16 chars; truncating
+-:6: warning: Unknown section name, defaulting to __TEXT segment
+-:7: warning: segment name is too long, max 16 chars; truncating
+-:8: warning: section name is too long, max 16 chars; truncating
+-:9: warning: segment name is too long, max 16 chars; truncating
+-:9: warning: section name is too long, max 16 chars; truncating
diff --git a/modules/objfmts/macho/tests/nasm32/macho32-sect.hex b/modules/objfmts/macho/tests/nasm32/macho32-sect.hex
new file mode 100644 (file)
index 0000000..eff781a
--- /dev/null
@@ -0,0 +1,789 @@
+ce 
+fa 
+ed 
+fe 
+07 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+e0 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+e0 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+fc 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+0a 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+74 
+65 
+78 
+74 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+54 
+45 
+58 
+54 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+14 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+80 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+64 
+61 
+74 
+61 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+44 
+41 
+54 
+41 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+14 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+78 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+54 
+45 
+58 
+54 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+14 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+79 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+59 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+14 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+7a 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+5a 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+14 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+62 
+61 
+72 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+59 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+14 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+72 
+65 
+61 
+6c 
+6c 
+79 
+6c 
+6f 
+6e 
+67 
+6e 
+61 
+6d 
+65 
+5f 
+5f 
+54 
+45 
+58 
+54 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+14 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+31 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+52 
+45 
+41 
+4c 
+4c 
+59 
+4c 
+4f 
+4e 
+47 
+53 
+45 
+47 
+4e 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+14 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+72 
+65 
+61 
+6c 
+6c 
+79 
+6c 
+6f 
+6e 
+67 
+73 
+65 
+63 
+74 
+5f 
+5f 
+32 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+14 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5f 
+5f 
+32 
+72 
+65 
+61 
+6c 
+6c 
+79 
+6c 
+6f 
+6e 
+67 
+73 
+65 
+63 
+5f 
+5f 
+32 
+52 
+45 
+41 
+4c 
+4c 
+59 
+4c 
+4f 
+4e 
+47 
+53 
+45 
+47 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+14 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+18 
+00 
+00 
+00 
+fc 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+fc 
+02 
+00 
+00 
+01 
+00 
+00 
+00 
+00