diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6e4b285077..20df6c9ef5 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,4 +1,32 @@
 2018-01-05  Tom Tromey  <tom@tromey.com>
+	    Simon Marchi  <simon.marchi@ericsson.com>
+
+	* dwarf2read.c (struct dwarf2_cu) <abbrev_table>: Remove.
+	(struct die_reader_specs) <abbrev_table>: New member.
+	(struct abbrev_table): Add constructor.
+	<alloc_abbrev, add_abbrev, lookup_abbrev>: Declare.
+	<abbrev_obstack>: Now an auto_obstack.
+	(abbrev_table_up): New typedef.
+	(init_cu_die_reader): Add abbrev_table parameter.
+	(read_cutu_die_from_dwo): Remove abbrev_table_provided parameter.
+	Add result_dwo_abbrev_table.
+	(init_tu_and_read_dwo_dies, init_cutu_and_read_dies)
+	(init_cutu_and_read_dies_no_follow, build_type_psymtabs_1):
+	Update.
+	(peek_die_abbrev): Take die_reader_specs, not dwarf_cu as
+	parameter.
+	(skip_children): Update.
+	(abbrev_table::alloc_abbrev): Rename from
+	abbrev_table_alloc_abbrev.
+	(abbrev_table::add_abbrev): Rename from abbrev_table_add_abbrev.
+	(abbrev_table::lookup_abbrev): Rename from
+	abbrev_table_lookup_abbrev.
+	(abbrev_table_read_table): Return abbrev_table_up.
+	(abbrev_table_free, abbrev_table_free_cleanup)
+	(dwarf2_read_abbrevs, dwarf2_free_abbrev_table): Remove.
+	(load_partial_dies): Update.
+
+2018-01-05  Tom Tromey  <tom@tromey.com>
 
 	* dwarf2read.c (dwarf2_compute_name): Update comment.
 	(read_func_scope, read_variable): Update.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 45f7feecde..d278aeb30d 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -687,11 +687,6 @@ struct dwarf2_cu
      distinguish these in buildsym.c.  */
   struct pending **list_in_scope;
 
-  /* The abbrev table for this CU.
-     Normally this points to the abbrev table in the objfile.
-     But if DWO_UNIT is non-NULL this is the abbrev table in the DWO file.  */
-  struct abbrev_table *abbrev_table;
-
   /* Hash table holding all the loaded partial DIEs
      with partial_die->offset.SECT_OFF as hash.  */
   htab_t partial_dies;
@@ -1258,6 +1253,9 @@ struct die_reader_specs
 
   /* The value of the DW_AT_comp_dir attribute.  */
   const char *comp_dir;
+
+  /* The abbreviation table to use when reading the DIEs.  */
+  struct abbrev_table *abbrev_table;
 };
 
 /* Type of function passed to init_cutu_and_read_dies, et.al.  */
