remove LFS64 symbol aliases; replace with dynamic linker remapping

originally the namespace-infringing "large file support" interfaces
were included as part of glibc-ABI-compat, with the intent that they
not be used for linking, since our off_t is and always has been
unconditionally 64-bit and since we usually do not aim to support
nonstandard interfaces when there is an equivalent standard interface.

unfortunately, having the symbols present and available for linking
caused configure scripts to detect them and attempt to use them
without declarations, producing all the expected ill effects that
entails.

as a result, commit 2dd8d5e1b8 was made
to prevent this, using macros to redirect the LFS64 names to the
standard names, conditional on _GNU_SOURCE or _LARGEFILE64_SOURCE.
however, this has turned out to be a source of further problems,
especially since g++ defines _GNU_SOURCE by default. in particular,
the presence of these names as macros breaks a lot of valid code.

this commit removes all the LFS64 symbols and replaces them with a
mechanism in the dynamic linker symbol lookup failure path to retry
with the spurious "64" removed from the symbol name. in the future,
if/when the rest of glibc-ABI-compat is moved out of libc, this can be
removed.
This commit is contained in:
Rich Felker 2022-09-26 17:14:18 -04:00
parent dec8f0a4fa
commit 246f1c8114
57 changed files with 38 additions and 135 deletions

View File

@ -3,22 +3,22 @@
struct stat32;
int __fxstat64(int ver, int fd, struct stat32 *buf)
int __fxstat(int ver, int fd, struct stat32 *buf)
{
return __fstat_time32(fd, buf);
}
int __fxstatat64(int ver, int fd, const char *path, struct stat32 *buf, int flag)
int __fxstatat(int ver, int fd, const char *path, struct stat32 *buf, int flag)
{
return __fstatat_time32(fd, path, buf, flag);
}
int __lxstat64(int ver, const char *path, struct stat32 *buf)
int __lxstat(int ver, const char *path, struct stat32 *buf)
{
return __lstat_time32(path, buf);
}
int __xstat64(int ver, const char *path, struct stat32 *buf)
int __xstat(int ver, const char *path, struct stat32 *buf)
{
return __stat_time32(path, buf);
}

View File

@ -7,5 +7,3 @@ int __aio_suspend_time32(const struct aiocb *const cbs[], int cnt, const struct
return aio_suspend(cbs, cnt, ts32 ? (&(struct timespec){
.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}) : 0);
}
weak_alias(aio_suspend, aio_suspend64);

View File

@ -13,5 +13,3 @@ int __fstat_time32(int fd, struct stat32 *restrict st32)
if (!r) memcpy(st32, &st, offsetof(struct stat, st_atim));
return r;
}
weak_alias(fstat, fstat64);

View File

@ -13,5 +13,3 @@ int __fstatat_time32(int fd, const char *restrict path, struct stat32 *restrict
if (!r) memcpy(st32, &st, offsetof(struct stat, st_atim));
return r;
}
weak_alias(fstatat, fstatat64);

View File

@ -13,5 +13,3 @@ int __lstat_time32(const char *restrict path, struct stat32 *restrict st32)
if (!r) memcpy(st32, &st, offsetof(struct stat, st_atim));
return r;
}
weak_alias(lstat, lstat64);

View File

@ -13,5 +13,3 @@ int __stat_time32(const char *restrict path, struct stat32 *restrict st32)
if (!r) memcpy(st32, &st, offsetof(struct stat, st_atim));
return r;
}
weak_alias(stat, stat64);

View File

