Skip to content

Commit 83924b3

Browse files
committed
x86-64: Restore PIC check for PCREL reloc against protected symbol
commit bd7ab16 Author: H.J. Lu <[email protected]> Date: Tue Feb 13 07:34:22 2018 -0800 x86-64: Generate branch with PLT32 relocation removed check R_X86_64_PC32 relocation against protected symbols in shared objects. Since elf_x86_64_check_relocs is called after we have seen all input files, we can check for PC-relative relocations in elf_x86_64_check_relocs. We should not allow PC-relative relocations against protected symbols since address of protected function and location of protected data may not be in the shared object. bfd/ PR ld/24151 * elf64-x86-64.c (elf_x86_64_need_pic): Check SYMBOL_DEFINED_NON_SHARED_P instead of def_regular. (elf_x86_64_relocate_section): Move PIC check for PC-relative relocations to ... (elf_x86_64_check_relocs): Here. (elf_x86_64_finish_dynamic_symbol): Use SYMBOL_DEFINED_NON_SHARED_P to check if a symbol is defined in a non-shared object. * elfxx-x86.h (SYMBOL_DEFINED_NON_SHARED_P): New. ld/ PR ld/24151 * testsuite/ld-x86-64/pr24151a-x32.d: New file. * testsuite/ld-x86-64/pr24151a.d: Likewise. * testsuite/ld-x86-64/pr24151a.s: Likewise. * testsuite/ld-x86-64/x86-64.exp: Run pr24151a and pr24151a-x32.
1 parent 4e9ac43 commit 83924b3

File tree

8 files changed

+124
-54
lines changed

8 files changed

+124
-54
lines changed

bfd/ChangeLog

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
2019-02-05 H.J. Lu <[email protected]>
2+
3+
PR ld/24151
4+
* elf64-x86-64.c (elf_x86_64_need_pic): Check
5+
SYMBOL_DEFINED_NON_SHARED_P instead of def_regular.
6+
(elf_x86_64_relocate_section): Move PIC check for PC-relative
7+
relocations to ...
8+
(elf_x86_64_check_relocs): Here.
9+
(elf_x86_64_finish_dynamic_symbol): Use SYMBOL_DEFINED_NON_SHARED_P
10+
to check if a symbol is defined in a non-shared object.
11+
* elfxx-x86.h (SYMBOL_DEFINED_NON_SHARED_P): New.
12+
113
2019-01-21 Sergio Durigan Junior <[email protected]>
214

315
* elf32-arm.c (elf32_arm_final_link_relocate): Use 'llabs' instead

bfd/elf64-x86-64.c

Lines changed: 79 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,7 +1426,7 @@ elf_x86_64_need_pic (struct bfd_link_info *info,
14261426
break;
14271427
}
14281428

1429-
if (!h->def_regular && !h->def_dynamic)
1429+
if (!SYMBOL_DEFINED_NON_SHARED_P (h) && !h->def_dynamic)
14301430
und = _("undefined ");
14311431
}
14321432
else
@@ -1855,6 +1855,7 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
18551855
const char *name;
18561856
bfd_boolean size_reloc;
18571857
bfd_boolean converted_reloc;
1858+
bfd_boolean do_check_pic;
18581859

18591860
r_symndx = htab->r_sym (rel->r_info);
18601861
r_type = ELF32_R_TYPE (rel->r_info);
@@ -2130,6 +2131,13 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
21302131
size_reloc = TRUE;
21312132
goto do_size;
21322133

2134+
case R_X86_64_PC8:
2135+
case R_X86_64_PC16:
2136+
case R_X86_64_PC32:
2137+
case R_X86_64_PC32_BND:
2138+
do_check_pic = TRUE;
2139+
goto check_pic;
2140+
21332141
case R_X86_64_32:
21342142
if (!ABI_64_P (abfd))
21352143
goto pointer;
@@ -2153,13 +2161,11 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
21532161
&x86_64_elf_howto_table[r_type]);
21542162
/* Fall through. */
21552163