@@ -1514,12 +1512,35 @@ struct attr_abbrev
 
 struct abbrev_table
 {
+  abbrev_table (sect_offset off)
+    : sect_off (off)
+  {
+    abbrevs =
+      XOBNEWVEC (&abbrev_obstack, struct abbrev_info *, ABBREV_HASH_SIZE);
+    memset (abbrevs, 0, ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
+  }
+
+  DISABLE_COPY_AND_ASSIGN (abbrev_table);
+
+  /* Allocate space for a struct abbrev_info object in
+     ABBREV_TABLE.  */
+  struct abbrev_info *alloc_abbrev ();
+
+  /* Add an abbreviation to the table.  */
+  void add_abbrev (unsigned int abbrev_number, struct abbrev_info *abbrev);
+
+  /* Look up an abbrev in the table.
+     Returns NULL if the abbrev is not found.  */
+
+  struct abbrev_info *lookup_abbrev (unsigned int abbrev_number);
+
+
   /* Where the abbrev table came from.
      This is used as a sanity check when the table is used.  */
   sect_offset sect_off;
 
   /* Storage for the abbrev table.  */
-  struct obstack abbrev_obstack;
+  auto_obstack abbrev_obstack;
 
   /* Hash table of abbrevs.
      This is an array of size ABBREV_HASH_SIZE allocated in abbrev_obstack.
@@ -1528,6 +1549,8 @@ struct abbrev_table
   struct abbrev_info **abbrevs;
 };
 
+typedef std::unique_ptr<struct abbrev_table> abbrev_table_up;
+
 /* Attributes have a name and a value.  */
 struct attribute
   {
@@ -1757,22 +1780,10 @@ static void dwarf2_read_symtab (struct partial_symtab *,
 
 static void psymtab_to_symtab_1 (struct partial_symtab *);
 
-static struct abbrev_info *abbrev_table_lookup_abbrev
-  (const struct abbrev_table *, unsigned int);
-
-static struct abbrev_table *abbrev_table_read_table
+static abbrev_table_up abbrev_table_read_table
   (struct dwarf2_per_objfile *dwarf2_per_objfile, struct dwarf2_section_info *,
    sect_offset);
 
-static void abbrev_table_free (struct abbrev_table *);
-
-static void abbrev_table_free_cleanup (void *);
-
-static void dwarf2_read_abbrevs (struct dwarf2_cu *,
-				 struct dwarf2_section_info *);
-
-static void dwarf2_free_abbrev_table (void *);
-
 static unsigned int peek_abbrev_code (bfd *, const gdb_byte *);
 
 static struct partial_die_info *load_partial_dies
@@ -7421,7 +7432,8 @@ static void
 init_cu_die_reader (struct die_reader_specs *reader,
 		    struct dwarf2_cu *cu,
 		    struct dwarf2_section_info *section,
-		    struct dwo_file *dwo_file)
+		    struct dwo_file *dwo_file,
+		    struct abbrev_table *abbrev_table)
 {
   gdb_assert (section->readin && section->buffer != NULL);
   reader->abfd = get_section_bfd_owner (section);
@@ -7431,6 +7443,7 @@ init_cu_die_reader (struct die_reader_specs *reader,
   reader->buffer = section->buffer;
   reader->buffer_end = section->buffer + section->size;
   reader->comp_dir = NULL;
+  reader->abbrev_table = abbrev_table;
 }
 
 /* Subroutine of init_cutu_and_read_dies to simplify it.
@@ -7446,25 +7459,26 @@ init_cu_die_reader (struct die_reader_specs *reader,
    STUB_COMP_DIR may be non-NULL.
    *RESULT_READER,*RESULT_INFO_PTR,*RESULT_COMP_UNIT_DIE,*RESULT_HAS_CHILDREN
    are filled in with the info of the DIE from the DWO file.
-   ABBREV_TABLE_PROVIDED is non-zero if the caller of init_cutu_and_read_dies
-   provided an abbrev table to use.
+   *RESULT_DWO_ABBREV_TABLE will be filled in with the abbrev table allocated
+   from the dwo.  Since *RESULT_READER references this abbrev table, it must be
+   kept around for at least as long as *RESULT_READER.
+
    The result is non-zero if a valid (non-dummy) DIE was found.  */
 
 static int
 read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
 			struct dwo_unit *dwo_unit,
-			int abbrev_table_provided,
 			struct die_info *stub_comp_unit_die,
 			const char *stub_comp_dir,
 			struct die_reader_specs *result_reader,
 			const gdb_byte **result_info_ptr,
 			struct die_info **result_comp_unit_die,
-			int *result_has_children)
+			int *result_has_children,
+			abbrev_table_up *result_dwo_abbrev_table)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_cu *cu = this_cu->cu;
-  struct dwarf2_section_info *section;
   bfd *abfd;
   const gdb_byte *begin_info_ptr, *info_ptr;
   struct attribute *comp_dir, *stmt_list, *low_pc, *high_pc, *ranges;
@@ -7527,13 +7541,12 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
 
   /* Set up for reading the DWO CU/TU.  */
   cu->dwo_unit = dwo_unit;
-  section = dwo_unit->section;
+  dwarf2_section_info *section = dwo_unit->section;
   dwarf2_read_section (objfile, section);
   abfd = get_section_bfd_owner (section);
   begin_info_ptr = info_ptr = (section->buffer
 			       + to_underlying (dwo_unit->sect_off));
   dwo_abbrev_section = &dwo_unit->dwo_file->sections.abbrev;
-  init_cu_die_reader (result_reader, cu, section, dwo_unit->dwo_file);
 
   if (this_cu->is_debug_types)
     {
@@ -7576,22 +7589,11 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
       dwo_unit->length = get_cu_length (&cu->header);
     }
 
-  /* Replace the CU's original abbrev table with the DWO's.
-     Reminder: We can't read the abbrev table until we've read the header.  */
-  if (abbrev_table_provided)
-    {
-      /* Don't free the provided abbrev table, the caller of
-	 init_cutu_and_read_dies owns it.  */
-      dwarf2_read_abbrevs (cu, dwo_abbrev_section);
-      /* Ensure the DWO abbrev table gets freed.  */
-      make_cleanup (dwarf2_free_abbrev_table, cu);
-    }
-  else
-    {
-      dwarf2_free_abbrev_table (cu);
-      dwarf2_read_abbrevs (cu, dwo_abbrev_section);
-      /* Leave any existing abbrev table cleanup as is.  */
-    }
+  *result_dwo_abbrev_table
+    = abbrev_table_read_table (dwarf2_per_objfile, dwo_abbrev_section,
+			       cu->header.abbrev_sect_off);
+  init_cu_die_reader (result_reader, cu, section, dwo_unit->dwo_file,
+		      result_dwo_abbrev_table->get ());
 
   /* Read in the die, but leave space to copy over the attributes
      from the stub.  This has the benefit of simplifying the rest of
@@ -7745,12 +7747,16 @@ init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
      abbrev table.  When reading DWOs with skeletonless TUs, all the TUs
      could share abbrev tables.  */
 
+  /* The abbreviation table used by READER, this must live at least as long as
+     READER.  */
+  abbrev_table_up dwo_abbrev_table;
+
   if (read_cutu_die_from_dwo (this_cu, sig_type->dwo_unit,
-			      0 /* abbrev_table_provided */,
 			      NULL /* stub_comp_unit_die */,
 			      sig_type->dwo_unit->dwo_file->comp_dir,
 			      &reader, &info_ptr,
-			      &comp_unit_die, &has_children) == 0)
+			      &comp_unit_die, &has_children,
+			      &dwo_abbrev_table) == 0)
     {
       /* Dummy die.  */
       do_cleanups (cleanups);
@@ -7772,10 +7778,6 @@ init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
 	     caller clean it up when finished with it.  */
 	  discard_cleanups (free_cu_cleanup);
 
-	  /* We can only discard free_cu_cleanup and all subsequent cleanups.
-	     So we have to manually free the abbrev table.  */
-	  dwarf2_free_abbrev_table (cu);
-
 	  /* Link this CU into read_in_chain.  */
 	  this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
 	  dwarf2_per_objfile->read_in_chain = this_cu;
@@ -7936,35 +7938,32 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
 
   /* If we don't have them yet, read the abbrevs for this compilation unit.
      And if we need to read them now, make sure they're freed when we're
-     done.  Note that it's important that if the CU had an abbrev table
-     on entry we don't free it when we're done: Somewhere up the call stack
-     it may be in use.  */
+     done (own the table through ABBREV_TABLE_HOLDER).  */
+  abbrev_table_up abbrev_table_holder;
   if (abbrev_table != NULL)
+    gdb_assert (cu->header.abbrev_sect_off == abbrev_table->sect_off);
+  else
     {
-      gdb_assert (cu->abbrev_table == NULL);
-      gdb_assert (cu->header.abbrev_sect_off == abbrev_table->sect_off);
-      cu->abbrev_table = abbrev_table;
-    }
-  else if (cu->abbrev_table == NULL)
-    {
-      dwarf2_read_abbrevs (cu, abbrev_section);
-      make_cleanup (dwarf2_free_abbrev_table, cu);
-    }
-  else if (rereading_dwo_cu)
-    {
-      dwarf2_free_abbrev_table (cu);
-      dwarf2_read_abbrevs (cu, abbrev_section);
+      abbrev_table_holder
+	= abbrev_table_read_table (dwarf2_per_objfile, abbrev_section,
+				   cu->header.abbrev_sect_off);
+      abbrev_table = abbrev_table_holder.get ();
     }
 
   /* Read the top level CU/TU die.  */
-  init_cu_die_reader (&reader, cu, section, NULL);
+  init_cu_die_reader (&reader, cu, section, NULL, abbrev_table);
   info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children);
 
   /* If we are in a DWO stub, process it and then read in the "real" CU/TU
-     from the DWO file.
+     from the DWO file.  read_cutu_die_from_dwo will allocate the abbreviation
+     table from the DWO file and pass the ownership over to us.  It will be
+     referenced from READER, so we must make sure to free it after we're done
+     with READER.
+
      Note that if USE_EXISTING_OK != 0, and THIS_CU->cu already contains a
      DWO CU, that this test will fail (the attribute will not be present).  */
   attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_name, cu);
