blob: 9afd55cbdca9dee8a0ced1e093a09e27b4e5f029 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001When compiling a project using -frepo, .rpo files are written alongside
2the .o file, the symbols either have O or C against them. During final linking,
3the objects can be recompiled with some of the entries tweaked/chosen by the
4tlink.c code (visible with TLINK_VERBOSE=3), it does this by changing O -> C
5in the .rpo files.
6
7My tests showed that init_repo (cp/repo.c) was correctly calling
8IDENTIFIER_REPO_CHOSEN against the right identifers and setting the
9chosen bit.
10
11By the time finish_repo() or emit_repo_p() were called, the pointer returned
12by get_identifier() for the symbol marked during init_repo had changed and
13the chosen bit was no longer set. This lead to linking bugs like:
14
15collect: relinking
16collect2: error: '_ZNK6sudoku5ClearINS_8SequenceEEclERS1_' was assigned to 'board.rpo', but was not defined during recompilation, or vice versa
17
18The problem is that the garbage collection is getting called before
19finish_repo() is called and ggc_protect_identifiers is set to false
20so the identifiers are not preserved. They are recreated but the
21chosen bits get wiped out which is why the pointer changes and the
22chosen bit is not set.
23
24The fix is to change ggc_protect_identifiers *after* the finish_repo
25calls are made.
26
27Reproduction is tricky since you need to trigger the garbage collector at
28just the right moment.
29
30RP 2013/10/9
31
32[YOCTO #5133]
33
34Upstream-Status: Pending
35
36Index: gcc-4.8.1/gcc/toplev.c
37===================================================================
38--- gcc-4.8.1.orig/gcc/toplev.c 2013-03-28 08:29:51.000000000 +0000
39+++ gcc-4.8.1/gcc/toplev.c 2013-10-09 20:27:17.089228023 +0000
40@@ -551,11 +551,11 @@
41 if (flag_syntax_only || flag_wpa)
42 return;
43
44- ggc_protect_identifiers = false;
45-
46 /* This must also call finalize_compilation_unit. */
47 lang_hooks.decls.final_write_globals ();
48
49+ ggc_protect_identifiers = false;
50+
51 if (seen_error ())
52 return;
53