[465] in Pthreads mailing list archive

home help back first fref pref prev next nref lref last post

shared ELF libpthread for Linux

daemon@ATHENA.MIT.EDU (Tristan Savatier)
Mon Oct 21 19:00:55 1996

Date: Mon, 21 Oct 1996 13:04:47 -0700
From: Tristan Savatier <tristan@creative.net>
To: proven@MIT.EDU
Cc: pthreads@MIT.EDU

Dera Chris,

I am currently trying to generate libpthread as a shared (dynamic)
ELF library for Linux, i.e. libpthread.so rather than libpthread.a .

(For infos on how to generate ELF shared libraries under Linux,
you can look at
http://www.nijenrode.nl/~steven/ldp/HOWTO/ELF-HOWTO-3.html)

I had no problem generating libpthread.a and running all the tests
on my system (I use pthreads-1_60_beta5 and Linux kernel 2.0.0).

When I tried to generate libpthread.so, I got the following linker
errors:

readv.o(.text+0x0): multiple definition of `machdep_sys_readv'
machdep.o(.text+0x510): first defined here
writev.o(.text+0x0): multiple definition of `machdep_sys_writev'
machdep.o(.text+0x5d0): first defined here

It appears that machdep_sys_readv and machdep_sys_writev are indeed
defined at different places, and the source code is not the same
at each place (although it may be functionally equivalent?).

For example, here is machdep_sys_writev as defined in machdep.c:

/*
==========================================================================
 * machdep_sys_readv()
 */
int machdep_sys_readv(int fd, struct iovec * vector, int count)
{
	size_t bytes, i;
   	char *buffer;
   	int ret;

	/* Find the total number of bytes to be read.  */
	for (bytes = 0, i = 0; i < count; ++i)
	bytes += vector[i].iov_len;

	/* 
	 * Allocate a temporary buffer to hold the data. 
	 * Don't use alloca because threads tend to have smaller stacks.
	 */
	if ((buffer = (char *)malloc(bytes)) == NULL) {
		return(-ENOMEM);
	}

	/* 
	 * Read the data, and then copy the data from 
	 * BUFFER into the memory specified by VECTOR. 
	 */
	if ((ret = (int)machdep_sys_read(fd, buffer, bytes)) > 0) {
   		for (bytes = (size_t)ret, i = 0; i < count; ++i) {
       		size_t copy = vector[i].iov_len > bytes ? vector[i].iov_len :
bytes;
       		(void) memcpy(vector[i].iov_base, buffer, copy);
       		buffer += copy;
       		bytes -= copy;
       		if (!bytes)
   				break;
		}
	}
	free(buffer);
	return(ret);
}

And, here is machdep_sys_writev as defined in pthreads/readv.c:

/*
==========================================================================
 * machdep_sys_readv()
 */
int machdep_sys_readv(int fd, struct iovec * vector, int count)
{
	size_t bytes, i;
	char *buffer;
	int ret = 0;

	/* Find the total number of bytes to be read.  */
	for (bytes = 0, i = 0; i < count; ++i)
  		bytes += vector[i].iov_len;

	if (bytes) {
		/*
		 * Allocate a temporary buffer to hold the data.
		 * Don't use alloca because threads tend to have smaller stacks.
		 */
		if ((buffer = (char *)malloc(bytes)) == NULL) {
			return(-ENOMEM);
		}
		ret = (int)machdep_sys_read(fd, buffer, bytes);

		/* Copy the data from memory specified by VECTOR to BUFFER */
		for (i = 0, bytes = 0; ret > 0; ret -= vector[i].iov_len) {
       		memcpy(vector[i].iov_base, buffer + bytes, 
			  ret > vector[i].iov_len ?  vector[i].iov_len : ret);
			bytes += vector[i].iov_len;
    	}
		free(buffer);
	}
	return(ret);
}

This error was not visible when producing libpthread.a, probably because
the 'ar r' command just silentely removes duplicated symbols.

Am I correct to assume that the machdep_sys_readv and
machdep_sys_writev should be removed from readv.c and writev.c,
and that the correct version for those routines is in
machdep.c ?

Please advise.

 
Regards,

-- Tristan Savatier (mailto:tristan@creative.net - http://www.mpeg.org)
   "My karma ran over my dogma"

home help back first fref pref prev next nref lref last post