Giter VIP home page Giter VIP logo

ack's Introduction

                     THE AMSTERDAM COMPILER KIT V6.1pre1
                     ===================================

                  © 1987-2005 Vrije Universiteit, Amsterdam
                                2022-08-19


INTRODUCTION
============

The Amsterdam Compiler Kit is a complete compiler toolchain consisting of
front end compilers for a number of different languages, code generators,
support libraries, and all the tools necessary to go from source code to
executable on any of the platforms it supports.

This is an early prerelease of the apocryphal version 6.1 release. Not a
lot is supported, the build mechanism needs work, and a lot of things are
probably broken. However, what's there should be sufficient to get things
done and to evaluate how the full 6.1 release should work. 



SUPPORT
=======

Languages:

ANSI C, B, Pascal, Modula 2, Basic. K&R is supported via the ANSI C compiler.

Platforms:

pc86          produces bootable floppy disk images for 8086 PCs
linux386      produces ELF executables for PC Linux systems
linux68k      produces ELF executables for m68020 Linux systems
linuxppc      produces ELF executables for PowerPC Linux systems
linuxmips     produces ELF executables for little-endian MIPS32r2 Linux systems
cpm           produces i80 CP/M .COM files
rpi           produces Raspberry Pi GPU binaries
pdpv7         produces PDP/11 V7 Unix binaries
msdos86       produces i86 MS-DOS .COM files
msdos386      produces i386 MS-DOS 32-bit DPMI .EXE files



INSTALLATION
============

The version 5.0 build mechanism has been completely rewritten. Installation
ought to be fairly straightforward. It will build on Unixishes including Linux,
OSX, and Windows using MSYS2 and mingw32.

Requirements:

- an ANSI C compiler. This defaults to gcc. You can change this by setting
  the CC make variable.

- flex and yacc.

- GNU make.

- Lua (any version) with the lua-posix library installed.

- (optionally) ninja; if you've got this, this will be autodetected and give
  you faster builds.

- about 115MB free in /tmp (or some other temporary directory).

- about 15MB in the target directory.

Instructions:

- edit the Makefile. There's a small section at the top where you can change
  the configuration. Probably the only one you may want to edit is PREFIX,
  which changes where the ACK installs to.

- Run:

    make

  ...from the command line. This will do the build.

  The make system is fully parallelisable. If you have a multicore system,
  install ninja and it'll use all your cores. If you don't have ninja, you
  can still use make for parallel builds with:

    make -r -j8   # or however many cores you have

  ...but frankly, I recommend ninja.

- Run:

    sudo make install

  ...from the command line. This will install the ACK in your PREFIX
  directory (by default, /usr/local).

The ACK should now be ready to use.



USAGE
=====

Currently I haven't sorted out all the documentation --- it's supplied in the
distribution, but not all of it gets installed yet --- so here is a quickstart
guide.

The main command to use is 'ack'. This invokes the compiler and the linker.
Some useful options include:

  -m<platform>     build for the specified platform
  -o <file>        specifies the output file
  -c               produce a .o file
  -c.s             produce a .s assembly file
  -O               enable optimisation (optimisation levels go up to 6)
  -ansi            compile ANSI C (when using the C compiler)
  -v               be more verbose (repeatable)
  <file>           build file

ack figures out which language to use from the file extension:

  .c               C (ANSI or K&R)
  .b               the PDP-11 dialect of B
  .bas             Basic
  .mod             Modula-2
  .ocm             Occam 1
  .p               Pascal
  .o               object files
  .s               assembly files
  .e               ACK intermediate code assembly files

For further information, see the man page (which actually does get
installed, but is rather out of date).

There are some (known working) example programs in the 'examples' directory.
A sample command line is:

ack -mlinux386 -O examples/paranoia.c



GOTCHAS
=======

There are some things you should be aware of.

- Look at plat/<PLATFORMNAME>/README for information about the supported
  platforms.
  
- The library support is fairly limited; for C, it's at roughly the ANSI C
  level, and for the other languages it's similar.
  
- When compiling languages other than C, the ACK will usually look at the
  first character of the file. If it's a #, then the file will be run through
  the C preprocessor anyway.

- BSD systems may need to up the number of file descriptors (e.g.
  'ulimit -n 200') before the ACK will compile.
  
- The ACK uses its own .o format. You won't be able to mix the ACK's object
  files and another compiler's.

- When compiling together multiple B source files, you need to do some extra
  work to initialise them properly otherwise your program will crash on
  startup; see the ack(1) and abmodules(1) man pages.

- The distribution contains *everything*, including the weird, ancient,
  archaic stuff that doesn't work any more and never will, such as the int EM
  interpreter and the assembler-linkers. Only some of it builds. Look for
  build.lua files.



DISCLAIMER
==========

The ACK is mature, well-tested software, but the environment in which it was
developed for and tested under is rather different from that available on
today's machines. There will probably be little in the way of logical bugs,
but there may be many compilation and API bugs.

If you wish to use the ACK, *please* join the mailing list. We are interested
in any reports of success and particularly, failure. If it does fail for you,
we would love to know why, in as much detail as possible. Bug fixes are even
more welcome.

The ACK is licensed under a BSD-like license. Please see the 'Copyright' file
for the full text.

You can find the mailing list on the project's web site:

	http://tack.sourceforge.net/
	
Please enjoy.

David Given (davidgiven on Github)
[email protected]
2018-09-18

ack's People

Contributors

ccodere avatar cerieljacobs avatar davidgiven avatar dram avatar dtrg avatar grobe0ba avatar kernigh avatar nick-less avatar tevorbl avatar tkchia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ack's Issues

[cygwin][make] How do I install ACK under cygwin?

If I run make I get the following errors:

util/LLgen+llgen/main
util/LLgen+llgen
lang/basic/src+llgen
"/home/fcaruso/ACK_INSTALL/ack/lang/basic/src/basic.g", line 65: (Warning) terminal DBLVALUE not used
"/home/fcaruso/ACK_INSTALL/ack/lang/basic/src/basic.g", line 67: (Warning) terminal UNARYSYM not used
"/home/fcaruso/ACK_INSTALL/ack/lang/basic/src/basic.g", line 77: (Warning) terminal BOOLOP not used
"/home/fcaruso/ACK_INSTALL/ack/lang/basic/src/basic.g", line 83: (Warning) terminal LESYM not used
"/home/fcaruso/ACK_INSTALL/ack/lang/basic/src/basic.g", line 84: (Warning) terminal GESYM not used
"/home/fcaruso/ACK_INSTALL/ack/lang/basic/src/basic.g", line 85: (Warning) terminal NESYM not used
"/home/fcaruso/ACK_INSTALL/ack/lang/basic/src/basic.g", line 86: (Warning) terminal UNARYMINUS not used
lang/basic/src+tokentab_h
lang/basic/src/maketokentab: line 3: ed: command not found
make[1]: *** [/tmp/ack-build/build.make:354: lang/basic/src+tokentab_h-IMPL] Error 127
make[1]: Leaving directory '/home/fcaruso/ACK_INSTALL/ack'
make: *** [Makefile:102: build-plus-goals] Error 2

