Open kernigh opened 7 years ago
lang/pc/libpc/READ_ME
also mentioned this problem. But this file is quite old, it maybe out of time.
Hmm, yeah.
Modula-2 doesn't suffer from this because it mangles Modula-2 symbol names to include the module name as well. Possibly Pascal should do the same thing? With the extern function declaration syntax, we could still import C symbols easily enough.
Looks like fpc does exactly this, BTW:
$ nm test.o
[...]
0000000000000000 T P$CALLMALLOC_$$_MALLOC
Luckily there's already at least some code in the Pascal compiler for doing this, in gen_proc_name(): https://github.com/davidgiven/ack/blob/default/lang/pc/comp/misc.c It's used for generating unique names for nested functions, but should be adaptable. I don't know how hard it would be to not mangle extern declarations.
Also, what about multiple compilation? How does Pascal normally handle this?
I think that ISO 7185 does not specify module system, which is added in ISO 10206, both can be found at here.
The ACK docs for the Pascal compiler (here: http://tack.sourceforge.net/olddocs/pascal.pdf) has a long list of ISO 7185 extensions which are implemented, none of which I can find references for. extern
is apparently defined in ISO 6.1.4. However, the doc says later (in section 10.2) that the compiler only works with programs, not modules, so that sounds like it's only possible to use extern
with non-Pascal identifiers.
That means that mangling Pascal symbol names but not extern
names should work fine here.
The doc is out of date. Here's our module system at work.
(* part1.p *)
program part1(output);
function secret : integer; extern;
begin
writeln('The secret is', secret);
end.
(* part2.p *)
function secret : integer;
begin
secret := 2000;
end;
Compile with ack -o part1 part1.p part2.p
. The compiler for part1 can't know if secret is in C or Pascal.
I found this feature by accident while looking for _m_a_i_n in the Pascal runtime. The compiler only emits _m_a_i_n in a program. If the Pascal file isn't a program, it's a module.
That's both really useful and very annoying --- because extern is used to link both external Pascal symbols and external C symbols we can't use different mangling to distinguish the two.
Open to suggestions --- I don't know what's the best thing to do here (potentially, nothing, and just live with the libc naming conflict problem).
The following Pascal program causes a linker error, because its procedure malloc conflicts with malloc in libc:
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 likeplat/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 likeclose
andopen
, but the regular names can conflict with Pascal programs.