How to add "-fstack-protector-all" to makefile? - linux

There is a error in my code:
*** stack smashing detected ***: ./mummergpu terminated
I search it in stackoverflow, a solution is add -fno-stack-protector to environment variableļ¼Œ but i don't know how to add it ? can anyone help me ?
nakefile follow:
all: clean mummergpu
.SUFFIXES : .cu .cu_dbg_o .c_dbg_o .cpp_dbg_o .cu_rel_o .c_rel_o .cpp_rel_o .cubin
## Reenable this for testing all variations
#include ../experiments/test_rule.mk
CUDA_INSTALL_PATH := /usr/local/cuda-8.0
# Compilers
NVCC := $(CUDA_INSTALL_PATH)/bin/nvcc
CXX := g++ $(PROFILE)
CC := gcc
LINK := g++ $(PROFILE)
# Add source files here
STATIC_LIB := libmummergpu.a
# Cuda source files (compiled with cudacc)
CUFILES := mummergpu.cu
# C/C++ source files (compiled with gcc / c++)
CCFILES := \
mummergpu_gold.cpp suffix-tree.cpp PoolMalloc.cpp

Consider using "-fstack-protector-strong" instead of "all".
With "-fstack-protector-all" it applies protection to all functions regardless they actually need this protection and hence make greater impact on performance.
Find more details here: https://lwn.net/Articles/584225/
The "Strong" stack protector aims to add stack protection only to those functions, which actually may need this protection.
You can use additional parameters to ./configure command to include stack protection:
./configure [options] CFLAGS='-fstack-protector-strong' CXXFLAGS='-fstack-protector-strong'
However, some packages may override this later.
Here is the command to apply stack protection for CFLAGS inside Makefile:
run:
sed '/^.*CFLAGS = / s/$/ -fstack-protector-strong' /path/to/Makefile
Once the output is verified and acceptable to apply changes on Makefile run sed with -i switch as follows:
sed -i '/^.*CFLAGS = / s/$/ -fstack-protector-strong' /path/to/Makefile

Related

conditional compilation in makefile so that command-line arguments are ignored

Using gcc compiler on linux, I have a C program that used command-line argument (one argument) like
./myprog 0
I want to write a makefile that uses conditional compilation so that if I compile like
make SPECIAL=1
then command-line argument is used.
if I compile without SPECIAL like
make
then command-line argument is ignored even if we enter it.
How to make it possible.
I am using following compilation command
gcc -o myprog myprog.c prog2.c prog3.c
The makefile can be trivial but the real work has to happen in the C code. Something like this, as a minimal example:
#include <stdio.h>
int main(int argc, char **argv, char **envp) {
int i;
#ifndef SPECIAL
argc=1;
argv[1] = NULL;
#endif
for(i=1; i<argc; ++i) {
printf(">>%s<<\n", argv[i]);
}
}
Now, you don't even really need a Makefile for this simple program.
bash$ make CFLAGS=-DSPECIAL=1 -f /dev/null myprog
cc -DSPECIAL=1 myprog.c -o myprog
Having said that, making your build nondeterministic by introducing variations which depend on ephemeral build-time whims is a recipe for insanity. Have two separate targets which create two separate binaries, one with the regular behavior, and the other with the foot-gun semantics.
DEPS := myprog.c prog2.c prog3.c # or whatever your dependencies are
myprog: $(DEPS)
myprog-footgun: CLAGS+=-DSPECIAL=1
myprog-footgun: $(DEPS) # same dependencies, different output file
$(CC) $(CFLAGS) -o $# $^
See Target-specific Variable Values in the GNU Make documentation for details of this syntax.
(Notice that Stack Overflow renders tabs in the Markdown source as spaces, so you will not be able to copy/paste this verbatim.)
I would perhaps in fact reverse the meaning of SPECIAL so that it enables the foot-gun version, rather than the other way around (the original version of this answer had this design, just because I had read your question that way originally).

Automake conditional compilation from C or Objective-C sources