PIM's FileSystem library is missing

PIM defines a low-level I/O and file system access library called FileSystem. See PIM 3rd edition page 178 and PIM 4th edition page 161. I don't have a copy of the 2nd edition at hand but I am dead certain that it is also part of the 2nd edition.

FileSystem is the smallest common denominator for PIM Modula-2. Using FileSystem as a base, it is possible to write portable code across different PIM implementations. InOut alone is insufficient for this purpose because it lacks certain functionality (namely checking if a file exists, delete and rename a file, all of which are essential).

I maintain a portable preprocessor for Modula-2 that is designed to compile on any Modula-2 compiler PIM or ISO.

https://github.com/m2sf/m2pp

For this I had to develop techniques and libraries to overcome the differences between the two dialects. In fact the primary purpose of the preprocessor is to allow the writing of portable code and let the preprocessor generate PIM and ISO versions if necessary.

Ironically, when FileSystem is available one can write portably across PIM implementations, but one cannot write portably across ISO Modula-2 implementations, precisely because the ISO standard doesn't provide FileSystem, nor any equivalent, nor any replacement for the missing functionality.

Thus, M2PP uses FileSystem as a base and provides per-compiler adapter libraries for ISO Modula-2 compilers to cover the missing functionality that the ISO standard doesn't provide.

There are eight ISO Modula-2 compilers, so we need eight separate implementations of the FileSystemAdapter library.

I believe a PIM compiler shouldn't require such an adapter. A PIM compiler should provide FileSystem in its library. So should ACK.

hilo.mod broken on powerpc

hilo.mod doesn't work on powerpc platforms. I remember that it worked in the past.

I built f1c357b from the default branch and copied staging/share/ack/examples/hilo_mod.linuxppc to my PowerPC Linux machine (a qemu-system-ppc running Debian). After I enter my name, the program enters an infinite loop until I hit ^C:

kernigh@lip:~$ ./hilo_mod.linuxppc 

Hi there! I'm written in Modula-2. Before we start, what is your name?
> George
...
> 
Try a bit higher.
> 
Try a bit higher.
> 
Try a bit higher.
^CSegmentation fault

I built 969e98b from my Mac OS X branch and copied hilo_mod.osxppc to my PowerPC Mac. It has the same problem:

Ghostborough:~/mack kernigh$ ./hilo_mod.osxppc 

Hi there! I'm written in Modula-2. Before we start, what is your name?
> George
...
> 
Try a bit higher.
> 
Try a bit higher.
> 
Try a bit higher.
> ^C"lang/m2/libm2/Traps.mod", line 54: got a unix signal

I get a message from Traps.mod in Mac OS X but a "Segmentation fault" in Linux. This might be a bug with signal handlers: Linux puts the signal number in register r3 but ACK reads it from 0(r1).

I also tried hilo_mod.osx386 (from my Mac OS X branch) on an Intel Mac. It doesn't have the bug, so I can guess numbers as usual. I also tried hilo_mod.pc86 (from the default branch) in qemu-system-i386. It doesn't have the bug. I only get the bug with PowerPC.

Can't use dot in PowerPC assembler

I'm running 559233e. I can't assemble this file for PowerPC:

.sect .text
	.data4 sz

.sect .rom
be:
	.asciz "A string"
sz = . - be

The command ack -mlinuxppc -c.o file.s fails with "file.s", line 7: expr syntax err. The commands ack -mlinux386 -c.o file.s and ack -mlinux68k -c.o file.s both succeed.

The problem is with the dot . in the expression . - be. The assembler defines "." as a DOT token in mach/proto/as/comm3.c, but the PowerPC assembler defines "." as a C token in mach/powerpc/as/mach3.c, so "." appears twice in the keytab. When the assembler searches the keytab, it seems to always find the C "." and never the DOT ".".

C and DOT need to be different tokens, or the yacc grammar would be ambiguous. To fix this problem, one might need to hack the lexer to decide whether each "." is a C or a DOT.

Long module names support for Modula-2

It seems that ACK do not support long module names for Modula-2, e.g.:

MODULE test;

IMPORT FooBarBazQux;

BEGIN
END test.

According to strace output, when compiling this example, ACK will try to open file FooBarBazQ.def instead of FooBarBazQux.def.

Bugs in libcc.ansi/misc/getpw.c

Function getpw() in libcc.ansi/misc/getpw.c

  1. in line 27
    if(ch = '\0') return 1;
    =>
    if(ch == '\0') return 1;

  2. should always fclose(pwf) before returning;

modern code generator bugs

I found two bugs in how mcg (commit 4ba409e) compiles plat/linux/libsys/write.c. The function being compiled is

int write(int fd, void* buffer, size_t count)
{
        return _syscall(__NR_write, fd, (quad) buffer, count);
}

The output of ack -mlinuxppc -O6 -c.so write.c is

.sect .text
.sect .rom
.sect .data
.sect .bss
.extern _write

.sect .text
_write:
! saved_size = 4 bytes
! spills_size = 0 bytes
! locals_size = 0 bytes
addi sp, sp, -12
mfspr r0, lr
stw fp, 4(sp)
stw r0, 8(sp)
addi fp, sp, 4
stw r31, 0(fp)

First bug: The saved r31 overwrites the saved r2. We have allocated 12 bytes of stack space, saved r2 in 4(sp), saved lr in 8(sp), but now save r31 in 4(sp), because addi fp, sp, 4 causes 0(fp) to be the same word as 4(sp).

stw r31, 0(fp)
lwz r12, 16(fp)
lwz r11, 12(fp)
lwz r10, 8(fp)
stwu r12, -4(sp)
stwu r11, -4(sp)
! FROMSI.I(int) -> int
stwu r10, -4(sp)
li32 r12, 4
stwu r12, -4(sp)
bl __syscall
addi sp, sp, 16
! FROMUI.I(int) -> int
mr r3, r31

Second bug: Functions seem to store their return values in r3 but load them from r31. This wrong mr r3, r31 is destroying the return value.

