summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2017-06-20 08:48:14 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2017-06-20 09:01:43 -0700
commitfb45f7075afa033de27e358739cbda0107af12b2 (patch)
tree010d44c8382fd68eb13ae680d96a3cfa83aba25a /src
parent6fcbbc393eced8350f6d4679d8070bfc48244aab (diff)
downloademacs-fb45f7075afa033de27e358739cbda0107af12b2.tar.gz
emacs-fb45f7075afa033de27e358739cbda0107af12b2.tar.bz2
emacs-fb45f7075afa033de27e358739cbda0107af12b2.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/unexelf.c12
-rw-r--r--src/widget.c13
-rw-r--r--src/widget.h2
-rw-r--r--src/xfns.c2
4 files changed, 24 insertions, 5 deletions
diff --git a/src/unexelf.c b/src/unexelf.c
index 7fad64fab17..5129784ade2 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 d7ec7028517..585039d58c6 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 2c5fb61df2f..97dd6ab61de 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 e463391c74a..7be2253cc3b 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;