Caught signal 11: SIGSEGV with newer z88dk

Post Reply
alank2
Member
Posts: 116
Joined: Wed Mar 01, 2017 7:24 pm

Caught signal 11: SIGSEGV with newer z88dk

Post by alank2 »

Using:
zcc +cpm -clib=sdcc_iy -create-app crc32.c -ocrc32.com

The latest nightly build gives the above error, if I use the 199c, it compiles fine.

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define uint8_t unsigned char
#define uint16_t unsigned int
#define uint32_t unsigned long

char *filenames;
int filenames_max;
unsigned long *crc32tab;

uint8_t F_BDOS(uint8_t ACommand, uint8_t *AFCB) __smallc __naked
  {
    AFCB;
    ACommand;
    __asm
    push ix
    ld hl,4         //get parameters
    add hl,sp
    ld e,(hl)
    inc hl
    ld d,(hl)       //de=AFCB
    inc hl
    ld c,(hl)       //c=ACommand
    call 5          //call bdos
    ld l,a
    pop ix
    ret
    __endasm;
  }

/*void F_DMAOFF(uint8_t *ADMA) __smallc __naked
  {
    ADMA;
    __asm
    push ix
    ld hl,4         //get parameters
    add hl,sp
    ld e,(hl)
    inc hl
    ld d,(hl)       //de=ADMA
    ld c,0x1A
    call 5          //call bdos
    pop ix
    ret
    __endasm;
  }*/

uint8_t F_OPEN(uint8_t *AFCB)
  {
    uint8_t c1;

    c1=F_BDOS(0x0f,AFCB);

    //clear cr
    AFCB[0x20]=0;

    return (c1<=0x03);
  }

uint8_t F_CLOSE(uint8_t *AFCB)
  {
    return (F_BDOS(0x10,AFCB)<=0x03);
  }

uint8_t F_SFIRST(uint8_t *AFCB)
  {
    uint8_t c1;

    //F_DMAOFF(ABuffer);

    c1=F_BDOS(0x11,AFCB);

    return c1;
  }

uint8_t F_SNEXT(uint8_t *AFCB)
  {
    uint8_t c1;

    //F_DMAOFF(ABuffer);

    c1=F_BDOS(0x12,AFCB);

    return c1;
  }

uint8_t F_IO(uint8_t AWrite, uint8_t *AFCB)
  {
    //F_DMAOFF(ABuffer);

    if (F_BDOS(AWrite?0x15:0x14,AFCB))
      return 0;

    return 1;
  }

uint8_t F_READ(uint8_t *AFCB)
  {
    return F_IO(0,AFCB);
  }

uint8_t F_WRITE(uint8_t *AFCB)
  {
    return F_IO(1,AFCB);
  }

char crc_maketable()
  {
    short i, inx;
    short carry32;
    unsigned long entry32;

    for (inx=0;inx<256;++inx)
      {
        entry32=inx;
        for (i=0;i<8;++i)
          {
            carry32=(short)(entry32&1);
            entry32>>=1;
            if (carry32)
              entry32^=0xedb88320UL;
          }
        crc32tab[inx]=entry32;
      }

    return 1;
  }

char crc_update(char * buf, unsigned int count, unsigned long * crc32)
  {
    unsigned long i;
    unsigned char inx32;

    if (count==0)
      return 0;
    for (i=0;i<count;++i)
      {
        inx32=(unsigned char)(buf[i]^*crc32);
        *crc32>>=8;
        *crc32^=crc32tab[inx32];
      }
    return 1;
  }

void dump(char*s, int bytes)
  {
    int i1;

    for (i1=0;bytes;bytes--)
      {
        printf("%02x ",*s);
        s++;
        i1++;
        if (i1==16)
          {
            printf("\n");
            i1=0;
          }
      }
  }


/*

add support for unamiguous filenames (skip directory scan completely)

finish crc code changes

rename to crc32

*/

int main(int argc, char *argv[])
  {
    uint32_t crc;
    uint8_t c1,*buffer,s1[16],s2[16];
    uint8_t fcb[37],drive;
    int i1,i2;

    buffer=(uint8_t*)0x80;
    
    filenames=malloc(512*11);
    crc32tab=malloc(1000);
    if (filenames==NULL || crc32tab==NULL)
      {
        printf("out of memory\n");
        return 0;
      }

    //we should have an option
    if (argc!=2)
      {
        printf("crc32 filespec\n");
        goto end;
      }
    strncpy(s1,argv[1],15);
    s1[15]=0;

    //debug remove
    //strcpy(s1,"*.*");

    //convert input to flat filename format and eliminate asterisk

    if (s1[1]==':' && toupper(s1[0])>='A' && toupper(s1[0])<='P')
      {
        drive=toupper(s1[0])-64;
        strcpy(s2,s1+2);
        strcpy(s1,s2);
      }
    else drive=0;

    memset(s2,' ',11);
    for (i1=0,i2=0;s1[i1];i1++)
      {
        if (s1[i1]=='.')
          {
            i1++;
            break;
          }
        else
        if (s1[i1]=='*')
          while (i2<8)
            s2[i2++]='?';
        else
        if (i2<8)
          s2[i2++]=toupper(s1[i1]);

      }
    for (i2=8;s1[i1];i1++)
      {
        if (s1[i1]=='.')
          break;
        else
        if (s1[i1]=='*')
          while (i2<11)
            s2[i2++]='?';
        else
        if (i2<11)
          s2[i2++]=toupper(s1[i1]);
      }
    s2[11]=0;
    strcpy(s1,s2);


    printf("Scanning directory...");
    memset(fcb,0,37);
    fcb[0]=drive;
    memcpy(&fcb[1],s1,11);
    c1=F_SFIRST(fcb);
    while (c1<0x04)
      {
        for (i1=0;i1<11;i1++)
          filenames[filenames_max*11+i1]=buffer[c1*32+1+i1] & 0x7f;
        filenames_max++;
        c1=F_SNEXT(fcb);
      }
    printf("\n");

    //build crc32 table
    crc_maketable();

    for (i1=0;i1<filenames_max;i1++)
      {
        //print filename
        printf("%-8.8s.%-3.3s --> ",filenames+i1*11,filenames+i1*11+8);
        
        //calculate crc32 for file
        memset(fcb,0,37);
        fcb[0]=drive;
        memcpy(&fcb[1],filenames+i1*11,11);
        if (!F_OPEN(fcb))
          {
            printf("Unable to open\n");
            continue;
          }
        crc=0xffffffffUL;
        while (F_READ(fcb))
          crc_update(buffer,128,&crc);
        crc^=0xffffffffUL;
        if (!F_CLOSE(fcb))
          {
            printf("no close\n");
            continue;
          }

        //print crc32
        printf("%08lX\n",crc);
      }

    end:
    free(crc32tab);
    free(filenames);
    return 0;
  }
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

So, it appears that in certain circumstances sdcc falls over after it's generated a call to a __smallc function. We think we've narrowed down the commit range in which this happened and an upstream bug has been raised.

Furthermore,I think it's caused by having a char in the prototype - we've not previously spotted it since classic promoted all chars to ints in prototypes to work around another sdcc bug.

So in this case, if you just change the uint8_t ACommand to a uint16_t ACommand then compilation should succeed.
alank2
Member
Posts: 116
Joined: Wed Mar 01, 2017 7:24 pm

Post by alank2 »

Thanks guys; good job on all the work on this.
Post Reply