! setret4
.anon_bb_0:
lwz r31, 0(fp)
lwz r0, 4(fp)
mtspr lr, r0
lwz r0, 0(fp)
addi sp, fp, 8
mr fp, r0
bclr 20, 0, 0

This is the first bug again. It's now restoring the caller's r31 from 0(r2) and the caller's r2 from 0(r2), but we lost the value of r2. In my test program, r31 held zero, and r2 held the frame pointer of main(). When main() tried to use the frame pointer, it segfaulted.

Use after free in ego

It's been a long time since I tried the ACK. I have installed luaposix and ninja, tweaked the top-level Makefile to run lua51 (not lua5.1), and I'm now trying to build 8c94b13. I'm running OpenBSD 6.0 on amd64. Build fails when ego gets a signal:

[945/2942] ACKDIR=/tmp/ack-build/stagi...obj/plat/linux386/include/headers -O6 
FAILED: /tmp/ack-build/obj/lang/cem/libcc.ansi/lib_linux386/memcpy/memcpy.o 
ACKDIR=/tmp/ack-build/staging /tmp/ack-build/staging/bin/ack -mlinux386 -c -o /tmp/ack-build/obj/lang/cem/libcc.ansi/lib_linux386/memcpy/memcpy.o lang/cem/libcc.ansi/string/memcpy.c -I/tmp/ack-build/obj/lang/cem/libcc.ansi/headers/headers -I/tmp/ack-build/obj/plat/linux386/include/headers -O6 
ego: /tmp/ack-build/staging/lib/ack/ego/cf got a unix signal
[946/2942] ACKDIR=/tmp/ack-build/stagi...obj/plat/linux386/include/headers -O6 
FAILED: /tmp/ack-build/obj/lang/cem/libcc.ansi/lib_linux386/strncmp/strncmp.o 
ACKDIR=/tmp/ack-build/staging /tmp/ack-build/staging/bin/ack -mlinux386 -c -o /tmp/ack-build/obj/lang/cem/libcc.ansi/lib_linux386/strncmp/strncmp.o lang/cem/libcc.ansi/string/strncmp.c -I/tmp/ack-build/obj/lang/cem/libcc.ansi/headers/headers -I/tmp/ack-build/obj/plat/linux386/include/headers -O6 
ego: /tmp/ack-build/staging/lib/ack/ego/cf got a unix signal
[947/2942] ACKDIR=/tmp/ack-build/stagi...obj/plat/linux386/include/headers -O6 
FAILED: /tmp/ack-build/obj/lang/cem/libcc.ansi/lib_linux386/tzset/tzset.o 
ACKDIR=/tmp/ack-build/staging /tmp/ack-build/staging/bin/ack -mlinux386 -c -o /tmp/ack-build/obj/lang/cem/libcc.ansi/lib_linux386/tzset/tzset.o lang/cem/libcc.ansi/time/tzset.c -I/tmp/ack-build/obj/lang/cem/libcc.ansi/headers/headers -I/tmp/ack-build/obj/plat/linux386/include/headers -O6 
ego: /tmp/ack-build/staging/lib/ack/ego/cf got a unix signal
ninja: build stopped: subcommand failed.
gmake: *** [Makefile:79: +ack] Error 1

Looking at the last core dump:

