From 0720671f7ab6bd2c8a60d2138b4befb52a1862db Mon Sep 17 00:00:00 2001 From: George Koehler Date: Thu, 8 Mar 2018 11:49:40 -0500 Subject: [PATCH] Fix wr_ranlib() for big-endian machines. With this change, I built and ran ack on a big-endian PowerPC Linux machine. I used gcc 4.9.4 to build ack, and I only built the linuxppc back end. Before this change, wr_ranlib() corrupted a value by changing it from 0x66 to 0x66000066. This value was too big, so led made a fatal error, "bad ranlib string offset". --- modules/src/object/wr_ranlib.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/modules/src/object/wr_ranlib.c b/modules/src/object/wr_ranlib.c index 91274d71c..b515ffb3b 100644 --- a/modules/src/object/wr_ranlib.c +++ b/modules/src/object/wr_ranlib.c @@ -10,16 +10,27 @@ wr_ranlib(fd, ran, cnt1) struct ranlib *ran; long cnt1; { - { - register long cnt = cnt1; - register struct ranlib *r = ran; - register char *c = (char *) r; + struct ranlib *r; + long cnt, val; + char *c; - while (cnt--) { - put4(r->ran_off,c); c += 4; - put4(r->ran_pos,c); c += 4; - r++; - } + /* + * We overwrite the structs in r with the bytes in c, so we + * don't need to allocate another buffer. + * + * put4(r->ran_off, c) can fail if r->ran_off and c overlap in + * memory, if this is a big-endian machine. It tries to swap + * the bytes from big to little endian, but overwrites some + * bytes before reading them. To prevent this, we must copy + * each value before we overwrite it. + */ + r = ran; + c = (char *)r; + cnt = cnt1; + while (cnt--) { + val = r->ran_off; put4(val, c); c += 4; + val = r->ran_pos; put4(val, c); c += 4; + r++; } wr_bytes(fd, (char *) ran, cnt1 * SZ_RAN); }