Discussion:
undefined reference to `strlwr' on 64bit Cygwin
Ken Brown
2013-03-17 02:08:43 UTC
Permalink
$ uname -a
CYGWIN_NT-6.1 fiona 1.7.18(0.263/5/3) 2013-03-15 16:35 x86_64 Cygwin

$ gcc --version
gcc (GCC) 4.8.0 20130307 (experimental)

$ cat strlwr_test.c
#include <string.h>
#include <stdio.h>

int
main ()
{
char str[] = "FRED";
printf ("%s\n", strlwr (str));
}

$ gcc strlwr_test.c
/tmp/ccW2SOn8.o:strlwr_test.c:(.text+0x20): undefined reference to `strlwr'
/tmp/ccW2SOn8.o:strlwr_test.c:(.text+0x20): relocation truncated to fit:
R_X86_64_PC32 against undefined symbol `strlwr'
/usr/lib/gcc/x86_64-pc-cygwin/4.8.0/../../../../x86_64-pc-cygwin/bin/ld:
/tmp/ccW2SOn8.o: bad reloc address 0x0 in section `.pdata'
/usr/lib/gcc/x86_64-pc-cygwin/4.8.0/../../../../x86_64-pc-cygwin/bin/ld:
final link failed: Invalid operation
collect2: error: ld returned 1 exit status

Ken