@ -337,6 +337,39 @@ static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
return find_sym2(dso, s, need_def, 0);
}
static struct symdef get_lfs64(const char *name)
{
static const char *p, lfs64_list[] =
"aio_cancel\0aio_error\0aio_fsync\0aio_read\0aio_return\0"
"aio_suspend\0aio_write\0alphasort\0creat\0fallocate\0"
"fgetpos\0fopen\0freopen\0fseeko\0fsetpos\0fstat\0"
"fstatat\0fstatfs\0fstatvfs\0ftello\0ftruncate\0ftw\0"
"getdents\0getrlimit\0glob\0globfree\0lio_listio\0"
"lockf\0lseek\0lstat\0mkostemp\0mkostemps\0mkstemp\0"
"mkstemps\0mmap\0nftw\0open\0openat\0posix_fadvise\0"
"posix_fallocate\0pread\0preadv\0prlimit\0pwrite\0"
"pwritev\0readdir\0scandir\0sendfile\0setrlimit\0"
"stat\0statfs\0statvfs\0tmpfile\0truncate\0versionsort\0"
"__fxstat\0__fxstatat\0__lxstat\0__xstat\0";
size_t l;
char buf[16];
for (l=0; name[l]; l++) {
if (l >= sizeof buf) goto nomatch;
buf[l] = name[l];
}
if (!strcmp(name, "readdir64_r"))
return find_sym(&ldso, "readdir_r", 1);
if (l<2 || name[l-2]!='6' || name[l-1]!='4')
goto nomatch;
buf[l-=2] = 0;
for (p=lfs64_list; *p; p++) {
if (!strcmp(buf, p)) return find_sym(&ldso, buf, 1);
while (*p) p++;
}
nomatch:
return (struct symdef){ 0 };
}
static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride)
{
unsigned char *base = dso->base;
@ -390,6 +423,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
def = (sym->st_info>>4) == STB_LOCAL
? (struct symdef){ .dso = dso, .sym = sym }
: find_sym(ctx, name, type==REL_PLT);
if (!def.sym) def = get_lfs64(name);
if (!def.sym && (sym->st_shndx != SHN_UNDEF
|| sym->st_info>>4 != STB_WEAK)) {
if (dso->lazy && (type==REL_PLT || type==REL_GOT)) {

View File

@ -409,10 +409,3 @@ void __aio_atfork(int who)
map[a][b][c][d] = 0;
pthread_rwlock_unlock(&maplock);
}
weak_alias(aio_cancel, aio_cancel64);
weak_alias(aio_error, aio_error64);
weak_alias(aio_fsync, aio_fsync64);
weak_alias(aio_read, aio_read64);
weak_alias(aio_write, aio_write64);
weak_alias(aio_return, aio_return64);

View File

@ -73,7 +73,3 @@ int aio_suspend(const struct aiocb *const cbs[], int cnt, const struct timespec
}
}
}
#if !_REDIR_TIME64
weak_alias(aio_suspend, aio_suspend64);
#endif

View File

@ -139,5 +139,3 @@ int lio_listio(int mode, struct aiocb *restrict const *restrict cbs, int cnt, st
return 0;
}
weak_alias(lio_listio, lio_listio64);

View File

@ -5,5 +5,3 @@ int alphasort(const struct dirent **a, const struct dirent **b)
{
return strcoll((*a)->d_name, (*b)->d_name);
}
weak_alias(alphasort, alphasort64);

View File

@ -25,5 +25,3 @@ struct dirent *readdir(DIR *dir)
dir->tell = de->d_off;
return de;
}
weak_alias(readdir, readdir64);

View File

@ -25,5 +25,3 @@ int readdir_r(DIR *restrict dir, struct dirent *restrict buf, struct dirent **re
*result = buf;
return 0;
}
weak_alias(readdir_r, readdir64_r);

View File

@ -43,5 +43,3 @@ int scandir(const char *path, struct dirent ***res,
*res = names;
return cnt;
}
weak_alias(scandir, scandir64);

View File

@ -6,6 +6,3 @@ int versionsort(const struct dirent **a, const struct dirent **b)
{
return strverscmp((*a)->d_name, (*b)->d_name);
}
#undef versionsort64
weak_alias(versionsort, versionsort64);

View File

@ -4,5 +4,3 @@ int creat(const char *filename, mode_t mode)
{
return open(filename, O_CREAT|O_WRONLY|O_TRUNC, mode);
}
weak_alias(creat, creat64);

View File

@ -19,5 +19,3 @@ int open(const char *filename, int flags, ...)
return __syscall_ret(fd);
}
weak_alias(open, open64);

View File

@ -15,5 +15,3 @@ int openat(int fd, const char *filename, int flags, ...)
return syscall_cp(SYS_openat, fd, filename, flags|O_LARGEFILE, mode);
}
weak_alias(openat, openat64);

View File

@ -14,5 +14,3 @@ int posix_fadvise(int fd, off_t base, off_t len, int advice)
__SYSCALL_LL_E(len), advice);
#endif
}
weak_alias(posix_fadvise, posix_fadvise64);

View File