I'm using the following to do conditional compilation in automake of the amhello example program [1]:
In configure.ac:
AC_INIT([amhello], [1.0], [bug-automake#gnu.org])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_PROG_OBJC
build_linux=no
build_windows=no
build_mac=no
AC_CANONICAL_HOST
case "${host_os}" in
cygwin*|mingw*)
build_windows=yes;;
darwin*)
build_mac=yes;;
*)
build_linux=yes;;
esac
AM_CONDITIONAL([LINUX], [test "$build_linux" = "yes"])
AM_CONDITIONAL([WINDOWS], [test "$build_windows" = "yes"])
AM_CONDITIONAL([MACOS], [test "$build_mac" = "yes"])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([
Makefile
src/Makefile
])
AC_OUTPUT
In src/Makefile.am:
bin_PROGRAMS = hello
hello_SOURCES = main.c
if MACOS
hello_SOURCES += hello-mac.m
endif
if LINUX
hello_SOURCES += hello-linux.c
endif
It works as expected except for one issue - even when compiling on Linux, it tries to use the Objective-C build suite instead of the C one. A side effect of this is that OBJCFLAGS gets used instead of CFLAGS, which is counter-intuitive given that no Objective-C source code is being compiled when built for Linux. A demonstration:
$ OBJCFLAGS="-DOBJCFLAGS" CFLAGS="-DCFLAGS" ./configure
...
$ make
make all-recursive
make[1]: Entering directory '/'
Making all in src
make[2]: Entering directory '/src'
gcc -DHAVE_CONFIG_H -I. -I.. -DCFLAGS -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gcc -DHAVE_CONFIG_H -I. -I.. -DCFLAGS -MT hello-linux.o -MD -MP -MF .deps/hello-linux.Tpo -c -o hello-linux.o hello-linux.c
mv -f .deps/hello-linux.Tpo .deps/hello-linux.Po
gcc -DOBJCFLAGS -o hello main.o hello-linux.o
...
From the generated src/Makefile:
...
hello$(EXEEXT): $(hello_OBJECTS) $(hello_DEPENDENCIES) $(EXTRA_hello_DEPENDENCIES)
#rm -f hello$(EXEEXT)
$(AM_V_OBJCLD)$(OBJCLINK) $(hello_OBJECTS) $(hello_LDADD) $(LIBS)
...
Is there a good way to have the C compiler / CFLAGS be used when building for Linux and have the Objective-C compiler / OBJCFLAGS only be used when building for MacOS (when the Objective-C source file is to actually be built)? I tried using both approaches to conditional compilation described in [2] but both exhibit the same behavior.
[1] https://www.gnu.org/software/automake/manual/html_node/Creating-amhello.html#Creating-amhello
[2] https://www.gnu.org/software/automake/manual/html_node/Conditional-Sources.html#Conditional-Sources
I expect that if you tell automake to build different executables for Linux, Windows and MacOS instead of building the same executable with some OS specific variants, automake should not try an Objective-C compiler for the Linux and Windows versions as long as the Linux and Windows do not use any Objective-C sources.
NOTE: This is speculative, verification is needed.
Now... you will need to call these three executables three distinct names if you are going to define them in the same Makefile.am, or define them in multiple Makefile.am files. I can see a few possibilities to do that, and you may need to add subdir-objects to AM_INIT_AUTOMAKE([...]) and re-run autoreconf.
Note that I have not tested any of this, as I have no idea about how to write Objective-C code. If you happen to have your project available somewhere to look (with maybe a proof-of-concept hello-windows.c using winapi, and absolutely hello-macos.m using MacOS APIs), I can try to figure out which of the following proposals works best.
Use recursive make and src/linux/hello, src/windows/hello, src/macos/hello with one Makefile.am each, and move the OS-specific hello-$OS.* into the appropriate subdirectory:
# src/linux/Makefile.am
if LINUX
bin_PROGRAMS = hello
hello_SOURCES = hello-linux.c ../main.c
endif
# src/macos/Makefile.am
if MACOS
bin_PROGRAMS = hello
hello_SOURCES = hello-macos.m ../main.c
endif
# src/windows/Makefile.am
if WINDOWS
bin_PROGRAMS = hello
hello_SOURCES = hello-windows.c ../main.c
# special rules to build object from resource file and adding it
endif
I do not like source files beginning with ../, though. And the less recursive make we use, the better on multicore machines.
Use non-recursive make for the three executables built as src/linux/hello, src/windows/hello, src/macos/hello with one Makefile-files file each, all included from src/Makefile.am, moving the OS specific sources to the OS specific subdirectory:
# src/linux/Makefile-files -*- makefile-automake -*
if LINUX
bin_PROGRAMS += linux/hello
linux_hello_SOURCES = linux/hello-linux.c main.c
endif
# src/macos/Makefile-files -*- makefile-automake -*
if MACOS
bin_PROGRAMS += macos/hello
macos_hello_SOURCES = macos/hello-macos.m main.c
endif
# src/windows/Makefile-files -*- makefile-automake -*
if WINDOWS
bin_PROGRAMS += windows/hello
windows_hello_SOURCES = windows/hello-windows.c main.c
# special rules to build object from resource file and adding it
endif
# src/Makefile.am
bin_PROGRAMS =
include linux/Makefile-files
include macos/Makefile-files
include windows/Makefile-files
I would write the Makefile-files files using %reldir% and %canon_reldir% (or %D% and %C%).
This allows OS specific files and build rules (e.g. Windows resource files and the rules to compile them and link them to the Windows executable) to be all neatly put into the OS specific subdirectory.
Probably my preferred option for the longer term.
Just call the executables linux/hello, windows/hello, and macos/hello from src/Makefile.am without moving the sources or the build rules away from src/:
# src/Makefile.am
bin_PROGRAMS =
if LINUX
bin_PROGRAMS += linux/hello
linux_hello_SOURCES = hello-linux.c main.c
endif
if MACOS
bin_PROGRAMS += macos/hello
macos_hello_SOURCES = hello-macos.m main.c
endif
if WINDOWS
bin_PROGRAMS += windows/hello
windows_hello_SOURCES = hello-windows.c main.c
# special rules to build object from resource file and adding it
endif
If there is a lot of OS specific source files and rules all in the single directory src/ and its src/Makefile.am, this might become difficult to read.
My preferred option for a quick minimum working example.
Call the executables hello-linux, hello-windows, hello-macos from src/Makefile.am and then deal with installing the different executables as hello or hello.exe in install-hooks and the like.
I would avoid this as those hooks and related stuff are non-trivial to get right.
It still needs to be checked whether configure will actually succeed when building for Linux and Windows without an Objective-C compiler to be found.
The OBJCFLAGS are used only at link time, because automake selects the Objective-C linker if it sees any Objective-C source files. See this page in the automake manual.
You can use a per-target _LINK variable to override the default linker selection. In Makefile.am, you can write this, to force the use of the C linker:
hello_LINK = $(LINK)

