The default linker in OpenBSD 3.9 segfaults reproducibly:
[EMAIL PROTECTED]:~$ gcc -o -Wall wav2bin wav2bin.c
collect2: ld terminated with signal 11 [Segmentation fault], core dumped
wav2bin(.init+0x0): In function `__init':
: multiple definition of `__init'
/usr/lib/crtbegin.o(.init+0x0): first defined here
wav2bin(.text+0x0): In function `_start':
: multiple definition of `__start'
/usr/lib/crt0.o(.text+0x0): first defined here
wav2bin(.data+0x0): multiple definition of `__progname'
/usr/lib/crt0.o(.data+0x0): first defined here
wav2bin(.text+0x0): In function `_start':
: multiple definition of `_start'
/usr/lib/crt0.o(.text+0x0): first defined here
wav2bin(.fini+0x0): In function `__fini':
: multiple definition of `__fini'
/usr/lib/crtbegin.o(.fini+0x0): first defined here
wav2bin(.text+0x18): In function `___start':
: multiple definition of `___start'
/usr/lib/crt0.o(.text+0x18): first defined here
/tmp//cce21751.o(.text+0x91): In function `process_byte':
: multiple definition of `process_byte'
wav2bin(.text+0x249): first defined here
/usr/bin/ld: Warning: size of symbol `process_byte' changed from 171 in wav2bin
to 242 in /tmp//cce21751.o
/tmp//cce21751.o(.text+0x183): In function `process_bit':
: multiple definition of `process_bit'
wav2bin(.text+0x2f4): first defined here
/tmp//cce21751.o(.text+0x1d0): In function `process_time':
: multiple definition of `process_time'
wav2bin(.text+0x341): first defined here
/tmp//cce21751.o(.text+0x27e): In function `squelch_reset':
: multiple definition of `squelch_reset'
wav2bin(.text+0x3ef): first defined here
/tmp//cce21751.o(.text+0x2fb): In function `process_loud_sample':
: multiple definition of `process_loud_sample'
wav2bin(.text+0x46c): first defined here
/tmp//cce21751.o(.text+0x37d): In function `process_sample':
: multiple definition of `process_sample'
wav2bin(.text+0x4ee): first defined here
/tmp//cce21751.o(.text+0x3e4): In function `process_samples':
: multiple definition of `process_samples'
wav2bin(.text+0x555): first defined here
/tmp//cce21751.o(.text+0x445): In function `main':
: multiple definition of `main'
wav2bin(.text+0x5b6): first defined here
/usr/lib/crt0.o(.dynamic+0x0): multiple definition of `_DYNAMIC'
/usr/lib/crt0.o(.got.plt+0x0): multiple definition of `_GLOBAL_OFFSET_TABLE_'
bt full:
(gdb) bt full
#0 0x1c01a6a6 in bfd_getl32 ()
No symbol table info available.
#1 0x1c0278a9 in bfd_elf32_swap_reloc_in ()
No symbol table info available.
#2 0x1c038b51 in elf_link_sort_relocs ()
No symbol table info available.
#3 0x1c03b4d7 in bfd_elf_final_link ()
No symbol table info available.
#4 0x1c0107be in ldwrite ()
No symbol table info available.
#5 0x1c00e69e in main ()
No symbol table info available.
What should I do to diagnose the problem? The .c file follows.
CL<
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define WAV_HDR_LEN 0x2c
#define SAMPLERATE_OFFSET 0x18
#define BDRY1 340 /* us */
#define BDRY2 555 /* us */
#define BDRY3 700 /* us */
#define LEAD 100 /* 100 edges */
#define SQUELCH_TIME 300 /* us */
#define PRINT_TIMES 0
#define HDR_SIZE 16
unsigned char wav_header[WAV_HDR_LEN];
float sample_time; /* In microseconds */
unsigned leader_counter=0;
int halfbit;
int firstbit;
unsigned byte_counter;
unsigned char byte_checksum;
unsigned char flagbyte;
unsigned char type;
unsigned char header[HDR_SIZE]; /* Tape header */
void read_wav_header(void)
{
unsigned short samplerate;
unsigned char *srptr=wav_header+SAMPLERATE_OFFSET;
fread(header, WAV_HDR_LEN, 1, stdin);
if (memcmp(wav_header,"RIFF",4)){
fprintf(stderr,"wav2bin: Error: input not a WAV file\n");
exit(1);
}
samplerate=*srptr+(*(srptr+1)<<8);
sample_time=1e6/samplerate;
}
/* Gets all bytes, including flag byte. */
void process_byte(unsigned char byte)
{
byte_checksum^=byte;
if (!byte_counter){
flagbyte=byte;
if (flagbyte==0xff){
fprintf(stderr,"Data\n");
}else if (flagbyte==0x00){
fprintf(stderr,"Header\n");
}else{
fprintf(stderr,"Invalid flagbyte\n");
exit(1);
}
}else{
if (!flagbyte){
if (byte_counter<HDR_SIZE) header[byte_counter]=byte;
else{
fprintf(stderr,"Header overrun!\n");
exit(1);
}
}
}
if (byte_counter) printf("0x%02x\n",byte);
byte_counter++;
}
void process_bit (int bit)
{
static int bits;
static int byte=0;
byte<<=1;
byte|=bit;
bits++;
if (bits>=8){
process_byte(byte);
bits=0;
byte=0;
}
}
void process_time(float time)
{
if (leader_counter<100){
if (time>=BDRY2&&time<BDRY3) leader_counter++;
else leader_counter=0;
return;
}
if (time<BDRY2){
halfbit^=1;
if (halfbit) return;
if (firstbit){
firstbit=0;
return;
}
#if PRINT_TIMES
printf("%f\n",time);
#else
process_bit(time>=BDRY1);
#endif
}
}
/* Resets the decoder when the sound ceases. */
void squelch_reset(void)
{
if (byte_counter){
if (byte_checksum)fprintf(stderr,"Bad checksum block"
" checksum=0x%02x\n", byte_checksum);
else fprintf(stderr,"Good checksum block\n");
}
leader_counter=0;
firstbit=1;
halfbit=0;
byte_counter=0;
byte_checksum=0;
}
void process_loud_sample(int sample)
{
static int last_sample=0;
static float time_since_last_edge=0;
if ((sample^last_sample)<0){
/* They have different signs */
float time; /* Time between the beginning of this sample and
the zero crossing */
time=sample_time*last_sample/(last_sample-sample);
time_since_last_edge+=time;
process_time(time_since_last_edge);
time_since_last_edge=sample_time-time;
}else{
/* They have the same signs */
time_since_last_edge+=sample_time;
}
last_sample=sample;
}
#define abs(x) ((x)>=0?(x):-(x))
void process_sample(int sample)
{
static float time_since_last_loud=0;
if (abs(sample)>3) time_since_last_loud=0;
else time_since_last_loud+=sample_time;
if (time_since_last_loud<SQUELCH_TIME) process_loud_sample(sample);
else squelch_reset();
}
void process_samples(void)
{
int sample;
again:
sample=getchar();
if (sample==EOF) return;
sample-=0x80;
process_sample(sample);
goto again;
}
int main(int argc, char **argv)
{
read_wav_header();
squelch_reset();
process_samples();
return 0;
}