]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix crash when built by GNU Gold linker on x86
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 20 Jun 2017 15:48:14 +0000 (08:48 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Tue, 20 Jun 2017 16:01:43 +0000 (09:01 -0700)
Problem reported by AndrĂ©s Musetti (Bug#27248).
* src/widget.c (emacsFrameClassRec): Do not initialize superclass here.
(emacsFrameClass): Now a function (which initializes the
superclass) instead of a variable.  All uses changed.

src/unexelf.c
src/widget.c
src/widget.h
src/xfns.c

index 7fad64fab170db8f99738a68a13b979e2c739f04..5129784ade2ec9ae5d23a5f0aca2efa1e9129223 100644 (file)
@@ -576,7 +576,17 @@ unexec (const char *new_name, const char *old_name)
     }
 
   /* This loop seeks out relocation sections for the data section, so
-     that it can undo relocations performed by the runtime loader.  */
+     that it can undo relocations performed by the runtime loader.
+
+     The following approach does not work on x86 platforms that use
+     the GNU Gold linker, which can generate .rel.dyn relocation
+     sections containing R_386_32 entries that the following code does
+     not grok.  Emacs works around this problem by avoiding C
+     constructs that generate such entries, which is horrible hack.
+
+     FIXME: Presumably more problems like this will crop up as linkers
+     get fancier.  We really need to stop assuming that Emacs can grok
+     arbitrary linker output.  See Bug#27248.  */
   for (n = new_file_h->e_shnum; 0 < --n; )
     {
       ElfW (Shdr) *rel_shdr = &NEW_SECTION_H (n);
index d7ec70285171581ed760bf30e708d30bb9a9fa65..585039d58c650fd48dbef952045ed5c6c3bcb53b 100644 (file)
@@ -108,7 +108,7 @@ emacsFrameTranslations [] = "\
 
 static EmacsFrameClassRec emacsFrameClassRec = {
     { /* core fields */
-    /* superclass              */      &widgetClassRec,
+    /* superclass              */      0, /* filled in by emacsFrameClass */
     /* class_name              */      (char *) "EmacsFrame",
     /* widget_size             */      sizeof (EmacsFrameRec),
     /* class_initialize                */      0,
@@ -146,7 +146,16 @@ static EmacsFrameClassRec emacsFrameClassRec = {
     }
 };
 
-WidgetClass emacsFrameClass = (WidgetClass) &emacsFrameClassRec;
+WidgetClass
+emacsFrameClass (void)
+{
+  /* Set the superclass here rather than relying on static
+     initialization, to work around an unexelf.c bug on x86 platforms
+     that use the GNU Gold linker (Bug#27248).  */
+  emacsFrameClassRec.core_class.superclass = &widgetClassRec;
+
+  return (WidgetClass) &emacsFrameClassRec;
+}
 
 static void
 get_default_char_pixel_size (EmacsFrame ew, int *pixel_width, int *pixel_height)
index 2c5fb61df2fde54154391652e7e521951b5a702e..97dd6ab61dea6db41a93c8165393ddfe0220e645 100644 (file)
@@ -90,7 +90,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 typedef struct _EmacsFrameRec *EmacsFrame;
 typedef struct _EmacsFrameClassRec *EmacsFrameClass;
 
-extern WidgetClass emacsFrameClass;
+extern WidgetClass emacsFrameClass (void);
 
 extern struct _DisplayContext *display_context;
 
index e463391c74a220e96c7b1f108ed8b04a8d734f2d..7be2253cc3b54f779b7f94e6a8b59ea8dce7a04f 100644 (file)
@@ -2875,7 +2875,7 @@ x_window (struct frame *f, long window_prompting)
   XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
   XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
   XtSetArg (al[ac], XtNborderWidth, 0); ac++;
-  frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
+  frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass (), pane_widget,
                                 al, ac);
 
   f->output_data.x->edit_widget = frame_widget;