* [PATCH] ld: Properly check static link of dynamic object
@ 2020-03-11 23:57 H.J. Lu
2020-03-12 4:09 ` Fangrui Song
2020-03-12 4:19 ` [PATCH] ld: Properly check static link of dynamic object Alan Modra
0 siblings, 2 replies; 6+ messages in thread
From: H.J. Lu @ 2020-03-11 23:57 UTC (permalink / raw)
To: binutils
When -static is passed to gcc, gcc passes it to linker before any input
files to create static executable. If -Bdynamic is also passed to linker
from command-line, linker should issue an error if dynamic object is used.
include/
PR ld/24920
* bfdlink.h (bfd_link_info): Add static_exec.
ld/
PR ld/24920
* ldfile.c (ldfile_try_open_bfd): Also check link_info.static_exec
for static link of dynamic object.
* lexsup.c (parse_args): Set link_info.static_exec to true if we
see -static before any input files.
* testsuite/ld-elf/pr24920.err: New file.
* testsuite/ld-elf/shared.exp: Run ld/24920 tests.
---
include/bfdlink.h | 3 +++
ld/ldfile.c | 6 ++++--
ld/lexsup.c | 4 ++++
ld/testsuite/ld-elf/pr24920.err | 1 +
ld/testsuite/ld-elf/shared.exp | 18 ++++++++++++++++++
5 files changed, 30 insertions(+), 2 deletions(-)
create mode 100644 ld/testsuite/ld-elf/pr24920.err
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 8d85530e39..a850c6102c 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -322,6 +322,9 @@ struct bfd_link_info
/* Output type. */
ENUM_BITFIELD (output_type) type : 2;
+ /* TRUE if building a static executable. */
+ unsigned int static_exec : 1;
+
/* TRUE if BFD should pre-bind symbols in a shared object. */
unsigned int symbolic: 1;
diff --git a/ld/ldfile.c b/ld/ldfile.c
index aa84906992..7b57bd9fb7 100644
--- a/ld/ldfile.c
+++ b/ld/ldfile.c
@@ -164,7 +164,8 @@ ldfile_try_open_bfd (const char *attempt,
checks out compatible, do not exit early returning TRUE, or
the plugins will not get a chance to claim the file. */
- if (entry->flags.search_dirs || !entry->flags.dynamic)
+ if (entry->flags.search_dirs
+ || (link_info.static_exec || !entry->flags.dynamic))
{
bfd *check;
@@ -274,7 +275,8 @@ ldfile_try_open_bfd (const char *attempt,
goto success;
}
- if (!entry->flags.dynamic && (entry->the_bfd->flags & DYNAMIC) != 0)
+ if ((link_info.static_exec || !entry->flags.dynamic)
+ && (entry->the_bfd->flags & DYNAMIC) != 0)
{
einfo (_("%F%P: attempted static link of dynamic object `%s'\n"),
attempt);
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 3d15cc491d..aeddc52466 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -786,6 +786,10 @@ parse_args (unsigned argc, char **argv)
break;
case OPTION_NON_SHARED:
input_flags.dynamic = FALSE;
+ /* If we see -static before any input files, we are building
+ a static executable. */
+ if (!lang_has_input_file)
+ link_info.static_exec = TRUE;
break;
case OPTION_CREF:
command_line.cref = TRUE;
diff --git a/ld/testsuite/ld-elf/pr24920.err b/ld/testsuite/ld-elf/pr24920.err
new file mode 100644
index 0000000000..8f5cab9167
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr24920.err
@@ -0,0 +1 @@
+.*: attempted static link of dynamic object `tmpdir/pr24920.so'
diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp
index b1762aff9b..0b8024dd1a 100644
--- a/ld/testsuite/ld-elf/shared.exp
+++ b/ld/testsuite/ld-elf/shared.exp
@@ -114,6 +114,24 @@ run_ld_link_tests [list \
{} \
"pr22649-1.so" \
] \
+ [list \
+ "Build pr24920.so" \
+ "$LFLAGS -shared" \
+ "" \
+ "$AFLAGS_PIC" \
+ {dummy.s} \
+ {} \
+ "pr24920.so" \
+ ] \
+ [list \
+ "Build pr24920" \
+ "$LFLAGS -static " \
+ "-Bdynamic tmpdir/pr24920.so" \
+ "" \
+ {start.s} \
+ {{ld pr24920.err}} \
+ "pr24920" \
+ ] \
]
if { [check_gc_sections_available] } {
--
2.24.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ld: Properly check static link of dynamic object
2020-03-11 23:57 [PATCH] ld: Properly check static link of dynamic object H.J. Lu
@ 2020-03-12 4:09 ` Fangrui Song
2020-03-13 12:29 ` [PATCH] x86: Check static link of dynamic objects H.J. Lu
2020-03-12 4:19 ` [PATCH] ld: Properly check static link of dynamic object Alan Modra
1 sibling, 1 reply; 6+ messages in thread
From: Fangrui Song @ 2020-03-12 4:09 UTC (permalink / raw)
To: hjl.tools; +Cc: binutils
> When -static is passed to gcc, gcc passes it to linker before any input
> files to create static executable. If -Bdynamic is also passed to linker
> from command-line, linker should issue an error if dynamic object is used.
>
> include/
>
> PR ld/24920
> * bfdlink.h (bfd_link_info): Add static_exec.
>
> ld/
>
> PR ld/24920
> * ldfile.c (ldfile_try_open_bfd): Also check link_info.static_exec
> for static link of dynamic object.
> * lexsup.c (parse_args): Set link_info.static_exec to true if we
> see -static before any input files.
> * testsuite/ld-elf/pr24920.err: New file.
> * testsuite/ld-elf/shared.exp: Run ld/24920 tests.
> ---
> include/bfdlink.h | 3 +++
> ld/ldfile.c | 6 ++++--
> ld/lexsup.c | 4 ++++
> ld/testsuite/ld-elf/pr24920.err | 1 +
> ld/testsuite/ld-elf/shared.exp | 18 ++++++++++++++++++
> 5 files changed, 30 insertions(+), 2 deletions(-)
> create mode 100644 ld/testsuite/ld-elf/pr24920.err
>
> diff --git a/include/bfdlink.h b/include/bfdlink.h
> index 8d85530e39..a850c6102c 100644
> --- a/include/bfdlink.h
> +++ b/include/bfdlink.h
> @@ -322,6 +322,9 @@ struct bfd_link_info
> /* Output type. */
> ENUM_BITFIELD (output_type) type : 2;
>
> + /* TRUE if building a static executable. */
> + unsigned int static_exec : 1;
> +
> /* TRUE if BFD should pre-bind symbols in a shared object. */
> unsigned int symbolic: 1;
>
> diff --git a/ld/ldfile.c b/ld/ldfile.c
> index aa84906992..7b57bd9fb7 100644
> --- a/ld/ldfile.c
> +++ b/ld/ldfile.c
> @@ -164,7 +164,8 @@ ldfile_try_open_bfd (const char *attempt,
> checks out compatible, do not exit early returning TRUE, or
> the plugins will not get a chance to claim the file. */
>
> - if (entry->flags.search_dirs || !entry->flags.dynamic)
> + if (entry->flags.search_dirs
> + || (link_info.static_exec || !entry->flags.dynamic))
> {
> bfd *check;
>
> @@ -274,7 +275,8 @@ ldfile_try_open_bfd (const char *attempt,
> goto success;
> }
>
> - if (!entry->flags.dynamic && (entry->the_bfd->flags & DYNAMIC) != 0)
> + if ((link_info.static_exec || !entry->flags.dynamic)
> + && (entry->the_bfd->flags & DYNAMIC) != 0)
> {
> einfo (_("%F%P: attempted static link of dynamic object `%s'\n"),
> attempt);
> diff --git a/ld/lexsup.c b/ld/lexsup.c
> index 3d15cc491d..aeddc52466 100644
> --- a/ld/lexsup.c
> +++ b/ld/lexsup.c
> @@ -786,6 +786,10 @@ parse_args (unsigned argc, char **argv)
> break;
> case OPTION_NON_SHARED:
> input_flags.dynamic = FALSE;
> + /* If we see -static before any input files, we are building
> + a static executable. */
> + if (!lang_has_input_file)
> + link_info.static_exec = TRUE;
> break;
> case OPTION_CREF:
> command_line.cref = TRUE;
> diff --git a/ld/testsuite/ld-elf/pr24920.err b/ld/testsuite/ld-elf/pr24920.err
> new file mode 100644
> index 0000000000..8f5cab9167
> --- /dev/null
> +++ b/ld/testsuite/ld-elf/pr24920.err
> @@ -0,0 +1 @@
> +.*: attempted static link of dynamic object `tmpdir/pr24920.so'
> diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp
> index b1762aff9b..0b8024dd1a 100644
> --- a/ld/testsuite/ld-elf/shared.exp
> +++ b/ld/testsuite/ld-elf/shared.exp
> @@ -114,6 +114,24 @@ run_ld_link_tests [list \
> {} \
> "pr22649-1.so" \
> ] \
> + [list \
> + "Build pr24920.so" \
> + "$LFLAGS -shared" \
> + "" \
> + "$AFLAGS_PIC" \
> + {dummy.s} \
> + {} \
> + "pr24920.so" \
> + ] \
> + [list \
> + "Build pr24920" \
> + "$LFLAGS -static " \
> + "-Bdynamic tmpdir/pr24920.so" \
> + "" \
> + {start.s} \
> + {{ld pr24920.err}} \
> + "pr24920" \
> + ] \
> ]
>
> if { [check_gc_sections_available] } {
> --
> 2.24.1
Does the patch reject valid use case like:
ld -Bstatic a.o -Bdynamic b.so
If the gcc driver detects the input file type, I think such an error should be emitted on its side.?
-static = -Bstatic. There is no need to teach it to know that the first -static/-Bstatic is different.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] x86: Check static link of dynamic objects
2020-03-12 4:09 ` Fangrui Song
@ 2020-03-13 12:29 ` H.J. Lu
2020-03-13 23:12 ` Alan Modra
0 siblings, 1 reply; 6+ messages in thread
From: H.J. Lu @ 2020-03-13 12:29 UTC (permalink / raw)
To: Fangrui Song; +Cc: binutils
On Wed, Mar 11, 2020 at 09:09:20PM -0700, Fangrui Song wrote:
> > When -static is passed to gcc, gcc passes it to linker before any input
> > files to create static executable. If -Bdynamic is also passed to linker
> > from command-line, linker should issue an error if dynamic object is used.
> >
> > include/
> >
> > PR ld/24920
> > * bfdlink.h (bfd_link_info): Add static_exec.
> >
> > ld/
> >
> > PR ld/24920
> > * ldfile.c (ldfile_try_open_bfd): Also check link_info.static_exec
> > for static link of dynamic object.
> > * lexsup.c (parse_args): Set link_info.static_exec to true if we
> > see -static before any input files.
> > * testsuite/ld-elf/pr24920.err: New file.
> > * testsuite/ld-elf/shared.exp: Run ld/24920 tests.
>
> Does the patch reject valid use case like:
>
> ld -Bstatic a.o -Bdynamic b.so
>
This isn't a valid use case for Linux/x86. At minimum, -dynamic-linker
is needed for Linux/x86 to create non-static executable unless
--no-dynamic-linker is used.
> If the gcc driver detects the input file type, I think such an error should be emitted on its side.?
>
The GCC driver passes everything at command-line to linker without any
checking.
>
> -static = -Bstatic. There is no need to teach it to know that the first -static/-Bstatic is different.
I am testing this patch. I will check it in there are no issues.
H.J.
---
On Linux/x86, when -static is passed to gcc, gcc passes it to linker
before all input files suitable for creating static executable. X86
linker will report error for dynamic input objects if -static is passed
at command-line before all input files without --dynamic-linker unless
--no-dynamic-linker is used.
bfd/
PR ld/24920
* elf-linker-x86.h (elf_linker_x86_params): Add
static_before_all_inputs and has_dynamic_linker.
* elfxx-x86.c (_bfd_x86_elf_link_setup_gnu_properties): Report
dynamic input objects if -static is passed at command-line
before all input files without --dynamic-linker unless
--no-dynamic-linker is used.
ld/
PR ld/24920
* emulparams/elf32_x86_64.sh: Use static.sh.
* emulparams/elf_i386.sh: Likewise.
* emulparams/elf_x86_64.sh: Likewise.
* emulparams/static.sh: New file.
* emultempl/elf-x86.em: Include "ldlex.h".
* testsuite/ld-elf/pr24920.err: New file.
* testsuite/ld-elf/linux-x86.exp: Run ld/24920 tests.
---
bfd/elf-linker-x86.h | 6 ++++++
bfd/elfxx-x86.c | 17 ++++++++++++++++
ld/emulparams/elf32_x86_64.sh | 1 +
ld/emulparams/elf_i386.sh | 1 +
ld/emulparams/elf_x86_64.sh | 1 +
ld/emulparams/static.sh | 12 +++++++++++
ld/emultempl/elf-x86.em | 1 +
ld/testsuite/ld-elf/linux-x86.exp | 33 +++++++++++++++++++++++++++----
ld/testsuite/ld-elf/pr24920.err | 1 +
9 files changed, 69 insertions(+), 4 deletions(-)
create mode 100644 ld/emulparams/static.sh
create mode 100644 ld/testsuite/ld-elf/pr24920.err
diff --git a/bfd/elf-linker-x86.h b/bfd/elf-linker-x86.h
index 8ede7299dd..d0cb20dde5 100644
--- a/bfd/elf-linker-x86.h
+++ b/bfd/elf-linker-x86.h
@@ -49,6 +49,12 @@ struct elf_linker_x86_params
/* TRUE if generate a 1-byte NOP as suffix for x86 call instruction. */
unsigned int call_nop_as_suffix : 1;
+ /* TRUE if -static is passed at command-line before all input files. */
+ unsigned int static_before_all_inputs : 1;
+
+ /* TRUE if --dynamic-linker is passed at command-line. */
+ unsigned int has_dynamic_linker : 1;
+
/* Report missing IBT and SHSTK properties. */
enum elf_x86_cet_report cet_report;
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 2e0e01e31d..108e04a158 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -2998,6 +2998,23 @@ _bfd_x86_elf_link_setup_gnu_properties
: bed->plt_alignment);
}
+ if (bfd_link_executable (info)
+ && !info->nointerp
+ && !htab->params->has_dynamic_linker
+ && htab->params->static_before_all_inputs)
+ {
+ /* Report error for dynamic input objects if -static is passed at
+ command-line before all input files without --dynamic-linker
+ unless --no-dynamic-linker is used. */
+ bfd *abfd;
+
+ for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
+ if ((abfd->flags & DYNAMIC))
+ info->callbacks->einfo
+ (_("%X%P: attempted static link of dynamic object `%pB'\n"),
+ abfd);
+ }
+
return pbfd;
}
diff --git a/ld/emulparams/elf32_x86_64.sh b/ld/emulparams/elf32_x86_64.sh
index 249553aaac..1f672c6e42 100644
--- a/ld/emulparams/elf32_x86_64.sh
+++ b/ld/emulparams/elf32_x86_64.sh
@@ -4,6 +4,7 @@ source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh
source_sh ${srcdir}/emulparams/reloc_overflow.sh
source_sh ${srcdir}/emulparams/call_nop.sh
source_sh ${srcdir}/emulparams/cet.sh
+source_sh ${srcdir}/emulparams/static.sh
SCRIPT_NAME=elf
ELFSIZE=32
OUTPUT_FORMAT="elf32-x86-64"
diff --git a/ld/emulparams/elf_i386.sh b/ld/emulparams/elf_i386.sh
index 645707ddbd..c98d5e6600 100644
--- a/ld/emulparams/elf_i386.sh
+++ b/ld/emulparams/elf_i386.sh
@@ -3,6 +3,7 @@ source_sh ${srcdir}/emulparams/extern_protected_data.sh
source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh
source_sh ${srcdir}/emulparams/call_nop.sh
source_sh ${srcdir}/emulparams/cet.sh
+source_sh ${srcdir}/emulparams/static.sh
SCRIPT_NAME=elf
OUTPUT_FORMAT="elf32-i386"
NO_RELA_RELOCS=yes
diff --git a/ld/emulparams/elf_x86_64.sh b/ld/emulparams/elf_x86_64.sh
index 2b34941986..be98082982 100644
--- a/ld/emulparams/elf_x86_64.sh
+++ b/ld/emulparams/elf_x86_64.sh
@@ -4,6 +4,7 @@ source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh
source_sh ${srcdir}/emulparams/reloc_overflow.sh
source_sh ${srcdir}/emulparams/call_nop.sh
source_sh ${srcdir}/emulparams/cet.sh
+source_sh ${srcdir}/emulparams/static.sh
SCRIPT_NAME=elf
ELFSIZE=64
OUTPUT_FORMAT="elf64-x86-64"
diff --git a/ld/emulparams/static.sh b/ld/emulparams/static.sh
new file mode 100644
index 0000000000..410839b8a5
--- /dev/null
+++ b/ld/emulparams/static.sh
@@ -0,0 +1,12 @@
+PARSE_AND_LIST_ARGS_CASES="$PARSE_AND_LIST_ARGS_CASES
+ case OPTION_DYNAMIC_LINKER:
+ params.has_dynamic_linker = TRUE;
+ return FALSE;
+
+ case OPTION_NON_SHARED:
+ /* Check if -static is passed at command-line before all input
+ files. */
+ if (!lang_has_input_file)
+ params.static_before_all_inputs = TRUE;
+ return FALSE;
+"
diff --git a/ld/emultempl/elf-x86.em b/ld/emultempl/elf-x86.em
index 8de4491699..e18caffbb2 100644
--- a/ld/emultempl/elf-x86.em
+++ b/ld/emultempl/elf-x86.em
@@ -22,6 +22,7 @@
#
fragment <<EOF
+#include "ldlex.h"
#include "elf-linker-x86.h"
static struct elf_linker_x86_params params;
diff --git a/ld/testsuite/ld-elf/linux-x86.exp b/ld/testsuite/ld-elf/linux-x86.exp
index d304fb1442..63a321b966 100644
--- a/ld/testsuite/ld-elf/linux-x86.exp
+++ b/ld/testsuite/ld-elf/linux-x86.exp
@@ -19,11 +19,36 @@
# MA 02110-1301, USA.
#
+# Linux/x86 tests.
+if { ![istarget "i?86-*-linux*"] \
+ && ![istarget "x86_64-*-linux*"] \
+ && ![istarget "amd64-*-linux*"] } {
+ return
+}
+
+run_ld_link_tests [list \
+ [list \
+ "Build pr24920.so" \
+ "-shared" \
+ "" \
+ "" \
+ {dummy.s} \
+ {} \
+ "pr24920.so" \
+ ] \
+ [list \
+ "Build pr24920" \
+ "-static " \
+ "-Bdynamic tmpdir/pr24920.so" \
+ "" \
+ {start.s} \
+ {{ld pr24920.err}} \
+ "pr24920" \
+ ] \
+]
+
# Test very simple native Linux/x86 programs with linux-x86.S.
-if { ![isnative] || ![check_compiler_available] \
- || (![istarget "i?86-*-linux*"] \
- && ![istarget "x86_64-*-linux*"] \
- && ![istarget "amd64-*-linux*"]) } {
+if { ![isnative] || ![check_compiler_available] } {
return
}
diff --git a/ld/testsuite/ld-elf/pr24920.err b/ld/testsuite/ld-elf/pr24920.err
new file mode 100644
index 0000000000..8f5cab9167
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr24920.err
@@ -0,0 +1 @@
+.*: attempted static link of dynamic object `tmpdir/pr24920.so'
--
2.24.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ld: Properly check static link of dynamic object
2020-03-11 23:57 [PATCH] ld: Properly check static link of dynamic object H.J. Lu
2020-03-12 4:09 ` Fangrui Song
@ 2020-03-12 4:19 ` Alan Modra
2020-03-12 9:36 ` H.J. Lu
1 sibling, 1 reply; 6+ messages in thread
From: Alan Modra @ 2020-03-12 4:19 UTC (permalink / raw)
To: H.J. Lu; +Cc: binutils
On Wed, Mar 11, 2020 at 04:57:52PM -0700, H.J. Lu via Binutils wrote:
> When -static is passed to gcc, gcc passes it to linker before any input
> files to create static executable. If -Bdynamic is also passed to linker
> from command-line, linker should issue an error if dynamic object is used.
I can't say I like the idea of giving -static special meaning when it
occurs before input files, making its effect sticky. The sticky
effect just seems wrong to me and liable to break some project
somewhere.
PR 24920 is really just a user being surprised when they misuse their
tools. That and the default dynamic linker being wrong. Why not fix
the x86_64 default dynamic linker?
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ld: Properly check static link of dynamic object
2020-03-12 4:19 ` [PATCH] ld: Properly check static link of dynamic object Alan Modra
@ 2020-03-12 9:36 ` H.J. Lu
0 siblings, 0 replies; 6+ messages in thread
From: H.J. Lu @ 2020-03-12 9:36 UTC (permalink / raw)
To: Alan Modra; +Cc: Binutils
On Wed, Mar 11, 2020 at 9:19 PM Alan Modra <amodra@gmail.com> wrote:
>
> On Wed, Mar 11, 2020 at 04:57:52PM -0700, H.J. Lu via Binutils wrote:
> > When -static is passed to gcc, gcc passes it to linker before any input
> > files to create static executable. If -Bdynamic is also passed to linker
> > from command-line, linker should issue an error if dynamic object is used.
>
> I can't say I like the idea of giving -static special meaning when it
> occurs before input files, making its effect sticky. The sticky
> effect just seems wrong to me and liable to break some project
> somewhere.
>
> PR 24920 is really just a user being surprised when they misuse their
> tools. That and the default dynamic linker being wrong. Why not fix
> the x86_64 default dynamic linker?
>
I want to use the generic x86-64 ELF backend for Linux. I will see
if I can just do -static for x86.
Besides, when -static is passed to GCC driver, I don't think -Wl,-Bdynamic
can completely override it at the linker command-line.
--
H.J.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2020-03-13 23:12 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-11 23:57 [PATCH] ld: Properly check static link of dynamic object H.J. Lu
2020-03-12 4:09 ` Fangrui Song
2020-03-13 12:29 ` [PATCH] x86: Check static link of dynamic objects H.J. Lu
2020-03-13 23:12 ` Alan Modra
2020-03-12 4:19 ` [PATCH] ld: Properly check static link of dynamic object Alan Modra
2020-03-12 9:36 ` H.J. Lu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).