summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog23
-rw-r--r--gdb/dwarf-index-cache.c31
-rw-r--r--gdb/dwarf-index-write.c272
-rw-r--r--gdb/dwarf-index-write.h13
-rw-r--r--gdb/dwarf2read.c32
-rw-r--r--gdb/dwarf2read.h38
-rw-r--r--gdb/testsuite/ChangeLog6
-rw-r--r--gdb/testsuite/gdb.dwarf2/gdb-index.exp15
8 files changed, 280 insertions, 150 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 1cf2b9bcdc8..ef62a4e6295 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,26 @@
+2019-06-16 Simon Marchi <simon.marchi@polymtl.ca>
+
+ PR gdb/24445
+ * dwarf-index-write.h (write_psymtabs_to_index): Add
+ dwz_basename parameter.
+ * dwarf-index-write.c (write_gdbindex): Move file writing to
+ write_gdbindex_1. Change return type void.
+ (assert_file_size): Move up, remove filename parameter.
+ (write_gdbindex_1): New function.
+ (write_debug_names): Change return type to void, call
+ assert_file_size.
+ (struct index_wip_file): New struct.
+ (write_psymtabs_to_index): Add dwz_basename parameter. Move
+ file logic to index_wip_file. Write index for dwz file if
+ needed.
+ (save_gdb_index_command): Pass basename of dwz file, if present.
+ * dwarf-index-cache.c (index_cache::store): Obtain and pass
+ build-id of dwz file, if present.
+ * dwarf2read.c (struct dwz_file): Move to dwarf2read.h.
+ (dwarf2_get_dwz_file): Likewise.
+ * dwarf2read.h (struct dwz_file): Move from dwarf2read.c.
+ (dwarf2_get_dwz_file): Likewise.
+
2019-06-16 Tom Tromey <tom@tromey.com>
* coffread.c (process_coff_symbol): Use xstrdup.
diff --git a/gdb/dwarf-index-cache.c b/gdb/dwarf-index-cache.c
index 7222f0528d7..d0179014935 100644
--- a/gdb/dwarf-index-cache.c
+++ b/gdb/dwarf-index-cache.c
@@ -93,6 +93,7 @@ index_cache::store (struct dwarf2_per_objfile *dwarf2_per_objfile)
if (!enabled ())
return;
+ /* Get build id of objfile. */
const bfd_build_id *build_id = build_id_bfd_get (obj->obfd);
if (build_id == nullptr)
{
@@ -102,14 +103,35 @@ index_cache::store (struct dwarf2_per_objfile *dwarf2_per_objfile)
return;
}
+ std::string build_id_str = build_id_to_string (build_id);
+
+ /* Get build id of dwz file, if present. */
+ gdb::optional<std::string> dwz_build_id_str;
+ const dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+ const char *dwz_build_id_ptr = NULL;
+
+ if (dwz != nullptr)
+ {
+ const bfd_build_id *dwz_build_id = build_id_bfd_get (dwz->dwz_bfd.get ());
+
+ if (dwz_build_id == nullptr)
+ {
+ if (debug_index_cache)
+ printf_unfiltered ("index cache: dwz objfile %s has no build id\n",
+ dwz->filename ());
+ return;
+ }
+
+ dwz_build_id_str = build_id_to_string (dwz_build_id);
+ dwz_build_id_ptr = dwz_build_id_str->c_str ();
+ }
+
if (m_dir.empty ())
{
warning (_("The index cache directory name is empty, skipping store."));
return;
}
- std::string build_id_str = build_id_to_string (build_id);
-
try
{
/* Try to create the containing directory. */
@@ -122,12 +144,13 @@ index_cache::store (struct dwarf2_per_objfile *dwarf2_per_objfile)
if (debug_index_cache)
printf_unfiltered ("index cache: writing index cache for objfile %s\n",
- objfile_name (obj));
+ objfile_name (obj));
/* Write the index itself to the directory, using the build id as the
filename. */
write_psymtabs_to_index (dwarf2_per_objfile, m_dir.c_str (),
- build_id_str.c_str (), dw_index_kind::GDB_INDEX);
+ build_id_str.c_str (), dwz_build_id_ptr,
+ dw_index_kind::GDB_INDEX);
}
catch (const gdb_exception_error &except)
{
diff --git a/gdb/dwarf-index-write.c b/gdb/dwarf-index-write.c
index 8734f99212d..9979ae44402 100644
--- a/gdb/dwarf-index-write.c
+++ b/gdb/dwarf-index-write.c
@@ -1289,15 +1289,81 @@ psyms_seen_size (struct dwarf2_per_objfile *dwarf2_per_objfile)
return psyms_count / 4;
}
-/* Write new .gdb_index section for OBJFILE into OUT_FILE.
- Return how many bytes were expected to be written into OUT_FILE. */
+/* Assert that FILE's size is EXPECTED_SIZE. Assumes file's seek
+ position is at the end of the file. */
-static size_t
-write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file)
+static void
+assert_file_size (FILE *file, size_t expected_size)
+{
+ const auto file_size = ftell (file);
+ if (file_size == -1)
+ perror_with_name (("ftell"));
+ gdb_assert (file_size == expected_size);
+}
+
+/* Write a gdb index file to OUT_FILE from all the sections passed as
+ arguments. */
+
+static void
+write_gdbindex_1 (FILE *out_file,
+ const data_buf &cu_list,
+ const data_buf &types_cu_list,
+ const data_buf &addr_vec,
+ const data_buf &symtab_vec,
+ const data_buf &constant_pool)
+{
+ data_buf contents;
+ const offset_type size_of_header = 6 * sizeof (offset_type);
+ offset_type total_len = size_of_header;
+
+ /* The version number. */
+ contents.append_data (MAYBE_SWAP (8));
+
+ /* The offset of the CU list from the start of the file. */
+ contents.append_data (MAYBE_SWAP (total_len));
+ total_len += cu_list.size ();
+
+ /* The offset of the types CU list from the start of the file. */
+ contents.append_data (MAYBE_SWAP (total_len));
+ total_len += types_cu_list.size ();
+
+ /* The offset of the address table from the start of the file. */
+ contents.append_data (MAYBE_SWAP (total_len));
+ total_len += addr_vec.size ();
+
+ /* The offset of the symbol table from the start of the file. */
+ contents.append_data (MAYBE_SWAP (total_len));
+ total_len += symtab_vec.size ();
+
+ /* The offset of the constant pool from the start of the file. */
+ contents.append_data (MAYBE_SWAP (total_len));
+ total_len += constant_pool.size ();
+
+ gdb_assert (contents.size () == size_of_header);
+
+ contents.file_write (out_file);
+ cu_list.file_write (out_file);
+ types_cu_list.file_write (out_file);
+ addr_vec.file_write (out_file);
+ symtab_vec.file_write (out_file);
+ constant_pool.file_write (out_file);
+
+ assert_file_size (out_file, total_len);
+}
+
+/* Write contents of a .gdb_index section for OBJFILE into OUT_FILE.
+ If OBJFILE has an associated dwz file, write contents of a .gdb_index
+ section for that dwz file into DWZ_OUT_FILE. If OBJFILE does not have an
+ associated dwz file, DWZ_OUT_FILE must be NULL. */
+
+static void
+write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file,
+ FILE *dwz_out_file)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
mapped_symtab symtab;
- data_buf cu_list;
+ data_buf objfile_cu_list;
+ data_buf dwz_cu_list;
/* While we're scanning CU's create a table that maps a psymtab pointer
(which is what addrmap records) to its index (which is what is recorded
@@ -1331,6 +1397,10 @@ write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file)
const auto insertpair = cu_index_htab.emplace (psymtab, i);
gdb_assert (insertpair.second);
+ /* The all_comp_units list contains CUs read from the objfile as well as
+ from the eventual dwz file. We need to place the entry in the
+ corresponding index. */
+ data_buf &cu_list = per_cu->is_dwz ? dwz_cu_list : objfile_cu_list;
cu_list.append_uint (8, BFD_ENDIAN_LITTLE,
to_underlying (per_cu->sect_off));
cu_list.append_uint (8, BFD_ENDIAN_LITTLE, per_cu->length);
@@ -1361,43 +1431,13 @@ write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file)
data_buf symtab_vec, constant_pool;
write_hash_table (&symtab, symtab_vec, constant_pool);
- data_buf contents;
- const offset_type size_of_contents = 6 * sizeof (offset_type);
- offset_type total_len = size_of_contents;
-
- /* The version number. */
- contents.append_data (MAYBE_SWAP (8));
-
- /* The offset of the CU list from the start of the file. */
- contents.append_data (MAYBE_SWAP (total_len));
- total_len += cu_list.size ();
-
- /* The offset of the types CU list from the start of the file. */
- contents.append_data (MAYBE_SWAP (total_len));
- total_len += types_cu_list.size ();
+ write_gdbindex_1(out_file, objfile_cu_list, types_cu_list, addr_vec,
+ symtab_vec, constant_pool);
- /* The offset of the address table from the start of the file. */
- contents.append_data (MAYBE_SWAP (total_len));
- total_len += addr_vec.size ();
-
- /* The offset of the symbol table from the start of the file. */
- contents.append_data (MAYBE_SWAP (total_len));
- total_len += symtab_vec.size ();
-
- /* The offset of the constant pool from the start of the file. */
- contents.append_data (MAYBE_SWAP (total_len));
- total_len += constant_pool.size ();
-
- gdb_assert (contents.size () == size_of_contents);
-
- contents.file_write (out_file);
- cu_list.file_write (out_file);
- types_cu_list.file_write (out_file);
- addr_vec.file_write (out_file);
- symtab_vec.file_write (out_file);
- constant_pool.file_write (out_file);
-
- return total_len;
+ if (dwz_out_file != NULL)
+ write_gdbindex_1 (dwz_out_file, dwz_cu_list, {}, {}, {}, {});
+ else
+ gdb_assert (dwz_cu_list.empty ());
}
/* DWARF-5 augmentation string for GDB's DW_IDX_GNU_* extension. */
@@ -1407,7 +1447,7 @@ static const gdb_byte dwarf5_gdb_augmentation[] = { 'G', 'D', 'B', 0 };
needed addition to .debug_str section to OUT_FILE_STR. Return how
many bytes were expected to be written into OUT_FILE. */
-static size_t
+static void
write_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
FILE *out_file, FILE *out_file_str)
{
@@ -1528,26 +1568,69 @@ write_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
types_cu_list.file_write (out_file);
nametable.file_write (out_file, out_file_str);
- return expected_bytes;
+ assert_file_size (out_file, expected_bytes);
}
-/* Assert that FILE's size is EXPECTED_SIZE. Assumes file's seek
- position is at the end of the file. */
+/* This represents an index file being written (work-in-progress).
-static void
-assert_file_size (FILE *file, const char *filename, size_t expected_size)
+ The data is initially written to a temporary file. When the finalize method
+ is called, the file is closed and moved to its final location.
+
+ On failure (if this object is being destroyed with having called finalize),
+ the temporary file is closed and deleted. */
+
+struct index_wip_file
{
- const auto file_size = ftell (file);
- if (file_size == -1)
- error (_("Can't get `%s' size"), filename);
- gdb_assert (file_size == expected_size);
-}
+ index_wip_file (const char *dir, const char *basename,
+ const char *suffix)
+ {
+ filename = (std::string (dir) + SLASH_STRING + basename
+ + suffix);
+
+ filename_temp = make_temp_filename (filename);
+
+ scoped_fd out_file_fd (gdb_mkostemp_cloexec (filename_temp.data (),
+ O_BINARY));
+ if (out_file_fd.get () == -1)
+ perror_with_name (("mkstemp"));
+
+ out_file = out_file_fd.to_file ("wb");
+
+ if (out_file == nullptr)
+ error (_("Can't open `%s' for writing"), filename_temp.data ());
+
+ unlink_file.emplace (filename_temp.data ());
+ }
+
+ void finalize ()
+ {
+ /* We want to keep the file. */
+ unlink_file->keep ();
+
+ /* Close and move the str file in place. */
+ unlink_file.reset ();
+ if (rename (filename_temp.data (), filename.c_str ()) != 0)
+ perror_with_name (("rename"));
+ }
+
+ std::string filename;
+ gdb::char_vector filename_temp;
+
+ /* Order matters here; we want FILE to be closed before
+ FILENAME_TEMP is unlinked, because on MS-Windows one cannot
+ delete a file that is still open. So, we wrap the unlinker in an
+ optional and emplace it once we know the file name. */
+ gdb::optional<gdb::unlinker> unlink_file;
+
+ gdb_file_up out_file;
+};
/* See dwarf-index-write.h. */
void
write_psymtabs_to_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
const char *dir, const char *basename,
+ const char *dwz_basename,
dw_index_kind index_kind)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
@@ -1566,74 +1649,33 @@ write_psymtabs_to_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
if (stat (objfile_name (objfile), &st) < 0)
perror_with_name (objfile_name (objfile));
- std::string filename (std::string (dir) + SLASH_STRING + basename
- + (index_kind == dw_index_kind::DEBUG_NAMES
- ? INDEX5_SUFFIX : INDEX4_SUFFIX));
- gdb::char_vector filename_temp = make_temp_filename (filename);
+ const char *index_suffix = (index_kind == dw_index_kind::DEBUG_NAMES
+ ? INDEX5_SUFFIX : INDEX4_SUFFIX);
- /* Order matters here; we want FILE to be closed before
- FILENAME_TEMP is unlinked, because on MS-Windows one cannot
- delete a file that is still open. So, we wrap the unlinker in an
- optional and emplace it once we know the file name. */
- gdb::optional<gdb::unlinker> unlink_file;
- scoped_fd out_file_fd (gdb_mkostemp_cloexec (filename_temp.data (),
- O_BINARY));
- if (out_file_fd.get () == -1)
- perror_with_name (("mkstemp"));
+ index_wip_file objfile_index_wip (dir, basename, index_suffix);
+ gdb::optional<index_wip_file> dwz_index_wip;
- gdb_file_up out_file = out_file_fd.to_file ("wb");
- if (out_file == nullptr)
- error (_("Can't open `%s' for writing"), filename_temp.data ());
-
- unlink_file.emplace (filename_temp.data ());
+ if (dwz_basename != NULL)
+ dwz_index_wip.emplace (dir, dwz_basename, index_suffix);
if (index_kind == dw_index_kind::DEBUG_NAMES)
{
- std::string filename_str (std::string (dir) + SLASH_STRING
- + basename + DEBUG_STR_SUFFIX);
- gdb::char_vector filename_str_temp = make_temp_filename (filename_str);
-
- /* As above, arrange to unlink the file only after the file
- descriptor has been closed. */
- gdb::optional<gdb::unlinker> unlink_file_str;
- scoped_fd out_file_str_fd
- (gdb_mkostemp_cloexec (filename_str_temp.data (), O_BINARY));
- if (out_file_str_fd.get () == -1)
- perror_with_name (("mkstemp"));
-
- gdb_file_up out_file_str = out_file_str_fd.to_file ("wb");
- if (out_file_str == nullptr)
- error (_("Can't open `%s' for writing"), filename_str_temp.data ());
-
- unlink_file_str.emplace (filename_str_temp.data ());
-
- const size_t total_len
- = write_debug_names (dwarf2_per_objfile, out_file.get (),
- out_file_str.get ());
- assert_file_size (out_file.get (), filename_temp.data (), total_len);
-
- /* We want to keep the file .debug_str file too. */
- unlink_file_str->keep ();
-
- /* Close and move the str file in place. */
- out_file_str.reset ();
- if (rename (filename_str_temp.data (), filename_str.c_str ()) != 0)
- perror_with_name (("rename"));
+ index_wip_file str_wip_file (dir, basename, DEBUG_STR_SUFFIX);
+
+ write_debug_names (dwarf2_per_objfile, objfile_index_wip.out_file.get (),
+ str_wip_file.out_file.get ());
+
+ str_wip_file.finalize ();
}
else
- {
- const size_t total_len
- = write_gdbindex (dwarf2_per_objfile, out_file.get ());
- assert_file_size (out_file.get (), filename_temp.data (), total_len);
- }
+ write_gdbindex (dwarf2_per_objfile, objfile_index_wip.out_file.get (),
+ (dwz_index_wip.has_value ()
+ ? dwz_index_wip->out_file.get () : NULL));
- /* We want to keep the file. */
- unlink_file->keep ();
+ objfile_index_wip.finalize ();
- /* Close and move the file in place. */
- out_file.reset ();
- if (rename (filename_temp.data (), filename.c_str ()) != 0)
- perror_with_name (("rename"));
+ if (dwz_index_wip.has_value ())
+ dwz_index_wip->finalize ();
}
/* Implementation of the `save gdb-index' command.
@@ -1678,8 +1720,14 @@ save_gdb_index_command (const char *arg, int from_tty)
try
{
const char *basename = lbasename (objfile_name (objfile));
+ const dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+ const char *dwz_basename = NULL;
+
+ if (dwz != NULL)
+ dwz_basename = lbasename (dwz->filename ());
+
write_psymtabs_to_index (dwarf2_per_objfile, arg, basename,
- index_kind);
+ dwz_basename, index_kind);
}
catch (const gdb_exception_error &except)
{
diff --git a/gdb/dwarf-index-write.h b/gdb/dwarf-index-write.h
index b1d1180c8e3..a8874c86438 100644
--- a/gdb/dwarf-index-write.h
+++ b/gdb/dwarf-index-write.h
@@ -23,12 +23,17 @@
#include "symfile.h"
#include "dwarf2read.h"
-/* Create an index file for OBJFILE in the directory DIR. BASENAME is the
- desired filename, minus the extension, which gets added by this function
- based on INDEX_KIND. */
+/* Create index files for OBJFILE in the directory DIR.
+
+ An index file is created for OBJFILE itself, and is created for its
+ associated dwz file, if it has one.
+
+ BASENAME is the desired filename base for OBJFILE's index. An extension
+ derived from INDEX_KIND is added to this base name. DWZ_BASENAME is the
+ same, but for the dwz file's index. */
extern void write_psymtabs_to_index
(struct dwarf2_per_objfile *dwarf2_per_objfile, const char *dir,
- const char *basename, dw_index_kind index_kind);
+ const char *basename, const char *dwz_basename, dw_index_kind index_kind);
#endif /* DWARF_INDEX_WRITE_H */
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 4cf9fcfa218..a51ae49e870 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -875,32 +875,6 @@ struct dwp_file
asection **elf_sections = nullptr;
};
-/* This represents a '.dwz' file. */
-
-struct dwz_file
-{
- dwz_file (gdb_bfd_ref_ptr &&bfd)
- : dwz_bfd (std::move (bfd))
- {
- }
-
- /* A dwz file can only contain a few sections. */
- struct dwarf2_section_info abbrev {};
- struct dwarf2_section_info info {};
- struct dwarf2_section_info str {};
- struct dwarf2_section_info line {};
- struct dwarf2_section_info macro {};
- struct dwarf2_section_info gdb_index {};
- struct dwarf2_section_info debug_names {};
-
- /* The dwz's BFD. */
- gdb_bfd_ref_ptr dwz_bfd;
-
- /* If we loaded the index from an external file, this contains the
- resources associated to the open file, memory mapping, etc. */
- std::unique_ptr<index_cache_resource> index_cache_res;
-};
-
/* Struct used to pass misc. parameters to read_die_and_children, et
al. which are used for both .debug_info and .debug_types dies.
All parameters here are unchanging for the life of the call. This
@@ -2668,11 +2642,9 @@ locate_dwz_sections (bfd *abfd, asection *sectp, void *arg)
}
}
-/* Open the separate '.dwz' debug file, if needed. Return NULL if
- there is no .gnu_debugaltlink section in the file. Error if there
- is such a section but the file cannot be found. */
+/* See dwarf2read.h. */
-static struct dwz_file *
+struct dwz_file *
dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
const char *filename;
diff --git a/gdb/dwarf2read.h b/gdb/dwarf2read.h
index 732654348a8..e8658950e36 100644
--- a/gdb/dwarf2read.h
+++ b/gdb/dwarf2read.h
@@ -405,4 +405,42 @@ DEF_VEC_P (sig_type_ptr);
ULONGEST read_unsigned_leb128 (bfd *, const gdb_byte *, unsigned int *);
+/* This represents a '.dwz' file. */
+
+struct dwz_file
+{
+ dwz_file (gdb_bfd_ref_ptr &&bfd)
+ : dwz_bfd (std::move (bfd))
+ {
+ }
+
+ const char *filename () const
+ {
+ return bfd_get_filename (this->dwz_bfd);
+ }
+
+ /* A dwz file can only contain a few sections. */
+ struct dwarf2_section_info abbrev {};
+ struct dwarf2_section_info info {};
+ struct dwarf2_section_info str {};
+ struct dwarf2_section_info line {};
+ struct dwarf2_section_info macro {};
+ struct dwarf2_section_info gdb_index {};
+ struct dwarf2_section_info debug_names {};
+
+ /* The dwz's BFD. */
+ gdb_bfd_ref_ptr dwz_bfd;
+
+ /* If we loaded the index from an external file, this contains the
+ resources associated to the open file, memory mapping, etc. */
+ std::unique_ptr<index_cache_resource> index_cache_res;
+};
+
+/* Open the separate '.dwz' debug file, if needed. Return NULL if
+ there is no .gnu_debugaltlink section in the file. Error if there
+ is such a section but the file cannot be found. */
+
+extern struct dwz_file *dwarf2_get_dwz_file
+ (struct dwarf2_per_objfile *dwarf2_per_objfile);
+
#endif /* DWARF2READ_H */
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 543865765a2..d1558f37894 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2019-06-16 Tom de Vries <tdevries@suse.de>
+
+ PR gdb/24445
+ * gdb.dwarf2/gdb-index.exp (add_gdb_index): Update dwz file with
+ generated index.
+
2019-06-16 Andrew Burgess <andrew.burgess@embecosm.com>
PR gdb/24686
diff --git a/gdb/testsuite/gdb.dwarf2/gdb-index.exp b/gdb/testsuite/gdb.dwarf2/gdb-index.exp
index 410e59684f3..6fca3c61299 100644
--- a/gdb/testsuite/gdb.dwarf2/gdb-index.exp
+++ b/gdb/testsuite/gdb.dwarf2/gdb-index.exp
@@ -34,8 +34,11 @@ if { [prepare_for_testing "failed to prepare" "${testfile}" \
proc add_gdb_index { program } {
set index_file ${program}.gdb-index
+ set dwz ${program}.dwz
+ set dwz_index_file ${dwz}.gdb-index
verbose -log "index_file: ${index_file}"
remote_file host delete ${index_file}
+ remote_file host delete ${dwz_index_file}
gdb_test_no_output "save gdb-index [file dirname ${index_file}]" \
"save gdb-index for file [file tail ${program}]"
@@ -55,6 +58,18 @@ proc add_gdb_index { program } {
if {[run_on_host "objcopy" [gdb_find_objcopy] "--remove-section .gdb_index --add-section .gdb_index=$index_file --set-section-flags .gdb_index=readonly ${program} ${program_with_index}"]} {
return ""
}
+
+ if { [remote_file host exists ${dwz_index_file}] } {
+ # We're modifying $dwz in place, otherwise we'd have to update
+ # .gnu_debugaltlink in $program.
+ set args [join [list "--remove-section .gdb_index" \
+ " --add-section .gdb_index=$dwz_index_file" \
+ " --set-section-flags .gdb_index=readonly $dwz"]]
+ if {[run_on_host "objcopy" [gdb_find_objcopy] "$args"]} {
+ return ""
+ }
+ }
+
return ${program_with_index}
}