Check the count in the first word of __CTOR_LIST__ before executing

the loop that invokes the static constructors.  That makes it safe
to link c++rt0.o into any shared library, even one that does not
have any static constructors.  Formerly, doing that would cause a
bus error.  If the library has no static constructors, __CTOR_LIST__
comes out as a simple 4-byte COMMON region, and it does not have
the usual NULL word that terminates the list of constructors.  This
caused the old code to "call" a garbage address via the non-existent
entry __CTOR_LIST__[1].

The analogous code that invokes the static destructors was already safe.

This change is fully backward-compatible.

Reviewed by:	dfr@render.com (Doug Rabson)
This commit is contained in:
John Polstra 1996-01-15 17:53:25 +00:00
parent 22d1e589b8
commit d5489b0d8f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=13441

View File

@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: c++rt0.c,v 1.2 1995/05/30 05:39:36 rgrimes Exp $
* $Id: c++rt0.c,v 1.3 1995/06/27 09:53:24 dfr Exp $
*/
/*
@ -54,10 +54,18 @@ __dtors(void)
static void
__ctors(void)
{
void (**p)(void) = __CTOR_LIST__ + 1;
/*
* If the shared library doesn't have any static constructors in it,
* then __CTOR_LIST__ will come out as a simple COMMON region of
* 4 bytes. That is why we have to check the count in the first
* word.
*/
if ((unsigned long) __CTOR_LIST__[0] > 0) {
void (**p)(void) = __CTOR_LIST__ + 1;
while (*p)
(**p++)();
while (*p)
(**p++)();
}
}
extern void __init() asm(".init");