+  abbrev_table_up dwo_abbrev_table;
   if (attr)
     {
       struct dwo_unit *dwo_unit;
@@ -7981,10 +7980,10 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
       if (dwo_unit != NULL)
 	{
 	  if (read_cutu_die_from_dwo (this_cu, dwo_unit,
-				      abbrev_table != NULL,
 				      comp_unit_die, NULL,
 				      &reader, &info_ptr,
-				      &dwo_comp_unit_die, &has_children) == 0)
+				      &dwo_comp_unit_die, &has_children,
+				      &dwo_abbrev_table) == 0)
 	    {
 	      /* Dummy die.  */
 	      do_cleanups (cleanups);
@@ -8014,10 +8013,6 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
 	     caller clean it up when finished with it.  */
 	  discard_cleanups (free_cu_cleanup);
 
-	  /* We can only discard free_cu_cleanup and all subsequent cleanups.
-	     So we have to manually free the abbrev table.  */
-	  dwarf2_free_abbrev_table (cu);
-
 	  /* Link this CU into read_in_chain.  */
 	  this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
 	  dwarf2_per_objfile->read_in_chain = this_cu;
@@ -8099,10 +8094,11 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
       return;
     }
 
-  dwarf2_read_abbrevs (&cu, abbrev_section);
-  make_cleanup (dwarf2_free_abbrev_table, &cu);
+  abbrev_table_up abbrev_table
+    = abbrev_table_read_table (dwarf2_per_objfile, abbrev_section,
+			       cu.header.abbrev_sect_off);
 
