[RFC-v2] BFD MinGW/Cygwin build error in bfd/peiXXgen.c

Pierre Muller
2013-12-19T11:45:09Z

Hi Nick,

After looking at the code a little longer,
I think that there were still other issues in that part
of the code.
1) The astring and bstring were still not declared
for the last macro case (hosts having no wchar header).
I solved this issue by placing the declarations
at the start of the function.
2) In GDB coding rules, we are not allowed to mix code and declaration.
The declaration of res after handling the ! is_name part
does not follow this rule.
Isn't that rule also used for Binutils project?
I moved the declaration of astring, alen, bstring and blen to
the start of the function. It does introduce a penalty, in the sense that
those variables are set even though this is not useful if is_name is false.
Otherwise adding an extra brace level might be the proper solution.
Another silly coding style question: Should there by a space
between the address operator "&" and the variable or expression following?

3) I was wondering why the Windows case started at astring + 2,
but I couldn't find any valid reason, so that I changed it to
compare the strings from the first position.
4) I did the same for the code if wchar is missing.
5) To have a symmetric code for cygwin versus mingw,
I introduced a macro called rscpcmp for both cases.

Finally, I also have a question regarding the codepage field.
According to Windows PE resources can use any codepage.
Is the new code restricted to UNICODE only?
If not, shouldn't the rsrc_cmp code also depend on whether
16-bit Windows UNICODE is used or any other page code?

The main problem is that I have no source code to test this code on...

Pierre Muller

PS: I removed the fixme as suggested by Pedro.

2013-12-19 Pierre Muller <muller@sourceware.org>

peXXigen.c (u16_mbtouc): Avoid unused function warning by excluding if
__CYGWIN__ or __MINGW32__ macro is defined.
(rsrc_cmp): Fix Windows host version and version without wchar header.
[__CYGWIN__, __MINGW32__]: Introduce rsrccmp macro.

diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index 2a33a77..f5879f6 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -2930,7 +2930,7 @@ rsrc_write_directory (rsrc_write_data * data,
BFD_ASSERT (nt == next_entry);
}

-#ifdef HAVE_WCHAR_H
+#if defined HAVE_WCHAR_H && ! defined __CYGWIN__ && ! defined __MINGW32__
/* Return the length (number of units) of the first character in S,
putting its 'ucs4_t' representation in *PUC. */

@@ -2974,22 +2974,30 @@ static signed int
rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b)
{
if (! is_name)
- return a->name_id.id - b->name_id.id;
+ return a->name_id.id - b->name_id.id;

/* We have to perform a case insenstive, unicode string comparison... */
int res;
-
-#ifdef __CYGWIN__
- /* Under Cygwin unicode == UTF-16 == wchar_t.
- FIXME: The same is true for MingGW - we should test for that too. */
- res = wcsncasecmp ((const wchar_t *) astring + 2, (const wchar_t *) bstring + 2, min (alen, blen));
-#elif defined HAVE_WCHAR_H
- unsigned int i;
bfd_byte * astring = a->name_id.name.string;
unsigned int alen = a->name_id.name.len;
bfd_byte * bstring = b->name_id.name.string;
unsigned int blen = b->name_id.name.len;

+#if defined __CYGWIN__ || defined __MINGW32__
+#undef rscpcmp
+#ifdef __CYGWIN__
+#define rscpcmp wcsncasecmp
+#endif
+#ifdef __MINGW32__
+#define rscpcmp wcsnicmp
+#endif
+ /* Under Windows hosts (both cygwin and mingw types),
+ unicode == UTF-16 == wchar_t. */
+ res = rscpcmp ((const wchar_t *) astring, (const wchar_t *) bstring,
+ min (alen, blen));
+#elif defined HAVE_WCHAR_H
+ unsigned int i;
+
res = 0;
for (i = min (alen, blen); i--; astring += 2, bstring += 2)
{
@@ -3008,7 +3016,7 @@ rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b)
break;
}
#else
- res = memcmp (astring + 2, bstring + 2, min (alen, blen) * 2);
+ res = memcmp (astring, bstring, min (alen, blen) * 2);
#endif

if (res == 0)