aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorThomas Preud'homme <thomas.preudhomme@arm.com>2016-08-26 10:59:26 +0100
committerThomas Preud'homme <thomas.preudhomme@arm.com>2016-08-26 11:00:36 +0100
commit0955507f6e7144c9c5e420bbcf617593b13de38b (patch)
tree01e7b1d24870728adf17b1bca5d21e2f937ef197 /ld
parent4edcc97c1a892325fcda1abe0d383802cc87a869 (diff)
downloadfsf-binutils-gdb-0955507f6e7144c9c5e420bbcf617593b13de38b.zip
fsf-binutils-gdb-0955507f6e7144c9c5e420bbcf617593b13de38b.tar.gz
fsf-binutils-gdb-0955507f6e7144c9c5e420bbcf617593b13de38b.tar.bz2
Add support for stable secure gateway veneers addresses
2016-08-26 Thomas Preud'homme <thomas.preudhomme@arm.com> bfd/ * bfd-in.h (bfd_elf32_arm_set_target_relocs): Add a new parameter for the input import library bfd. * bfd-in2.h: Regenerate. * elf32-arm.c (struct elf32_arm_link_hash_table): New in_implib_bfd and new_cmse_stub_offset fields. (stub_hash_newfunc): Initialize stub_offset and stub_template_size to -1. (elf32_arm_add_stub): Likewise for stub_offset. (arm_new_stubs_start_offset_ptr): New function. (arm_build_one_stub): Only allocate a stub_offset if it is -1. Allow empty SG veneers to have zero relocations. (arm_size_one_stub): Only initialize stub size and template information for non empty veneers. Do not update veneer section size if veneer already has an offset. (elf32_arm_create_stub): Return the stub entry pointer or NULL instead of a boolean indicating success or failure. (cmse_scan): Change stub_changed parameter into an integer pointer parameter cmse_stub_created to count the number of stub created and adapt to change of return value in elf32_arm_create_stub. (cmse_entry_fct_p): New function. (arm_list_new_cmse_stub): Likewise. (set_cmse_veneer_addr_from_implib): Likewise. (elf32_arm_size_stubs): Define cmse_stub_created, pass its address to cmse_scan instead of that of cmse_stub_changed to compute the number of stub created and use it to initialize stub_changed. Call set_cmse_veneer_addr_from_implib after all cmse_scan. Adapt to change of return value in elf32_arm_create_stub. Use arm_stub_section_start_offset () if not NULL to initialize size of secure gateway veneers section. Initialize stub_offset of Cortex-A8 erratum fix to -1. Use ret to hold return value. (elf32_arm_build_stubs): Use arm_stub_section_start_offset () if not NULL to initialize size of secure gateway veneers section. Adapt comment to stress the importance of zeroing veneer section content. (bfd_elf32_arm_set_target_relocs): Add new in_implib_bfd parameter to initialize eponymous field in struct elf32_arm_link_hash_table. ld/ * emultempl/armelf.em (in_implib_filename): Declare and initialize new variable. (arm_elf_create_output_section_statements): Open import input library file for writing and pass resulting in_implib_bfd to bfd_elf32_arm_set_target_relocs. (PARSE_AND_LIST_PROLOGUE): Define OPTION_IN_IMPLIB option. (PARSE_AND_LIST_LONGOPTS): Define --in-implib option. (PARSE_AND_LIST_OPTIONS): Add help message for --in-implib option. (PARSE_AND_LIST_ARGS_CASES): Handle new OPTION_IN_IMPLIB case. * ld.texinfo (--cmse-implib): Update to mention --in-implib. (--in-implib): Document new option. * NEWS: Likewise. * testsuite/ld-arm/arm-elf.exp (Secure gateway import library generation): add --defsym VER=1 to gas CLI. (Secure gateway import library generation: errors): Likewise. (Input secure gateway import library): New test. (Input secure gateway import library: no output import library): Likewise. (Input secure gateway import library: not an SG input import library): Likewise. (Input secure gateway import library: earlier stub section base): Likewise. (Input secure gateway import library: later stub section base): Likewise. (Input secure gateway import library: veneer comeback): Likewise. (Input secure gateway import library: entry function change): Likewise. * testsuite/ld-arm/cmse-implib.s: Add input import library testing. * testsuite/ld-arm/cmse-implib.rd: Update accordingly. * testsuite/ld-arm/cmse-new-implib.out: New file. * testsuite/ld-arm/cmse-new-implib.rd: Likewise. * testsuite/ld-arm/cmse-new-implib-no-output.out: Likewise. * testsuite/ld-arm/cmse-new-implib-not-sg-in-implib.out: Likewise. * testsuite/ld-arm/cmse-new-earlier-later-implib.out: Likewise. * testsuite/ld-arm/cmse-new-comeback-implib.rd: Likewise. * testsuite/ld-arm/cmse-new-wrong-implib.out: Likewise.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog40
-rw-r--r--ld/NEWS5
-rw-r--r--ld/emultempl/armelf.em27
-rw-r--r--ld/ld.texinfo12
-rw-r--r--ld/testsuite/ld-arm/arm-elf.exp47
-rw-r--r--ld/testsuite/ld-arm/cmse-implib.s17
-rw-r--r--ld/testsuite/ld-arm/cmse-new-comeback-implib.rd15
-rw-r--r--ld/testsuite/ld-arm/cmse-new-earlier-later-implib.out3
-rw-r--r--ld/testsuite/ld-arm/cmse-new-implib-no-output.out4
-rw-r--r--ld/testsuite/ld-arm/cmse-new-implib-not-sg-in-implib.out2
-rw-r--r--ld/testsuite/ld-arm/cmse-new-implib.out1
-rw-r--r--ld/testsuite/ld-arm/cmse-new-implib.rd14
-rw-r--r--ld/testsuite/ld-arm/cmse-new-wrong-implib.out3
13 files changed, 187 insertions, 3 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 95a63ea..fccaea3b 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,43 @@
+2016-08-26 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
+ * emultempl/armelf.em (in_implib_filename): Declare and initialize new
+ variable.
+ (arm_elf_create_output_section_statements): Open import input library
+ file for writing and pass resulting in_implib_bfd to
+ bfd_elf32_arm_set_target_relocs.
+ (PARSE_AND_LIST_PROLOGUE): Define OPTION_IN_IMPLIB option.
+ (PARSE_AND_LIST_LONGOPTS): Define --in-implib option.
+ (PARSE_AND_LIST_OPTIONS): Add help message for --in-implib option.
+ (PARSE_AND_LIST_ARGS_CASES): Handle new OPTION_IN_IMPLIB case.
+ * ld.texinfo (--cmse-implib): Update to mention --in-implib.
+ (--in-implib): Document new option.
+ * NEWS: Likewise.
+ * testsuite/ld-arm/arm-elf.exp
+ (Secure gateway import library generation): add --defsym VER=1 to gas
+ CLI.
+ (Secure gateway import library generation: errors): Likewise.
+ (Input secure gateway import library): New test.
+ (Input secure gateway import library: no output import library):
+ Likewise.
+ (Input secure gateway import library: not an SG input import library):
+ Likewise.
+ (Input secure gateway import library: earlier stub section base):
+ Likewise.
+ (Input secure gateway import library: later stub section base):
+ Likewise.
+ (Input secure gateway import library: veneer comeback): Likewise.
+ (Input secure gateway import library: entry function change):
+ Likewise.
+ * testsuite/ld-arm/cmse-implib.s: Add input import library testing.
+ * testsuite/ld-arm/cmse-implib.rd: Update accordingly.
+ * testsuite/ld-arm/cmse-new-implib.out: New file.
+ * testsuite/ld-arm/cmse-new-implib.rd: Likewise.
+ * testsuite/ld-arm/cmse-new-implib-no-output.out: Likewise.
+ * testsuite/ld-arm/cmse-new-implib-not-sg-in-implib.out: Likewise.
+ * testsuite/ld-arm/cmse-new-earlier-later-implib.out: Likewise.
+ * testsuite/ld-arm/cmse-new-comeback-implib.rd: Likewise.
+ * testsuite/ld-arm/cmse-new-wrong-implib.out: Likewise.
+
2016-08-25 Alan Modra <amodra@gmail.com>
* configure.tgt (powerpc*-*-linux* et al): Rewrite, adding LE
diff --git a/ld/NEWS b/ld/NEWS
index 2a0b4ac..0f316bf 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -2,6 +2,11 @@
Changes in 2.28:
+* Add --in-implib=<infile> to the ARM linker to enable specifying a set of
+ Secure Gateway veneers that must exist in the output import library specified
+ by --out-implib=<outfile> and the address they must have. As such,
+ --in-implib is only supported in combination with --cmse-implib.
+
* Extended the --out-implib=<file> option, previously restricted to x86 PE
targets, to any ELF based target. This allows the generation of an import
library for an ELF executable, which can then be used by another application
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index 2678740..306caf1 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -43,6 +43,7 @@ static int pic_veneer = 0;
static int merge_exidx_entries = -1;
static int fix_arm1176 = 1;
static int cmse_implib = 0;
+static char *in_implib_filename = NULL;
static void
gld${EMULATION_NAME}_before_parse (void)
@@ -499,6 +500,8 @@ gld${EMULATION_NAME}_finish (void)
static void
arm_elf_create_output_section_statements (void)
{
+ bfd *in_implib_bfd;
+
if (strstr (bfd_get_target (link_info.output_bfd), "arm") == NULL)
{
/* The arm backend needs special fields in the output hash structure.
@@ -509,6 +512,20 @@ arm_elf_create_output_section_statements (void)
return;
}
+ if (in_implib_filename)
+ {
+ in_implib_bfd = bfd_openr (in_implib_filename,
+ bfd_get_target (link_info.output_bfd));
+
+ if (in_implib_bfd == NULL)
+ einfo ("%F%s: Can't open: %E\n", in_implib_filename);
+
+ if (!bfd_check_format (in_implib_bfd, bfd_object))
+ einfo ("%F%s: Not a relocatable file: %E\n", in_implib_filename);
+ }
+ else
+ in_implib_bfd = NULL;
+
bfd_elf32_arm_set_target_relocs (link_info.output_bfd, &link_info,
target1_is_rel,
target2_type, fix_v4bx, use_blx,
@@ -516,7 +533,7 @@ arm_elf_create_output_section_statements (void)
no_enum_size_warning,
no_wchar_size_warning,
pic_veneer, fix_cortex_a8,
- fix_arm1176, cmse_implib);
+ fix_arm1176, cmse_implib, in_implib_bfd);
stub_file = lang_add_input_file ("linker stubs",
lang_input_file_is_fake_enum,
@@ -586,6 +603,7 @@ PARSE_AND_LIST_PROLOGUE='
#define OPTION_LONG_PLT 319
#define OPTION_STM32L4XX_FIX 320
#define OPTION_CMSE_IMPLIB 321
+#define OPTION_IN_IMPLIB 322
'
PARSE_AND_LIST_SHORTOPTS=p
@@ -613,6 +631,7 @@ PARSE_AND_LIST_LONGOPTS='
{ "no-fix-arm1176", no_argument, NULL, OPTION_NO_FIX_ARM1176 },
{ "long-plt", no_argument, NULL, OPTION_LONG_PLT },
{ "cmse-implib", no_argument, NULL, OPTION_CMSE_IMPLIB },
+ { "in-implib", required_argument, NULL, OPTION_IN_IMPLIB },
'
PARSE_AND_LIST_OPTIONS='
@@ -635,6 +654,8 @@ PARSE_AND_LIST_OPTIONS='
" to handle large .plt/.got displacements\n"));
fprintf (file, _(" --cmse-implib Make import library to be a secure gateway import\n"
" library as per ARMv8-M Security Extensions\n"));
+ fprintf (file, _(" --in-implib Import library whose symbols address must\n"
+ " remain stable\n"));
fprintf (file, _("\
--stub-group-size=N Maximum size of a group of input sections that\n\
can be handled by one stub section. A negative\n\
@@ -759,6 +780,10 @@ PARSE_AND_LIST_ARGS_CASES='
case OPTION_CMSE_IMPLIB:
cmse_implib = 1;
break;
+
+ case OPTION_IN_IMPLIB:
+ in_implib_filename = optarg;
+ break;
'
# We have our own before_allocation etc. functions, but they call
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index e6813f2..0213851 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -6866,6 +6866,18 @@ specified by the @samp{--out-implib} and @samp{--in-implib} options are
secure gateway import libraries, suitable for linking a non-secure
executable against secure code as per ARMv8-M Security Extensions.
+@kindex --in-implib=@var{file}
+@cindex Input import library
+The @samp{--in-implib=file} specifies an input import library whose symbols
+must keep the same address in the executable being produced. A warning is
+given if no @samp{--out-implib} is given but new symbols have been introduced
+in the executable that should be listed in its import library. Otherwise, if
+@samp{--out-implib} is specified, the symbols are added to the output import
+library. A warning is also given if some symbols present in the input import
+library have disappeared from the executable. This option is only effective
+for Secure Gateway import libraries, ie. when @samp{--cmse-implib} is
+specified.
+
@ifclear GENERIC
@lowersections
@end ifclear
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index 5524085..24d0b4c 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -670,16 +670,59 @@ set armeabitests_nonacl {
"cmse-veneers-mainline"}
{"Secure gateway import library generation: errors"
"--section-start .gnu.sgstubs=0x20000 --out-implib=tmpdir/cmse-implib.lib --cmse-implib" ""
- "-march=armv8-m.base -mthumb --defsym CHECK_ERRORS=1"
+ "-march=armv8-m.base -mthumb --defsym CHECK_ERRORS=1 --defsym VER=1"
{cmse-implib.s}
{{ld cmse-implib-errors.out}}
"cmse-implib"}
{"Secure gateway import library generation"
"--section-start .gnu.sgstubs=0x20000 --out-implib=tmpdir/cmse-implib.lib --cmse-implib" ""
- "-march=armv8-m.base -mthumb"
+ "-march=armv8-m.base -mthumb --defsym VER=1"
{cmse-implib.s}
{{readelf {-s tmpdir/cmse-implib.lib} cmse-implib.rd}}
"cmse-implib"}
+ {"Input secure gateway import library"
+ "--section-start .gnu.sgstubs=0x20000 --out-implib=tmpdir/cmse-new-implib.lib --in-implib=tmpdir/cmse-implib.lib --cmse-implib" ""
+ "-march=armv8-m.base -mthumb --defsym VER=2"
+ {cmse-implib.s}
+ {{ld cmse-new-implib.out}
+ {readelf {-s tmpdir/cmse-new-implib.lib} cmse-new-implib.rd}}
+ "cmse-new-implib"}
+ {"Input secure gateway import library: no output import library"
+ "--section-start .gnu.sgstubs=0x20000 --in-implib=tmpdir/cmse-implib.lib --cmse-implib" ""
+ "-march=armv8-m.base -mthumb --defsym VER=2"
+ {cmse-implib.s}
+ {{ld cmse-new-implib-no-output.out}}
+ "cmse-new-implib-no-output"}
+ {"Input secure gateway import library: not an SG input import library"
+ "--section-start .gnu.sgstubs=0x20000 --in-implib=tmpdir/cmse-implib.lib" ""
+ "-march=armv8-m.base -mthumb --defsym VER=2"
+ {cmse-implib.s}
+ {{ld cmse-new-implib-not-sg-in-implib.out}}
+ "cmse-new-implib-not-sg-in-implib"}
+ {"Input secure gateway import library: earlier stub section base"
+ "--section-start .gnu.sgstubs=0x19000 --out-implib=tmpdir/cmse-new-earlier-implib.lib --in-implib=tmpdir/cmse-implib.lib --cmse-implib" ""
+ "-march=armv8-m.base -mthumb --defsym VER=2"
+ {cmse-implib.s}
+ {{ld cmse-new-earlier-later-implib.out}}
+ "cmse-new-earlier-implib"}
+ {"Input secure gateway import library: later stub section base"
+ "--section-start .gnu.sgstubs=0x30000 --out-implib=tmpdir/cmse-new-later-implib.lib --in-implib=tmpdir/cmse-implib.lib --cmse-implib" ""
+ "-march=armv8-m.base -mthumb --defsym VER=2"
+ {cmse-implib.s}
+ {{ld cmse-new-earlier-later-implib.out}}
+ "cmse-new-later-implib"}
+ {"Input secure gateway import library: veneer comeback"
+ "--section-start .gnu.sgstubs=0x20000 --out-implib=tmpdir/cmse-new-comeback-implib.lib --in-implib=tmpdir/cmse-implib.lib --cmse-implib" ""
+ "-march=armv8-m.base -mthumb --defsym VER=3"
+ {cmse-implib.s}
+ {{readelf {-s tmpdir/cmse-new-comeback-implib.lib} cmse-new-comeback-implib.rd}}
+ "cmse-new-comeback-implib"}
+ {"Input secure gateway import library: entry function change"
+ "--section-start .gnu.sgstubs=0x20000 --out-implib=tmpdir/cmse-new-wrong-implib.lib --in-implib=tmpdir/cmse-implib.lib --cmse-implib" ""
+ "-march=armv8-m.base -mthumb --defsym VER=4"
+ {cmse-implib.s}
+ {{ld cmse-new-wrong-implib.out}}
+ "cmse-new-wrong-implib"}
{"R_ARM_THM_JUMP19 Relocation veneers: Short"
"--section-start destsect=0x000108002 --section-start .text=0x8000" ""
diff --git a/ld/testsuite/ld-arm/cmse-implib.s b/ld/testsuite/ld-arm/cmse-implib.s
index a42da63..9dd7839 100644
--- a/ld/testsuite/ld-arm/cmse-implib.s
+++ b/ld/testsuite/ld-arm/cmse-implib.s
@@ -20,12 +20,29 @@ __acle_se_\name:
.endm
@ Valid setups for veneer generation
+.if (VER >= 2)
+ entry exported_entry_veneer1, global
+.endif
+.if (VER != 4)
entry exported_entry_veneer2, global
+.else
+ entry exported_entry_veneer2, weak
+.endif
+.if (VER != 2)
entry exported_entry_veneer3, global
+.endif
+.if (VER > 1)
+ entry exported_entry_veneer4, global
+.endif
@ Valid setup for entry function without veneer generation
entry exported_entry_fct1, global, sg
+.if (VER != 4)
entry exported_entry_fct2, global, sg
+.else
+ @ Invalid setup for entry function without veneer generation
+ entry exported_entry_fct2, global, nop
+.endif
@ Normal symbol not exported to SG import library
.align 2
diff --git a/ld/testsuite/ld-arm/cmse-new-comeback-implib.rd b/ld/testsuite/ld-arm/cmse-new-comeback-implib.rd
new file mode 100644
index 0000000..c88d9d5
--- /dev/null
+++ b/ld/testsuite/ld-arm/cmse-new-comeback-implib.rd
@@ -0,0 +1,15 @@
+File: tmpdir/cmse-new-.*implib.lib
+
+Symbol table '.symtab' contains 7 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 0: 00000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 00020001 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer3
+ 2: 00020011 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer4
+ 3: 00020019 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer1
+ 4: [0-9a-f]+ 6 FUNC GLOBAL DEFAULT ABS exported_entry_fct1
+ 5: 00020009 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer2
+ 6: [0-9a-f]+ 6 FUNC GLOBAL DEFAULT ABS exported_entry_fct2
+
+File: tmpdir/cmse-new-.*implib
+
+#...
diff --git a/ld/testsuite/ld-arm/cmse-new-earlier-later-implib.out b/ld/testsuite/ld-arm/cmse-new-earlier-later-implib.out
new file mode 100644
index 0000000..b49ad0a
--- /dev/null
+++ b/ld/testsuite/ld-arm/cmse-new-earlier-later-implib.out
@@ -0,0 +1,3 @@
+.*: Entry function `exported_entry_veneer3' disappeared from secure code.
+.*: Start address of `.gnu.sgstubs' is different from previous link.
+.*: cannot size stub section: Invalid operation
diff --git a/ld/testsuite/ld-arm/cmse-new-implib-no-output.out b/ld/testsuite/ld-arm/cmse-new-implib-no-output.out
new file mode 100644
index 0000000..0590b71
--- /dev/null
+++ b/ld/testsuite/ld-arm/cmse-new-implib-no-output.out
@@ -0,0 +1,4 @@
+.*: Entry function `exported_entry_veneer3' disappeared from secure code.
+.*: new entry function\(s\) introduced but no output import library specified:
+.*: exported_entry_veneer4
+.*: exported_entry_veneer1
diff --git a/ld/testsuite/ld-arm/cmse-new-implib-not-sg-in-implib.out b/ld/testsuite/ld-arm/cmse-new-implib-not-sg-in-implib.out
new file mode 100644
index 0000000..c93c3fb
--- /dev/null
+++ b/ld/testsuite/ld-arm/cmse-new-implib-not-sg-in-implib.out
@@ -0,0 +1,2 @@
+.*: --in-implib only supported for Secure Gateway import libraries.
+.*: cannot size stub section: Invalid operation
diff --git a/ld/testsuite/ld-arm/cmse-new-implib.out b/ld/testsuite/ld-arm/cmse-new-implib.out
new file mode 100644
index 0000000..c8af280
--- /dev/null
+++ b/ld/testsuite/ld-arm/cmse-new-implib.out
@@ -0,0 +1 @@
+.*: Entry function `exported_entry_veneer3' disappeared from secure code.
diff --git a/ld/testsuite/ld-arm/cmse-new-implib.rd b/ld/testsuite/ld-arm/cmse-new-implib.rd
new file mode 100644
index 0000000..9ff0fd8
--- /dev/null
+++ b/ld/testsuite/ld-arm/cmse-new-implib.rd
@@ -0,0 +1,14 @@
+File: tmpdir/cmse-new-.*implib.lib
+
+Symbol table '.symtab' contains 6 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 0: 00000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 00020011 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer4
+ 2: 00020019 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer1
+ 3: [0-9a-f]+ 6 FUNC GLOBAL DEFAULT ABS exported_entry_fct1
+ 4: 00020009 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer2
+ 5: [0-9a-f]+ 6 FUNC GLOBAL DEFAULT ABS exported_entry_fct2
+
+File: tmpdir/cmse-new-.*implib
+
+#...
diff --git a/ld/testsuite/ld-arm/cmse-new-wrong-implib.out b/ld/testsuite/ld-arm/cmse-new-wrong-implib.out
new file mode 100644
index 0000000..2afe407
--- /dev/null
+++ b/ld/testsuite/ld-arm/cmse-new-wrong-implib.out
@@ -0,0 +1,3 @@
+.*: .*: visibility of symbol `exported_entry_veneer2' has changed.
+.*: `exported_entry_fct2' refers to a non entry function.
+.*: cannot size stub section: Invalid operation