~ubuntu-branches/ubuntu/natty/eglibc/natty-security

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
                                                        -*- mode: text -*-

                      Cross-Testing With EGLIBC
                  Jim Blandy <jimb@codesourcery.com>


Introduction

Developers writing software for embedded systems often use a desktop
or other similarly capable computer for development, but need to run
tests on the embedded system, or perhaps on a simulator.  When
configured for cross-compilation, the stock GNU C library simply
disables running tests altogether: the command 'make tests' builds
test programs, but does not run them.  EGLIBC, however, provides
facilities for compiling tests and generating data files on the build
system, but running the test programs themselves on a remote system or
simulator.


Test environment requirements

The test environment must meet certain conditions for EGLIBC's
cross-testing facilities to work:

- Shared filesystems.  The 'build' system, on which you configure and
  compile EGLIBC, and the 'host' system, on which you intend to run
  EGLIBC, must share a filesystem containing the EGLIBC build and
  source trees.  Files must appear at the same paths on both systems.

- Remote-shell like invocation.  There must be a way to run a program
  on the host system from the build system, passing it properly quoted
  command-line arguments, setting environment variables, and
  inheriting the caller's standard input and output.


Usage

To use EGLIBC's cross-testing support, provide values for the
following Make variables when you invoke 'make':

- cross-test-wrapper

  This should be the name of the cross-testing wrapper command, along
  with any arguments.

- cross-localedef

  This should be the name of a cross-capable localedef program, like
  that included in the EGLIBC 'localedef' module, along with any
  arguments needed.

These are each explained in detail below.


The Cross-Testing Wrapper

To run test programs reliably, the stock GNU C library takes care to
ensure that test programs use the newly compiled dynamic linker and
shared libraries, and never the host system's installed libraries.  To
accomplish this, it runs the tests by explicitly invoking the dynamic
linker from the build tree, passing it a list of build tree
directories to search for shared libraries, followed by the name of
the executable to run and its arguments.

For example, where one might normally run a test program like this:

    $ ./tst-foo arg1 arg2

the GNU C library might run that program like this:

    $ $objdir/elf/ld-linux.so.3 --library-path $objdir \
      ./tst-foo arg1 arg2

(where $objdir is the path to the top of the build tree, and the
trailing backslash indicates a continuation of the command).  In other
words, each test program invocation is 'wrapped up' inside an explicit
invocation of the dynamic linker, which must itself execute the test
program, having loaded shared libraries from the appropriate
directories.

To support cross-testing, EGLIBC allows the developer to optionally
set the 'cross-test-wrapper' Make variable to another wrapper command,
to which it passes the entire dynamic linker invocation shown above as
arguments.  For example, if the developer supplies a wrapper of
'my-wrapper hostname', then EGLIBC would run the test above as
follows:

    $ my-wrapper hostname \
      $objdir/elf/ld-linux.so.3 --library-path $objdir \
      ./tst-foo arg1 arg2

The 'my-wrapper' command is responsible for executing the command
given on the host system.

Since tests are run in varying directories, the wrapper should either
be in your command search path, or 'cross-test-wrapper' should give an
absolute path for the wrapper.

The wrapper must meet several requirements:

- It must preserve the current directory.  As explained above, the
  build directory tree must be visible on both the build and host
  systems, at the same path.  The test wrapper must ensure that the
  current directory it inherits is also inherited by the dynamic
  linker (and thus the test program itself).

- It must preserve environment variables' values.  Many EGLIBC tests
  set environment variables for test runs; in native testing, it
  invokes programs like this:

    $ GCONV_PATH=$objdir/iconvdata \
      $objdir/elf/ld-linux.so.3 --library-path $objdir \
      ./tst-foo arg1 arg2

  With the cross-testing wrapper, that invocation becomes:

    $ GCONV_PATH=$objdir/iconvdata \
      my-wrapper hostname \
      $objdir/elf/ld-linux.so.3 --library-path $objdir \
      ./tst-foo arg1 arg2

  Here, 'my-wrapper' must ensure that the value it sees for
  'GCONV_PATH' will be seen by the dynamic linker, and thus 'tst-foo'
  itself.  (The wrapper supplied with GLIBC simply preserves the
  values of *all* enviroment variables, with a fixed set of
  exceptions.)

  If your wrapper is a shell script, take care to correctly propagate
  environment variables whose values contain spaces and shell
  metacharacters.

- It must pass the command's arguments, unmodified.  The arguments
  seen by the test program should be exactly those seen by the wrapper
  (after whatever arguments are given to the wrapper itself).  The
  EGLIBC test framework performs all needed shell word splitting and
  expansion (wildcard expansion, parameter substitution, and so on)
  before invoking the wrapper; further expansion may break the tests.


The 'cross-test-ssh.sh' script

If you want to use 'ssh' (or something sufficiently similar) to run
test programs on your host system, EGLIBC includes a shell script,
'scripts/cross-test-ssh.sh', which you can use as your wrapper
command.  This script takes care of setting the test command's current
directory, propagating environment variable values, and carrying
command-line arguments, all across an 'ssh' connection.  You may even
supply an alternative to 'ssh' on the command line, if needed.

For more details, pass 'cross-test-ssh.sh' the '--help' option.


The Cross-Compiling Locale Definition Command

Some EGLIBC tests rely on locales generated especially for the test
process.  In a native configuration, these tests simply run the
'localedef' command built by the normal EGLIBC build process,
'locale/localedef', to process and install their locales.  However, in
a cross-compiling configuration, this 'localedef' is built for the
host system, not the build system, and since it requires quite a bit
of memory to run (we have seen it fail on systems with 64MiB of
memory), it may not be practical to run it on the host system.

If set, EGLIBC uses the 'cross-localedef' Make variable as the command
to run on the build system to process and install locales.  The
localedef program built from the EGLIBC 'localedef' module is
suitable.

The value of 'cross-localedef' may also include command-line arguments
to be passed to the program; if you are using EGLIBC's 'localedef',
you may include endianness and 'uint32_t' alignment arguments here.


Example

In developing EGLIBC's cross-testing facility, we invoked 'make' with
the following script:

    #!/bin/sh

    srcdir=...
    test_hostname=...
    localedefdir=...
    cross_gxx=...-g++

    wrapper="$srcdir/scripts/cross-test-ssh.sh $test_hostname"
    localedef="$localedefdir/localedef --little-endian --uint32-align=4"

    make cross-test-wrapper="$wrapper" \
         cross-localedef="$localedef" \
         CXX="$cross_gxx" \
         "$@"


Other Cross-Testing Concerns

Here are notes on some other issues which you may encounter in running
the EGLIBC tests in a cross-compiling environment:

- Some tests require a C++ cross-compiler; you should set the 'CXX'
  Make variable to the name of an appropriate cross-compiler.

- Some tests require access to libstdc++.so.6 and libgcc_s.so.1; we
  simply place copies of these libraries in the top EGLIBC build
  directory.