$ gdb /tmp/ack-build/staging/lib/ack/ego/cf cf.core
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "amd64-unknown-openbsd6.0"...
Core was generated by `cf'.
Program terminated with signal 10, Bus error.
Loaded symbols for /tmp/ack-build/staging/lib/ack/ego/cf
Reading symbols from /usr/lib/libc.so.88.0...done.
Loaded symbols for /usr/lib/libc.so.88.0
Reading symbols from /usr/libexec/ld.so...done.
Loaded symbols for /usr/libexec/ld.so
#0  putunit (kind=Variable "kind" is not available.
) at util/ego/share/put.c:436
436                     Ldeleteset(b->b_loops);
(gdb) bt
#0  putunit (kind=Variable "kind" is not available.
) at util/ego/share/put.c:436
#1  0x00001c55fec01ca0 in main (argc=Variable "argc" is not available.
) at util/ego/cf/cf.c:596
(gdb) print b
$1 = 0xdfdfdfdfdfdfdfdf

Looks like b is in freed memory. The 0xdf bytes are probably junk from OpenBSD's free(), see malloc.conf(5). I'm now looking for the bug in ego's code.

qemuppc won't run tests bigger than 4kB

It looks like qemu only loads (or at least, maps) the bottom 4kB of the kernel. So far our tests haven't been big enough to hit this limit, but now we have a big one (written in Modula-2) which is about 20kB, and won't run.

I've turned off qemuppc test running for the time being.

plats need to depend on the language compilers

They already depend on the language libraries, but not the compilers, which are built by the top-level build.lua --- so there's a race between what gets built first. We should refactor so that each plat depends on all the tools it needs. This would fix the race, and also allow plats to be built one at a time.

BASIC: _mid() can return uninitialized pointer

Hi,

cppcheck found this in function _mid()
[lang/basic/lib/string.c:161]: (error) Uninitialized variable: s2

IMO it is better to return(s) or call error() than to return an uninitialized pointer.

mach/m68020/as/mach4.c: two bad bitmasks ?

mach/m68020/as/mach4.c:476]: (style) Expression '(X & 0x38) == 0x1' is always false.

Source code is

if ((mrg_2&070) == 1 && $3!= 02000)

mach/m68020/as/mach4.c:487]: (style) Expression '(X & 0x38) == 0x1' is always false.

Duplicate

undefined behavior in cpp.ansi/LLlex.c

cppcheck reports
lang/cem/cpp.ansi/LLlex.c:265

shifting a 32-bit value (1) by 63 bits (from sizeof(long)) is undefined behavior
and gives a signed integer overflow.
Patch:
arith ubound = ~(1<<(sizeof(arith)*8-1))/(base/2);
=>
arith ubound = ~(1UL<<(sizeof(arith)*8-1))/(base/2);

Probably this was no problem as long as sizeof(int) == sizeof(long)...

libc, libsys have name conflict with Pascal

The following Pascal program causes a linker error, because its procedure malloc conflicts with malloc in libc:

program callmalloc(output);

var p : ^integer;

procedure malloc;
begin
   writeln('pass');
end;

begin
   new(p);
   malloc;
end.
$ ack -mlinuxppc -o callmalloc callmalloc.p 
led: /home/kernigh/park/ack-build/staging/share/ack/linuxppc/libc.a(malloc.o): _malloc: multiply defined (error)

This only happens because Pascal's new uses libc's malloc (since c084f9f). If I delete the new(p); line and the p variable, then the program prints pass.

This kind of name conflict seems to be caused by recent changes to ACK. Older ACK did more to prevent name conflicts between Pascal and C. In older ACK, Pascal programs did not link to libc. Old descr files like lib/i386/descr don't link libc to Pascal programs, but new descr files like plat/linux386/descr do link libc.

Also in older ack, libsys had alternate names for some system calls. These names had underscores, like _exit and _times. They hid from Pascal because Pascal has no underscores in its names. Pascal's libpc called the hidden names. Commit 1c83baa in 2007, and later commits, switched some calls to the regular names like close and open, but the regular names can conflict with Pascal programs.

em_led can't handle addresses >= 0x80010000

I seem to have met a bug in em_led (util/led) while trying to get plat/linuxppc to work. With my local changes, I am building linuxppc executables that sometimes crash. One such executable (a modified examples/paranoia.c) had a string at 0x800120cc, but the machine code tries to load it from 0x800020cc. I had compiled it this way:

$ ack -mlinuxppc -o modpar.linuxppc modpar.c
$ ack -mlinuxppc -c.out modpar.c
$ ack -mlinuxppc -c.s modpar.c

By studying modpar.s, I found my string at label _544. By running anm modpar.out, I found the address: 800120cc 1 - _544. By running gdb modpar.linuxppc on the target machine (Debian 8.5 in qemu-system-ppc), gdb disassembled this code:

   0x80003d20:  3d 80 80 00     lis     r12,-32768
   0x80003d24:  61 8c 20 cc     ori     r12,r12,8396
   0x80003d28:  95 81 ff fc     stwu    r12,-4(r1)
=> 0x80003d2c:  48 00 06 85     bl      0x800043b0

As I had stopped the program there (with break *0x80003d2c), gdb showed me that $r12 contained 0x800020cc, but I wanted the string at 0x800120cc:

(gdb) print/x $r12
$1 = 0x800020cc
(gdb) print/s (char*)0x800020cc
$2 = 0x800020cc "H"
(gdb) print/s (char*)0x800120cc
$3 = 0x800120cc "Trying to enter the main loop.\n"

This seems to be a bug in em_led: it put the correct address 0x800120cc in the symbol table (as I saw in anm) but the wrong address 0x800020cc in the relocated machine code.

I might not fix this bug. I will try to dodge this bug by loading code at a lower address. plat/powerpc/descr was using -b0:0x80000054 but linux386 and linux68k are already using lower addresses. One might reproduce this bug by using -b0:0x80000054 and putting printf("Some string\n") in paranoia's main(). Strings in 0x8000???? work but strings in 0x8001???? fail, so the problem seems to start around 0x80010000.

mcg calls getopt() in non-portable way

mach/proto/ncg/main.c, line 51:

        int c = getopt(argc, argv, "-d:D:C:o:");

The '-' in "-d:D:C:o:" is special to GNU libc or OpenBSD libc, and not portable to some other systems. mcg uses the special '-' to find its input file. I suspect that mcg would fail to find its input file when running on systems like FreeBSD.

The fix would look like my commit 50a7031, where I removed the special '-' from em_b and em_ego. I did not touch mcg because we now don't build mcg.

mcg crash, also bug with a > b

I played with mcg in 559233e. I changed plat/linuxppc/descr from ncg to mcg, then rebuilt the ack. (I'm running OpenBSD 6.0 for amd64.) It crashed, as mcg "got signal 11" (SIGSEGV) when compiling something in libcc.ansi. When I looked at the core dump, I found that data_block() in mach/proto/mcg/data.c had taken data pointing to memory shorter than size. I made this change:

diff --git a/mach/proto/mcg/parse_em.c b/mach/proto/mcg/parse_em.c
index b66b177..91d90b6 100644
--- a/mach/proto/mcg/parse_em.c
+++ b/mach/proto/mcg/parse_em.c
@@ -237,8 +237,12 @@ static void parse_pseu(void)
                 }
 
 				case str_ptyp:
-                    data_block(strdup(em.em_string), em.em_size, ro);
+                {
+                    void* buf = malloc(em.em_size);
+                    memcpy(buf, em.em_string, em.em_size);
+                    data_block(buf, em.em_size, ro);
 					break;
+                }
 
                 case cst_ptyp:
                     data_int(em.em_cst, EM_wordsize, ro);

I guess that the buffer from strdup() was shorter than em.em_size bytes, so I changed it to malloc() and memcpy(). After this change, mcg didn't crash.

Then I ran my tests from https://bitbucket.org/kernigh/ack-ptest with mcg compiling for linuxppc. Some tests failed. I want to report these 3 failures from logic.c:

not ok 6 - six > twelve (2nd)
not ok 18 - negnine > six (2nd)
not ok 42 - !(six < twelve) (2nd)

These failed to be false. Seems that if (a > b) works, but passing a > b to a function is broken. I want to have comparisons that work, so we can use them in other tests. It might be time to copy and adapt my logic.c (or something like it) to the tests in plat/tests.

resource leaks in readfile()

Hi,

cppcheck found a memory and a resource leak in readfile()
lang/cem/cemcom/mcomm.c:91

On return the file descriptor fd is leaked and the malloc()ed cbuf.

in C, "char *g = (char *)f + 11;" loses the 11

The following program prints "pass" with gcc but "fail" with ack:

#include <stdio.h>
void f(void) {}
char *g = (char *)f + 11;

int main(void) {
	char *h = g - 11;
	if (h == (char *)f) {
		puts("pass");
		return 0;
	} else {
		puts("fail");
		return 1;
	}
}

In OpenBSD/amd64: ack -mlinuxppc -o cka ckpointer.c

In Debian Linux/powerpc:

$ gcc -o ckg ckpointer.c
$ ./cka
fail
$ ./ckg
pass

The bug is with char *g = (char *)f + 11; where g is a global variable and f is a function. Now gcc is correct, but ack silently loses the 11 and effectively does char *g = (char *)f;. After running ack -c.e ckpointer.c, I can see g defined as

g
 con $f

To get this bug, f must be a function, and I must cast it to another pointer type like char *. If I don't cast f, or if I cast f to an integer type, then ack gives an error for an illegal initializer.

pc86 tests time out in qemu 2.11.1 because @@@@FFIINNIISSHHEED

After my upgrade from qemu 2.10.1 to 2.11.1 (as part of my upgrade from OpenBSD/amd64 6.2 to 6.3), the pc86 tests time out. The test never outputs @@FINISHED. It outputs @@@@FFIINNIISSHHEED. Each character appears twice because pc86 writes it to both the VGA console and the serial port, but the emulator now redirects the VGA console to the serial port.

**** /home/kernigh/park/ack-build/obj/plat/pc86/tests/tests/pc86-StringTest_mod-testlog.txt
@@TIMEDOUT                                                                      
SeaBIOS (version rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org)            
                                                                                
                                                                                
iPXE (http://ipxe.org) 00:03.0 C980 PCI2.10 PnP PMM+07F915A0+07EF15A0 C980     
                                                                               
                                                                                
                                                                               
Booting from Hard Disk...                                                      
Boot failed: could not read the boot disk                                       
                                                                               
Booting from Floppy...                                                         
ACKBOOT                                                                         
...................                                                             
Running.                                                                        
@@@@FFIINNIISSHHEED                                                             
D                                                                               
                                                                                
Halted.                                                                         

This seems to be a new feature in SeaBIOS 11.1.0 called "sercon" or server console. The BIOS detects qemu-system-i386 -nographic and redirects the console to serial. I need to remove -nographic to disable the redirection. Then I need to use other options to shut off the graphic display and connect the serial to qemu's stdout. The next diff works for me.

diff --git a/tests/plat/testdriver.sh b/tests/plat/testdriver.sh
index 07f206a5e..76cf79c27 100755
--- a/tests/plat/testdriver.sh
+++ b/tests/plat/testdriver.sh
@@ -22,7 +22,8 @@ get_test_output() {
                 qemu-system-ppc)  img="-kernel $img" ;;
             esac
 
-            $timeoutprog -t $timeout -- $method -nographic $img 2>&1
+            $timeoutprog -t $timeout -- $method -display none \
+                -serial mon:stdio $img 2>&1
             ;;
 
         qemu-*)

Either -serial stdio or -serial mon:stdio works. I use -serial mon:stdio to put the QEMU monitor on stdio, because -nographic also does that. The monitor commands are C-a h for help and C-a x to exit qemu.

tests/plat/testdriver.sh[48]: timeout: not found

FAILED: /home/kernigh/park/ack-build/obj/plat/qemuppc/tests/from_si_to_d_e/stamp 
tests/plat/testdriver.sh qemu-system-ppc /home/kernigh/park/ack-build/obj/plat/qemuppc/tests/from_si_to_d_e_bin/from_si_to_d_e_bin 5 && touch /home/kernigh/park/ack-build/obj/plat/qemuppc/tests/from_si_to_d_e/stamp 
tests/plat/testdriver.sh[48]: timeout: not found

The build fails just because I run OpenBSD and I haven't installed a timeout command. I'm working around this disabling all the tests: I comment out lines in build.lua so vars.plats_with_tests becomes an empty list.

It seems odd to run the tests during a build. What if a test fails but I still want to build ack? I suggest to move the tests from gmake to gmake test.

Add driver support for -x <language>

It looks like there isn't a way to force a particular source file to be interpreted as a particular language; this is needed if the file has an unexpected extension. We should add one.

The standard seems to be the -x <language> option, so we should use that.

Using ACK to bootstrap Pascal-P5

Pascal-P5 is a Pascal compiler confirmed to ISO 7185, updated form Pascal-P4.

As I found that Pascal compiler in ACK followed ISO 7185 quite closely, it would be interesting if ACK can be used to bootstrap Pascal-P5.

Currently, following error occurred when compiling pcom.pas and pint.pas. It seems that one serious problem is that ACK do not support using subrange as base type of SET, see (pcom.p:L265 and pint.p:L286).

% ack -o pcom pcom.p 
"pcom.p", line 265: illegal integer base type of set
"pcom.p", line 276: (warning) old-fashioned syntax ':' missing
"pcom.p", line 535: (warning) old-fashioned syntax ':' missing
"pcom.p", line 539: (warning) old-fashioned syntax ':' missing
"pcom.p", line 788: (warning) "lp" used before set
"pcom.p", line 908: (warning) "m" unused in "strltnvf"
"pcom.p", line 1362: (warning) "i" used before set
"pcom.p", line 3122: "IN": right operand must be a set
"pcom.p", line 3631: (warning) "llev" unused in "pageprocedure"
"pcom.p", line 4413: "+": illegal operand type(s)
"pcom.p", line 4439: "+": illegal operand type(s)
"pcom.p", line 4460: "<>": illegal operand type(s)
% ack -o pint pint.p 
"pint.p", line 286: illegal integer base type of set
"pint.p", line 494: (warning) old-fashioned syntax ':' missing
"pint.p", line 513: (warning) old-fashioned syntax ':' missing
"pint.p", line 531: (warning) old-fashioned syntax ':' missing
"pint.p", line 549: (warning) old-fashioned syntax ':' missing
"pint.p", line 587: (warning) old-fashioned syntax ':' missing
"pint.p", line 605: (warning) old-fashioned syntax ':' missing
"pint.p", line 657: (warning) old-fashioned syntax ':' missing
"pint.p", line 675: (warning) old-fashioned syntax ':' missing
"pint.p", line 769: (warning) "ads" unused in "lstins"
"pint.p", line 1385: "+": illegal operand type(s)
"pint.p", line 2599: "=": illegal operand type(s)
"pint.p", line 2607: "<>": illegal operand type(s)
"pint.p", line 2614: ">=": illegal operand type(s)
"pint.p", line 2632: "<=": illegal operand type(s)
"pint.p", line 2676: "IN": right operand must be a set
"pint.p", line 2678: "IN": right operand must be a set
"pint.p", line 2748: "-": illegal operand type(s)
"pint.p", line 2749: "*": illegal operand type(s)
"pint.p", line 2750: "+": illegal operand type(s)
"pint.p", line 2751: "IN": right operand must be a set
"pint.p", line 2894: (warning) "c" unused in "pcode"
"pint.p", line 2894: (warning) "ad3" unused in "pcode"
"pint.p", line 2894: (warning) "option" unused in "pcode"

mcg broken by changes to PowerPC libem

In my pull request #59, @davidgiven reports, "the libem ABI changes break mcg."

I change the ABI in PowerPC libem because I rename some procedures and move some parameters to different locations. I change ncg to use the new ABI, but I don't change mcg. This breaks mcg, because ncg and mcg share the same libem. It remains broken until someone modifies mcg and/or libem to fit together.

We currently don't build mcg by default.

  • plat/linuxppc/build-tools.lua commented out the dependency of +tools on +mcg, so it doesn't build mcg for linuxppc.
  • The top build.lua commented out qemuppc, so it doesn't enter plat/qemuppc and doesn't build mcg for qemuppc.
  • We never built mcg for osxppc.

Missing dependencies on .h files

The current build system (ackbuilder and ninja) is missing some dependences on .h files. When I edit a .h file, the build system fails to rebuild some .c files, and I must do gmake clean to get a working build.

I edited modules/src/flt_arith/flt_arith.h to reduce the size of a struct. It seems that programs linking to flt_arith (like cemcom.ansi and ncg) depend on flt_arith.h, but the modules/src/flt_arith/*.c files don't depend on flt_arith.h. So gmake built cemcom.ansi and ncg with the new flt_arith.h but kept flt_arith built with the old flt_arith.h; this caused buffer overflows when cemcom.ansi and ncg allocated the smaller struct but flt_arith wrote the bigger struct. I tried to look for code that would overflow the struct, but the problem was in the build system, not the code.

I run OpenBSD 6.0 for amd64 and use its base gcc to compile ack. I have GNU make 4.2.1 and ninja 1.7.1. The gcc turns on -fstack-protector by default, and this caught overflows from a struct allocated on the stack.

(I am editing flt_arith to look for errors in the conversion of floating-point literals. For example, a literal 0.5 in C code became slightly less than 0.5. This is causing problems with my attempts to test PowerPC floating point.)

infinite rebuilds after editing input to llgen

If I build ack, then edit any file that llgen takes as input, then the build system gets stuck in infinite rebuilds. These commands reproduce the problem:

$ gmake
$ touch lang/pc/comp/statement.g
$ gmake
$ gmake

I'm using ninja. The first gmake builds everything. After touching statement.g, the second gmake seems to succeed. It runs llgen and rebuilds everything that depends on llgen's output. The third gmake repeats the actions of the second gmake, by running llgen again and rebuilding the same things.

To stop the infinite rebuilds and work around this problem, I run gmake clean. The problem recurs whenever I edit a .g file, or when I edit a .c file and the build system generates a .g file from the .c file.

I observe that llgen succeeds without touching some of its output files; this might be confusing ninja.

$ ls -l lang/pc/comp/statement.g                                               
-rw-r--r--  1 kernigh  kernigh  9276 Nov 14 14:53 lang/pc/comp/statement.g
$ cd ../ack-build/obj                                                          
$ ls -l lang/pc/comp/llgen/                                                    
total 312
-rw-r--r--  1 kernigh  kernigh  14207 Nov 13 22:15 Lpars.c
-rw-r--r--  1 kernigh  kernigh    959 Nov 13 22:15 Lpars.h
-rw-r--r--  1 kernigh  kernigh  62723 Nov 13 22:15 declar.c
-rw-r--r--  1 kernigh  kernigh  24979 Nov 13 22:15 expression.c
-rw-r--r--  1 kernigh  kernigh   5335 Nov 13 22:15 program.c
-rw-r--r--  1 kernigh  kernigh  29180 Nov 13 22:15 statement.c
-rw-------  1 kernigh  kernigh   1728 Nov 13 22:15 tokenfile.c

sys_time is broken

It returns a long; if time_t won't fit in a long, like on i386 OpenBSD, it mangles the result.

sys_time() needs to go.

Failed to compile in CentOS 7

ACK failed to compile in CentOS 7, following is a snippet of error messages:

/tmp/ack-build/obj/util/ncgg/cggparser/y.tab.h: In function ‘enterkeyw’:
/tmp/ack-build/obj/util/ncgg/cggparser/y.tab.h:161:66: error: ‘ADDR’ undeclared (first use in this function)
 int yyparse ();
                                                                  ^
/tmp/ack-build/obj/util/ncgg/cggparser/y.tab.h:161:66: note: each undeclared identifier is reported only once for ea
ch function it appears in
/tmp/ack-build/obj/util/ncgg/cggparser/y.tab.h:162:71: error: ‘COERCIONS’ undeclared (first use in this function)
 #endif
                                                                       ^
/tmp/ack-build/obj/util/ncgg/cggparser/y.tab.h:163:74: error: ‘INSTRUCTIONS’ undeclared (first use in this function)
 #endif /* ! YYPARSE_PARAM */
                                                                          ^
/tmp/ack-build/obj/util/ncgg/cggparser/y.tab.h:164:65: error: ‘INT’ undeclared (first use in this function)

                                                                 ^
/tmp/ack-build/obj/util/ncgg/cggparser/y.tab.h:165:67: error: ‘MOVES’ undeclared (first use in this function)
 #endif /* !YY_YY_TMP_ACK_BUILD_OBJ_UTIL_NCGG_CGGPARSER_Y_TAB_H_INCLUDED  */
                                                                   ^
/tmp/ack-build/obj/util/ncgg/cggparser/y.tab.h:166:70: error: ‘PATTERNS’ undeclared (first use in this function)

...

confusing stack comments in mach/powerpc/libem

In a Forth comment like ( a b c -- d ), I expect that c was on top of the stack. After commit e7e29d3, comments in powerpc/libem don't match my expectation.

Forth would ignore the comment, but Factor would parse it as a stack effect. The convention from Factor's manual is, "Stack elements in a stack effect are ordered so that the top of the stack is on the right side." So in ( a b c -- d ), the top is c.

mach/powerpc/libem/rck.s gives the comment ( descriptor value -- ), but the code seems to load the descriptor from 0(sp) and the value from 4(sp), so the actual stack effect seems to be ( value descriptor -- ).

libem/ior.s gives the comment ( size b a -- a+b ), but the actual stack effect seems to be ( b a size -- a+b ). In contrast, libem/csb.s gives the comment ( value tableaddr -- ), and the actual stack effect seems to agree with the comment, with tableaddr as top.

Undefined `_execve` for Unix module of Modula-2

When compiling following code:

MODULE test;

IMPORT Unix;

VAR
  r: INTEGER;
BEGIN
  r := Unix.execve (NIL, NIL, NIL);
END test.

ACK reports an error:

"test.mod", line 9: (warning) variable "r" never used
Undefined:
        _execve

Investigate issues on ILP64 systems

Apparently the ACK doesn't work at all on the Itanium, probably because of the 64-bit ints. This is almost certainly due to assumptions about the size of types, and could be related to K&R C with its rather fuzzy type system.

At some point we should investigate why and try to fix it.

Failed to compile in FreeBSD 10.3 i386

Compile ack default branch in FreeBSD 10.3 i386 failed with following error:

CPP /tmp/ack-build/obj/i86/mach/proto/as/comm2.y.m
INSTALL /tmp/ack-build/obj/plat/pc86//preprocessed-comm2.y
YACC /tmp/ack-build/obj/plat/pc86//y.tab.c
yacc: 1 shift/reduce conflict.
CC /tmp/ack-build/obj/i86//tmp/ack-build/obj/plat/pc86//y.tab.o
/tmp/ack-build/obj/plat/pc86//preprocessed-comm2.y:96:3: error: conflicting types for '__mbstate_t'
 } __mbstate_t;
   ^
In file included from /usr/local/lib/gcc48/gcc/i386-portbld-freebsd10.1/4.8.5/include-fixed/stdlib.h:47:0,
                 from /tmp/ack-build/obj/plat/pc86//preprocessed-comm2.y:2:
/usr/include/sys/_types.h:113:3: note: previous declaration of '__mbstate_t' was here
 } __mbstate_t;
   ^
plat/pc86/build.mk:29: recipe for target '/tmp/ack-build/obj/i86//tmp/ack-build/obj/plat/pc86//y.tab.o' failed
gmake: *** [/tmp/ack-build/obj/i86//tmp/ack-build/obj/plat/pc86//y.tab.o] Error 1

Incorrect error message for invalid function call for Modula-2

For following Modula-2 code:

MODULE test;

IMPORT Arguments;

VAR
  program: ARRAY [0..1024] OF CHAR;

BEGIN
  Arguments.Argv (0, program);
END test.

ACK report following error:

"test.mod", line 9: procedure call expected instead of function call

Which I think should be "function call expected instead of procedure call", as Arguments.Argv has a return value.

BTW, this message was changed to current form by commit 7f9fd96 in 1988.

hilo.b crashes on PowerPC; bad symbols

When I run ./hilo_b.osxppc, I get an immediate segmentation fault.

$ ./hilo_b.osxppc
Segmentation fault

When I run ./hilo_b.linuxppc, I get a segmentation fault after I input my name.

$ ./hilo_b.linuxppc 

Hi there! I'm written in B. Before we start, what is your name?
> George
Segmentation fault

For this bug report, I built the current master 03386b9 on my OpenBSD/amd64 machine, then copied hilo_b.osxppc and hilo_b.linuxppc to the machines that run them. I'm using my PowerBook G4 for OS X and qemu-system-ppc for Linux.

Some symbols have the wrong value. OS X nm reveals that ioctl points to the middle of a function in B's library:

$ nm -m hilo_b.osxppc | less
...
00001bd0 t __II8
00001cdc t __II9
00001d28 T _ioctl
00001e20 T _patch_addresses
00001e88 T _main

In gdb, disas isatty shows that isatty() calls ioctl() at 0x1d28; and disas ioctl shows the middle of a function. The program crashes because stdio calls isatty() to check if stdout is a tty. Then the program wrongly jumps to 0x1d28 and continues with a corrupt program counter until it crashes.

Linux nm shows that brk points outside the program text:

0000001b a EBADGTO
0000003f a EUNIMPL
00001b44 T _brk
10000078 T __m_a_i_n
100000c8 T _i_strcopy

The program doesn't seem to call brk(), so I don't know what causes the crash.

So far, I only have this problem with some B programs on PowerPC. I can reproduce this problem in OS X by simply calling putchar(). Here's the B program:

main()
{
	putchar('a');
	return (0);
}

Ran ack -mosxppc -o simple simple.b, copied it to my Mac, then ./simple segfaulted, again because ioctl has the wrong value. This program still works in Linux.

I remember that B worked on PowerPC in the past. My recent changes to the assembler or linker might have broken something.

sbrk issues: sbrk(int) vs sbrk(intptr_t)

Is it sbrk(int) or sbrk(intptr_t)? Our libsys and libcc.ansi use intptr_t, but our libpc and libm2 use int. This will become a problem if we add a platform where int and intptr_t have different sizes.

I have been using OpenBSD's manual pages as a reference. OpenBSD says sbrk(2) takes an int and sets errno = ENOMEM on failure. Some of our libsys implementations don't set errno.

Our ncg tables have broken rules for lor 2, str 2 to load/store the EM heap pointer. These are broken because they don't use sbrk. We only use lor 2, str 2 in the Pascal library, and only for the mark, release keywords. Seems that new, dis got fixed to use sbrk; but mark, release never got fixed.

Our brk() for Linux fails to update the value of sbrk(0).

It seems that calloc() went missing from libcc.ansi after the memory allocator got replaced.

Modula-2: wrong value of 31 MOD (-10)

I expect that (a DIV b) * b + (a MOD b) = a
but our Modula-2 compiler fails me when (a > 0) and (b < 0).
It does 31 DIV (-10) = -4 and 31 MOD (-10) = 9.

Because 31 ÷ -10 = -3.1, one may round it to -3 or -4.
If it's -3 then (-3 × -10) + 1 = 31.
If it's -4 then (-4 × -10) + -9 = 31.
So the value of 31 MOD (-10) must be 1 or -9.
It can't be 9.

The compiler forgot to fix the sign from 9 to -9. But if it did fix the sign, then it would still not agree with other Modula-2 compilers.

A document of GNU Modula-2 specifies:

                  Pim2/3          Pim4                ISO
               -----------    -----------    ----------------------
lval    rval   DIV     MOD    DIV     MOD    DIV    MOD    /    REM
 31      10      3       1      3       1      3      1     3     1
-31      10     -3      -1     -4       9     -4      9    -3    -1
 31     -10     -3       1     -3       1     Exception    -3     1
-31     -10      3      -1      4       9     Exception     3    -1

I tested MacMETH and ACK and got these results:

                MacMETH       MacMETH         ACK        Lua Python
                  Pim3          Pim4          Pim3        Ruby Tcl
               ----------    ----------    ----------    ----------
lval    rval   DIV    MOD    DIV    MOD    DIV    MOD    DIV    MOD
 31      10      3      1      3      1      3      1      3      1
-31      10     -3     -1     -4      9     -4      9     -4      9
 31     -10     -3      1     -3      1     -4      9     -4     -9
-31     -10      3     -1      2    -11      3     -1      3     -1

GNU Modula-2 and MacMETH agree that in Pim3, DIV rounds toward zero and MOD follows sign of 1st operand. (This is like C, awk, bc, and EM.) GNU Modula-2 and MacMETH almost agree about Pim4, except MacMETH strangely has (-31) DIV (-10) = 2. ACK almost agrees with Lua, Python, Ruby, Tcl, where DIV rounds down and MOD follows sign of 2nd operand.

(MacMETH also raises a compiler error if MOD has a negative operand in a constant expression. I got the above results by using MOD with variables.)

I don't have Pim3 or Pim4, but I checked the draft of Modula-2 Revision 2010 (m2r2010), where DIV rounds up or down such that MOD is always positive. This agrees with GNU-Modula 2 Pim4.

Add ".pas" to "lib/descr/fe" for Pascal

I find that current days most Pascal source files are saved with ".pas" extension, it would be nice to make ACK support it.

BTW, does ack have any option to specifiy compiler directly instead of relying on file name?

optimiser changes xx(! i, i) to xx(1)

Months ago on 2017-04-27, Rune mailed tack-devel to report this bug:
https://sourceforge.net/p/tack/mailman/message/35809953/

@davidgiven reproduced the bug and pointed to the peephole optimiser (util/opt).

I create this GitHub issue now so I have a bug number to create tests/plat/bugs/bug-??-notvar_var_e.c. I will be testing this change:

diff --git a/util/opt/patterns b/util/opt/patterns
index 8d949dfd8..34bcc760a 100644
--- a/util/opt/patterns
+++ b/util/opt/patterns
@@ -641,13 +641,13 @@ lol lol bne $1==$2 :
 loe loe bne $1==$2 :
 lil lil bne $1==$2 :
 
-lol lol teq $1==$2 : loc 1
-loe loe teq $1==$2 : loc 1
-lil lil teq $1==$2 : loc 1
+lol lol cms teq $1==$2 && $3==w : loc 1
+loe loe cms teq $1==$2 && $3==w : loc 1
+lil lil cms teq $1==$2 && $3==w : loc 1
 
-lol lol tne $1==$2 : loc 0
-loe loe tne $1==$2 : loc 0
-lil lil tne $1==$2 : loc 0
+lol lol cms tne $1==$2 && $3==w : loc 0
+loe loe cms tne $1==$2 && $3==w : loc 0
+lil lil cms tne $1==$2 && $3==w : loc 0
 
 lol loc CBO stl $3==w && $1==$4 : loc $2 lol $1 CBO w stl $4
 lol loe CBO stl $3==w && $1==$4 : loe $2 lol $1 CBO w stl $4

compile minix2 on *any* just *any* hardware

Is there some way the ack can be used to compile minix 2 on any hardware. I'm trying hard to follow the book for minix2 but I want to be able to play with code on a real machine.

Is there an old x86 machine I can buy? I don't know what specific model would work though.

Thanks

obstacles to build ack on macOS

It is not yet possible to build ack on macOS using Apple's compiler. I list some obstacles; there may be other obstacles.

clang and traditional C

In recent versions of macOS, Apple's compiler is clang. There is a gcc link that just calls clang. (Some users mistakingly believe that this compiler is gcc. It isn't.)

Right now, clang can't build ack. The problem is that clang makes errors in traditional C code that uses return; in functions with an implicit int return type. Such code exists because traditional C had no void type. I used clang 4.0.0 on OpenBSD 6.2 to build ack from October 2017, but switched to gcc 4.9.4 in February 2018, because the new plat/pdpv7 enabled some traditional C code where clang makes errors.

My old PowerPC machine has Mac OS X 10.4 and Xcode 2.5, where Apple's compiler was gcc 4.2.1, not clang.

case-insensitive filesystem

Mac filesystems are almost always case-insensitive. This is bug #58 (Does not build on case insensitive filesystems), possibly fixed in commit a1043bc, but no person confirmed that ack now builds on any case-insensitive filesystem.

Apple sbrk()

The sbrk() function in Apple's libc has a limit of only 4 megabytes. If any ack tool uses sbrk(), it might run out of memory.

  • util/led uses sbrk() to allocate memory. One might need to switch it from sbrk() to malloc().
  • util/opt already uses malloc() instead of sbrk() by default.
  • util/LLgen and util/ncgg call sbrk() to measure memory usage. This is not an obstacle if the measurement is wrong but the tool still works. I have seen ncgg reporting "0K heap used" in OpenBSD, because malloc() used mmap(), not sbrk().

common symbols in static libraries

By default, Apple's archiver doesn't index common symbols in static libraries. This caused a linker error that stopped the build in my old Mac.

I started the build because my old Mac has gcc, not clang. The system's GNU make 3.80 is too old for our top Makefile, so I compiled and used GNU make 4.2.1. (Newer versions of macOS have GNU make 3.81, which might be new enough.) For util/ack, our build system puts the .o files in a static library with ar cqs out.a in.o..., then links the executable. The symbols from data.c went missing because data.o had only common symbols. So I got a linker error.

The manual says that libtool -c or ranlib -c can index the common symbols. (This manual says so in my old Mac, but also in a newer cctools from https://opensource.apple.com/.) The command would be ar cqS out.a in.o... && ranlib -c out.a or /usr/bin/libtool -c -static -o out.a in.o.... The latter must run Apple libtool, not GNU libtool.

can't compile hilo.b for linux68k

I'm running OpenBSD 6.0 for amd64. The build of git fd83b09 fails:

[11/754] ACKDIR=/home/kernigh/park/ack...xamples/hilo_b_linux68k/platstamp -O6 
FAILED: /home/kernigh/park/ack-build/obj/examples/hilo_b_linux68k/main/hilo/hilo.o 
ACKDIR=/home/kernigh/park/ack-build/staging /home/kernigh/park/ack-build/staging/bin/ack -mlinux68k -c -o /home/kernigh/park/ack-build/obj/examples/hilo_b_linux68k/main/hilo/hilo.o examples/hilo.b -I/home/kernigh/park/ack-build/obj/examples/hilo_b_linux68k/platstamp -O6 
/home/kernigh/park/ack-build/staging/bin/ack: warning, No definition for ABC_F
"Ack_167bdf.s", line 359: syntax error
[13/754] ACKDIR=/home/kernigh/park/ack.../cem/libcc.ansi/string/strpbrk.c  -O6 
ninja: build stopped: subcommand failed.
gmake: *** [Makefile:82: +ack] Error 1

I can reproduce it with the partly-built ack:

$ cd examples
$ ack -mlinux68k -c.o hilo.b -O6 
ack: warning, No definition for ABC_F
"Ack_7426f.s", line 359: syntax error

By using -c.s, I can generate the assembly code. Line 359 is the $Id$ 1f in

move.l #78,d1
move.l (sp)+,d2
cmp.l d1,d0
$Id$ 1f
bset #0,d2
1:
tst.l d2
beq I6_2

It seems that something goes wrong inside ncg for linux68k, so it outputs $Id$ when it should output a branch instruction.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.