-  init_cu_die_reader (&reader, &cu, section, dwo_file);
+  init_cu_die_reader (&reader, &cu, section, dwo_file, abbrev_table.get ());
   info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children);
 
   die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data);
@@ -8578,7 +8574,7 @@ build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
   struct cleanup *cleanups;
-  struct abbrev_table *abbrev_table;
+  abbrev_table_up abbrev_table;
   sect_offset abbrev_offset;
   struct tu_abbrev_offset *sorted_by_abbrev;
   int i;
@@ -8630,8 +8626,6 @@ build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
 	 sizeof (struct tu_abbrev_offset), sort_tu_by_abbrev_offset);
 
   abbrev_offset = (sect_offset) ~(unsigned) 0;
-  abbrev_table = NULL;
-  make_cleanup (abbrev_table_free_cleanup, &abbrev_table);
 
   for (i = 0; i < dwarf2_per_objfile->n_type_units; ++i)
     {
@@ -8641,13 +8635,6 @@ build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
       if (abbrev_table == NULL
 	  || tu->abbrev_offset != abbrev_offset)
 	{
-	  if (abbrev_table != NULL)
-	    {
-	      abbrev_table_free (abbrev_table);
-	      /* Reset to NULL in case abbrev_table_read_table throws
-		 an error: abbrev_table_free_cleanup will get called.  */
-	      abbrev_table = NULL;
-	    }
 	  abbrev_offset = tu->abbrev_offset;
 	  abbrev_table =
 	    abbrev_table_read_table (dwarf2_per_objfile,
@@ -8656,8 +8643,8 @@ build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
 	  ++tu_stats->nr_uniq_abbrev_tables;
 	}
 
-      init_cutu_and_read_dies (&tu->sig_type->per_cu, abbrev_table, 0, 0,
-			       build_type_psymtabs_reader, NULL);
+      init_cutu_and_read_dies (&tu->sig_type->per_cu, abbrev_table.get (),
+			       0, 0, build_type_psymtabs_reader, NULL);
     }
 
   do_cleanups (cleanups);
@@ -9606,25 +9593,26 @@ peek_abbrev_code (bfd *abfd, const gdb_byte *info_ptr)
   return read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
 }
 
