Skip to content

Commit

Permalink
Formatting fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
somasis committed Oct 20, 2017
1 parent 97e74da commit d5b10c6
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 114 deletions.
8 changes: 4 additions & 4 deletions compatibility.md
Expand Up @@ -3,7 +3,7 @@
Compatibility of the interfaces provided by musl with existing standards and
software packages.

## Standards compatibility tables
# Standards compatibility tables

- [POSIX 2008 API coverage][POSIX2008] (obsolete STREAMS and posix_trace APIs
are not included)
Expand All @@ -14,14 +14,14 @@ software packages.
[C99]: http://repo.or.cz/w/musl-tools.git/blob_plain/HEAD:/tab_c99.html
[C11]: http://repo.or.cz/w/musl-tools.git/blob_plain/HEAD:/tab_c11.html

## Compatibility with other implementations
# Compatibility with other implementations

- [Functional differences from glibc]
- [Comparison] with other Linux libc implementations.

[Comparison]: https://www.etalabs.net/compare_libcs.html

## Software compatibility, patches and build instructions
# Software compatibility, patches and build instructions

- pkgsrc based software compatibility table:
- ~~Pkgsrc results~~ outdated.
Expand All @@ -35,7 +35,7 @@ software packages.
- [Alpine ports]
- [Gentoo overlay with musl support]
- See the packaging work in various other
[distributions][Projects using musl#linux-distributions-using-musl].
[distributions][Projects using musl#Linux distributions using musl].

[musl-pkgsrc-patches (hg)]: http://bitbucket.org/GregorR/musl-pkgsrc-patches
[musl-pkgsrc-patches (git)]: https://github.com/GregorR/musl-pkgsrc-patches
Expand Down
44 changes: 23 additions & 21 deletions design-concepts.md
Expand Up @@ -86,7 +86,9 @@ implemented by glibc and other libraries:
3. Disable asynchronous cancellation (actually restore the old state).

The first idea to remedy the situation appeared in musl 0.7.5, but turned out to
have its own set of flaws. The new approach, which works like this:
have its own set of flaws.

The new approach works like this...

A specialized version of the syscall wrapper assembly code is used for
cancellation points. Originally, it recorded its stack address and a pointer to
Expand Down Expand Up @@ -146,19 +148,19 @@ contrast to other implementations such as glibc which are forced to abort when
lazy allocation fails.

There are only two operations which can increase a process's TLS needs:
pthread_create and dlopen. During dlopen, a lock is held which prevents the
creation of new threads, so dlopen can use the current thread count to allocate
`pthread_create` and `dlopen`. During `dlopen`, a lock is held which prevents the
creation of new threads, so `dlopen` can use the current thread count to allocate
sufficient storage for all currently-running threads at the time the library is
loaded; if storage cannot be obtained dlopen returns failure. Before releasing
the lock that prevents thread creation, dlopen updates the record of how much
loaded; if storage cannot be obtained `dlopen` returns failure. Before releasing
the lock that prevents thread creation, `dlopen` updates the record of how much
TLS storage new threads will need and makes it available future calls to
pthread_create, which pre-allocate storage for TLS in all libraries that were
`pthread_create`, which pre-allocate storage for TLS in all libraries that were
loaded at the time of the call.

Before a new thread begins execution, TLS pointers are already setup, and the
TLS images have all been copied, for TLS belonging to libraries that were loaded
before the thread was created. If a thread attempts to access TLS in a library
that was loaded after the thread started, the \_\_tls_get_addr function searches
that was loaded after the thread started, the `__tls_get_addr` function searches
the list of loaded libraries to find the pre-allocated storage that was obtained
when the library was loaded, and uses an atomic-fetch-and-add operation to
adjust the index into this storage. This makes access to the pre-allocated
Expand All @@ -167,10 +169,10 @@ and async-signal-safe (important for supporting the case where the first access
to a library's TLS takes place in a signal handler or after forking).

One consequence of this design is that there is memory which is never freed.
However, the point at which this memory is allocated is in dlopen, an interface
However, the point at which this memory is allocated is in `dlopen`, an interface
which inherently allocates an unfreeable (in musl, for various good reasons)
resource: a shared library. If for some reason there exists an extreme,
unusually large number of threads at the moment dlopen is called, however, the
unusually large number of threads at the moment `dlopen` is called, however, the
permanent allocations could be costly. It may be possible to arrange for some or
all of this memory to be freeable upon thread exit, by carving up the large
allocation into individual pieces returnable to the malloc subsystem via free.
Expand All @@ -181,33 +183,33 @@ Such enhancements will be considered at a later time if there is demand.
Adapted from <http://www.openwall.com/lists/musl/2013/07/16/16>

Internally, all POSIX times (seconds since epoch) are passed around as long
long. This ensures that values derived from struct tm, timezone rules, etc. can
long. This ensures that values derived from `struct tm`, timezone rules, etc. can
never overflow, and allows overflow checking to be deferred until it's time to
convert the value back into time_t. Without this design, handling the "partial
years" at the edge of time_t overflow range is very difficult, as is handling
the denormalized struct tm forms mktime is required to support and normalize
convert the value back into `time_t`. Without this design, handling the "partial
years" at the edge of `time_t` overflow range is very difficult, as is handling
the denormalized `struct tm` forms mktime is required to support and normalize
(for instance, overflowing the year range by using a very large month number).

Instead of converting back and forth to broken-down struct tm for applying
Instead of converting back and forth to broken-down `struct tm` for applying
timezone rules, the new code simply converts the combination of year and TZ rule
string to a POSIX time within the given year at which the transition occurs.
This value has type long long so that it cannot overflow even at the boundary
years. Determining whether DST is in effect at a given time is simply a range
comparison, just like the comparison used for processing zoneinfo-format
timezone rules.

For years within the currently-reasonable range/32-bit time_t, the hot path for
For years within the currently-reasonable range/32-bit `time_t`, the hot path for
converting a year to seconds since the epoch involves no division. We can get
away with >>2 and &3 since in the range [1901,2099] the leap year rule is simply
that multiple-of-4 years are leap years. I would like it be able to have the
compiler throw away the larger, slower, general-case code on 32-bit-time_t
compiler throw away the larger, slower, general-case code on 32-bit-`time_t`
targets, but unfortunately the need to use long long internally to avoid
difficult corner cases is precluding that.

Any representable struct tm will successfully convert to time_t if and only if
it represents a value of seconds-since-the-epoch that fits in time_t. Any
representable time_t will successfully convert to struct tm if and only if it
represents a (normalized) date and time repr esentable in struct tm. The
Any representable `struct tm` will successfully convert to `time_t` if and only if
it represents a value of seconds-since-the-epoch that fits in `time_t`. Any
representable `time_t` will successfully convert to `struct tm` if and only if it
represents a (normalized) date and time representable in `struct tm`. The
relevant functions will avoid setting errno except on error so that a caller can
distinguish between a time_t value of -1 as a valid result and as an error.
distinguish between a `time_t` value of -1 as a valid result and as an error.

28 changes: 14 additions & 14 deletions environment-variables.md
@@ -1,38 +1,38 @@
# Environment Variables

# PATH
# `PATH`

Used by execvp, execlp, and posix_spawnp as specified in POSIX.
Used by `execvp`, `execlp`, and `posix_spawnp` as specified in POSIX.

# TZ
# `TZ`

Specifies the local timezone to be used for functions which deal with local
time. The value of TZ can be either a [POSIX timezone specification] in the form
stdoffset[dst[offset][,start[/time],end[/time]] or the name of a
zoneinfo-binary-format timezone file (the form used by glibc and almost all
other systems). The zoneinfo file is interpreted as an absolute pathname if it
begins with a slash, a relative pathname if it begins with a dot, and otherwise
is searched in /usr/share/zoneinfo, /share/zoneinfo, and /etc/zoneinfo. When
is searched in `/usr/share/zoneinfo`, `/share/zoneinfo`, and `/etc/zoneinfo`. When
searching these paths, strings including any dots are rejected.

[POSIX timezone specification]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03

# DATEMSK
# `DATEMSK`

Used by the getdate function as a pathname for the file containing date formats
Used by the `getdate` function as a pathname for the file containing date formats
to scan, per POSIX.

# PWD
# `PWD`

Used by the nonstandard get_current_dir_name function; if it matches the actual
current directory, it is returned instead of using getcwd to obtain the
Used by the nonstandard `get_current_dir_name` function; if it matches the actual
current directory, it is returned instead of using `getcwd` to obtain the
canonical pathname.

# LOGNAME
# `LOGNAME`

The getlogin function simply returns the value of the LOGNAME variable.
The `getlogin` function simply returns the value of the `LOGNAME` variable.

# LD_PRELOAD
# `LD_PRELOAD`

Colon-separated list of shared libraries that will be preloaded by the dynamic
linker before processing the application's dependency list. Components can be
Expand All @@ -41,11 +41,11 @@ absolute or relative pathnames or filenames in the default library search path.
This variable is completely ignored in programs invoked setuid, setgid, or with
other elevated capabilities.

# LD\_LIBRARY_PATH
# `LD_LIBRARY_PATH`

Colon-separated list of pathnames that will be searched for shared libraries
requested without an explicit pathname. This path is searched prior to the
default path (which is specified in $(syslibdir)/../etc.ld-musl-$(ARCH).path
default path (which is specified in `$(syslibdir)/../etc.ld-musl-$(ARCH).path`
with built-in default fallback if this file is missing).

This variable is completely ignored in programs invoked setuid, setgid, or with
Expand Down
37 changes: 20 additions & 17 deletions faq.md
@@ -1,6 +1,6 @@
# FAQ

# Q: lib[m|pthread|crypt].a/so are empty?
# Q: lib(m|pthread|crypt).a/so are empty?

Yes, this is by design. musl puts everything into libc.a/so to avoid memory
bloat. The empty files are only there for compatibilit reasons. The official
Expand Down Expand Up @@ -200,22 +200,25 @@ a compilation error instead of offering a portable fallback version of their
code, so they can show you their muscles when you come to ask for help as the
error message suggests to do. See
<http://www.mail-archive.com/bug-gnulib@gnu.org/msg27386.html> and
<http://www.mail-archive.com/search?q=musl&l=bug-gnulib%40gnu.org>. To fix it,
either update the in-tree gnulib (no idea how to do that), or use a hack: each
one of the gnulib function is triggered by a configure test, the condition being
either "libc doesnt have this function" or "this libc function doesnt behave
like GNUlib dictators want it to be". all of those configure checks use a cache
variable like "gl_cv_func_isnanl_works=yes" [bigger list]. so you can prevent
their code getting compiled in when you start configure with ./configure
gl_cv_func_isnanl_works=yes. alternatively you can put all of these symbols into
a file called config.cache and start ./configure -C (the -C makes configure pick
up the cache). so all these checks will be skipped. to prevent additional
breakage, [overwrite all .c files in the gnulib folder that try to replace libc
functionality with an empty file][overwrite]. if that's still not enough to make
the $*!#/ gnulib happy, you may have to do additional preprocessor hacks so
their "rpl_" functions get again mapped to the real libc thing: for example
CFLAGS="-Dgnu_fnmatch=fnmatch -Drpl_getgroups=getgroups
-Drpl_nanosleep=nanosleep -Drpl_futimens=futimens" ./configure ... [1].
<http://www.mail-archive.com/search?q=musl&l=bug-gnulib%40gnu.org>.

To fix it, either update the in-tree gnulib (no idea how to do that), or use a
hack: each one of the gnulib function is triggered by a configure test, the
condition being either "libc doesnt have this function" or "this libc function
doesnt behave like GNUlib dictators want it to be". All of those configure
checks use a cache variable like "gl_cv_func_isnanl_works=yes" [bigger list].

So, you can prevent their code getting compiled in when you start configure with
`./configure gl_cv_func_isnanl_works=yes`. Alternatively, you can put all of
these symbols into a file called config.cache and run `./configure -C` (the `-C`
makes configure pick up the cache), so all these checks will be skipped.

To prevent additional breakage, [overwrite all .c files in the gnulib folder that try to replace libc functionality with an empty file][overwrite].
If that's still not enough to make gnulib happy, you may have to do additional preprocessor hacks so
their "rpl_" functions get again mapped to the real libc thing.

For example: `CFLAGS="-Dgnu_fnmatch=fnmatch -Drpl_getgroups=getgroups
-Drpl_nanosleep=nanosleep -Drpl_futimens=futimens" ./configure` ... [1].

[1]: https://github.com/sabotage-linux/sabotage/blob/master/pkg/coreutils#L16
[bigger list]: https://github.com/sabotage-linux/sabotage/blob/master/KEEP/config.cache#L1430
Expand Down

0 comments on commit d5b10c6

Please sign in to comment.