emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master fb45f70: Fix crash when built by GNU Gold linker on


From: Paul Eggert
Subject: [Emacs-diffs] master fb45f70: Fix crash when built by GNU Gold linker on x86
Date: Tue, 20 Jun 2017 12:01:49 -0400 (EDT)

branch: master
commit fb45f7075afa033de27e358739cbda0107af12b2
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    Fix crash when built by GNU Gold linker on x86
    
    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 | 12 +++++++++++-
 src/widget.c  | 13 +++++++++++--
 src/widget.h  |  2 +-
 src/xfns.c    |  2 +-
 4 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/src/unexelf.c b/src/unexelf.c
index 7fad64f..5129784 100644
--- a/src/unexelf.c
+++ b/src/unexelf.c
@@ -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);
diff --git a/src/widget.c b/src/widget.c
index d7ec702..585039d 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -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)
diff --git a/src/widget.h b/src/widget.h
index 2c5fb61..97dd6ab 100644
--- a/src/widget.h
+++ b/src/widget.h
@@ -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;
 
diff --git a/src/xfns.c b/src/xfns.c
index e463391..7be2253 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -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;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]