]>
Commit | Line | Data |
---|---|---|
6ed6bacf AM |
1 | http://sourceware.org/ml/gdb-patches/2011-02/msg00630.html |
2 | Subject: [patch] [i386] Fix {,un}prelinked libraries for attach/core-load | |
3 | ||
4 | Hi, | |
5 | ||
6 | please see comments in the patch. The adjusted testcase FAILs on i386. | |
7 | ||
8 | "Prelink", March 4, 2004 - by Jakub Jelinek: | |
9 | http://people.redhat.com/jakub/prelink.pdf | |
10 | primarily section 7 - REL to RELA conversion | |
11 | ||
12 | An example of unprelinked -> prelinked library change: | |
13 | Program Headers: | |
14 | Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align | |
15 | - LOAD 0x000000 0x00000000 0x00000000 0x00538 0x00538 R E 0x1000 | |
16 | - LOAD 0x000538 0x00001538 0x00001538 0x00100 0x00110 RW 0x1000 | |
17 | - DYNAMIC 0x000550 0x00001550 0x00001550 0x000c8 0x000c8 RW 0x4 | |
18 | - NOTE 0x0000f4 0x000000f4 0x000000f4 0x00024 0x00024 R 0x4 | |
19 | - GNU_EH_FRAME 0x0004e8 0x000004e8 0x000004e8 0x00014 0x00014 R 0x4 | |
20 | + LOAD 0x000000 0x411b3000 0x411b3000 0x00558 0x00558 R E 0x1000 | |
21 | + LOAD 0x000558 0x411b4558 0x411b4558 0x00100 0x00110 RW 0x1000 | |
22 | + DYNAMIC 0x000570 0x411b4570 0x411b4570 0x000c8 0x000c8 RW 0x4 | |
23 | + NOTE 0x0000f4 0x411b30f4 0x411b30f4 0x00024 0x00024 R 0x4 | |
24 | + GNU_EH_FRAME 0x000508 0x411b3508 0x411b3508 0x00014 0x00014 R 0x4 | |
25 | GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 | |
26 | ||
27 | So far GDB expected all such displacements will be always PAGE_SIZE aligned. | |
28 | This applies for example for re-prelinking of an already prelinked file. | |
29 | But it does not apply for prelinking of an unprelinked file or unprelinking of | |
30 | a prelinked file, there can be arbitrary displacement. | |
31 | ||
32 | It affects i386 (=i686, prelink doc reports also ARM and MIPS) which uses REL. | |
33 | x86_64 always uses RELA, therefore I have not noticed it so far. i386 still | |
34 | has to be supported. | |
35 | ||
36 | This affects both attachment to a PID and core file loads. | |
37 | ||
38 | This applies in real world if you transfer a core file between hosts and try to | |
39 | backtrace them, libraries of both hosts may differ whether they are / are not | |
40 | prelinked. | |
41 | ||
42 | I could implement some (displacement-forgiving and prelink-modifications | |
43 | forgiving) comparison of both DYNAMIC segments found. But I do not think it is | |
44 | useful, if the DYNAMIC address from linkmap vs. bfd do not match it is still a | |
45 | better chance to try a displacement to make them match. Keeping the file | |
46 | relocation cannot work anyway when the DYNAMIC address is verified as wrong. | |
47 | ||
48 | No regressions on {x86_64,x86_64-m32,i686}-fedora15-linux-gnu. | |
49 | ||
50 | Mostly do you agree the DYNAMIC content does not have to be verifed? | |
51 | Do you have any comments on the in-code long comments? | |
52 | ||
53 | ||
54 | Thanks, | |
55 | Jan | |
56 | ||
57 | ||
58 | gdb/ | |
59 | 2011-02-22 Jan Kratochvil <jan.kratochvil@redhat.com> | |
60 | ||
61 | Fix libraries displacement if they change whether they were prelinked. | |
62 | * solib-svr4.c (LM_ADDR_CHECK): Set L_ADDR even if the DYNAMIC pointer | |
63 | does not match. Comment why. | |
64 | ||
65 | gdb/testsuite/ | |
66 | 2011-02-22 Jan Kratochvil <jan.kratochvil@redhat.com> | |
67 | ||
68 | * gdb.base/break-interp-lib.c (v, vptr): New variables. | |
69 | * gdb.base/break-interp.exp (test_attach): New comment. | |
70 | ||
71 | --- a/gdb/solib-svr4.c | |
72 | +++ b/gdb/solib-svr4.c | |
73 | @@ -237,11 +237,11 @@ LM_ADDR_CHECK (struct so_list *so, bfd *abfd) | |
74 | ||
75 | Even on PPC it must be zero-aligned at least for MINPAGESIZE. */ | |
76 | ||
77 | + l_addr = l_dynaddr - dynaddr; | |
78 | + | |
79 | if ((l_addr & (minpagesize - 1)) == 0 | |
80 | && (l_addr & align) == ((l_dynaddr - dynaddr) & align)) | |
81 | { | |
82 | - l_addr = l_dynaddr - dynaddr; | |
83 | - | |
84 | if (info_verbose) | |
85 | printf_unfiltered (_("Using PIC (Position Independent Code) " | |
86 | "prelink displacement %s for \"%s\".\n"), | |
87 | @@ -249,9 +249,20 @@ LM_ADDR_CHECK (struct so_list *so, bfd *abfd) | |
88 | so->so_name); | |
89 | } | |
90 | else | |
91 | - warning (_(".dynamic section for \"%s\" " | |
92 | - "is not at the expected address " | |
93 | - "(wrong library or version mismatch?)"), so->so_name); | |
94 | + { | |
95 | + /* There is no way to verify the library file matches. prelink | |
96 | + can during prelinking of an unprelinked file (or unprelinking | |
97 | + of a prelinked file) shift the DYNAMIC segment by arbitrary | |
98 | + offset without any page size alignment. There is no way to | |
99 | + find out the ELF header and/or Program Headers for a limited | |
100 | + verification if it they match. One could do a verification | |
101 | + of the DYNAMIC segment. Still the found address is the best | |
102 | + one GDB could find. */ | |
103 | + | |
104 | + warning (_(".dynamic section for \"%s\" " | |
105 | + "is not at the expected address " | |
106 | + "(wrong library or version mismatch?)"), so->so_name); | |
107 | + } | |
108 | } | |
109 | ||
110 | set_addr: | |
111 | --- a/gdb/testsuite/gdb.base/break-interp-lib.c | |
112 | +++ b/gdb/testsuite/gdb.base/break-interp-lib.c | |
113 | @@ -20,6 +20,10 @@ | |
114 | #include <assert.h> | |
115 | #include <stdio.h> | |
116 | ||
117 | +/* Force REL->RELA conversion on i386, see "Prelink", March 4, 2004. */ | |
118 | +volatile int v[2]; | |
119 | +volatile int *vptr = &v[1]; | |
120 | + | |
121 | void | |
122 | libfunc (const char *action) | |
123 | { | |
124 | --- a/gdb/testsuite/gdb.base/break-interp.exp | |
125 | +++ b/gdb/testsuite/gdb.base/break-interp.exp | |
126 | @@ -352,6 +352,14 @@ proc test_attach {file displacement {relink_args ""}} { | |
127 | # test simplicity, we merged this test and the test above by not | |
128 | # restoring $INTERP after $EXEC prelink. $INTERP gets restored | |
129 | # later below. | |
130 | + # | |
131 | + # `(wrong library or version mismatch?)' messages are printed for | |
132 | + # $binfile_lib on platforms converting REL->RELA relocations by | |
133 | + # prelink (such as on i386). There is no reliable way to verify | |
134 | + # the library file matches the running library in such case but | |
135 | + # GDB at least attempts to set the right displacement. We test | |
136 | + # `libfunc' is present in the backtrace and therefore the | |
137 | + # displacement has been guessed right. | |
138 | ||
139 | if [prelink$relink $relink_args [file tail $exec]] { | |
140 | # /proc/PID/exe cannot be loaded as it is "EXECNAME (deleted)". | |
141 |