GAS: Allow automatically assigned entries in the file table to be reassigned if the source file specifically requests to use the assigned slot.

PR 25878
	* dwarf2dbg.c (struct file_entry): Add auto_assigned field.
	(assign_file_to_slot): New function.  Fills in an entry in the
	files table.
	(allocate_filenum): Use new function.
	(allocate_filename_to_slot): Use new function.  If the specified
	slot entry is already in use, but was chosen automatically then
	reassign the automatic entry.
This commit is contained in:
Nick Clifton
2020-04-27 11:35:25 +01:00
parent 25e29062d2
commit 714e6c969f
2 changed files with 71 additions and 51 deletions

View File

@ -1,3 +1,14 @@
2020-04-27 Nick Clifton <nickc@redhat.com>
PR 25878
* dwarf2dbg.c (struct file_entry): Add auto_assigned field.
(assign_file_to_slot): New function. Fills in an entry in the
files table.
(allocate_filenum): Use new function.
(allocate_filename_to_slot): Use new function. If the specified
slot entry is already in use, but was chosen automatically then
reassign the automatic entry.
2020-04-26 Hongtao Liu <hongtao.liu@intel.com 2020-04-26 Hongtao Liu <hongtao.liu@intel.com
* config/tc-i386.c (lfence_before_ret_shl): New member. * config/tc-i386.c (lfence_before_ret_shl): New member.

View File

@ -206,6 +206,7 @@ struct file_entry
{ {
const char * filename; const char * filename;
unsigned int dir; unsigned int dir;
bfd_boolean auto_assigned;
unsigned char md5[NUM_MD5_BYTES]; unsigned char md5[NUM_MD5_BYTES];
}; };
@ -620,6 +621,36 @@ get_directory_table_entry (const char * dirname,
return d; return d;
} }
static bfd_boolean
assign_file_to_slot (unsigned long i, const char *file, unsigned int dir, bfd_boolean auto_assign)
{
if (i >= files_allocated)
{
unsigned int old = files_allocated;
files_allocated = i + 32;
/* Catch wraparound. */
if (files_allocated <= old)
{
as_bad (_("file number %lu is too big"), (unsigned long) i);
return FALSE;
}
files = XRESIZEVEC (struct file_entry, files, files_allocated);
memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry));
}
files[i].filename = file;
files[i].dir = dir;
files[i].auto_assigned = auto_assign;
memset (files[i].md5, 0, NUM_MD5_BYTES);
if (files_in_use < i + 1)
files_in_use = i + 1;
return TRUE;
}
/* Get a .debug_line file number for PATHNAME. If there is a /* Get a .debug_line file number for PATHNAME. If there is a
directory component to PATHNAME, then this will be stored directory component to PATHNAME, then this will be stored
in the directory table, if it is not already present. in the directory table, if it is not already present.
@ -663,7 +694,7 @@ allocate_filenum (const char * pathname)
dir = get_directory_table_entry (pathname, dir_len, FALSE); dir = get_directory_table_entry (pathname, dir_len, FALSE);
/* Do not use slot-0. That is specificailly reserved for use by /* Do not use slot-0. That is specifically reserved for use by
the '.file 0 "name"' directive. */ the '.file 0 "name"' directive. */
for (i = 1; i < files_in_use; ++i) for (i = 1; i < files_in_use; ++i)
if (files[i].dir == dir if (files[i].dir == dir
@ -675,28 +706,9 @@ allocate_filenum (const char * pathname)
return i; return i;
} }
if (i >= files_allocated) if (!assign_file_to_slot (i, file, dir, TRUE))
{
unsigned int old = files_allocated;
files_allocated = i + 32;
/* Catch wraparound. */
if (files_allocated <= old)
{
as_bad (_("file number %lu is too big"), (unsigned long) i);
return -1; return -1;
}
files = XRESIZEVEC (struct file_entry, files, files_allocated);
memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry));
}
files[i].filename = file;
files[i].dir = dir;
memset (files[i].md5, 0, NUM_MD5_BYTES);
if (files_in_use < i + 1)
files_in_use = i + 1;
last_used = i; last_used = i;
last_used_dir_len = dir_len; last_used_dir_len = dir_len;
@ -769,6 +781,20 @@ allocate_filename_to_slot (const char * dirname,
} }
fail: fail:
/* If NUM was previously allocated automatically then
choose another slot for it, so that we can reuse NUM. */
if (files[num].auto_assigned)
{
/* Find an unused slot. */
for (i = 1; i < files_in_use; ++i)
if (files[i].filename == NULL)
break;
if (! assign_file_to_slot (i, files[num].filename, files[num].dir, TRUE))
return FALSE;
files[num].filename = NULL;
}
else
{
as_bad (_("file table slot %u is already occupied by a different file (%s%s%s vs %s%s%s)"), as_bad (_("file table slot %u is already occupied by a different file (%s%s%s vs %s%s%s)"),
num, num,
dir == NULL ? "" : dir, dir == NULL ? "" : dir,
@ -779,6 +805,7 @@ allocate_filename_to_slot (const char * dirname,
filename); filename);
return FALSE; return FALSE;
} }
}
if (dirname == NULL) if (dirname == NULL)
{ {
@ -795,24 +822,9 @@ allocate_filename_to_slot (const char * dirname,
d = get_directory_table_entry (dirname, dirlen, num == 0); d = get_directory_table_entry (dirname, dirlen, num == 0);
i = num; i = num;
if (i >= files_allocated) if (! assign_file_to_slot (i, file, d, FALSE))
{
unsigned int old = files_allocated;
files_allocated = i + 32;
/* Catch wraparound. */
if (files_allocated <= old)
{
as_bad (_("file number %lu is too big"), (unsigned long) i);
return FALSE; return FALSE;
}
files = XRESIZEVEC (struct file_entry, files, files_allocated);
memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry));
}
files[i].filename = file;
files[i].dir = d;
if (with_md5) if (with_md5)
{ {
if (target_big_endian) if (target_big_endian)
@ -863,9 +875,6 @@ allocate_filename_to_slot (const char * dirname,
else else
memset (files[i].md5, 0, NUM_MD5_BYTES); memset (files[i].md5, 0, NUM_MD5_BYTES);
if (files_in_use < i + 1)
files_in_use = i + 1;
return TRUE; return TRUE;
} }