strftime results are unspecified in this case, but should not invoke
undefined behaviour.
tm_wday, tm_yday, tm_mon and tm_year fields were used in signed int
arithmetic that could overflow.
based on patch by Szabolcs Nagy.
since commit c5e34dabbb, crt1.c has
provided a "mostly-C" implementation of the crt1 start file that
avoids the need for arch-specific symbol referencing, PIC/PIE-specific
code variants, etc. but for archs that had existing hand-written
versions, the new code was initially unused, and later only used as
the dynamic linker entry point. this commit switches all archs to
using the new code.
the code being removed was a recurring source of subtle errors, and
was still broken at least on arm, where it failed to properly align
the stack pointer before calling into C code.
as found and reported by Brian Mastenbrook, the expressions
400*qc_cycles and years+100 in __secs_to_tm were both subject to
integer overflow for extreme values of the input t.
this patch by Szabolcs Nagy fixes the code by switching to larger
types, and matches the original intent I had in mind when writing this
code.
the specification for these functions requires that the buffer/size
exposed to the caller be valid after any successful call to fflush or
fclose on the stream. the implementation's approach is to update them
only at flush time, but that misses the case where fflush or fclose is
called without any writes having taken place, in which case the write
flushing callback will not be called.
to fix both the observable bug and the desired invariant, setup empty
buffers at open time and fail the open operation if no memory is
available.
fdiv and fmul instructions were wrongly matched by the rules for
integer div and mul instructions, leading to incorrect conclusions
about register values being clobbered.
There is a lot which could be common between i386 and x86_64, but none
of it will be useful for any other arch. These should be useful for
all archs, however.
commit 844212d94f, which did not make it
into any releases, changed nl_langinfo(CODESET) to always return
"UTF-8", even in the byte-based C locale. this was problematic because
application software was found to use the string match for "UTF-8" to
activate its own UTF-8 processing. this both undermines the byte-based
functionality of the C locale, and if mixed with with calls to the
standard multibyte functions, which happened in practice, could result
in severe mis-handling of input.
the motive for the previous change was that, to avoid widespread
compatibility problems, the string returned by nl_langinfo(CODESET)
needs to be accepted by iconv and by third-party character conversion
code. thus, the only remaining choice is "ASCII". this choice
accurately represents the intent that high bytes do not have
individual meaning in the C locale, but it does mean that iconv, when
passed nl_langinfo(CODESET) in the C locale, will produce errors in
cases where mbrtowc would have succeeded. for reference, glibc behaves
similarly in this regard, so I don't think it will be a problem.
some newer binutils versions print scary warnings about protected data
because most gcc versions fail to produce the right address
references/relocations for such data that might be subject to copy
relocations. originally vis.h explicitly assigned default visibility
to all public data symbols to avoid this issue, but commit
b8dda24fe1 removed this treatment for
stdin/out/err to work around a gcc 3.x bug, and since they don't
actually need it (because taking their addresses is not valid C).
instead, a check for the gcc 3.x bug is added to the configure check
for vis.h preinclude support; this feature will simply be disabled
when using a buggy version of gcc.
previously, __lookup_ipliteral only checked its argument against the
requested address family, so IPv4 literals passed through to
__lookup_name if the caller asked for only IPv6 results, and likewise
for IPv6 literals when the caller asked for only IPv4. this resulted
in spurious DNS lookups that reportedly even succeeded with some
nameservers.
now, __lookup_ipliteral attempts to parse its argument as both IPv4
and IPv6, and returns an error (to stop further search) rather than 0
(no results yet) if the form of the argument mismatches the requested
address family.
based on patch by Julien Ramseier.
The value of *size is not relevant in case of failure, but it's
better not to copy garbage from the stack into it.
(The compiler cannot see through the syscall, so optimization
was not affected by the unspecified value).
the restorer function pointer provided in the kernel sigaction
structure is interpreted by the kernel as a raw code address, not a
function descriptor.
this commit moves the declarations of the __restore and __restore_rt
symbols to ksigaction.h so that arch versions of the file can override
them, and introduces a version for sh which declares them as objects
rather than functions.
an alternate solution would have been defining SA_RESTORER to 0 so
that the functions are not used, but this both requires executable
stack (since the sh kernel does not have a vdso page with permanent
restorer functions) and crashes on qemu user-level emulation.
lookup the dso an address falls in based on the loadmap and not just a
base/length. fix the main app's fake loadmap used when loaded by a
non-fdpic-aware loader so that it does not cover the whole memory
space.
function descriptor addresses are also matched for future use by
dladdr, but reverse lookups of function descriptors via dladdr have
not been implemented yet. some revisions may be needed in the future
once reclaim_gaps supports fdpic, so that function descriptors
allocated in reclaimed heap space do not get detected as belonging to
the module whose gaps they were allocated in.
previously these resolved to the code address rather than the address
of the function descriptor.
the conditions for accepting or rejecting symbols are quite
inconsistent between the different points in the dynamic linker code
where such decisions are made. this commit attempts to be at least as
correct as anything already there, but does not improve consistency.
it has been tested to correctly avoid symbols that are merely
references to functions defined in other modules, at least in simple
usage, but at some point all symbol lookup logic should be reviewed
and refactored/unified.
the entry point code supports being loaded by a loader which is not
fdpic-aware (in practice, either kernel with mmu or qemu without fdpic
support). this mostly just works, but signal handling will wrongly use
a function descriptor address as a code address if the personality is
not adjusted to fdpic.
ideally this code could be placed with sigaction so that it's not
needed except if/when a signal handler is installed. however,
personality is incorrectly maintained per-thread by the kernel, rather
than per-process, so it's necessary to correct the personality before
any threads are started. also, in order to skip the personality
syscall when an fdpic-aware loader is used, we need to be able to
detect how the program was loaded, and this information is only
readily available at the entry point.
this change is needed to be compatible with fdpic, where some of the
main application's relocations may be performed as part of the crt1
entry point. if we call init functions before passing control, these
relocations will not yet have been performed, and the init code will
potentially make use of invalid pointers.
conceptually, no code provided by the application or third-party
libraries should run before the application entry point. the
difference is not observable to programs using the crt1 we provide,
but it could come into play if custom entry point code is used, so
it's better to be doing this right anyway.
previously, the normal ELF library loading code was used even for
fdpic, so only the kernel-loaded dynamic linker and main app could
benefit from separate placement of segments and shared text.
this is always an error and usually results from failure to find/link
the compiler runtime library, but it could also result from
implementation errors in libc, using functions that don't (yet) exist.
either way the resulting libc.so will crash mysteriously at runtime.
the crash happens too early to produce a meaningful error, so these
crashes are very confusing to users and waste a lot of debugging time.
this commit should ensure that they do not happen.
the __fdpic_fixup code is not needed for ET_DYN executables, which
instead use reloctions, so we can omit it from the dynamic linker and
static-pie entry point and save some code size.
the C implementation of __unmapself used for potentially-nommu sh
assumed CRTJMP takes a function descriptor rather than a code address;
however, the actual dynamic linker needs a code address, and so commit
7a9669e977 changed the definition of the
macro in reloc.h. this commit puts the old macro back in a place where
it only affects __unmapself.
this is an ugly workaround and should be cleaned up at some point, but
at least it's well isolated.
at this point not all functionality is complete. the dynamic linker
itself, and main app if it is also loaded by the kernel, take
advantage of fdpic and do not need constant displacement between
segments, but additional libraries loaded by the dynamic linker follow
normal ELF semantics for mapping still. this fully works, but does not
admit shared text on nommu.
in terms of actual functional correctness, dlsym's results are
presently incorrect for function symbols, RTLD_NEXT fails to identify
the caller correctly, and dladdr fails almost entirely.
with the dynamic linker entry point working, support for static pie is
automatically included, but linking the main application as ET_DYN
(pie) probably does not make sense for fdpic anyway. ET_EXEC is
equally relocatable but more efficient at representing relocations.
the fdpic code will need to count symbols, and it may be useful
elsewhere in the future too. counting is trivial as long as sysv hash
is present, but for gnu-hash-only libraries it's complex.
the behavior of the count is changed slightly: we now include symbols
that are not accessible by the gnu hash table in the count. this may
make dladdr slightly slower. if this is a problem, dladdr can subtract
out the part that should not be accessible. unlike in the old code,
subtracting this out is easy even in the fast path where sysv hash is
available too.
these are in do_relocs. the first one was omitted in commit
301335a80b because it slightly changes
code (using dso->base rather than cached local var base) and would
have prevented easy verification. the other was an oversight.
for ordinary ELF with fixed segment displacements, load address
computation is simply adding the base load address. but for FDPIC,
each segment has its own load address, and virtual addresses need to
be adjusted according to the segment they fall in. abstracting this
computation is the first step to making the dynamic linker ready for
FDPIC.
for this first commit, a macro is used rather than a function in order
to facilitate correctness checking. I have verified that the generated
code does not change on my i386 build.
this new generic version of the stage-2 function lookup should work
for any arch where static data is accessible via got-relative or
pc-relative addressing, using approximately the technique described in
the log message for commit 2907afb8db.
since all the mips-like archs that need got slots fo access static
data have already transitioned to the new stage chaining scheme, the
old dynamic symbol lookup code is now removed.
aarch64, arm, and sh have not yet transitioned; with this commit, they
are now using the new generic code.
previously, the call into stage 2 was made by looking up the symbol
name "__dls2" (which was chosen short to be easy to look up) from the
dynamic symbol table. this was no problem for the dynamic linker,
since it always exports all its symbols. in the case of the static pie
entry point, however, the dynamic symbol table does not contain the
necessary symbol unless -rdynamic/-E was used when linking. this
linking requirement is a major obstacle both to practical use of
static-pie as a nommu binary format (since it greatly enlarges the
file) and to upstream toolchain support for static-pie (adding -E to
default linking specs is not reasonable).
this patch replaces the runtime symbolic lookup with a link-time
lookup via an inline asm fragment, which reloc.h is responsible for
providing. in this initial commit, the asm is provided only for i386,
and the old lookup code is left in place as a fallback for archs that
have not yet transitioned.
modifying crt_arch.h to pass the stage-2 function pointer as an
argument was considered as an alternative, but such an approach would
not be compatible with fdpic, where it's impossible to compute
function pointers without already having performed relocations. it was
also deemed desirable to keep crt_arch.h as simple/minimal as
possible.
in principle, archs with pc-relative or got-relative addressing of
static variables could instead load the stage-2 function pointer from
a static volatile object. that does not work for fdpic, and is not
safe against reordering on mips-like archs that use got slots even for
static functions, but it's a valid on i386 and many others, and could
provide a reasonable default implementation in the future.
this attribute was applied to pthread_self and the functions providing
the locations for errno and h_errno as an optimization; however, it is
subtly incorrect. as specified, it means the return value will always
be the same, which is not true; it varies per-thread.
this attribute also implies that the function does not depend on any
state, and that calls to it can safely be reordered across any other
code. however such reordering is unsafe for these functions: they
break when reordered before initialization of the thread pointer. such
breakage was actually observed when compiled by libfirm/cparser.
to some extent the reordering problem could be solved with strong
compiler barriers between the stages of early startup code, but the
specified meaning of of attribute((const)) is sufficiently strong that
a compiler would theoretically be justified inserting gratuitous calls
to attribute((const)) const functions at random locations (e.g. to
save the value in static storage for later use).
this reverts commit cbf35978a9.
their absence completely breaks format string warnings in programs
with gettext message translations: -Wformat gives no results, and
-Wformat-nonliteral produces spurious warnings.
with gcc, the problem manifests only in standards-conforming profiles;
otherwise gcc sets these attributes by default for the gettext family.
with clang, the problem always manifests; clang has no such defaults.
with this commit it should be possible to produce a working
static-linked fdpic libc and application binaries for sh.
the changes in reloc.h are largely unused at this point since dynamic
linking is not supported, but the CRTJMP macro is used one place
outside of dynamic linking, in __unmapself.