17d62b00eSchristos /* DWARF DWZ handling for GDB. 27d62b00eSchristos 3*6881a400Schristos Copyright (C) 2003-2023 Free Software Foundation, Inc. 47d62b00eSchristos 57d62b00eSchristos This file is part of GDB. 67d62b00eSchristos 77d62b00eSchristos This program is free software; you can redistribute it and/or modify 87d62b00eSchristos it under the terms of the GNU General Public License as published by 97d62b00eSchristos the Free Software Foundation; either version 3 of the License, or 107d62b00eSchristos (at your option) any later version. 117d62b00eSchristos 127d62b00eSchristos This program is distributed in the hope that it will be useful, 137d62b00eSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 147d62b00eSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 157d62b00eSchristos GNU General Public License for more details. 167d62b00eSchristos 177d62b00eSchristos You should have received a copy of the GNU General Public License 187d62b00eSchristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 197d62b00eSchristos 207d62b00eSchristos #include "defs.h" 217d62b00eSchristos #include "dwarf2/dwz.h" 227d62b00eSchristos 23*6881a400Schristos #include "build-id.h" 24*6881a400Schristos #include "debuginfod-support.h" 25*6881a400Schristos #include "dwarf2/read.h" 26*6881a400Schristos #include "dwarf2/sect-names.h" 27*6881a400Schristos #include "filenames.h" 28*6881a400Schristos #include "gdb_bfd.h" 29*6881a400Schristos #include "gdbcore.h" 30*6881a400Schristos #include "gdbsupport/pathstuff.h" 31*6881a400Schristos #include "gdbsupport/scoped_fd.h" 32*6881a400Schristos 337d62b00eSchristos const char * 347d62b00eSchristos dwz_file::read_string (struct objfile *objfile, LONGEST str_offset) 357d62b00eSchristos { 367d62b00eSchristos str.read (objfile); 377d62b00eSchristos 387d62b00eSchristos if (str.buffer == NULL) 397d62b00eSchristos error (_("DW_FORM_GNU_strp_alt used without .debug_str " 407d62b00eSchristos "section [in module %s]"), 417d62b00eSchristos bfd_get_filename (dwz_bfd.get ())); 427d62b00eSchristos if (str_offset >= str.size) 437d62b00eSchristos error (_("DW_FORM_GNU_strp_alt pointing outside of " 447d62b00eSchristos ".debug_str section [in module %s]"), 457d62b00eSchristos bfd_get_filename (dwz_bfd.get ())); 467d62b00eSchristos gdb_assert (HOST_CHAR_BIT == 8); 477d62b00eSchristos if (str.buffer[str_offset] == '\0') 487d62b00eSchristos return NULL; 497d62b00eSchristos return (const char *) (str.buffer + str_offset); 507d62b00eSchristos } 51*6881a400Schristos 52*6881a400Schristos /* A helper function to find the sections for a .dwz file. */ 53*6881a400Schristos 54*6881a400Schristos static void 55*6881a400Schristos locate_dwz_sections (bfd *abfd, asection *sectp, dwz_file *dwz_file) 56*6881a400Schristos { 57*6881a400Schristos /* Note that we only support the standard ELF names, because .dwz 58*6881a400Schristos is ELF-only (at the time of writing). */ 59*6881a400Schristos if (dwarf2_elf_names.abbrev.matches (sectp->name)) 60*6881a400Schristos { 61*6881a400Schristos dwz_file->abbrev.s.section = sectp; 62*6881a400Schristos dwz_file->abbrev.size = bfd_section_size (sectp); 63*6881a400Schristos } 64*6881a400Schristos else if (dwarf2_elf_names.info.matches (sectp->name)) 65*6881a400Schristos { 66*6881a400Schristos dwz_file->info.s.section = sectp; 67*6881a400Schristos dwz_file->info.size = bfd_section_size (sectp); 68*6881a400Schristos } 69*6881a400Schristos else if (dwarf2_elf_names.str.matches (sectp->name)) 70*6881a400Schristos { 71*6881a400Schristos dwz_file->str.s.section = sectp; 72*6881a400Schristos dwz_file->str.size = bfd_section_size (sectp); 73*6881a400Schristos } 74*6881a400Schristos else if (dwarf2_elf_names.line.matches (sectp->name)) 75*6881a400Schristos { 76*6881a400Schristos dwz_file->line.s.section = sectp; 77*6881a400Schristos dwz_file->line.size = bfd_section_size (sectp); 78*6881a400Schristos } 79*6881a400Schristos else if (dwarf2_elf_names.macro.matches (sectp->name)) 80*6881a400Schristos { 81*6881a400Schristos dwz_file->macro.s.section = sectp; 82*6881a400Schristos dwz_file->macro.size = bfd_section_size (sectp); 83*6881a400Schristos } 84*6881a400Schristos else if (dwarf2_elf_names.gdb_index.matches (sectp->name)) 85*6881a400Schristos { 86*6881a400Schristos dwz_file->gdb_index.s.section = sectp; 87*6881a400Schristos dwz_file->gdb_index.size = bfd_section_size (sectp); 88*6881a400Schristos } 89*6881a400Schristos else if (dwarf2_elf_names.debug_names.matches (sectp->name)) 90*6881a400Schristos { 91*6881a400Schristos dwz_file->debug_names.s.section = sectp; 92*6881a400Schristos dwz_file->debug_names.size = bfd_section_size (sectp); 93*6881a400Schristos } 94*6881a400Schristos } 95*6881a400Schristos 96*6881a400Schristos /* Attempt to find a .dwz file (whose full path is represented by 97*6881a400Schristos FILENAME) in all of the specified debug file directories provided. 98*6881a400Schristos 99*6881a400Schristos Return the equivalent gdb_bfd_ref_ptr of the .dwz file found, or 100*6881a400Schristos nullptr if it could not find anything. */ 101*6881a400Schristos 102*6881a400Schristos static gdb_bfd_ref_ptr 103*6881a400Schristos dwz_search_other_debugdirs (std::string &filename, bfd_byte *buildid, 104*6881a400Schristos size_t buildid_len) 105*6881a400Schristos { 106*6881a400Schristos /* Let's assume that the path represented by FILENAME has the 107*6881a400Schristos "/.dwz/" subpath in it. This is what (most) GNU/Linux 108*6881a400Schristos distributions do, anyway. */ 109*6881a400Schristos size_t dwz_pos = filename.find ("/.dwz/"); 110*6881a400Schristos 111*6881a400Schristos if (dwz_pos == std::string::npos) 112*6881a400Schristos return nullptr; 113*6881a400Schristos 114*6881a400Schristos /* This is an obvious assertion, but it's here more to educate 115*6881a400Schristos future readers of this code that FILENAME at DWZ_POS *must* 116*6881a400Schristos contain a directory separator. */ 117*6881a400Schristos gdb_assert (IS_DIR_SEPARATOR (filename[dwz_pos])); 118*6881a400Schristos 119*6881a400Schristos gdb_bfd_ref_ptr dwz_bfd; 120*6881a400Schristos std::vector<gdb::unique_xmalloc_ptr<char>> debugdir_vec 121*6881a400Schristos = dirnames_to_char_ptr_vec (debug_file_directory.c_str ()); 122*6881a400Schristos 123*6881a400Schristos for (const gdb::unique_xmalloc_ptr<char> &debugdir : debugdir_vec) 124*6881a400Schristos { 125*6881a400Schristos /* The idea is to iterate over the 126*6881a400Schristos debug file directories provided by the user and 127*6881a400Schristos replace the hard-coded path in the "filename" by each 128*6881a400Schristos debug-file-directory. 129*6881a400Schristos 130*6881a400Schristos For example, suppose that filename is: 131*6881a400Schristos 132*6881a400Schristos /usr/lib/debug/.dwz/foo.dwz 133*6881a400Schristos 134*6881a400Schristos And suppose that we have "$HOME/bar" as the 135*6881a400Schristos debug-file-directory. We would then adjust filename 136*6881a400Schristos to look like: 137*6881a400Schristos 138*6881a400Schristos $HOME/bar/.dwz/foo.dwz 139*6881a400Schristos 140*6881a400Schristos which would hopefully allow us to find the alt debug 141*6881a400Schristos file. */ 142*6881a400Schristos std::string ddir = debugdir.get (); 143*6881a400Schristos 144*6881a400Schristos if (ddir.empty ()) 145*6881a400Schristos continue; 146*6881a400Schristos 147*6881a400Schristos /* Make sure the current debug-file-directory ends with a 148*6881a400Schristos directory separator. This is needed because, if FILENAME 149*6881a400Schristos contains something like "/usr/lib/abcde/.dwz/foo.dwz" and 150*6881a400Schristos DDIR is "/usr/lib/abc", then could wrongfully skip it 151*6881a400Schristos below. */ 152*6881a400Schristos if (!IS_DIR_SEPARATOR (ddir.back ())) 153*6881a400Schristos ddir += SLASH_STRING; 154*6881a400Schristos 155*6881a400Schristos /* Check whether the beginning of FILENAME is DDIR. If it is, 156*6881a400Schristos then we are dealing with a file which we already attempted to 157*6881a400Schristos open before, so we just skip it and continue processing the 158*6881a400Schristos remaining debug file directories. */ 159*6881a400Schristos if (filename.size () > ddir.size () 160*6881a400Schristos && filename.compare (0, ddir.size (), ddir) == 0) 161*6881a400Schristos continue; 162*6881a400Schristos 163*6881a400Schristos /* Replace FILENAME's default debug-file-directory with 164*6881a400Schristos DDIR. */ 165*6881a400Schristos std::string new_filename = ddir + &filename[dwz_pos + 1]; 166*6881a400Schristos 167*6881a400Schristos dwz_bfd = gdb_bfd_open (new_filename.c_str (), gnutarget); 168*6881a400Schristos 169*6881a400Schristos if (dwz_bfd == nullptr) 170*6881a400Schristos continue; 171*6881a400Schristos 172*6881a400Schristos if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid)) 173*6881a400Schristos { 174*6881a400Schristos dwz_bfd.reset (nullptr); 175*6881a400Schristos continue; 176*6881a400Schristos } 177*6881a400Schristos 178*6881a400Schristos /* Found it. */ 179*6881a400Schristos break; 180*6881a400Schristos } 181*6881a400Schristos 182*6881a400Schristos return dwz_bfd; 183*6881a400Schristos } 184*6881a400Schristos 185*6881a400Schristos /* See dwz.h. */ 186*6881a400Schristos 187*6881a400Schristos struct dwz_file * 188*6881a400Schristos dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd, bool require) 189*6881a400Schristos { 190*6881a400Schristos bfd_size_type buildid_len_arg; 191*6881a400Schristos size_t buildid_len; 192*6881a400Schristos bfd_byte *buildid; 193*6881a400Schristos 194*6881a400Schristos if (per_bfd->dwz_file != NULL) 195*6881a400Schristos return per_bfd->dwz_file.get (); 196*6881a400Schristos 197*6881a400Schristos bfd_set_error (bfd_error_no_error); 198*6881a400Schristos gdb::unique_xmalloc_ptr<char> data 199*6881a400Schristos (bfd_get_alt_debug_link_info (per_bfd->obfd, 200*6881a400Schristos &buildid_len_arg, &buildid)); 201*6881a400Schristos if (data == NULL) 202*6881a400Schristos { 203*6881a400Schristos if (bfd_get_error () == bfd_error_no_error) 204*6881a400Schristos { 205*6881a400Schristos if (!require) 206*6881a400Schristos return nullptr; 207*6881a400Schristos error (_("could not read '.gnu_debugaltlink' section")); 208*6881a400Schristos } 209*6881a400Schristos error (_("could not read '.gnu_debugaltlink' section: %s"), 210*6881a400Schristos bfd_errmsg (bfd_get_error ())); 211*6881a400Schristos } 212*6881a400Schristos 213*6881a400Schristos gdb::unique_xmalloc_ptr<bfd_byte> buildid_holder (buildid); 214*6881a400Schristos 215*6881a400Schristos buildid_len = (size_t) buildid_len_arg; 216*6881a400Schristos 217*6881a400Schristos std::string filename = data.get (); 218*6881a400Schristos 219*6881a400Schristos if (!IS_ABSOLUTE_PATH (filename.c_str ())) 220*6881a400Schristos { 221*6881a400Schristos gdb::unique_xmalloc_ptr<char> abs 222*6881a400Schristos = gdb_realpath (bfd_get_filename (per_bfd->obfd)); 223*6881a400Schristos 224*6881a400Schristos filename = ldirname (abs.get ()) + SLASH_STRING + filename; 225*6881a400Schristos } 226*6881a400Schristos 227*6881a400Schristos /* First try the file name given in the section. If that doesn't 228*6881a400Schristos work, try to use the build-id instead. */ 229*6881a400Schristos gdb_bfd_ref_ptr dwz_bfd (gdb_bfd_open (filename.c_str (), gnutarget)); 230*6881a400Schristos if (dwz_bfd != NULL) 231*6881a400Schristos { 232*6881a400Schristos if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid)) 233*6881a400Schristos dwz_bfd.reset (nullptr); 234*6881a400Schristos } 235*6881a400Schristos 236*6881a400Schristos if (dwz_bfd == NULL) 237*6881a400Schristos dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid); 238*6881a400Schristos 239*6881a400Schristos if (dwz_bfd == nullptr) 240*6881a400Schristos { 241*6881a400Schristos /* If the user has provided us with different 242*6881a400Schristos debug file directories, we can try them in order. */ 243*6881a400Schristos dwz_bfd = dwz_search_other_debugdirs (filename, buildid, buildid_len); 244*6881a400Schristos } 245*6881a400Schristos 246*6881a400Schristos if (dwz_bfd == nullptr) 247*6881a400Schristos { 248*6881a400Schristos gdb::unique_xmalloc_ptr<char> alt_filename; 249*6881a400Schristos const char *origname = bfd_get_filename (per_bfd->obfd); 250*6881a400Schristos 251*6881a400Schristos scoped_fd fd (debuginfod_debuginfo_query (buildid, 252*6881a400Schristos buildid_len, 253*6881a400Schristos origname, 254*6881a400Schristos &alt_filename)); 255*6881a400Schristos 256*6881a400Schristos if (fd.get () >= 0) 257*6881a400Schristos { 258*6881a400Schristos /* File successfully retrieved from server. */ 259*6881a400Schristos dwz_bfd = gdb_bfd_open (alt_filename.get (), gnutarget); 260*6881a400Schristos 261*6881a400Schristos if (dwz_bfd == nullptr) 262*6881a400Schristos warning (_("File \"%s\" from debuginfod cannot be opened as bfd"), 263*6881a400Schristos alt_filename.get ()); 264*6881a400Schristos else if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid)) 265*6881a400Schristos dwz_bfd.reset (nullptr); 266*6881a400Schristos } 267*6881a400Schristos } 268*6881a400Schristos 269*6881a400Schristos if (dwz_bfd == NULL) 270*6881a400Schristos error (_("could not find '.gnu_debugaltlink' file for %s"), 271*6881a400Schristos bfd_get_filename (per_bfd->obfd)); 272*6881a400Schristos 273*6881a400Schristos std::unique_ptr<struct dwz_file> result 274*6881a400Schristos (new struct dwz_file (std::move (dwz_bfd))); 275*6881a400Schristos 276*6881a400Schristos for (asection *sec : gdb_bfd_sections (result->dwz_bfd)) 277*6881a400Schristos locate_dwz_sections (result->dwz_bfd.get (), sec, result.get ()); 278*6881a400Schristos 279*6881a400Schristos gdb_bfd_record_inclusion (per_bfd->obfd, result->dwz_bfd.get ()); 280*6881a400Schristos per_bfd->dwz_file = std::move (result); 281*6881a400Schristos return per_bfd->dwz_file.get (); 282*6881a400Schristos } 283