2156-
case R_X86_64_PC8:
2157-
case R_X86_64_PC16:
2158-
case R_X86_64_PC32:
2159-
case R_X86_64_PC32_BND:
21602164
case R_X86_64_PC64:
21612165
case R_X86_64_64:
21622166
pointer:
2167+
do_check_pic = FALSE;
2168+
check_pic:
21632169
if (eh != NULL && (sec->flags & SEC_CODE) != 0)
21642170
eh->zero_undefweak |= 0x2;
21652171
/* We are called after all symbols have been resolved. Only
@@ -2223,6 +2229,67 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
22232229
}
22242230
}
22252231

2232+
if (do_check_pic)
2233+
{
2234+
/* Don't complain about -fPIC if the symbol is undefined
2235+
when building executable unless it is unresolved weak
2236+
symbol, references a dynamic definition in PIE or
2237+
-z nocopyreloc is used. */
2238+
bfd_boolean no_copyreloc_p
2239+
= (info->nocopyreloc
2240+
|| (h != NULL
2241+
&& eh->def_protected
2242+
&& elf_has_no_copy_on_protected (h->root.u.def.section->owner)));
2243+
if ((sec->flags & SEC_ALLOC) != 0
2244+
&& (sec->flags & SEC_READONLY) != 0
2245+
&& h != NULL
2246+
&& ((bfd_link_executable (info)
2247+
&& ((h->root.type == bfd_link_hash_undefweak
2248+
&& (eh == NULL
2249+
|| !UNDEFINED_WEAK_RESOLVED_TO_ZERO (info,
2250+
eh)))
2251+
|| (bfd_link_pie (info)
2252+
&& !SYMBOL_DEFINED_NON_SHARED_P (h)
2253+
&& h->def_dynamic)
2254+
|| (no_copyreloc_p
2255+
&& h->def_dynamic
2256+
&& !(h->root.u.def.section->flags & SEC_CODE))))
2257+
|| bfd_link_dll (info)))
2258+
{
2259+
bfd_boolean fail = FALSE;
2260+
if (SYMBOL_REFERENCES_LOCAL_P (info, h))
2261+
{
2262+
/* Symbol is referenced locally. Make sure it is
2263+
defined locally. */
2264+
fail = !SYMBOL_DEFINED_NON_SHARED_P (h);
2265+
}
2266+
else if (bfd_link_pie (info))
2267+
{
2268+
/* We can only use PC-relative relocations in PIE
2269+
from non-code sections. */
2270+
if (h->type == STT_FUNC
2271+
&& (sec->flags & SEC_CODE) != 0)
2272+
fail = TRUE;
2273+
}
2274+
else if (no_copyreloc_p || bfd_link_dll (info))
2275+
{
2276+
/* Symbol doesn't need copy reloc and isn't
2277+
referenced locally. Don't allow PC-relative
2278+
relocations against default and protected
2279+
symbols since address of protected function
2280+
and location of protected data may not be in
2281+
the shared object. */
2282+
fail = (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2283+
|| ELF_ST_VISIBILITY (h->other) == STV_PROTECTED);
2284+
}
2285+
2286+
if (fail)
2287+
return elf_x86_64_need_pic (info, abfd, sec, h,
2288+
symtab_hdr, isym,
2289+
&x86_64_elf_howto_table[r_type]);
2290+
}
2291+
}
2292+
22262293
size_reloc = FALSE;
22272294
do_size:
22282295
if (NEED_DYNAMIC_RELOCATION_P (info, TRUE, h, sec, r_type,
@@ -3065,56 +3132,14 @@ elf_x86_64_relocate_section (bfd *output_bfd,
30653132
case R_X86_64_PC16:
30663133
case R_X86_64_PC32:
30673134
case R_X86_64_PC32_BND:
3068-
/* Don't complain about -fPIC if the symbol is undefined when
3069-
building executable unless it is unresolved weak symbol,
3070-
references a dynamic definition in PIE or -z nocopyreloc
3071-
is used. */
3072-
if ((input_section->flags & SEC_ALLOC) != 0
3073-
&& (input_section->flags & SEC_READONLY) != 0
3074-
&& h != NULL
3075-
&& ((bfd_link_executable (info)
3076-
&& ((h->root.type == bfd_link_hash_undefweak
3077-
&& !resolved_to_zero)
3078-
|| (bfd_link_pie (info)
3079-
&& !h->def_regular
3080-
&& h->def_dynamic)
3081-
|| ((info->nocopyreloc
3082-
|| (eh->def_protected
3083-
&& elf_has_no_copy_on_protected (h->root.u.def.section->owner)))
3084-
&& h->def_dynamic
3085-
&& !(h->root.u.def.section->flags & SEC_CODE))))
3086-
|| bfd_link_dll (info)))
3087-
{
3088-
bfd_boolean fail = FALSE;
3089-
if (SYMBOL_REFERENCES_LOCAL_P (info, h))
3090-
{
3091-
/* Symbol is referenced locally. Make sure it is
3092-
defined locally. */
3093-
fail = !(h->def_regular || ELF_COMMON_DEF_P (h));
3094-
}
3095-
else if (!(bfd_link_pie (info)
3096-
&& (h->needs_copy || eh->needs_copy)))
3097-
{
3098-
/* Symbol doesn't need copy reloc and isn't referenced
3099-
locally. Address of protected function may not be
3100-
reachable at run-time. */
3101-
fail = (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3102-
|| (ELF_ST_VISIBILITY (h->other) == STV_PROTECTED
3103-
&& h->type == STT_FUNC));
3104-
}
3105-
3106-
if (fail)
3107-
return elf_x86_64_need_pic (info, input_bfd, input_section,
3108-
h, NULL, NULL, howto);
3109-
}
31103135
/* Since x86-64 has PC-relative PLT, we can use PLT in PIE
31113136
as function address. */
3112-
else if (h != NULL
3113-
&& (input_section->flags & SEC_CODE) == 0
3114-
&& bfd_link_pie (info)
3115-
&& h->type == STT_FUNC
3116-
&& !h->def_regular
3117-
&& h->def_dynamic)
3137+
if (h != NULL
3138+
&& (input_section->flags & SEC_CODE) == 0
3139+
&& bfd_link_pie (info)
3140+
&& h->type == STT_FUNC
3141+
&& !h->def_regular
3142+
&& h->def_dynamic)
31183143
goto use_plt;
31193144
/* Fall through. */
31203145

@@ -4271,7 +4296,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
42714296
else if (bfd_link_pic (info)
42724297
&& SYMBOL_REFERENCES_LOCAL_P (info, h))
42734298
{
4274-
if (!(h->def_regular || ELF_COMMON_DEF_P (h)))
4299+
if (!SYMBOL_DEFINED_NON_SHARED_P (h))
42754300
return FALSE;
42764301
BFD_ASSERT((h->got.offset & 1) != 0);
42774302
rela.r_info = htab->r_info (0, R_X86_64_RELATIVE);

bfd/elfxx-x86.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,13 @@
161161
|| (ELF_ST_VISIBILITY ((H)->other) \
162162
&& (H)->root.type == bfd_link_hash_undefweak))
163163

164+
/* TRUE if this symbol isn't defined by a shared object. */
165+
#define SYMBOL_DEFINED_NON_SHARED_P(H) \
166+
((H)->def_regular \
167+
|| (H)->root.linker_def \
168+
|| (H)->root.ldscript_def \
169+
|| ELF_COMMON_DEF_P (H))
170+
164171
/* TRUE if relative relocation should be generated. GOT reference to
165172
global symbol in PIC will lead to dynamic symbol. It becomes a
166173
problem when "time" or "times" is defined as a variable in an

ld/ChangeLog

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
2019-02-05 H.J. Lu <[email protected]>
2+
3+
PR ld/24151
4+
* testsuite/ld-x86-64/pr24151a-x32.d: New file.
5+
* testsuite/ld-x86-64/pr24151a.d: Likewise.
6+
* testsuite/ld-x86-64/pr24151a.s: Likewise.
7+
* testsuite/ld-x86-64/x86-64.exp: Run pr24151a and pr24151a-x32.
8+
19
2019-01-31 Alan Modra <[email protected]>
210

311
* NEWS: Mention -t change.

ld/testsuite/ld-x86-64/pr24151a-x32.d

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#source: pr24151a.s
2+
#as: --x32
3+
#ld: -shared -melf32_x86_64
4+
#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object

ld/testsuite/ld-x86-64/pr24151a.d

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#as: --64
2+
#ld: -shared -melf_x86_64
3+
#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object

ld/testsuite/ld-x86-64/pr24151a.s

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.text
2+
.globl bar
3+
.type bar,@function
4+
bar:
5+
movl $30, foo(%rip)
6+
.size bar, .-bar
7+
.protected foo
8+
.type foo,@object
9+
.comm foo,4,4

ld/testsuite/ld-x86-64/x86-64.exp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,8 @@ run_dump_test "pr23486d-x32"
424424
run_dump_test "pr23854"
425425
run_dump_test "pr23930"
426426
run_dump_test "pr23930-x32"
427+
run_dump_test "pr24151a"
428+
run_dump_test "pr24151a-x32"
427429

428430
if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
429431
return

0 commit comments

Comments
 (0)