[465] in Pthreads mailing list archive
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"