I am trying to compile a simple program on Flex & Bison on my Mac running Yosemite but get the following error:
Undefined symbols for architecture x86_64:
"_yyerror", referenced from:
_yyparse in pr1-19c182.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
My two files look like this, they compile on my teacher's Ubuntu installation but I can't get them to work on my Mac:
pr1.y
%{
#include <stdio.h>
%}
%%
expr : expr '+' term {printf(" + ");}
| term
;
term : term '*' fact {printf(" * ");}
| fact
;
fact : "(" expr ")"
| '0' {printf("0");}
| '1' {printf("1");}
| '2' {printf("2");}
| '3' {printf("3");}
| '4' {printf("4");}
| '5' {printf("5");}
| '6' {printf("6");}
| '7' {printf("7");}
| '8' {printf("8");}
| '9' {printf("9");}
%%
pr1.l
%{
#include "pr1.tab.h"
%}
%%
[0-9] {return (yytext[0]);}
[+*()] {return (yytext[0]);}
\n {return (0);}
. {}
%%
I compile everything using the following commands:
bison -d pr1.y
flex pr1.l
gcc -o result lex.yy.c pr1.tab.c -lfl -std=gnu89
The reason I use the -std flag is because the default is c99 and the code generated by flex and bison gets warnings and errors. Any ideas???
You need to define yyerror in your bison input file (pr1.y). And you need to declare yylex or you will get another warning.
The following would be fine:
%{
#include <stdio.h>
void yyerror(const char* msg) {
fprintf(stderr, "%s\n", msg);
}
int yylex();
%}
I have no idea how it works without that on your teacher's machine.
Also, Mac OS X has very old versions of bison and flex. You might want to upgrade.
Check out the 2nd comment of the answer on this post Unable to compile output of lex
On Mac OS X, if you're trying to compile from the command line, you need to link against the libl.a library, by using -ll instead of -lfl. Apparently OS X has no libfl.a library. So try this...
gcc -o result lex.yy.c pr1.tab.c -ll
Don't know about your need for the -std=gnu89 option.
Related
This is quite similar to GCC define function-like macros using -D argument but I couldn't find a relation to my use case.
Consider the following code, main.c:
#include <stdio.h>
const char greeting[] = "hello world";
//#define printf(fmt, ...) (0)
int main() {
printf("%s!\n", greeting);
return 0;
}
If I compile and run this, it works as expected:
$ gcc -Wall -g main.c -o main.exe
$ ./main.exe
hello world!
$
Ok, now I want to How to disable printf function? so I uncomment the #define in the code; I get some warnings, but things again work as as expected (as there is no printout):
$ gcc -Wall -g main.c -o main.exe
main.c: In function 'main':
main.c:5:26: warning: statement with no effect [-Wunused-value]
5 | #define printf(fmt, ...) (0)
| ^
main.c:8:5: note: in expansion of macro 'printf'
8 | printf("%s!\n", greeting);
| ^~~~~~
$ ./main.exe
$
Now, go back to the example as originally posted - that is, comment the #define like - and let's try to set that define via the command-line -D argument:
$ gcc -Wall -D'printf(fmt, ...)=(0)' -g main.c -o main.exe
<command-line>: error: expected identifier or '(' before numeric constant
main.c: In function 'main':
<command-line>: warning: statement with no effect [-Wunused-value]
main.c:8:5: note: in expansion of macro 'printf'
8 | printf("%s!\n", greeting);
| ^~~~~~
Well, the command line argument -D'printf(fmt, ...)=(0)' causes the compilation to fail.
Is there any way I can format this macro somehow, so I can set it via the gcc command line using the -D argument? (Bonus: can it be formulated somehow, so it does not raise warnings like "statement with no effect")
EDIT: contents of C:/msys64/mingw64/include/stdio.h lines 366 to 372:
366 __mingw_ovr
367 __attribute__((__format__ (gnu_printf, 1, 2))) __MINGW_ATTRIB_NONNULL(1)
368 int printf (const char *__format, ...)
369 {
370 int __retval;
371 __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format );
372 __retval = __mingw_vfprintf( stdout, __format, __local_argv );
373 __builtin_va_end( __local_argv );
374 return __retval;
375 }
When you use:
#define printf(fmt, ...) (0)
The preprocessor turns the code into this:
int main() {
(0);
return 0;
}
That free standing (0) is not allowed. However if you define it this way:
#define printf(fmt, ...)
You can also use the command line definition:
"-Dprintf(fmt, ...)="
Everything works.
I have a minimal c program for the m1 arm cpu that returns 42:
void _start() {
asm("mov x0, #42;");
asm("mov x16, #1;");
asm("svc 0x80;");
}
This code compiles after telling clang to use the _start symbol and returns the correct value.
clang -Wl,-e, -Wl,__start test.c -o dyn.out
./dyn.out ; echo $?
42
However this binary still has dynamic links according to otool:
otool -L ./dyn.out
./dyn.out:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)
After telling clang to produce a unsigned static binary however macOS then immediately kills the binary when trying to run.
clang -Wl,-e, -Wl,__start -static -nostdlib test.c -o static_no_sign.out
zsh: killed ./static_no_sign.out
Signing the binary before running also produces the same problem.
clang -Wl,-e, -Wl,__start -static -nostdlib test.c -o static_sign.out
codesign -s - static_sign.out
./static_sign.out
zsh: killed ./static_sign.out
The following messages are produced in Console:
taskgated: UNIX error exception: 3
taskgated: no signature for pid=93166 (cannot make code: UNIX[No such process])
But codesign can verify the signature
codesign -v -v static_sign.out
static_sign.out: valid on disk
static_sign.out: satisfies its Designated Requirement
Can anyone clarify why macOS is deciding to kill the clang produced binaries?
Because static binaries are explicitly disallowed on any architecture other than x86_64.
XNU contains this code piece in the Mach-O loader:
case MH_EXECUTE:
if (depth != 1 && depth != 3) {
return LOAD_FAILURE;
}
if (header->flags & MH_DYLDLINK) {
/* Check properties of dynamic executables */
if (!(header->flags & MH_PIE) && pie_required(header->cputype, header->cpusubtype & ~CPU_SUBTYPE_MASK)) {
return LOAD_FAILURE;
}
result->needs_dynlinker = TRUE;
} else if (header->cputype == CPU_TYPE_X86_64) {
/* x86_64 static binaries allowed */
} else {
/* Check properties of static executables (disallowed except for development) */
#if !(DEVELOPMENT || DEBUG)
return LOAD_FAILURE;
#endif
}
break;
If you do the exact same thing on x86_64, it works:
void _start()
{
__asm__ volatile
(
".intel_syntax noprefix\n"
"mov eax, 0x2000001\n"
"mov edi, 42\n"
"syscall"
);
}
% clang -Wl,-e,__start -static -nostdlib t.c -o t -arch x86_64
% ./t
% echo $?
42
I was able to compiled the gateway but I got the error below running the make command.
gcc -D_REENTRANT=1 -I. -Igw -g -O2 -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_LARGE_FILES= -I/usr/include/libxml2 -I/usr/include/mysql -o gwlib/dbpool.o -c gwlib/dbpool.c
In file included from /usr/include/x86_64-linux-gnu/bits/libc-header-start.h:33,
from /usr/include/stdlib.h:25,
from gwlib/gwlib.h:70,
from gwlib/dbpool.c:70:
/usr/include/features.h:187:3: warning: #warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE" [-Wcpp]
187 | # warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"
In file included from gwlib/gwlib.h:83,
from gwlib/dbpool.c:70:
gwlib/dbpool_mysql.c: In function ‘mysql_select’:
gwlib/dbpool_mysql.c:224:48: error: ‘my_bool’ undeclared (first use in this function); did you mean ‘xr_bool’?
224 | bind[i].is_null = gw_malloc(sizeof(my_bool));
gwlib/gwmem.h:122:43: note: in definition of macro ‘gw_malloc’
122 | #define gw_malloc(size) (gw_native_malloc(size))|
gwlib/dbpool_mysql.c:224:48: note: each undeclared identifier is reported only once for each function it appears in
224 | bind[i].is_null = gw_malloc(sizeof(my_bool));
gwlib/gwmem.h:122:43: note: in definition of macro ‘gw_malloc’
122 | #define gw_malloc(size) (gw_native_malloc(size))
make: *** [Makefile:230: gwlib/dbpool.o] Error 1`
This error comes when you're compiling with mysql 8
To fix this, add these lines to gwlib/dbpool_mysql.c
/* define my_bool for newer versions because they use the bool or int C type instead */
#if MYSQL_VERSION_ID >= 80000 && !defined(MARIADB_BASE_VERSION)
typedef bool my_bool;
#endif
I'm trying to assemble a file that uses ARM's CRC instruction. The assembler is producing an error Error: selected processor does not support 'crc32b w1,w0,w0'.
There are runtime checks in place, so we are safe with the instruction. The technique works fine on i686 and x86_64. For example, I can assemble a file that uses Intel CRC intrinsics or SHA Intrinsics without -mcrc or -msha (and on a machine without the features).
Here is the test case:
$ cat test.cxx
#include <arm_neon.h>
#define GCC_INLINE_ATTRIB __attribute__((__gnu_inline__, __always_inline__, __artificial__))
#if defined(__GNUC__) && !defined(__ARM_FEATURE_CRC32)
__inline unsigned int GCC_INLINE_ATTRIB
CRC32B(unsigned int crc, unsigned char v)
{
unsigned int r;
asm ("crc32b %w2, %w1, %w0" : "=r"(r) : "r"(crc), "r"((unsigned int)v));
return r;
}
#else
// Use the intrinsic
# define CRC32B(a,b) __crc32b(a,b)
#endif
int main(int argc, char* argv[])
{
return CRC32B(argc, argc);
}
And here is the result:
$ g++ test.cxx -c
/tmp/ccqHBPUf.s: Assembler messages:
/tmp/ccqHBPUf.s:23: Error: selected processor does not support `crc32b w1,w0,w0'
Placing the ASM code in a source file and compiling with different options is not feasible because CRC32B will be used in C++ header files, too.
How do I get GAS to assemble the instruction?
GCC's configuration and options are the reason we are trying to do things this way. User's don't read manuals, so they won't add -march=armv8-a+crc+crypto -mtune=cortex-a53 to CFLAGS and CXXFLAGS.
In addition, distros compile to a "least capable" machine, so we want the hardware acceleration routines available. When the library is provided by a distro like Linaro, both code paths (software CRC and hardware accelerated CRC) will be available.
The machine is a LeMaker HiKey, which is ARMv8/Aarch64. It has an A53 processor with CRC and Crypto (CRC and Crypto is optional under the architecture):
$ cat /proc/cpuinfo
Processor : AArch64 Processor rev 3 (aarch64)
processor : 0
...
processor : 7
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
CPU implementer : 0x41
CPU architecture: AArch64
GCC lacks most of the usual defines one expects to be present by default:
$ g++ -dM -E - </dev/null | sort | egrep -i '(arm|neon|aarch|asimd)'
#define __aarch64__ 1
#define __AARCH64_CMODEL_SMALL__ 1
#define __AARCH64EL__ 1
Using GCC's -march=native does not work on ARM:
$ g++ -march=native -dM -E - </dev/null | sort | egrep -i '(arm|neon|aarch|asimd)'
cc1: error: unknown value ‘native’ for -march
And Clang:
$ clang++ -dM -E - </dev/null | sort | egrep -i '(arm|neon|aarch|asimd)'
#define __AARCH64EL__ 1
#define __ARM_64BIT_STATE 1
#define __ARM_ACLE 200
#define __ARM_ALIGN_MAX_STACK_PWR 4
#define __ARM_ARCH 8
#define __ARM_ARCH_ISA_A64 1
#define __ARM_ARCH_PROFILE 'A'
#define __ARM_FEATURE_CLZ 1
#define __ARM_FEATURE_DIV 1
#define __ARM_FEATURE_FMA 1
#define __ARM_FEATURE_UNALIGNED 1
#define __ARM_FP 0xe
#define __ARM_FP16_FORMAT_IEEE 1
#define __ARM_FP_FENV_ROUNDING 1
#define __ARM_NEON 1
#define __ARM_NEON_FP 0xe
#define __ARM_PCS_AAPCS64 1
#define __ARM_SIZEOF_MINIMAL_ENUM 4
#define __ARM_SIZEOF_WCHAR_T 4
#define __aarch64__ 1
GCC version:
$ gcc -v
...
gcc version 4.9.2 (Debian/Linaro 4.9.2-10)
GAS version:
$ as -v
GNU assembler version 2.24 (aarch64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.24
This answer came from Jiong Wang on the Binutils mailing list. It bypasses GAS's architectural requirements and plays well with GCC:
__inline unsigned int GCC_INLINE_ATTRIB
CRC32W(unsigned int crc, unsigned int val)
{
#if 1
volatile unsigned int res;
asm ("\n"
"\t" ".set reg_x0, 0\n"
"\t" ".set reg_x1, 1\n"
"\t" ".set reg_x2, 2\n"
"\t" ".set reg_x3, 3\n"
"\t" ".set reg_x4, 4\n"
"\t" ".set reg_x5, 5\n"
"\t" ".set reg_x6, 6\n"
"\t" ".set reg_x7, 7\n"
"\t" "#crc32w %w0, %w1, %w2\n"
"\t" ".inst 0x1ac04800 | (reg_%2 << 16) | (reg_%1 << 5) | (reg_%0)\n"
: "=r"(res) : "r"(crc), "r"(val)
);
return res;
#else
volatile unsigned int res;
asm (".cpu generic+fp+simd+crc+crypto \n"
"crc32w %w0, %w1, %w2 \n"
: "=r"(res) : "r"(crc), "r"(val));
return res;
#endif
}
The second one commented out by the preprocessor block was suggested by Nick Clifton on the Binutils mailing list. The idea is GCC generates code using the ISA based on -march=XXX, so it does not matter if we increase capabilities to get past the assembler. We decided to go with Wang's answer because we did not want potential side effects from modifying the .cpu.
And the verification with GCC 4.8 and Binutils 2.24:
$ g++ -O1 test.cxx -c
$ objdump --disassemble test.o
test.o: file format elf64-littleaarch64
Disassembly of section .text:
0000000000000000 <main>:
0: 12001c01 and w1, w0, #0xff
4: 1ac14800 crc32w w0, w0, w1
8: d65f03c0 ret
I'm trying to compile GCC 4.7.2 on a Buffalo LinkStation Pro Duo (after unlocking it) which runs Linux 2.6.31.8 armv5tel.
Unfortunately, make throws quite some errors, starting with
gcc -c -DIN_GCC_FRONTEND -g -fkeep-inline-functions -DIN_GCC -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-formIn file included from ../../gcc-4.7.2/gcc/tree.h:32,
from ../../gcc-4.7.2/gcc/c-lang.c:27:
../../gcc-4.7.2/gcc/real.h:53: error: 'SIZEOF_LONG' undeclared here (not in a function)
In file included from ../../gcc-4.7.2/gcc/tree.h:32,
from ../../gcc-4.7.2/gcc/c-lang.c:27:
../../gcc-4.7.2/gcc/real.h:87:5: error: division by zero in #if
../../gcc-4.7.2/gcc/real.h:87:5: error: division by zero in #if
../../gcc-4.7.2/gcc/real.h:90:6: error: division by zero in #if
Line 53 of real.h reads unsigned long sig[SIGSZ];, where SIGSZ is defined at line 40 as
#define SIGSZ (SIGNIFICAND_BITS / HOST_BITS_PER_LONG)
while line 87 is #if REAL_WIDTH == 1 with REAL_WIDTH defined starting at line 72 as
#define REAL_WIDTH \
(REAL_VALUE_TYPE_SIZE/HOST_BITS_PER_WIDE_INT \
+ (REAL_VALUE_TYPE_SIZE%HOST_BITS_PER_WIDE_INT ? 1 : 0)) /* round up */
This seems to boil down to the HOST_BITS_PER_* being zero. Do I have to define these manually with some configure parameter or how can this issue be resolved?
update
config.log contains the following errors:
conftest.c:10:19: error: ppl_c.h: No such file or directory
conftest.c: In function 'main':
conftest.c:16: error: 'choke' undeclared (first use in this function)
conftest.c:16: error: (Each undeclared identifier is reported only once
conftest.c:16: error: for each function it appears in.)
conftest.c:16: error: expected ';' before 'me'
configure:5708: $? = 1
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME ""
| #define PACKAGE_TARNAME ""
| #define PACKAGE_VERSION ""
| #define PACKAGE_STRING ""
| #define PACKAGE_BUGREPORT ""
| #define PACKAGE_URL ""
| #define LT_OBJDIR ".libs/"
| /* end confdefs.h. */
| #include "ppl_c.h"
| int
| main ()
| {
|.
| #if PPL_VERSION_MAJOR != 0 || PPL_VERSION_MINOR < 11
| choke me
| #endif
|.
| ;
| r
Following this post I seem to have forgotten to install ppl, which I'll try now
SIZEOF_LONG should be #defined by configure in the file auto-host.h. Your auto-host.h should contain something like:
/* The size of `long', as computed by sizeof. */
#ifndef USED_FOR_TARGET
#define SIZEOF_LONG 8
#endif
If the above is not present (and it looks like in your case it's indeed so), check config.log for errors. Search for errors around the string checking size of long.
Thanks to chill's answer I checked config.log to discover
conftest.c:10:19: error: ppl_c.h: No such file or directory
(which, curiously, did not prevent configure from creating a Makefile and returning a success error code). The first google hit on that was this post, showing I didn't provide the ppl dependency.
The ppl-1.0 compilation greeted me with
checked_float.inlines.hh:1012: error: 'frexpl' was not declared in this scope
which led me to this post suggesting I'd use the 1.1 snapshot instead, which worked
Now, gcc's make offered me another "helpful" error:
gcc/../libcpp/include/line-map.h:66: error: 'CHAR_BIT'
which turned out to be due to C_INCLUDE_PATH ending with a colon (I already experienced the checking LIBRARY_PATH variable... contains current directory error mentioned in that post, but didn't think about checking other variables for that as well)
Compilation is still running, so far no more errors...