@ -6,5 +6,3 @@ int posix_fallocate(int fd, off_t base, off_t len)
return -__syscall(SYS_fallocate, fd, 0, __SYSCALL_LL_E(base),
__SYSCALL_LL_E(len));
}
weak_alias(posix_fallocate, posix_fallocate64);

View File

@ -7,5 +7,3 @@ int ftw(const char *path, int (*fn)(const char *, const struct stat *, int), int
* actually undefined, but works on all real-world machines. */
return nftw(path, (int (*)())fn, fd_limit, FTW_PHYS);
}
weak_alias(ftw, ftw64);

View File

@ -7,6 +7,3 @@ int fallocate(int fd, int mode, off_t base, off_t len)
return syscall(SYS_fallocate, fd, mode, __SYSCALL_LL_E(base),
__SYSCALL_LL_E(len));
}
#undef fallocate64
weak_alias(fallocate, fallocate64);

View File

@ -8,5 +8,3 @@ int getdents(int fd, struct dirent *buf, size_t len)
if (len>INT_MAX) len = INT_MAX;
return syscall(SYS_getdents, fd, buf, len);
}
weak_alias(getdents, getdents64);

View File

@ -21,6 +21,3 @@ int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, struct rlim
}
return r;
}
#undef prlimit64
weak_alias(prlimit, prlimit64);

View File

@ -5,5 +5,3 @@ ssize_t sendfile(int out_fd, int in_fd, off_t *ofs, size_t count)
{
return syscall(SYS_sendfile, out_fd, in_fd, ofs, count);
}
weak_alias(sendfile, sendfile64);

View File

@ -26,5 +26,3 @@ int getrlimit(int resource, struct rlimit *rlim)
return ret;
#endif
}
weak_alias(getrlimit, getrlimit64);

View File

@ -28,5 +28,3 @@ int lockf(int fd, int op, off_t size)
errno = EINVAL;
return -1;
}
weak_alias(lockf, lockf64);

View File

@ -138,5 +138,3 @@ int nftw(const char *path, int (*fn)(const char *, const struct stat *, int, str
pthread_setcancelstate(cs, 0);
return r;
}
weak_alias(nftw, nftw64);

View File

@ -49,5 +49,3 @@ int setrlimit(int resource, const struct rlimit *rlim)
return __syscall_ret(ret);
#endif
}
weak_alias(setrlimit, setrlimit64);

View File

@ -37,5 +37,3 @@ void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)
}
weak_alias(__mmap, mmap);
weak_alias(mmap, mmap64);

View File

@ -306,6 +306,3 @@ void globfree(glob_t *g)
g->gl_pathc = 0;
g->gl_pathv = NULL;
}
weak_alias(glob, glob64);
weak_alias(globfree, globfree64);

View File

@ -22,11 +22,6 @@ int __xstat(int ver, const char *path, struct stat *buf)
return stat(path, buf);
}
weak_alias(__fxstat, __fxstat64);
weak_alias(__fxstatat, __fxstatat64);
weak_alias(__lxstat, __lxstat64);
weak_alias(__xstat, __xstat64);
#endif
int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev)

View File

@ -11,7 +11,3 @@ int __fstat(int fd, struct stat *st)
}
weak_alias(__fstat, fstat);
#if !_REDIR_TIME64
weak_alias(fstat, fstat64);
#endif

View File

@ -151,7 +151,3 @@ int __fstatat(int fd, const char *restrict path, struct stat *restrict st, int f
}
weak_alias(__fstatat, fstatat);
#if !_REDIR_TIME64
weak_alias(fstatat, fstatat64);
#endif

View File

@ -5,7 +5,3 @@ int lstat(const char *restrict path, struct stat *restrict buf)
{
return fstatat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
}
#if !_REDIR_TIME64
weak_alias(lstat, lstat64);
#endif

View File

@ -5,7 +5,3 @@ int stat(const char *restrict path, struct stat *restrict buf)
{
return fstatat(AT_FDCWD, path, buf, 0);
}
#if !_REDIR_TIME64
weak_alias(stat, stat64);
#endif

View File

@ -56,8 +56,3 @@ int fstatvfs(int fd, struct statvfs *buf)
fixup(buf, &kbuf);
return 0;
}
weak_alias(statvfs, statvfs64);
weak_alias(statfs, statfs64);
weak_alias(fstatvfs, fstatvfs64);
weak_alias(fstatfs, fstatfs64);

