From 94313f361f6116eb48c1f07e82ec7c4ae1dfe2a8 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 2 Jun 2009 18:51:34 +0000 Subject: [PATCH] bfd/ * coff-rs6000.c (xcoff_ppc_relocate_section): Allow undefined symbols to be left unimported when linking statically. * xcofflink.c (xcoff_link_add_symbols): Ignore global linkage code when linking statically. ld/testsuite/ * ld-powerpc/aix-glink-3.s, ld-powerpc/aix-glink-3a.s, ld-powerpc/aix-glink-3b.s, ld-powerpc/aix-glink-3.dd, ld-powerpc/aix-glink-3-32.d, ld-powerpc/aix-glink-3-64.d: New tests. * ld-powerpc/aix52.exp: Run them. Move the lineno tests to maintain alphabetical order. --- bfd/ChangeLog | 7 +++++ bfd/coff-rs6000.c | 2 ++ bfd/xcofflink.c | 39 +++++++++++------------ ld/testsuite/ChangeLog | 8 +++++ ld/testsuite/ld-powerpc/aix-glink-3-32.d | 5 +++ ld/testsuite/ld-powerpc/aix-glink-3-64.d | 5 +++ ld/testsuite/ld-powerpc/aix-glink-3.dd | 14 +++++++++ ld/testsuite/ld-powerpc/aix-glink-3.s | 5 +++ ld/testsuite/ld-powerpc/aix-glink-3a.s | 10 ++++++ ld/testsuite/ld-powerpc/aix-glink-3b.s | 11 +++++++ ld/testsuite/ld-powerpc/aix52.exp | 40 ++++++++++++++++++------ 11 files changed, 116 insertions(+), 30 deletions(-) create mode 100644 ld/testsuite/ld-powerpc/aix-glink-3-32.d create mode 100644 ld/testsuite/ld-powerpc/aix-glink-3-64.d create mode 100644 ld/testsuite/ld-powerpc/aix-glink-3.dd create mode 100644 ld/testsuite/ld-powerpc/aix-glink-3.s create mode 100644 ld/testsuite/ld-powerpc/aix-glink-3a.s create mode 100644 ld/testsuite/ld-powerpc/aix-glink-3b.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 77f080c9278..b43f595ca0d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2009-06-02 Richard Sandiford + + * coff-rs6000.c (xcoff_ppc_relocate_section): Allow undefined + symbols to be left unimported when linking statically. + * xcofflink.c (xcoff_link_add_symbols): Ignore global linkage + code when linking statically. + 2009-06-02 H.J. Lu * elf32-i386.c (elf_i386_check_relocs): Increment diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 4859f31b2b4..d1931538c14 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -3460,6 +3460,8 @@ xcoff_ppc_relocate_section (output_bfd, info, input_bfd, else { BFD_ASSERT (info->relocatable + || (info->static_link + && (h->flags & XCOFF_WAS_UNDEFINED) != 0) || (h->flags & XCOFF_DEF_DYNAMIC) != 0 || (h->flags & XCOFF_IMPORT) != 0); } diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index 896292b393e..1c2d0cbc23f 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -1889,6 +1889,15 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) || sym._n._n_n._n_offset == 0) copy = TRUE; + /* Ignore global linkage code when linking statically. */ + if (info->static_link + && (smtyp == XTY_SD || smtyp == XTY_LD) + && aux.x_csect.x_smclas == XMC_GL) + { + section = bfd_und_section_ptr; + value = 0; + } + /* The AIX linker appears to only detect multiple symbol definitions when there is a reference to the symbol. If a symbol is defined multiple times, and the only @@ -1913,8 +1922,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) We also have to handle the case of statically linking a shared object, which will cause symbol redefinitions, although this is an easier case to detect. */ - - if (info->output_bfd->xvec == abfd->xvec) + else if (info->output_bfd->xvec == abfd->xvec) { if (! bfd_is_und_section (section)) *sym_hash = xcoff_link_hash_lookup (xcoff_hash_table (info), @@ -1934,23 +1942,8 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) && ! bfd_is_com_section (section)) { /* This is a second definition of a defined symbol. */ - if ((abfd->flags & DYNAMIC) != 0 - && ((*sym_hash)->smclas != XMC_GL - || aux.x_csect.x_smclas == XMC_GL - || ((*sym_hash)->root.u.def.section->owner->flags - & DYNAMIC) == 0)) - { - /* The new symbol is from a shared library, and - either the existing symbol is not global - linkage code or this symbol is global linkage - code. If the existing symbol is global - linkage code and the new symbol is not, then - we want to use the new symbol. */ - section = bfd_und_section_ptr; - value = 0; - } - else if (((*sym_hash)->flags & XCOFF_DEF_REGULAR) == 0 - && ((*sym_hash)->flags & XCOFF_DEF_DYNAMIC) != 0) + if (((*sym_hash)->flags & XCOFF_DEF_REGULAR) == 0 + && ((*sym_hash)->flags & XCOFF_DEF_DYNAMIC) != 0) { /* The existing symbol is from a shared library. Replace it. */ @@ -2049,7 +2042,9 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) { int flag; - if (smtyp == XTY_ER || smtyp == XTY_CM) + if (smtyp == XTY_ER + || smtyp == XTY_CM + || section == bfd_und_section_ptr) flag = XCOFF_REF_REGULAR; else flag = XCOFF_DEF_REGULAR; @@ -2741,6 +2736,10 @@ xcoff_mark_symbol (struct bfd_link_info *info, struct xcoff_link_hash_entry *h) /* We handle writing out the contents of the descriptor in xcoff_write_global_symbol. */ } + else if (info->static_link) + /* We can't get a symbol value dynamically, so just assume + that it's undefined. */ + h->flags |= XCOFF_WAS_UNDEFINED; else if ((h->flags & XCOFF_CALLED) != 0) { /* This is a function symbol for which we need to create diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 6c73acfe214..fc606d1da8a 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2009-06-02 Richard Sandiford + + * ld-powerpc/aix-glink-3.s, ld-powerpc/aix-glink-3a.s, + ld-powerpc/aix-glink-3b.s, ld-powerpc/aix-glink-3.dd, + ld-powerpc/aix-glink-3-32.d, ld-powerpc/aix-glink-3-64.d: New tests. + * ld-powerpc/aix52.exp: Run them. Move the lineno tests to maintain + alphabetical order. + 2009-06-02 H.J. Lu * ld-ifunc/ifunc-5-i386.d: Renamed to ... diff --git a/ld/testsuite/ld-powerpc/aix-glink-3-32.d b/ld/testsuite/ld-powerpc/aix-glink-3-32.d new file mode 100644 index 00000000000..754789f5677 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-glink-3-32.d @@ -0,0 +1,5 @@ +#name: Glink test 3 (error) (32-bit) +#source: aix-glink-3.s +#as: -a32 +#ld: -b32 -bnoautoimp tmpdir/aix-glink-3b.so +#error: undefined reference to `\.g' diff --git a/ld/testsuite/ld-powerpc/aix-glink-3-64.d b/ld/testsuite/ld-powerpc/aix-glink-3-64.d new file mode 100644 index 00000000000..3ea6817a473 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-glink-3-64.d @@ -0,0 +1,5 @@ +#name: Glink test 3 (error) (64-bit) +#source: aix-glink-3.s +#as: -a64 +#ld: -b64 -bnoautoimp tmpdir/aix64-glink-3b.so +#error: undefined reference to `\.g' diff --git a/ld/testsuite/ld-powerpc/aix-glink-3.dd b/ld/testsuite/ld-powerpc/aix-glink-3.dd new file mode 100644 index 00000000000..b1549362f15 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-glink-3.dd @@ -0,0 +1,14 @@ + +.* + + +Disassembly of section \.text: + +0*10000000 <\.f>: + *10000000: 48 00 00 05 bl 10000004 <\.g> + +0*10000004 <\.g>: + *10000004: 4e 80 00 20 bl?r + +0*10000008 <__start>: + *10000008: 4b ff ff f9 bl 10000000 <\.f> diff --git a/ld/testsuite/ld-powerpc/aix-glink-3.s b/ld/testsuite/ld-powerpc/aix-glink-3.s new file mode 100644 index 00000000000..355dcc6385f --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-glink-3.s @@ -0,0 +1,5 @@ + .extern .f + .globl __start + .csect __start[PR] +__start: + bl .f diff --git a/ld/testsuite/ld-powerpc/aix-glink-3a.s b/ld/testsuite/ld-powerpc/aix-glink-3a.s new file mode 100644 index 00000000000..76aad8c8af7 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-glink-3a.s @@ -0,0 +1,10 @@ + .toc + + .globl .g + .csect .g[PR] +.g: + blr + + .globl g + .csect g[DS] +g: .long .g,TOC[tc0],0 diff --git a/ld/testsuite/ld-powerpc/aix-glink-3b.s b/ld/testsuite/ld-powerpc/aix-glink-3b.s new file mode 100644 index 00000000000..0bedb3b0049 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-glink-3b.s @@ -0,0 +1,11 @@ + .toc + + .extern .g + .globl .f + .csect .f[PR] +.f: + bl .g + + .globl f + .csect f[DS] +f: .long .f,TOC[tc0],0 diff --git a/ld/testsuite/ld-powerpc/aix52.exp b/ld/testsuite/ld-powerpc/aix52.exp index 25479ddb390..d608490259d 100644 --- a/ld/testsuite/ld-powerpc/aix52.exp +++ b/ld/testsuite/ld-powerpc/aix52.exp @@ -145,16 +145,6 @@ set aix52tests { {{objdump {-D -j.text -j.data} aix-glink-1-SIZE.dd}} "aix-glink-1.so"} - {"Line number test 1 (no discards)" "-e.main" - "" {aix-lineno-1.s} - {{objdump -dS aix-lineno-1a.dd} {nm {} aix-lineno-1a.nd}} - "aix-lineno-1a.exe"} - - {"Line number test 1 (discard locals)" "-e.main -x" - "" {aix-lineno-1.s} - {{objdump -dS aix-lineno-1b.dd} {nm {} aix-lineno-1b.nd}} - "aix-lineno-1b.exe"} - {"Glink test 2 (part a)" "-shared -bE:aix-glink-2a.ex" "" {aix-glink-2a.s} {} @@ -176,6 +166,32 @@ set aix52tests { {{objdump -d aix-glink-2-SIZE.dd}} "aix-glink-2"} + {"Glink test 3 (shared library a)" + "-shared -bexpall" + "" {aix-glink-3a.s} + {} "aix-glink-3a.so"} + + {"Glink test 3 (shared library b)" + "-shared -bexpall" + "" {aix-glink-3b.s} + {} "aix-glink-3b.so"} + + {"Glink test 3 (main test)" + "-bnoautoimp tmpdir/aix-glink-3b.so tmpdir/aix-glink-3a.so" + "" {aix-glink-3.s} + {{objdump -d aix-glink-3.dd}} + "aix-glink-3"} + + {"Line number test 1 (no discards)" "-e.main" + "" {aix-lineno-1.s} + {{objdump -dS aix-lineno-1a.dd} {nm {} aix-lineno-1a.nd}} + "aix-lineno-1a.exe"} + + {"Line number test 1 (discard locals)" "-e.main -x" + "" {aix-lineno-1.s} + {{objdump -dS aix-lineno-1b.dd} {nm {} aix-lineno-1b.nd}} + "aix-lineno-1b.exe"} + {"Relocatable test 1" "-r" "" {aix-rel-1.s} {{objdump -hr aix-rel-1.od}} "aix-rel-1.ro"} @@ -236,5 +252,9 @@ foreach test $aix52tests { } } +run_dump_test "aix-glink-1-32" +run_dump_test "aix-glink-1-64" +run_dump_test "aix-glink-3-32" +run_dump_test "aix-glink-3-64" run_dump_test "aix-weak-3-32" run_dump_test "aix-weak-3-64" -- 2.30.2