| /* 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 <stdio.h> | |
| #include <unistd.h> | |
| #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<DataDescriptor*> *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: | |
| // <exp>/archives/<libc.so_check_sum> | |
| // <exp>/M_r0.er/archives/libc.so_<hash> -> ../../archives/<libc.so_check_sum> | |
| 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); | |
| } |