Prepend DW_AT_comp_dir to relative line number directory table entries.

Relative directories may appear in the line number program for a CPU if
files were included via a relative path, for instance with "-I.".
Previously, dwarf_srclines(3) and dwarf_srcfiles(3) would return the
relative path, so addr2line, for instance, would do the same.  However,
we can get an absolute path by prepending the compilation directory, so
change libdwarf to do that to improve compatibility with GNU binutils
and since it is more useful in general.

Reviewed by:	jhb
Discussed with:	emaste
MFC after:	2 weeks
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D19705
This commit is contained in:
Mark Johnston 2019-03-27 19:32:21 +00:00
parent 014ddcbce4
commit 1fc6236006
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=345593

View File

@ -33,9 +33,10 @@ _dwarf_lineno_add_file(Dwarf_LineInfo li, uint8_t **p, const char *compdir,
Dwarf_Error *error, Dwarf_Debug dbg)
{
Dwarf_LineFile lf;
const char *dirname;
FILE *filepath;
const char *incdir;
uint8_t *src;
int slen;
size_t slen;
src = *p;
@ -54,20 +55,33 @@ _dwarf_lineno_add_file(Dwarf_LineInfo li, uint8_t **p, const char *compdir,
return (DW_DLE_DIR_INDEX_BAD);
}
/* Make full pathname if need. */
/* Make a full pathname if needed. */
if (*lf->lf_fname != '/') {
dirname = compdir;
filepath = open_memstream(&lf->lf_fullpath, &slen);
if (filepath == NULL) {
free(lf);
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
return (DW_DLE_MEMORY);
}
if (lf->lf_dirndx > 0)
dirname = li->li_incdirs[lf->lf_dirndx - 1];
if (dirname != NULL) {
slen = strlen(dirname) + strlen(lf->lf_fname) + 2;
if ((lf->lf_fullpath = malloc(slen)) == NULL) {
free(lf);
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
return (DW_DLE_MEMORY);
}
snprintf(lf->lf_fullpath, slen, "%s/%s", dirname,
lf->lf_fname);
incdir = li->li_incdirs[lf->lf_dirndx - 1];
else
incdir = NULL;
/*
* Prepend the compilation directory if the directory table
* entry is relative.
*/
if (incdir == NULL || *incdir != '/')
fprintf(filepath, "%s/", compdir);
if (incdir != NULL)
fprintf(filepath, "%s/", incdir);
fprintf(filepath, "%s", lf->lf_fname);
if (fclose(filepath) != 0) {
free(lf);
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
return (DW_DLE_MEMORY);
}
}