P.S. Is this still the appropriate list for 64bit bug reports, or is it
time to move to the main cygwin list?
Corinna Vinschen
2013-03-17 09:51:41 UTC
Permalink
Post by Ken Brown
$ uname -a
CYGWIN_NT-6.1 fiona 1.7.18(0.263/5/3) 2013-03-15 16:35 x86_64 Cygwin
$ gcc --version
gcc (GCC) 4.8.0 20130307 (experimental)
$ cat strlwr_test.c
#include <string.h>
#include <stdio.h>
int
main ()
{
char str[] = "FRED";
printf ("%s\n", strlwr (str));
}
$ gcc strlwr_test.c
/tmp/ccW2SOn8.o:strlwr_test.c:(.text+0x20): undefined reference to `strlwr'
/tmp/ccW2SOn8.o:strlwr_test.c:(.text+0x20): relocation truncated to
fit: R_X86_64_PC32 against undefined symbol `strlwr'
/tmp/ccW2SOn8.o: bad reloc address 0x0 in section `.pdata'
final link failed: Invalid operation
collect2: error: ld returned 1 exit status
Thanks for the hint, I added it back to cygwin64.din.

However, do you really use this function? It's broken by design. In
theory it's one of those functions which should never have been exported
since it only works on single-byte charsets and glibc rightfully doesn't
provide it at all. If you use it with UTF-8 non-ASCII chars, the result
is random nonsense.
Post by Ken Brown
Ken
P.S. Is this still the appropriate list for 64bit bug reports, or is
it time to move to the main cygwin list?
No, that's fine. Let's stick to the developers list (or cygwin-apps for
stuff which rather affects setup and packaging) until we do our first
official release.


Thanks,
Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat
Ken Brown
2013-03-17 12:53:44 UTC
Permalink
Post by Corinna Vinschen
Post by Ken Brown
$ uname -a
CYGWIN_NT-6.1 fiona 1.7.18(0.263/5/3) 2013-03-15 16:35 x86_64 Cygwin
$ gcc --version
gcc (GCC) 4.8.0 20130307 (experimental)
$ cat strlwr_test.c
#include <string.h>
#include <stdio.h>
int
main ()
{
char str[] = "FRED";
printf ("%s\n", strlwr (str));
}
$ gcc strlwr_test.c
/tmp/ccW2SOn8.o:strlwr_test.c:(.text+0x20): undefined reference to `strlwr'
/tmp/ccW2SOn8.o:strlwr_test.c:(.text+0x20): relocation truncated to
fit: R_X86_64_PC32 against undefined symbol `strlwr'
/tmp/ccW2SOn8.o: bad reloc address 0x0 in section `.pdata'
final link failed: Invalid operation
collect2: error: ld returned 1 exit status
Thanks for the hint, I added it back to cygwin64.din.
However, do you really use this function? It's broken by design. In
theory it's one of those functions which should never have been exported
since it only works on single-byte charsets and glibc rightfully doesn't
provide it at all. If you use it with UTF-8 non-ASCII chars, the result
is random nonsense.
It's used in the cygw32 build of emacs, in w32font.c. The native
Windows build uses _strlwr, and Daniel added `#define _strlwr strlwr'
for Cygwin. Maybe he can comment on this.

Ken
Corinna Vinschen
2013-03-18 13:07:23 UTC
Permalink
Post by Ken Brown
Post by Corinna Vinschen
Post by Ken Brown
$ uname -a
CYGWIN_NT-6.1 fiona 1.7.18(0.263/5/3) 2013-03-15 16:35 x86_64 Cygwin
$ gcc --version
gcc (GCC) 4.8.0 20130307 (experimental)
$ cat strlwr_test.c
#include <string.h>
#include <stdio.h>
int
main ()
{
char str[] = "FRED";
printf ("%s\n", strlwr (str));
}
$ gcc strlwr_test.c
/tmp/ccW2SOn8.o:strlwr_test.c:(.text+0x20): undefined reference to `strlwr'
/tmp/ccW2SOn8.o:strlwr_test.c:(.text+0x20): relocation truncated to
fit: R_X86_64_PC32 against undefined symbol `strlwr'
/tmp/ccW2SOn8.o: bad reloc address 0x0 in section `.pdata'
final link failed: Invalid operation
collect2: error: ld returned 1 exit status
Thanks for the hint, I added it back to cygwin64.din.
However, do you really use this function? It's broken by design. In
theory it's one of those functions which should never have been exported
since it only works on single-byte charsets and glibc rightfully doesn't
provide it at all. If you use it with UTF-8 non-ASCII chars, the result
is random nonsense.
It's used in the cygw32 build of emacs, in w32font.c. The native
Windows build uses _strlwr, and Daniel added `#define _strlwr
strlwr' for Cygwin. Maybe he can comment on this.
Btw., a safe method to uppercase/lowercase a multibyte string is this:

#include <stdlib.h>
#include <wchar.h>
#include <wctype.h>

/* Return converted string in newly malloc'd buffer */
char *
safe_strupr (const char *str)
{
size_t len;
wchar_t *wstr = NULL;
char *res = NULL;

len = mbstowcs (NULL, str, 0) + 1;
if (len != (size_t) -1)
wstr = (wchar_t *) malloc (len * sizeof (wchar_t));
if (!wstr)
return NULL;
mbstowcs (wstr, str, len);
while (len-- > 0) /* Ignore WEOF here */
wstr[len] = (wchar_t) towupper ((wint_t) wstr[len]);
len = wcstombs (NULL, wstr, 0) + 1;
if (len != (size_t) -1)
{
res = (char *) malloc (len);
if (res)
wcstombs (res, wstr, len);
}
free (wstr);
return res;
}


Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat
Ken Brown
2013-03-18 16:44:28 UTC
Permalink
Post by Corinna Vinschen
Post by Ken Brown
Post by Corinna Vinschen
Post by Ken Brown
$ uname -a
CYGWIN_NT-6.1 fiona 1.7.18(0.263/5/3) 2013-03-15 16:35 x86_64 Cygwin
$ gcc --version
gcc (GCC) 4.8.0 20130307 (experimental)
$ cat strlwr_test.c
#include <string.h>
#include <stdio.h>
int
main ()
{
char str[] = "FRED";
printf ("%s\n", strlwr (str));
}
$ gcc strlwr_test.c
/tmp/ccW2SOn8.o:strlwr_test.c:(.text+0x20): undefined reference to `strlwr'
/tmp/ccW2SOn8.o:strlwr_test.c:(.text+0x20): relocation truncated to
fit: R_X86_64_PC32 against undefined symbol `strlwr'
/tmp/ccW2SOn8.o: bad reloc address 0x0 in section `.pdata'
final link failed: Invalid operation
collect2: error: ld returned 1 exit status
Thanks for the hint, I added it back to cygwin64.din.
However, do you really use this function? It's broken by design. In
theory it's one of those functions which should never have been exported
since it only works on single-byte charsets and glibc rightfully doesn't
provide it at all. If you use it with UTF-8 non-ASCII chars, the result
is random nonsense.
It's used in the cygw32 build of emacs, in w32font.c. The native
Windows build uses _strlwr, and Daniel added `#define _strlwr
strlwr' for Cygwin. Maybe he can comment on this.
#include <stdlib.h>
#include <wchar.h>
#include <wctype.h>
/* Return converted string in newly malloc'd buffer */
char *
safe_strupr (const char *str)
{
size_t len;
wchar_t *wstr = NULL;
char *res = NULL;
len = mbstowcs (NULL, str, 0) + 1;
if (len != (size_t) -1)
wstr = (wchar_t *) malloc (len * sizeof (wchar_t));
if (!wstr)
return NULL;
mbstowcs (wstr, str, len);
while (len-- > 0) /* Ignore WEOF here */
wstr[len] = (wchar_t) towupper ((wint_t) wstr[len]);
len = wcstombs (NULL, wstr, 0) + 1;
if (len != (size_t) -1)
{
res = (char *) malloc (len);
if (res)
wcstombs (res, wstr, len);
}
free (wstr);
return res;
}
Thanks Corinna!

Ken
Daniel Colascione
2013-03-19 04:29:33 UTC
Permalink
Post by Corinna Vinschen
Post by Ken Brown
$ uname -a
CYGWIN_NT-6.1 fiona 1.7.18(0.263/5/3) 2013-03-15 16:35 x86_64 Cygwin
$ gcc --version
gcc (GCC) 4.8.0 20130307 (experimental)
$ cat strlwr_test.c
#include <string.h>
#include <stdio.h>
int
main ()
{
char str[] = "FRED";
printf ("%s\n", strlwr (str));
}
$ gcc strlwr_test.c
/tmp/ccW2SOn8.o:strlwr_test.c:(.text+0x20): undefined reference to `strlwr'
/tmp/ccW2SOn8.o:strlwr_test.c:(.text+0x20): relocation truncated to
fit: R_X86_64_PC32 against undefined symbol `strlwr'
/tmp/ccW2SOn8.o: bad reloc address 0x0 in section `.pdata'
final link failed: Invalid operation
collect2: error: ld returned 1 exit status
Thanks for the hint, I added it back to cygwin64.din.
However, do you really use this function? It's broken by design. In
theory it's one of those functions which should never have been exported
since it only works on single-byte charsets and glibc rightfully doesn't
provide it at all. If you use it with UTF-8 non-ASCII chars, the result
is random nonsense.
It's used in the cygw32 build of emacs, in w32font.c. The native Windows build
uses _strlwr, and Daniel added `#define _strlwr strlwr' for Cygwin. Maybe he
can comment on this.
Unfortunately, I don't have any special insight into the use of this function
--- Emacs is very, very old, and we still technically support Windows 95. Now,
we've changed _strlwr to _mbslwr in a few places, so maybe we can fix the rest.
The specific use in w32font.c is probably best addressed by adding support for
UNICODE LOGFONTW throughout.

I also found this worrisome code in w32.c:

static DWORD
generate_inode_val (const char * name)
{
char fullname[ MAX_PATH ];
char * p;
unsigned hash;

/* Get the truly canonical filename, if it exists. (Note: this
doesn't resolve aliasing due to subst commands, or recognize hard
links. */
if (!w32_get_long_filename ((char *)name, fullname, MAX_PATH))
emacs_abort ();

parse_root (fullname, &p);
/* Normal W32 filesystems are still case insensitive. */
_strlwr (p);
return hashval (p);
}

Thing is, that's completely unnecessary --- modern versions of Windows have real
inode numbers! (Well, 64-bit FileIds, but close enough.)

Anyway, I need to
Corinna Vinschen
2013-03-19 08:56:28 UTC
Permalink
Post by Daniel Colascione
Post by Corinna Vinschen
However, do you really use this function? It's broken by design. In
theory it's one of those functions which should never have been exported
since it only works on single-byte charsets and glibc rightfully doesn't
provide it at all. If you use it with UTF-8 non-ASCII chars, the result
is random nonsense.
It's used in the cygw32 build of emacs, in w32font.c. The native Windows build
uses _strlwr, and Daniel added `#define _strlwr strlwr' for Cygwin. Maybe he
can comment on this.
Unfortunately, I don't have any special insight into the use of this function
--- Emacs is very, very old, and we still technically support Windows 95. Now,
we've changed _strlwr to _mbslwr in a few places, so maybe we can fix the rest.
The specific use in w32font.c is probably best addressed by adding support for
UNICODE LOGFONTW throughout.
static DWORD
generate_inode_val (const char * name)
{
char fullname[ MAX_PATH ];
char * p;
unsigned hash;
/* Get the truly canonical filename, if it exists. (Note: this
doesn't resolve aliasing due to subst commands, or recognize hard
links. */
if (!w32_get_long_filename ((char *)name, fullname, MAX_PATH))
emacs_abort ();
parse_root (fullname, &p);
/* Normal W32 filesystems are still case insensitive. */
_strlwr (p);
return hashval (p);
}
Thing is, that's completely unnecessary --- modern versions of Windows have real
inode numbers! (Well, 64-bit FileIds, but close enough.)
Uhm... not quite. While Windows supports FileIDs, they are not
unambiguous on FAT and FAT32. The FileIds of a file may change on these
filesystems by adding or removing other files in the same dir.
Therefore, the right thing to do is to check the filesystem. If it's
FAT*, don't trust the FileId.


Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat
Corinna Vinschen
2013-03-19 09:17:46 UTC
Permalink
Post by Daniel Colascione
Post by Corinna Vinschen
However, do you really use this function? It's broken by design. In
theory it's one of those functions which should never have been exported
since it only works on single-byte charsets and glibc rightfully doesn't
provide it at all. If you use it with UTF-8 non-ASCII chars, the result
is random nonsense.
It's used in the cygw32 build of emacs, in w32font.c. The native Windows build
uses _strlwr, and Daniel added `#define _strlwr strlwr' for Cygwin. Maybe he
can comment on this.
Unfortunately, I don't have any special insight into the use of this function
--- Emacs is very, very old, and we still technically support Windows 95. Now,
we've changed _strlwr to _mbslwr in a few places, so maybe we can fix the rest.
The specific use in w32font.c is probably best addressed by adding support for
UNICODE LOGFONTW throughout.
static DWORD
generate_inode_val (const char * name)
{
char fullname[ MAX_PATH ];
char * p;
unsigned hash;
/* Get the truly canonical filename, if it exists. (Note: this
doesn't resolve aliasing due to subst commands, or recognize hard
links. */
if (!w32_get_long_filename ((char *)name, fullname, MAX_PATH))
emacs_abort ();
parse_root (fullname, &p);
/* Normal W32 filesystems are still case insensitive. */
_strlwr (p);
return hashval (p);
}
Thing is, that's completely unnecessary --- modern versions of Windows have real
inode numbers! (Well, 64-bit FileIds, but close enough.)
Uhm... not quite. While Windows supports FileIDs, they are not
unambiguous on FAT and FAT32. The FileIds of a file may change on these
filesystems by adding or removing other files in the same dir.
Therefore, the right thing to do is to check the filesystem. If it's
FAT*, don't trust the FileId.


Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat
Loading...