View File

@ -7,5 +7,3 @@ int fgetpos(FILE *restrict f, fpos_t *restrict pos)
*(long long *)pos = off;
return 0;
}
weak_alias(fgetpos, fgetpos64);

View File

@ -29,5 +29,3 @@ FILE *fopen(const char *restrict filename, const char *restrict mode)
__syscall(SYS_close, fd);
return 0;
}
weak_alias(fopen, fopen64);

View File

@ -51,5 +51,3 @@ fail:
fclose(f);
return NULL;
}
weak_alias(freopen, freopen64);

View File

@ -46,5 +46,3 @@ int fseek(FILE *f, long off, int whence)
}
weak_alias(__fseeko, fseeko);
weak_alias(fseeko, fseeko64);

View File

@ -4,5 +4,3 @@ int fsetpos(FILE *f, const fpos_t *pos)
{
return __fseeko(f, *(const long long *)pos, SEEK_SET);
}
weak_alias(fsetpos, fsetpos64);

View File

@ -37,5 +37,3 @@ long ftell(FILE *f)
}
weak_alias(__ftello, ftello);
weak_alias(ftello, ftello64);

View File

@ -27,5 +27,3 @@ FILE *tmpfile(void)
}
return 0;
}
weak_alias(tmpfile, tmpfile64);

View File

@ -5,5 +5,3 @@ int mkostemp(char *template, int flags)
{
return __mkostemps(template, 0, flags);
}
weak_alias(mkostemp, mkostemp64);

View File

@ -26,4 +26,3 @@ int __mkostemps(char *template, int len, int flags)
}
weak_alias(__mkostemps, mkostemps);
weak_alias(__mkostemps, mkostemps64);

View File

@ -4,5 +4,3 @@ int mkstemp(char *template)
{
return __mkostemps(template, 0, 0);
}
weak_alias(mkstemp, mkstemp64);

View File

@ -5,5 +5,3 @@ int mkstemps(char *template, int len)
{
return __mkostemps(template, len, 0);
}
weak_alias(mkstemps, mkstemps64);

View File

@ -5,5 +5,3 @@ int ftruncate(int fd, off_t length)
{
return syscall(SYS_ftruncate, fd, __SYSCALL_LL_O(length));
}
weak_alias(ftruncate, ftruncate64);

View File

@ -12,4 +12,3 @@ off_t __lseek(int fd, off_t offset, int whence)
}
weak_alias(__lseek, lseek);
weak_alias(__lseek, lseek64);

View File

@ -17,4 +17,3 @@ off_t __lseek(int fd, off_t offset, int whence)
}
weak_alias(__lseek, lseek);
weak_alias(__lseek, lseek64);

View File

@ -5,5 +5,3 @@ ssize_t pread(int fd, void *buf, size_t size, off_t ofs)
{
return syscall_cp(SYS_pread, fd, buf, size, __SYSCALL_LL_PRW(ofs));
}
weak_alias(pread, pread64);

View File

@ -8,5 +8,3 @@ ssize_t preadv(int fd, const struct iovec *iov, int count, off_t ofs)
return syscall_cp(SYS_preadv, fd, iov, count,
(long)(ofs), (long)(ofs>>32));
}
weak_alias(preadv, preadv64);

View File

@ -5,5 +5,3 @@ ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs)
{
return syscall_cp(SYS_pwrite, fd, buf, size, __SYSCALL_LL_PRW(ofs));
}
weak_alias(pwrite, pwrite64);

View File

@ -8,5 +8,3 @@ ssize_t pwritev(int fd, const struct iovec *iov, int count, off_t ofs)
return syscall_cp(SYS_pwritev, fd, iov, count,
(long)(ofs), (long)(ofs>>32));
}
weak_alias(pwritev, pwritev64);

View File

@ -5,5 +5,3 @@ int truncate(const char *path, off_t length)
{
return syscall(SYS_truncate, path, __SYSCALL_LL_O(length));
}
weak_alias(truncate, truncate64);

View File

@ -12,4 +12,3 @@ off_t __lseek(int fd, off_t offset, int whence)
}
weak_alias(__lseek, lseek);
weak_alias(__lseek, lseek64);