diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 3efedc8..f20512a 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1346,9 +1346,11 @@ gdb1$(EXEEXT): gdb$(EXEEXT)
 # Put the proper machine-specific files first, so M-. on a machine
 # specific routine gets the one for the correct machine.  (FIXME: those
 # files go in twice; we should be removing them from the main list).
-
-# TAGS depends on all the files that go into it so you can rebuild TAGS
-# with `make TAGS' and not have to say `rm TAGS' first.
+# TAGS,DTAGS depend on all the files that go into them so they can be
+# rebuilt without having to remove them first.
+# Because more and more function comments are being moved to headers,
+# we now create a second tags file, DTAGS, which contains just the
+# headers.  See contrib/dtags.el for example code on how to use it.
 
 GDB_NM_FILE = @GDB_NM_FILE@
 TAGS: $(TAGFILES_NO_SRCDIR) $(TAGFILES_WITH_SRCDIR)
@@ -1361,7 +1363,16 @@ TAGS: $(TAGFILES_NO_SRCDIR) $(TAGFILES_WITH_SRCDIR)
 	done) | sed -e 's/\.o$$/\.c/'` \
 	`find $(srcdir)/config -name '*.h' -print`
 
-tags: TAGS
+DTAGS: $(HFILES_NO_SRCDIR) $(HFILES_WITH_SRCDIR)
+	@echo Making DTAGS
+	etags -o $@ --declarations \
+	    `(for i in $(HFILES_NO_SRCDIR); do \
+		echo $(srcdir)/$$i ; \
+	done ; for i in $(HFILES_WITH_SRCDIR); do \
+		echo $$i ; \
+	done)`
+
+tags: TAGS DTAGS
 
 clean mostlyclean: $(CONFIG_CLEAN)
 	@$(MAKE) $(FLAGS_TO_PASS) DO=clean "DODIRS=$(CLEANDIRS)" subdir_do
diff --git a/gdb/contrib/dtags.el b/gdb/contrib/dtags.el
new file mode 100644
index 0000000..a90783c
--- /dev/null
+++ b/gdb/contrib/dtags.el
@@ -0,0 +1,73 @@
+;; DTAGS support.
+;; Copyright (C) 2014 Free Software Foundation, Inc.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; DTAGS is just a variant of TAGS that contains declarations from header
+;; files for documentation purposes.  The "D" in DTAGS is for documentation,
+;; not declaration.  It's needed because more and more function comments
+;; are being moved to headers, making M-. less and less useful.
+;; The goal is to support fast lookup of a function's comment.
+;;
+;; N.B. This is just a prototype cribbed from emacs's etags.el.
+
+(defvar doc-tags-file-name nil
+  "*File name of doc tags table.
+To switch to a new doc tags table, setting this variable is sufficient.
+If you set this variable, do not also set `doc-tags-table-list'.
+Use the `etags' program to make a tags table file.")
+
+(defcustom doc-tags-table-list nil
+  "*List of file names of tags tables to search.
+An element that is a directory means the file \"TAGS\" in that directory.
+To switch to a new list of tags tables, setting this variable is sufficient.
+If you set this variable, do not also set `doc-tags-file-name'.
+Use the `etags' program to make a tags table file."
+  :group 'etags
+  :type '(repeat file))
+
+(defun find-doc-tag (tagname &optional next-p regexp-p)
+  "Find tag (in current tags table) whose name contains TAGNAME.
+Select the buffer containing the tag's definition, and move point there.
+The default for TAGNAME is the expression in the buffer around or before point.
+
+If second arg NEXT-P is t (interactively, with prefix arg), search for
+another tag that matches the last tagname or regexp used.  When there are
+multiple matches for a tag, more exact matches are found first.  If NEXT-P
+is the atom `-' (interactively, with prefix arg that is a negative number
+or just \\[negative-argument]), pop back to the previous tag gone to.
+
+If third arg REGEXP-P is non-nil, treat TAGNAME as a regexp.
+
+A marker representing the point when this command is invoked is pushed
+onto a ring and may be popped back to with \\[pop-tag-mark].
+Contrast this with the ring of marks gone to by the command.
+
+See documentation of variable `tags-file-name'."
+  ;; FIXME: Assumes using tags-file-name, and not tags-table-list.
+  (interactive (find-tag-interactive "Find doc tag: "))
+  (let ((tags-file-name doc-tags-file-name)
+	(tags-table-list doc-tags-table-list))
+    (let* ((buf (find-tag-noselect tagname next-p regexp-p))
+	   (pos (with-current-buffer buf (point))))
+      (setq doc-tags-file-name tags-file-name)
+      (setq doc-tags-table-list tags-table-list)
+      (condition-case nil
+	  (switch-to-buffer buf)
+	(error (pop-to-buffer buf)))
+      (goto-char pos))))
+
+;; TODO: visit-doc-tags-table, anything else?
+
+;;(global-set-key "\M-," 'find-doc-tag)
