aboutsummaryrefslogtreecommitdiff
path: root/gcc/lto-streamer-out.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-09-10 11:25:02 +0200
committerJakub Jelinek <jakub@redhat.com>2020-09-10 11:25:02 +0200
commit3d0af0c997fe42a7f0963d970a9c495b81041206 (patch)
tree8f5a07c519e81d791ee3f7cdc65f452afb045c6e /gcc/lto-streamer-out.c
parent47ddf4c7b1d4471cb9534f27844ab5e4279c2168 (diff)
downloadgcc-3d0af0c997fe42a7f0963d970a9c495b81041206.zip
gcc-3d0af0c997fe42a7f0963d970a9c495b81041206.tar.gz
gcc-3d0af0c997fe42a7f0963d970a9c495b81041206.tar.bz2
lto: Stream current working directory for first streamed relative filename and adjust relative paths [PR93865]
If the gcc -c -flto ... commands to compile some or all objects are run in a different directory (or in different directories) from the directory in which the gcc -flto link line is invoked, then the .debug_line will be incorrect if there are any relative filenames, it will use those relative filenames while .debug_info will contain a different DW_AT_comp_dir. The following patch streams (at most once after each clear_line_info) the current working directory (what we record in DW_AT_comp_dir) when encountering the first relative pathname, and when reading the location info reads it back and if the current working directory at that point is different from the saved one, adjusts relative paths by adding a relative prefix how to go from the current working directory to the previously saved path (with a fallback e.g. for DOS e:\\foo vs. d:\\bar change to use absolute directory). 2020-09-10 Jakub Jelinek <jakub@redhat.com> PR debug/93865 * lto-streamer.h (struct output_block): Add emit_pwd member. * lto-streamer-out.c: Include toplev.h. (clear_line_info): Set emit_pwd. (lto_output_location_1): Encode the ob->current_file != xloc.file bit directly into the location number. If changing file, emit additionally a bit whether pwd is emitted and emit it before the first relative pathname since clear_line_info. (output_function, output_constructor): Don't call clear_line_info here. * lto-streamer-in.c (struct string_pair_map): New type. (struct string_pair_map_hasher): New type. (string_pair_map_hasher::hash): New method. (string_pair_map_hasher::equal): New method. (path_name_pair_hash_table, string_pair_map_allocator): New variables. (relative_path_prefix, canon_relative_path_prefix, canon_relative_file_name): New functions. (canon_file_name): Add relative_prefix argument, if non-NULL and string is a relative path, return canon_relative_file_name. (lto_location_cache::input_location_and_block): Decode file change bit from the location number. If changing file, unpack bit whether pwd is streamed and stream in pwd. Adjust canon_file_name caller. (lto_free_file_name_hash): Delete path_name_pair_hash_table and string_pair_map_allocator.
Diffstat (limited to 'gcc/lto-streamer-out.c')
-rw-r--r--gcc/lto-streamer-out.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index 884ce98..354ba01 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "file-prefix-map.h" /* remap_debug_filename() */
#include "output.h"
#include "ipa-utils.h"
+#include "toplev.h"
static void lto_write_tree (struct output_block*, tree, bool);
@@ -61,6 +62,7 @@ clear_line_info (struct output_block *ob)
ob->current_col = 0;
ob->current_sysp = false;
ob->reset_locus = true;
+ ob->emit_pwd = true;
/* Initialize to something that will never appear as block,
so that the first location with block in a function etc.
always streams a change_block bit and the first block. */
@@ -189,9 +191,6 @@ lto_output_location_1 (struct output_block *ob, struct bitpack_d *bp,
{
location_t loc = LOCATION_LOCUS (orig_loc);
- bp_pack_int_in_range (bp, 0, RESERVED_LOCATION_COUNT,
- loc < RESERVED_LOCATION_COUNT
- ? loc : RESERVED_LOCATION_COUNT);
if (loc >= RESERVED_LOCATION_COUNT)
{
expanded_location xloc = expand_location (loc);
@@ -207,13 +206,30 @@ lto_output_location_1 (struct output_block *ob, struct bitpack_d *bp,
ob->reset_locus = false;
}
- bp_pack_value (bp, ob->current_file != xloc.file, 1);
+ /* As RESERVED_LOCATION_COUNT is 2, we can use the spare value of
+ 3 without wasting additional bits to signalize file change.
+ If RESERVED_LOCATION_COUNT changes, reconsider this. */
+ gcc_checking_assert (RESERVED_LOCATION_COUNT == 2);
+ bp_pack_int_in_range (bp, 0, RESERVED_LOCATION_COUNT + 1,
+ RESERVED_LOCATION_COUNT
+ + (ob->current_file != xloc.file));
+
bp_pack_value (bp, ob->current_line != xloc.line, 1);
bp_pack_value (bp, ob->current_col != xloc.column, 1);
if (ob->current_file != xloc.file)
{
- bp_pack_string (ob, bp, remap_debug_filename (xloc.file), true);
+ bool stream_pwd = false;
+ const char *remapped = remap_debug_filename (xloc.file);
+ if (ob->emit_pwd && remapped && !IS_ABSOLUTE_PATH (remapped))
+ {
+ stream_pwd = true;
+ ob->emit_pwd = false;
+ }
+ bp_pack_value (bp, stream_pwd, 1);
+ if (stream_pwd)
+ bp_pack_string (ob, bp, get_src_pwd (), true);
+ bp_pack_string (ob, bp, remapped, true);
bp_pack_value (bp, xloc.sysp, 1);
}
ob->current_file = xloc.file;
@@ -227,6 +243,8 @@ lto_output_location_1 (struct output_block *ob, struct bitpack_d *bp,
bp_pack_var_len_unsigned (bp, xloc.column);
ob->current_col = xloc.column;
}
+ else
+ bp_pack_int_in_range (bp, 0, RESERVED_LOCATION_COUNT + 1, loc);
if (block_p)
{
@@ -2376,7 +2394,6 @@ output_function (struct cgraph_node *node)
fn = DECL_STRUCT_FUNCTION (function);
ob = create_output_block (LTO_section_function_body);
- clear_line_info (ob);
ob->symbol = node;
gcc_assert (current_function_decl == NULL_TREE && cfun == NULL);
@@ -2462,7 +2479,6 @@ output_constructor (struct varpool_node *node)
timevar_push (TV_IPA_LTO_CTORS_OUT);
ob = create_output_block (LTO_section_function_body);
- clear_line_info (ob);
ob->symbol = node;
/* Make string 0 be a NULL string. */