1 /* Copyright (C) 2021 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
25 #include "DbeSession.h"
27 #include "SourceFile.h"
28 #include "DefaultMap.h"
30 #include "LoadObject.h"
33 int SourceFile::curId = 0;
35 SourceFile::SourceFile (const char *file_name)
42 functions = new DefaultMap<Function *, Function *>();
43 dbeFile = new DbeFile (file_name);
44 dbeFile->filetype |= DbeFile::F_SOURCE | DbeFile::F_FILE;
45 set_name ((char *) file_name);
46 srcMTime = (time_t) 0;
50 id = (uint64_t) ((Histable::SOURCEFILE << 24) + curId) << 32;
54 SourceFile::~SourceFile ()
56 destroy_map (DbeLine *, dbeLines);
66 free (srcLines->get (0));
74 SourceFile::set_name (char* _name)
76 name = dbe_strdup (_name);
80 SourceFile::get_name (NameFormat)
86 SourceFile::readSource ()
91 char *location = dbeFile->get_location ();
95 srcMTime = dbeFile->sbuf.st_mtime;
96 srcInode = dbeFile->sbuf.st_ino;
97 size_t srcLen = dbeFile->sbuf.st_size;
98 int fd = open64 (location, O_RDONLY);
104 char *srcMap = (char *) malloc (srcLen + 1);
105 int64_t sz = read_from_file (fd, srcMap, srcLen);
106 if (sz != (int64_t) srcLen)
107 append_msg (CMSG_ERROR, GTXT ("%s: Can read only %lld bytes instead %lld"),
108 location, (long long) sz, (long long) srcLen);
112 // Count the number of lines in the file, converting <nl> to zero
113 srcLines = new Vector<char*>();
114 srcLines->append (srcMap);
115 for (int64_t i = 0; i < sz; i++)
117 if (srcMap[i] == '\r')
120 if (i + 1 < sz && srcMap[i + 1] != '\n')
121 srcLines->append (srcMap + i + 1);
123 else if (srcMap[i] == '\n')
127 srcLines->append (srcMap + i + 1);
132 Vector<DbeLine *> *v = dbeLines->values ();
133 for (long i = 0, sz1 = v ? v->size () : 0; i < sz1; i++)
135 DbeLine *p = v->get (i);
136 if (p->lineno >= srcLines->size ())
137 append_msg (CMSG_ERROR, GTXT ("Wrong line number %d. '%s' has only %d lines"),
138 p->lineno, dbeFile->get_location (), srcLines->size ());
147 SourceFile::getLine (int lineno)
149 assert (srcLines != NULL);
150 if (lineno > 0 && lineno <= srcLines->size ())
151 return srcLines->get (lineno - 1);
156 SourceFile::find_dbeline (Function *func, int lineno)
158 if (lineno < 0 || (lineno == 0 && func == NULL))
160 DbeLine *dbeLine = NULL;
162 { // the source is available
163 if (lineno > lines->size ())
166 dbeLine = dbeLines->get (lineno);
168 append_msg (CMSG_ERROR,
169 GTXT ("Wrong line number %d. '%s' has only %d lines"),
170 lineno, dbeFile->get_location (), lines->size ());
174 dbeLine = lines->fetch (lineno);
177 dbeLine = new DbeLine (NULL, this, lineno);
178 lines->store (lineno, dbeLine);
183 { // the source is not yet read or lineno is wrong
184 if (dbeLines == NULL)
185 dbeLines = new DefaultMap<int, DbeLine *>();
186 dbeLine = dbeLines->get (lineno);
189 dbeLine = new DbeLine (NULL, this, lineno);
190 dbeLines->put (lineno, dbeLine);
194 for (DbeLine *last = dbeLine;; last = last->dbeline_func_next)
196 if (last->func == func)
198 if (last->dbeline_func_next == NULL)
200 DbeLine *dl = new DbeLine (func, this, lineno);
201 if (functions->get (func) == NULL)
202 functions->put (func, func);
203 last->dbeline_func_next = dl;
204 dl->dbeline_base = dbeLine;
211 SourceFile::get_functions ()
215 // Create all DbeLines for this Source
217 Vector<LoadObject *> *lobjs = dbeSession->get_LoadObjects ();
218 for (long i = 0, sz = VecSize (lobjs); i < sz; i++)
220 LoadObject *lo = lobjs->get (i);
221 for (long i1 = 0, sz1 = VecSize (lo->seg_modules); i1 < sz1; i1++)
223 Module *mod = lo->seg_modules->get (i1);
228 return functions->keySet ();