/* Copyright (C) 2021-2024 Free Software Foundation, Inc. Contributed by Oracle. This file is part of GNU Binutils. 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, 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, write to the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include #include #include "util.h" #include "DbeSession.h" #include "LoadObject.h" #include "ArchiveExp.h" #include "DbeFile.h" #include "CallStack.h" #include "gp-archive.h" #include "Function.h" #include "Module.h" ArchiveExp::ArchiveExp (char *path) : Experiment () { force_flag = false; copyso_flag = false; use_fndr_archives = true; status = find_expdir (path); if (status == SUCCESS) read_log_file (); } ArchiveExp::~ArchiveExp () { } void ArchiveExp::read_data (int s_option) { read_archives (); read_map_file (); if (read_java_classes_file () == SUCCESS) { for (int i = 0, sz = loadObjs ? loadObjs->size () : 0; i < sz; i++) { LoadObject *lo = loadObjs->get (i); Dprintf (DEBUG_ARCHIVE, NTXT ("%s:%d loadObjs[%d]=%-25s %s\n"), get_basename (__FILE__), (int) __LINE__, i, STR (lo->get_name ()), STR (lo->get_pathname ())); if ((lo->dbeFile->filetype & DbeFile::F_JAVACLASS) == 0) continue; lo->isUsed = true; if ((s_option & ARCH_EXE_ONLY) != 0) continue; lo->sync_read_stabs (); } } if ((s_option & (ARCH_USED_EXE_ONLY | ARCH_USED_SRC_ONLY)) != 0) { read_frameinfo_file (); resolveFrameInfo = true; Vector *ddscr = getDataDescriptors (); delete ddscr; // getDataDescriptors() forces reading of experiment data CallStack *callStack = callTree (); if (callStack) { if (DEBUG_ARCHIVE) { Dprintf (DEBUG_ARCHIVE, NTXT ("stacks=%p\n"), callStack); callStack->print (NULL); } for (int n = 0;; n++) { CallStackNode *node = callStack->get_node (n); if (node == NULL) break; do { Histable *h = node->get_instr (); Histable::Type t = h->get_type (); if (t == Histable::INSTR) { DbeInstr *dbeInstr = (DbeInstr *) h; if (!dbeInstr->isUsed) { Function *func = (Function *) dbeInstr->convertto (Histable::FUNCTION); if (!func->isUsed) { func->isUsed = true; func->module->isUsed = true; func->module->loadobject->isUsed = true; } DbeLine *dbeLine = (DbeLine *) dbeInstr->convertto (Histable::LINE); if (dbeLine) dbeLine->sourceFile->isUsed = true; } } else if (t == Histable::LINE) { DbeLine * dbeLine = (DbeLine *) h; dbeLine->sourceFile->isUsed = true; } node = node->ancestor; } while (node); } } } } char * ArchiveExp::createLinkToFndrArchive (LoadObject *lo, int /* hide_msg */) { // For example, archives of libc.so will be: // /archives/ // /M_r0.er/archives/libc.so_ -> ../../archives/ if (!create_dir (get_fndr_arch_name ())) { fprintf (stderr, GTXT ("Unable to create directory `%s'\n"), get_fndr_arch_name ()); return NULL; } uint32_t checksum = lo->get_checksum (); char *linkName = dbe_sprintf (NTXT ("../../%s/%u"), SP_ARCHIVES_DIR, checksum); char *nm = lo->get_pathname (); char *symLinkName = getNameInArchive (nm, false); if (symlink (linkName, symLinkName) != 0) { fprintf (stderr, GTXT ("Unable to create link `%s' -> `%s'\n"), symLinkName, linkName); free (linkName); free (symLinkName); return NULL; } free (linkName); free (symLinkName); // Return a full path inside founder archive: return dbe_sprintf (NTXT ("%s/%u"), get_fndr_arch_name (), checksum); }