mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
fd67aa1129
Adds two new external authors to etc/update-copyright.py to cover bfd/ax_tls.m4, and adds gprofng to dirs handled automatically, then updates copyright messages as follows: 1) Update cgen/utils.scm emitted copyrights. 2) Run "etc/update-copyright.py --this-year" with an extra external author I haven't committed, 'Kalray SA.', to cover gas testsuite files (which should have their copyright message removed). 3) Build with --enable-maintainer-mode --enable-cgen-maint=yes. 4) Check out */po/*.pot which we don't update frequently.
232 lines
5.5 KiB
C++
232 lines
5.5 KiB
C++
/* 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 <unistd.h>
|
|
|
|
#include "util.h"
|
|
#include "DbeSession.h"
|
|
#include "Function.h"
|
|
#include "SourceFile.h"
|
|
#include "DefaultMap.h"
|
|
#include "DbeFile.h"
|
|
#include "LoadObject.h"
|
|
#include "Module.h"
|
|
|
|
int SourceFile::curId = 0;
|
|
|
|
SourceFile::SourceFile (const char *file_name)
|
|
{
|
|
status = OS_NOTREAD;
|
|
srcLines = NULL;
|
|
srcInode = -1;
|
|
lines = NULL;
|
|
dbeLines = NULL;
|
|
functions = new DefaultMap<Function *, Function *>();
|
|
dbeFile = new DbeFile (file_name);
|
|
dbeFile->filetype |= DbeFile::F_SOURCE | DbeFile::F_FILE;
|
|
set_name ((char *) file_name);
|
|
srcMTime = (time_t) 0;
|
|
isTmpFile = false;
|
|
flags = 0;
|
|
read_stabs = false;
|
|
id = (uint64_t) ((Histable::SOURCEFILE << 24) + curId) << 32;
|
|
curId++;
|
|
}
|
|
|
|
SourceFile::~SourceFile ()
|
|
{
|
|
destroy_map (DbeLine *, dbeLines);
|
|
delete functions;
|
|
delete dbeFile;
|
|
if (lines)
|
|
{
|
|
lines->destroy ();
|
|
delete lines;
|
|
}
|
|
if (srcLines)
|
|
{
|
|
free (srcLines->get (0));
|
|
delete srcLines;
|
|
}
|
|
if (isTmpFile)
|
|
unlink (name);
|
|
}
|
|
|
|
void
|
|
SourceFile::set_name (char* _name)
|
|
{
|
|
name = dbe_strdup (_name);
|
|
}
|
|
|
|
char*
|
|
SourceFile::get_name (NameFormat)
|
|
{
|
|
return name;
|
|
}
|
|
|
|
bool
|
|
SourceFile::readSource ()
|
|
{
|
|
if (srcLines)
|
|
return true;
|
|
status = OS_NOSRC;
|
|
char *location = dbeFile->get_location ();
|
|
if (location == NULL)
|
|
return false;
|
|
if (!isTmpFile)
|
|
srcMTime = dbeFile->sbuf.st_mtime;
|
|
srcInode = dbeFile->sbuf.st_ino;
|
|
size_t srcLen = dbeFile->sbuf.st_size;
|
|
int fd = open64 (location, O_RDONLY);
|
|
if (fd == -1)
|
|
{
|
|
status = OS_NOSRC;
|
|
return false;
|
|
}
|
|
char *srcMap = (char *) malloc (srcLen + 1);
|
|
int64_t sz = read_from_file (fd, srcMap, srcLen);
|
|
if (sz != (int64_t) srcLen)
|
|
append_msg (CMSG_ERROR, GTXT ("%s: Can read only %lld bytes instead %lld"),
|
|
location, (long long) sz, (long long) srcLen);
|
|
srcMap[sz] = 0;
|
|
close (fd);
|
|
|
|
// Count the number of lines in the file, converting <nl> to zero
|
|
srcLines = new Vector<char*>();
|
|
srcLines->append (srcMap);
|
|
for (int64_t i = 0; i < sz; i++)
|
|
{
|
|
if (srcMap[i] == '\r')
|
|
{ // Window style
|
|
srcMap[i] = 0;
|
|
if (i + 1 < sz && srcMap[i + 1] != '\n')
|
|
srcLines->append (srcMap + i + 1);
|
|
}
|
|
else if (srcMap[i] == '\n')
|
|
{
|
|
srcMap[i] = '\0';
|
|
if (i + 1 < sz)
|
|
srcLines->append (srcMap + i + 1);
|
|
}
|
|
}
|
|
if (dbeLines)
|
|
{
|
|
Vector<DbeLine *> *v = dbeLines->values ();
|
|
for (long i = 0, sz1 = v ? v->size () : 0; i < sz1; i++)
|
|
{
|
|
DbeLine *p = v->get (i);
|
|
if (p->lineno >= srcLines->size ())
|
|
append_msg (CMSG_ERROR, GTXT ("Wrong line number %d. '%s' has only %d lines"),
|
|
(int) p->lineno, dbeFile->get_location (),
|
|
(int) srcLines->size ());
|
|
}
|
|
delete v;
|
|
}
|
|
status = OS_OK;
|
|
return true;
|
|
}
|
|
|
|
char *
|
|
SourceFile::getLine (int lineno)
|
|
{
|
|
assert (srcLines != NULL);
|
|
if (lineno > 0 && lineno <= srcLines->size ())
|
|
return srcLines->get (lineno - 1);
|
|
return NTXT ("");
|
|
}
|
|
|
|
DbeLine *
|
|
SourceFile::find_dbeline (Function *func, int lineno)
|
|
{
|
|
if (lineno < 0 || (lineno == 0 && func == NULL))
|
|
return NULL;
|
|
DbeLine *dbeLine = NULL;
|
|
if (lines)
|
|
{ // the source is available
|
|
if (lineno > lines->size ())
|
|
{
|
|
if (dbeLines)
|
|
dbeLine = dbeLines->get (lineno);
|
|
if (dbeLine == NULL)
|
|
append_msg (CMSG_ERROR,
|
|
GTXT ("Wrong line number %d. '%s' has only %d lines"),
|
|
(int) lineno, dbeFile->get_location (),
|
|
(int) lines->size ());
|
|
}
|
|
else
|
|
{
|
|
dbeLine = lines->fetch (lineno);
|
|
if (dbeLine == NULL)
|
|
{
|
|
dbeLine = new DbeLine (NULL, this, lineno);
|
|
lines->store (lineno, dbeLine);
|
|
}
|
|
}
|
|
}
|
|
if (dbeLine == NULL)
|
|
{ // the source is not yet read or lineno is wrong
|
|
if (dbeLines == NULL)
|
|
dbeLines = new DefaultMap<int, DbeLine *>();
|
|
dbeLine = dbeLines->get (lineno);
|
|
if (dbeLine == NULL)
|
|
{
|
|
dbeLine = new DbeLine (NULL, this, lineno);
|
|
dbeLines->put (lineno, dbeLine);
|
|
}
|
|
}
|
|
|
|
for (DbeLine *last = dbeLine;; last = last->dbeline_func_next)
|
|
{
|
|
if (last->func == func)
|
|
return last;
|
|
if (last->dbeline_func_next == NULL)
|
|
{
|
|
DbeLine *dl = new DbeLine (func, this, lineno);
|
|
if (functions->get (func) == NULL)
|
|
functions->put (func, func);
|
|
last->dbeline_func_next = dl;
|
|
dl->dbeline_base = dbeLine;
|
|
return dl;
|
|
}
|
|
}
|
|
}
|
|
|
|
Vector<Function *> *
|
|
SourceFile::get_functions ()
|
|
{
|
|
if (!read_stabs)
|
|
{
|
|
// Create all DbeLines for this Source
|
|
read_stabs = true;
|
|
Vector<LoadObject *> *lobjs = dbeSession->get_LoadObjects ();
|
|
for (long i = 0, sz = VecSize (lobjs); i < sz; i++)
|
|
{
|
|
LoadObject *lo = lobjs->get (i);
|
|
for (long i1 = 0, sz1 = VecSize (lo->seg_modules); i1 < sz1; i1++)
|
|
{
|
|
Module *mod = lo->seg_modules->get (i1);
|
|
mod->read_stabs ();
|
|
}
|
|
}
|
|
}
|
|
return functions->keySet ();
|
|
}
|