adding additional sources directory to c makefile

sorry if this is noob question.
In my c function, I use a macro defined in btrfs_inode.h file.
When I include the file directly to path:
#include "/data/kernel/linux-4.1.21-x86_64/fs/btrfs/btrfs_inode.h"
the project compiles with no errors, I dont want to use that direct path, I download the package kernel-source that contains this header file.
The location of the header file after installing the package is at: /usr/src/linux/fs/btrfs/
So I change the #include to :
#include "btrfs_inode.h"
and i wish to add "/usr/src/linux/fs/btrfs/" as a location that it will search for "btrfs_inode.h" and get: "/usr/src/linux/fs/btrfs/btrfs_inode.h"
I get error:
/bin/sh: 1: /usr/src/linux/fs/btrfs/: Permission denied
I am running make as root.
Makefile:
all:: user
obj-m += my-driver.o
# Make arguments
PWD := $(shell pwd)
INCLUDE := -I/usr/include/asm/mach-default/
KDIR := /lib/modules/$(KERNEL_HEADERS)/build;/usr/src/linux/fs/btrfs/
# Add flags to auto build
EXTRA_CFLAGS +=-D__Linux -std=gnu99
# extra warning flags
ccflags-y := -Wall -Wextra #-pedantic
# disable some warning flags
ccflags-y += -Wno-unused-parameter
# make all warnings into errors
ccflags-y += -Werror
# increase verbosity
KBUILD_VERBOSE := 1
all::
$(MAKE) -C $(KDIR) $(INCLUDE) SUBDIRS=$(PWD) modules
So first off, avoid making as root when possible. Next, you added your directory to KDIR, not to INCLUDE (and then you pass KDIR to the -C argument of make, so you would have a line that looks like:
make -C /lib/modules/$(KERNEL_HEADERS)/build;/usr/src/linux/fs/btrfs/ ...
Notice the semicolon, which bash will interperet as the end of a command, and beginning of the next command. So it tries to run make, and then tries to run /usr/src/linux/fs/btrfs/, and gives you your warning. What you should have is something like:
# Make arguments
PWD := $(shell pwd)
INCLUDE := -I/usr/include/asm/mach-default/
INCLUDE += -I/usr/src/linux/fs/btrfs/
KDIR := /lib/modules/$(KERNEL_HEADERS)/build
(you want a -I in front of the path to tell make to search for include files in that directory).
EDIT
You are also not passing the -I to your $(CC) or $(CXX) commands. To do this, you have a couple of options, though I'll suggest the least error prone one: First of all, you have to pass the flags to the sub make. To do this, first add the line:
export INCLUDE
to your main makefile. Your submake now has access to the variable $(INCLUDE). From there, if you have an explicit rule to compile the CC files, you can add $(INCLUDE) to the compile command. Something like
%.o: %.c
$(CC) $(CFLAGS) $(INCLUDE) -o $# $<
or, if you are using the built-in implicit rules, simply add $(INCLUDE) to CPP_FLAGS:
CPP_FLAGS += $(INCLUDE)
(note, CPP_FLAGS are used by default for both c and c++ compilation).
Finally, do not pass $(INCLUDE) to your make command. If you do, it tells make to look look for sub-makefiles in those directories (not gcc...).
From what I could understand via this question, you can add multiple -I flags to your Makefile.

how to compile linux kernel module with -ggdb flag

I modify my module Makefile to make kernel module with -ggdb flag,
KERNROOT := /lib/modules/$(shell uname -r)/build
ccflags-y += -ggdb3
#ccflags-y += -g
test:
$(MAKE) $(ccflags-y) -C $(KERNROOT) M=$(shell pwd)
But it didn't work. The fail message:
make: invalid option -- 'g'
make: invalid option -- 'g'
make: invalid option -- '3'
Usage: make [options] [target] ..
.
Any help? Thanks a lot.
try enabling it through .config file, configurations are taken from there even for compiling the external modules. you can also refer from here you can also enable it from
make menuconfig > Kernel Hacking > Compile kernel with debug info
some reference | some more reference | kernel doc regarding gdb | kernel reference for gdb
When calling make, put KCFLAGS=-ggdb3 prior to any target you're using. For example, to make vmlinux, modules, and bzImage with ggdb3 symbols enabled, run make KCFLAGS=-ggdb3 all.
Note that this is NOT the same as just enabling kernel debug symbols as described in the other answer. The -ggdb3 flag adds additional information to the symbol file that is not included by default (such as macro definitions).

How to keep asm output from Linux kernel module build

I'm working on a Linux kernel module for a 2.6.x kernel and I need to view the assembly output, though it's currently being done as a temporary file an deleted afterwords. I'd like to have the assembly output mixed with my C source file so I can easily trace where my problem lies. This is for an ARMv6 core and apparently objdump doesn't support this architecture. I've included my makefile below.
ETREP=/xxSourceTreexx/
GNU_BIN=$(ETREP)/arm-none-linux-gnueabi/bin
CROSS_COMPILE := $(GNU_BIN)/arm-none-linux-gnueabi-
ARCH := arm
KDIR=$(ETREP)/linux-2.6.31/
MAKE= CROSS_COMPILE=$(CROSS_COMPILE) ARCH=$(ARCH) make
obj-m += xxfile1xx.o
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
Objdump does support that architecture. Your executable will be called arm-none-linux-gnueabi-objdump
Assuming gcc and the gnu assembler a more readable output than objdump can be had. Tell the assembler to retain its intermediate code using flags to gcc:
-Wa,-alh=basename.s
And to get basename to be the actual source filename you need to tell make:
-Wa,-alh=$<.s
which will leave piles of foo.c.s files laying around your source directory. The big problem here is that the way gcc works it uses temporary files between code generation and assembly. I can't find a way to make gcc save its intermediates but the assembler is happy to stash a listing for you.
Getting that argument into the Makefile CFLAGS is left as an exercise for the reader (because I kinda hate "make" and hate "gnu info" even more.
To get an assembly language listing of my Linux kernel modules, I added the assembler switches to the kernel scripts/Makefile.build.
#cmd_cc_o_c = $(CC) $(c_flags) -c -o $(#D)/.tmp_$(#F) $<
cmd_cc_o_c = $(CC) $(c_flags) -c -Wa,-alh=$<.lst -o $(#D)/.tmp_$(#F) $<
You could try the flag "-save-temps" to gcc.
It works for me in my embedded project, I haven't tried it on kernel builds.
The proper way is likely to add target dependencies in your module makefile / Kbuild file:
always-m += basename.s
(As kbuild has the proper targets to generate the .s files)
If you are lazy as I am, this could look like:
MOD_NAME := some_module_name
myunits := file1 file2 file3 ... and many more... without .c extension
obj-m := $(MOD_NAME).o
$(MOD_NAME)-y := $(addsuffix .o,$(myunits))
# Comment/uncomment to generate assembly / preprocessor output
always-m += $(addsuffix .s,$(myunits)) $(MOD_NAME).mod.s
always-m += $(addsuffix .i,$(myunits)) $(MOD_NAME).mod.i
(2 bonuses here: assembly for the generated module meta-registration file, and the preprocessor output)

Resources