Skip to content

Commit

Permalink
fix Issue 15019 - [ICE] Heisencrash on OS X 32-bit with non-trivial p…
Browse files Browse the repository at this point in the history
…rojects
  • Loading branch information
WalterBright committed Sep 14, 2015
1 parent 8d5d4c3 commit 300f95c
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 20 deletions.
3 changes: 1 addition & 2 deletions src/backend/elfobj.c
Expand Up @@ -2425,8 +2425,7 @@ unsigned Obj::bytes(int seg, targ_size_t offset, unsigned nbytes, void *p)
int save = buf->size();
//dbg_printf("Obj::bytes(seg=%d, offset=x%lx, nbytes=%d, p=x%x)\n",
//seg,offset,nbytes,p);
buf->setsize(offset);
buf->reserve(nbytes);
buf->position(offset, nbytes);
if (p)
{
buf->writen(p,nbytes);
Expand Down
5 changes: 2 additions & 3 deletions src/backend/machobj.c
Expand Up @@ -2285,8 +2285,7 @@ if (!buf) halt();
int save = buf->size();
//dbg_printf("Obj::bytes(seg=%d, offset=x%lx, nbytes=%d, p=x%x)\n",
//seg,offset,nbytes,p);
buf->setsize(offset);
buf->reserve(nbytes);
buf->position(offset, nbytes);
if (p)
{
buf->writen(p,nbytes);
Expand Down Expand Up @@ -2574,7 +2573,7 @@ int Obj::reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val,

Outbuffer *buf = SegData[seg]->SDbuf;
int save = buf->size();
buf->setsize(offset);
buf->position(offset, retsize);
//printf("offset = x%llx, val = x%llx\n", offset, val);
if (retsize == 8)
buf->write64(val);
Expand Down
37 changes: 23 additions & 14 deletions src/backend/outbuf.c
Expand Up @@ -24,6 +24,8 @@
#if DEBUG
static char __file__[] = __FILE__; // for tassert.h
#include "tassert.h"
#else
#include <assert.h>
#endif

Outbuffer::Outbuffer()
Expand Down Expand Up @@ -107,23 +109,25 @@ void Outbuffer::enlarge(size_t nbytes)
p = buf + used;
}

// Position buffer for output at a specified location and size.
// If data will extend buffer size, reserve space
// If data will rewrite existing data
// position for write and return previous buffer size
//
// If data will append to buffer
// position for write and return new size
size_t Outbuffer::position(size_t pos, size_t nbytes)
/*****************************************
* Position buffer for output at a specified location and size.
* Params:
* offset = specified location
* nbytes = number of bytes to be written at offset
*/
void Outbuffer::position(size_t offset, size_t nbytes)
{
size_t current_sz = size();
unsigned char *fend = buf+pos+nbytes; // future end of buffer
if (fend >= pend)
if (offset + nbytes > len)
{
reserve (fend - pend);
enlarge(offset + nbytes - (p - buf));
}
setsize(pos);
return pos+nbytes > current_sz ? pos+nbytes : current_sz;
p = buf + offset;
#if DEBUG
assert(buf <= p);
assert(p <= pend);
assert(len == pend - buf);
assert(p + nbytes <= pend);
#endif
}

// Write an array to the buffer.
Expand Down Expand Up @@ -264,6 +268,11 @@ char *Outbuffer::toString()
void Outbuffer::setsize(size_t size)
{
p = buf + size;
#if DEBUG
assert(buf <= p);
assert(p <= pend);
assert(len == pend - buf);
#endif
}

void Outbuffer::writesLEB128(int value)
Expand Down
2 changes: 1 addition & 1 deletion src/backend/outbuf.h
Expand Up @@ -51,7 +51,7 @@ struct Outbuffer
void *writezeros(size_t n);

// Position buffer to accept the specified number of bytes at offset
size_t position(size_t offset, size_t nbytes);
void position(size_t offset, size_t nbytes);

// Write an array to the buffer, no reserve check
void writen(const void *b, size_t len)
Expand Down
74 changes: 74 additions & 0 deletions test/compilable/test15019.d
@@ -0,0 +1,74 @@
// https://issues.dlang.org/show_bug.cgi?id=15019
// dmd -m32 -c all.d

import std.string;

struct Color()
{
static fromHex(char[] s)
{
import std.conv;
s.to!ubyte;
}
}

Color!() RGB ;

struct Matrix(T, int R, int C)
{
Vector!(T, C) row_t;
T[C] v; // all elements

/// Covnerts to pretty string.
string toString() const
{
try
return format("%s", v);
catch
assert(false); // should not happen since format is right
}
}

// GLSL is a big inspiration here
// we defines types with more or less the same names
template mat2x2(T) { Matrix!(T, 2, 2) mat2x2; }
template mat3x3(T) { Matrix!(T, 3, 3) mat3x3; }
template mat4x4(T) { Matrix!(T, 4, 4) mat4x4; }

alias mat2x2 mat2;
alias mat3x3 mat3; // shorter names for most common matrices
alias mat4x4 mat4;

string definePostfixAliases(string type)
{
return "alias " ~ type ~ "!byte " ~ type ~ "b;\n"
"alias " ~ type ~ "!ubyte " ~ type ~ "ub;\n"
"alias " ~ type ~ "!short " ~ type ~ "s;\n"
"alias " ~ type ~ "!ushort " ~ type ~ "us;\n"
"alias " ~ type ~ "!int " ~ type ~ "i;\n"
"alias " ~ type ~ "!uint " ~ type ~ "ui;\n"
"alias " ~ type ~ "!long " ~ type ~ "l;\n"
"alias " ~ type ~ "!ulong " ~ type ~ "ul;\n"
"alias " ~ type ~ "!float " ~ type ~ "f;\n"
"alias " ~ type ~ "!double " ~ type ~ "d;\n";
}

// define a lot of type names
mixin(definePostfixAliases("mat2"));
mixin(definePostfixAliases("mat3"));
mixin(definePostfixAliases("mat4"));
import std.string;

struct Vector(T, int N)
{
T[N] v;

string toString()
{
try
return format("%s", v);
catch
assert(false);
}
}

0 comments on commit 300f95c

Please sign in to comment.