diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 11 | ||||
-rw-r--r-- | gas/dwarf2dbg.c | 111 |
2 files changed, 71 insertions, 51 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index c4df0e1..eeeb17d 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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 * config/tc-i386.c (lfence_before_ret_shl): New member. diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c index 6a66225..9fdb34f 100644 --- a/gas/dwarf2dbg.c +++ b/gas/dwarf2dbg.c @@ -206,6 +206,7 @@ struct file_entry { const char * filename; unsigned int dir; + bfd_boolean auto_assigned; unsigned char md5[NUM_MD5_BYTES]; }; @@ -620,6 +621,36 @@ get_directory_table_entry (const char * dirname, 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 directory component to PATHNAME, then this will be stored 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); - /* 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. */ for (i = 1; i < files_in_use; ++i) if (files[i].dir == dir @@ -675,28 +706,9 @@ allocate_filenum (const char * pathname) return i; } - 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 -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 (!assign_file_to_slot (i, file, dir, TRUE)) + return -1; - if (files_in_use < i + 1) - files_in_use = i + 1; last_used = i; last_used_dir_len = dir_len; @@ -769,15 +781,30 @@ allocate_filename_to_slot (const char * dirname, } fail: - as_bad (_("file table slot %u is already occupied by a different file (%s%s%s vs %s%s%s)"), - num, - dir == NULL ? "" : dir, - dir == NULL ? "" : "/", - files[num].filename, - dirname == NULL ? "" : dirname, - dirname == NULL ? "" : "/", - filename); - return FALSE; + /* 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)"), + num, + dir == NULL ? "" : dir, + dir == NULL ? "" : "/", + files[num].filename, + dirname == NULL ? "" : dirname, + dirname == NULL ? "" : "/", + filename); + return FALSE; + } } if (dirname == NULL) @@ -795,24 +822,9 @@ allocate_filename_to_slot (const char * dirname, d = get_directory_table_entry (dirname, dirlen, num == 0); i = num; - 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)); - } + if (! assign_file_to_slot (i, file, d, FALSE)) + return FALSE; - files[i].filename = file; - files[i].dir = d; if (with_md5) { if (target_big_endian) @@ -863,9 +875,6 @@ allocate_filename_to_slot (const char * dirname, else memset (files[i].md5, 0, NUM_MD5_BYTES); - if (files_in_use < i + 1) - files_in_use = i + 1; - return TRUE; } |