# <- this character "#" indicates a comment; # the rest of a line, following "#", is ignored # For tidyness, we create a directory in which we will download # files and perform compilations. The command "mkdir" creates # a directory. As usual, see "man mkdir" for documentation. mkdir lecture_4 # We move into this directory cd lecture_4 # We download the files into this directory. This can be done # from the browser, or even from the command line: # wget https://www.poirrier.ca/courses/softeng/slides/objcode.c # wget https://www.poirrier.ca/courses/softeng/slides/optimize.c # wget https://www.poirrier.ca/courses/softeng/slides/overcommit.c # or # curl -O https://www.poirrier.ca/courses/softeng/slides/objcode.c # curl -O https://www.poirrier.ca/courses/softeng/slides/optimize.c # curl -O https://www.poirrier.ca/courses/softeng/slides/overcommit.c # curl and wget perfrom roughly equivalent tasks, but one of them # may already be installed. As usual "man wget" / "man curl". # Just to familiarize ourselves with "hexdump", we display the source # code, and verify that it indeed contains all ASCII characters. hexdump -C objcode.c # We compile objcode.c. The "-c" option specifies that we want no linking. # On MacOS, any "gcc" command can be replaced by "clang" and will work # in the same way. gcc -Wall -c -o objcode.o objcode.c # We visualize the data in the object file hexdump -C objcode.o # There is too much data, so we use a "pipe" and the "pager" command "less". hexdump -C objcode.o | less # Let us check the documentation of "readelf" man readelf # ... and use it: readelf -a objcode.o | less # The "-p" parameter of "objdump" gives us similar information # (readelf is not easily installed on MacOS, use "objdump -p" on that platform) objdump -p objcode.o | less # Let us disassemble objcode.o, i.e. show the assembly that corresponds # to its machine code sections: objdump -M intel -d objcode.o | less # We can now link objcode.o and see the results of linking, # either by re-using our previously-compiled file: gcc -o objcode objcode.o # or, equivalently, directly from the source: # gcc -Wall -o objcode objcode.c # Observe that, in both cases, we omitted the "-c" option, # so linking takes place. When gcc is given "objcode.o", the # ".o" suffix is enough to let it understand that no compilation # is necessary, only linking. # We can now observe the resulting linked machine code hexdump -C objcode | less objdump -p objcode | less objdump -M intel -d objcode | less # Let us now see the impact of the optimization parameters # of gcc (and, equivalently, clang): # First without optimization: gcc -c -o optimize.o optimize.c objdump -M intel -d optimize.o | less # The assembly is as we expect. # Next with optimization: gcc -O3 -c -o optimize.o optimize.c objdump -M intel -d optimize.o | less # Now the whole function main just returns the value 2,000,000. # Compiling the demonstration of virtual memory overcommitting: gcc -O3 -Wall -o overcommit overcommit.c ./overcommit # And, in a different window, again: ./overcommit # We observe that malloc() succeeds, but the system still crashes # when running out of physical memory. # Example shell script (here we deviate slightly from class so # that everything is self-contained): # First, the command "echo" just reprints its parameters echo "Hello" # output: Hello # As a reminder, we can "pipe" or "redirect" the output of any command: echo "Hello" | less echo "Hello" > hello.txt # Let us create a compilation script echo "gcc -O3 -Wall -o overcommit overcommit.c" > compile_overcommit.sh # The script is just a text file containing the command we used to # compile "overcommit.c". Let us try to run the script: ./compile_overcommit.sh # bash: ./compile_overcommit.sh: Permission denied # ^ We get this error message because we do not have execution permissions # for the file compile_overcommit.sh. Let us verify this: ls -l # Let us add the execution permission chmod +x ./compile_overcommit.sh # Now we can run the script: ./compile_overcommit.sh # Note that contrary to objcode, optimization or overcommit, this file # is a script and does not contain machine code. The OS detects this # and runs it, accordingly, as a "shell script": a series of command-line # commands. As usual "man ls", "man chmod" for more.