-/* Read the initial uleb128 in the die at INFO_PTR in compilation unit CU.
+/* Read the initial uleb128 in the die at INFO_PTR in compilation unit
+   READER::CU.  Use READER::ABBREV_TABLE to lookup any abbreviation.
+
    Return the corresponding abbrev, or NULL if the number is zero (indicating
    an empty DIE).  In either case *BYTES_READ will be set to the length of
    the initial number.  */
 
 static struct abbrev_info *
-peek_die_abbrev (const gdb_byte *info_ptr, unsigned int *bytes_read,
-		 struct dwarf2_cu *cu)
+peek_die_abbrev (const die_reader_specs &reader,
+		 const gdb_byte *info_ptr, unsigned int *bytes_read)
 {
+  dwarf2_cu *cu = reader.cu;
   bfd *abfd = cu->per_cu->dwarf2_per_objfile->objfile->obfd;
-  unsigned int abbrev_number;
-  struct abbrev_info *abbrev;
-
-  abbrev_number = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
+  unsigned int abbrev_number
+    = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
 
   if (abbrev_number == 0)
     return NULL;
 
-  abbrev = abbrev_table_lookup_abbrev (cu->abbrev_table, abbrev_number);
+  abbrev_info *abbrev = reader.abbrev_table->lookup_abbrev (abbrev_number);
   if (!abbrev)
     {
       error (_("Dwarf Error: Could not find abbrev number %d in %s"
@@ -9643,13 +9631,11 @@ peek_die_abbrev (const gdb_byte *info_ptr, unsigned int *bytes_read,
 static const gdb_byte *
 skip_children (const struct die_reader_specs *reader, const gdb_byte *info_ptr)
 {
-  struct dwarf2_cu *cu = reader->cu;
-  struct abbrev_info *abbrev;
-  unsigned int bytes_read;
-
   while (1)
     {
-      abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu);
+      unsigned int bytes_read;
+      abbrev_info *abbrev = peek_die_abbrev (*reader, info_ptr, &bytes_read);
+
       if (abbrev == NULL)
 	return info_ptr + bytes_read;
       else
@@ -18015,7 +18001,7 @@ read_full_die_1 (const struct die_reader_specs *reader,
       return info_ptr;
     }
 
-  abbrev = abbrev_table_lookup_abbrev (cu->abbrev_table, abbrev_number);
+  abbrev = reader->abbrev_table->lookup_abbrev (abbrev_number);
   if (!abbrev)
     error (_("Dwarf Error: could not find abbrev number %d [in module %s]"),
 	   abbrev_number,
@@ -18076,12 +18062,12 @@ read_full_die (const struct die_reader_specs *reader,
 
 /* Allocate space for a struct abbrev_info object in ABBREV_TABLE.  */
 
-static struct abbrev_info *
-abbrev_table_alloc_abbrev (struct abbrev_table *abbrev_table)
+struct abbrev_info *
+abbrev_table::alloc_abbrev ()
 {
   struct abbrev_info *abbrev;
 
-  abbrev = XOBNEW (&abbrev_table->abbrev_obstack, struct abbrev_info);
+  abbrev = XOBNEW (&abbrev_obstack, struct abbrev_info);
   memset (abbrev, 0, sizeof (struct abbrev_info));
 
   return abbrev;
@@ -18089,30 +18075,28 @@ abbrev_table_alloc_abbrev (struct abbrev_table *abbrev_table)
 
 /* Add an abbreviation to the table.  */
 
-static void
-abbrev_table_add_abbrev (struct abbrev_table *abbrev_table,
-			 unsigned int abbrev_number,
-			 struct abbrev_info *abbrev)
+void
+abbrev_table::add_abbrev (unsigned int abbrev_number,
+			  struct abbrev_info *abbrev)
 {
   unsigned int hash_number;
 
   hash_number = abbrev_number % ABBREV_HASH_SIZE;
-  abbrev->next = abbrev_table->abbrevs[hash_number];
-  abbrev_table->abbrevs[hash_number] = abbrev;
+  abbrev->next = abbrevs[hash_number];
+  abbrevs[hash_number] = abbrev;
 }
 
 /* Look up an abbrev in the table.
    Returns NULL if the abbrev is not found.  */
 
-static struct abbrev_info *
-abbrev_table_lookup_abbrev (const struct abbrev_table *abbrev_table,
-			    unsigned int abbrev_number)
+struct abbrev_info *
+abbrev_table::lookup_abbrev (unsigned int abbrev_number)
 {
   unsigned int hash_number;
   struct abbrev_info *abbrev;
 
   hash_number = abbrev_number % ABBREV_HASH_SIZE;
-  abbrev = abbrev_table->abbrevs[hash_number];
+  abbrev = abbrevs[hash_number];
 
   while (abbrev)
     {
@@ -18125,14 +18109,13 @@ abbrev_table_lookup_abbrev (const struct abbrev_table *abbrev_table,
 
 /* Read in an abbrev table.  */
 
-static struct abbrev_table *
+static abbrev_table_up
 abbrev_table_read_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 			 struct dwarf2_section_info *section,
 			 sect_offset sect_off)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   bfd *abfd = get_section_bfd_owner (section);
-  struct abbrev_table *abbrev_table;
   const gdb_byte *abbrev_ptr;
   struct abbrev_info *cur_abbrev;
   unsigned int abbrev_number, bytes_read, abbrev_name;
@@ -18140,14 +18123,7 @@ abbrev_table_read_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
   struct attr_abbrev *cur_attrs;
   unsigned int allocated_attrs;
 
-  abbrev_table = XNEW (struct abbrev_table);
-  abbrev_table->sect_off = sect_off;
-  obstack_init (&abbrev_table->abbrev_obstack);
-  abbrev_table->abbrevs =
-    XOBNEWVEC (&abbrev_table->abbrev_obstack, struct abbrev_info *,
-	       ABBREV_HASH_SIZE);
-  memset (abbrev_table->abbrevs, 0,
-	  ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
+  abbrev_table_up abbrev_table (new struct abbrev_table (sect_off));
 
   dwarf2_read_section (objfile, section);
   abbrev_ptr = section->buffer + to_underlying (sect_off);
@@ -18160,7 +18136,7 @@ abbrev_table_read_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
   /* Loop until we reach an abbrev number of 0.  */
   while (abbrev_number)
     {
-      cur_abbrev = abbrev_table_alloc_abbrev (abbrev_table);
+      cur_abbrev = abbrev_table->alloc_abbrev ();
 
       /* read in abbrev header */
       cur_abbrev->number = abbrev_number;
@@ -18215,7 +18191,7 @@ abbrev_table_read_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
       memcpy (cur_abbrev->attrs, cur_attrs,
 	      cur_abbrev->num_attrs * sizeof (struct attr_abbrev));
 
-      abbrev_table_add_abbrev (abbrev_table, abbrev_number, cur_abbrev);
+      abbrev_table->add_abbrev (abbrev_number, cur_abbrev);
 
       /* Get next abbreviation.
          Under Irix6 the abbreviations for a compilation unit are not
@@ -18228,7 +18204,7 @@ abbrev_table_read_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	break;
       abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
       abbrev_ptr += bytes_read;
-      if (abbrev_table_lookup_abbrev (abbrev_table, abbrev_number) != NULL)
+      if (abbrev_table->lookup_abbrev (abbrev_number) != NULL)
 	break;
     }
 
@@ -18236,55 +18212,6 @@ abbrev_table_read_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
   return abbrev_table;
 }
 
-/* Free the resources held by ABBREV_TABLE.  */
-
-static void
-abbrev_table_free (struct abbrev_table *abbrev_table)
-{
-  obstack_free (&abbrev_table->abbrev_obstack, NULL);
-  xfree (abbrev_table);
-}
-
-/* Same as abbrev_table_free but as a cleanup.
-   We pass in a pointer to the pointer to the table so that we can
-   set the pointer to NULL when we're done.  It also simplifies
-   build_type_psymtabs_1.  */
-
-static void
-abbrev_table_free_cleanup (void *table_ptr)
-{
-  struct abbrev_table **abbrev_table_ptr = (struct abbrev_table **) table_ptr;
-
-  if (*abbrev_table_ptr != NULL)
-    abbrev_table_free (*abbrev_table_ptr);
-  *abbrev_table_ptr = NULL;
-}
-
-/* Read the abbrev table for CU from ABBREV_SECTION.  */
-
-static void
-dwarf2_read_abbrevs (struct dwarf2_cu *cu,
-		     struct dwarf2_section_info *abbrev_section)
-{
-  cu->abbrev_table =
-    abbrev_table_read_table (cu->per_cu->dwarf2_per_objfile, abbrev_section,
-			     cu->header.abbrev_sect_off);
-}
-
-/* Release the memory used by the abbrev table for a compilation unit.  */
-
-static void
-dwarf2_free_abbrev_table (void *ptr_to_cu)
-{
-  struct dwarf2_cu *cu = (struct dwarf2_cu *) ptr_to_cu;
-
-  if (cu->abbrev_table != NULL)
-    abbrev_table_free (cu->abbrev_table);
-  /* Set this to NULL so that we SEGV if we try to read it later,
-     and also because free_comp_unit verifies this is NULL.  */
-  cu->abbrev_table = NULL;
-}
-
 /* Returns nonzero if TAG represents a type that we might generate a partial
    symbol for.  */
 
@@ -18327,7 +18254,6 @@ load_partial_dies (const struct die_reader_specs *reader,
   struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct partial_die_info *part_die;
   struct partial_die_info *parent_die, *last_die, *first_die = NULL;
-  struct abbrev_info *abbrev;
   unsigned int bytes_read;
   unsigned int load_all = 0;
   int nesting_level = 1;
@@ -18352,7 +18278,7 @@ load_partial_dies (const struct die_reader_specs *reader,
 
   while (1)
     {
-      abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu);
+      abbrev_info *abbrev = peek_die_abbrev (*reader, info_ptr, &bytes_read);
 
       /* A NULL abbrev means the end of a series of children.  */
       if (abbrev == NULL)
