Skip to content

Commit 4d6bf2f

Browse files
committed
Merge branch 'master' of https://github.com/SRI-CSL/gllvm
2 parents cd8022e + 78c7185 commit 4d6bf2f

File tree

2 files changed

+160
-1
lines changed

2 files changed

+160
-1
lines changed

examples/linux-kernel/bash_profile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ export GOPATH=/vagrant/go
88

99
export LLVM_COMPILER=clang
1010
export WLLVM_OUTPUT_LEVEL=WARNING
11-
export WLLVM_OUTPUT_FILE=/vagrant/wrapper.log
11+
export WLLVM_OUTPUT_FILE=/vagrant/wrapper-logs/wrapper.log
1212
export PATH=${GOPATH}/bin:${LLVM_HOME}/bin:${PATH}
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
2+
## Building the linux kernel from llvm bitcode requires writing scripts to copy, extract and recompile a lot of files in the right order.
3+
## A script is only valid for one configuration of the kernel
4+
5+
## The goal of this Python script is to automate the script building process for any configuration of the kernel.
6+
7+
## It takes one or more argument : the first argument is where to write the final script, and all the others are paths to files of which we should not use the bitcode.
8+
9+
import sys,os
10+
import subprocess
11+
12+
# This is where most of the script gets written.
13+
# This function takes as argument:
14+
# a list of path that should not be translated into bitcode
15+
# the depth from the root (this is a recursive function)
16+
# the path from the root to the current folder (its length should be depth)
17+
def write_script(excluded_paths, depth, base_dir):
18+
builtin = open (base_dir+"arbi","w")
19+
subprocess.call(["ar", "-t", base_dir+"built-in.o"],stdout=builtin )
20+
builtin.close()
21+
builtin = open(base_dir+"arbi","r")
22+
out.writelines("mkdir -p $build_home/built-ins/"+base_dir+" \n")
23+
# In directories we store the list of depth 1 directories (and files) found in builtin
24+
directories=[]
25+
for line in builtin.readlines():
26+
line=line.split('\n')[0]
27+
words=line.split('/')
28+
if words[0]=="arch": # We had to make an exception for the arch folder which does not have a built-in.o at the root.
29+
words[0]=words[0]+'/'+words[1]
30+
if words[2] in archbi: #A second exception for arch, not all files in the folder are referenced in the arch/x86/built-in.o. We store the exceptions in the archi list
31+
words[0]=words[0]+'/'+words[2]
32+
if words[depth] not in directories and line not in standalone_objects: #Some objects are not listed in a built-in.o except at the root, so we include them separately in order not to mess the order of linking
33+
directories.append(words[depth])
34+
35+
# folders in which there are excluded folders which we will need to act on recursively
36+
excluded_roots = [path[depth] for path in excluded_paths]
37+
38+
for direc in directories:
39+
print base_dir+direc
40+
# the folder contains an excluded folder
41+
if direc in excluded_roots:
42+
# Check if we have an excluded folder
43+
if base_dir+direc in excluded_dirs:
44+
out.writelines("convert-thin-archive.sh "+base_dir+direc+"/built-in.o \n")
45+
out.writelines("cp "+ base_dir +direc+"/built-in.o.new $build_home/built-ins/"+base_dir+direc+"bi.o \n \n")
46+
link_args.writelines("built-ins/"+base_dir + direc +"bi.o ")
47+
# Else we filter the excluded_path list for only relevant stuff and we call the recursion on that folder
48+
else:
49+
relevant_excluded = [path for path in excluded_paths if (path[depth]==direc and len(path)>depth+1) ]
50+
if relevant_excluded:
51+
write_script(relevant_excluded,depth+1,base_dir+direc+"/")
52+
else:
53+
#If the "directory" is a file, we copy it into the relevant objects folder and compile it
54+
if direc[-2:] == ".o":
55+
out.writelines("get-bc -b "+base_dir+direc+"\n")
56+
out.writelines("mkdir -p $build_home/built-ins/"+base_dir+"objects \n")
57+
out.writelines("cp "+ base_dir+direc+".bc $build_home/built-ins/"+base_dir+"objects \n")
58+
out.writelines("clang -c -no-integrated-as -mcmodel=kernel -o $build_home/built-ins/"+base_dir+ direc + " $build_home/built-ins/"+base_dir+"objects/" + direc+".bc \n \n")
59+
# We then add it to the linker arguments file
60+
link_args.writelines("built-ins/"+base_dir + direc +" ")
61+
# When dealing with a folder, we get the bitcode from the built-in.o file and check for errors in the log.
62+
# For each file that does not have a bitcode version (compiled straight from assembly) we copy it into the build folder directly and add it to the linker args
63+
else:
64+
if os.path.isfile("/vagrant/wrapper-logs/wrapper.log"):
65+
direc_no_slash=direc.split('/')[0]
66+
os.rename("/vagrant/wrapper-logs/wrapper.log","/vagrant/wrapper-logs/before_"+direc_no_slash+".log")
67+
#os.remove("/vagrant/wrapper-logs/wrapper.log")
68+
path = base_dir + direc +"/built-in.o"
69+
subprocess.call(["get-bc", "-b", path ])
70+
subprocess.call(["touch","/vagrant/wrapper-logs/wrapper.log"])
71+
72+
# Checking to see if any file failed to be extracted to bitcode
73+
llvm_log=open("/vagrant/wrapper-logs/wrapper.log","r")
74+
assembly_objects=[]
75+
for line in llvm_log.readlines():
76+
if len(line)>=54 and line[:54]=="WARNING:Error reading the .llvm_bc section of ELF file":
77+
assembly_objects.append(line[55:-2])
78+
llvm_log.close()
79+
80+
# Deal with those files
81+
if assembly_objects:
82+
out.writelines("mkdir -p $build_home/built-ins/" + base_dir +direc+"\n")
83+
for asf in assembly_objects:
84+
out.writelines("cp "+ asf + " $build_home/built-ins/" + base_dir +direc +"\n")
85+
filename= asf.split('/')[-1]
86+
link_args.writelines("built-ins/"+base_dir + direc +'/'+filename+" ")
87+
# Deal with the rest
88+
if os.path.isfile(base_dir + direc +"/built-in.o.a.bc"):
89+
out.writelines("cp "+ base_dir + direc +"/built-in.o.a.bc $build_home/built-ins/"+ base_dir + direc+"bi.o.bc \n")
90+
out.writelines("clang -c -no-integrated-as -mcmodel=kernel -o $build_home/built-ins/"+ base_dir + direc + "bibc.o $build_home/built-ins/" + base_dir+direc+"bi.o.bc \n \n")
91+
link_args.writelines("built-ins/"+base_dir + direc +"bibc.o ")
92+
93+
builtin.close()
94+
95+
96+
# excluded_dirs is a list where the folders excluded from bitcode translation will be stored
97+
excluded_dirs=[]
98+
99+
if len(sys.argv) > 2:
100+
excluded_dirs=sys.argv[2:]
101+
102+
# Output file path
103+
script_out= sys.argv[1]
104+
105+
#We transform excluded_dirs into a 2D array for better access to individual folders in the path
106+
excluded=[path.split('/') for path in excluded_dirs]
107+
108+
out = open(script_out,"w+")
109+
link_args = open("/home/vagrant/standalone-build/link-args","w+")
110+
out.writelines("# Script written by the built-in-parsing.py script \n")
111+
out.writelines("export build_home=/home/vagrant/standalone-build\n")
112+
113+
# List exceptions
114+
standalone_objects = ["arch/x86/kernel/head_64.o","arch/x86/kernel/head64.o","arch/x86/kernel/ebda.o","arch/x86/kernel/platform-quirks.o"]#,"usr/initramfs_data.o"]
115+
archbi=["lib","pci","video","power"]
116+
117+
# Calling the main function
118+
write_script(excluded,0,"")
119+
120+
# Dealing with both lib files
121+
out.writelines("get-bc -b lib/lib.a \n")
122+
out.writelines("mkdir $build_home/lib")
123+
out.writelines("cp lib/lib.a.bc $build_home/lib \n")
124+
out.writelines("clang -c -no-integrated-as -mcmodel=kernel -o $build_home/lib/lib.a.o $build_home/lib/lib.a.bc \n")
125+
126+
if os.path.isfile("/vagrant/wrapper-logs/wrapper.log"):
127+
os.rename("/vagrant/wrapper-logs/wrapper.log","/vagrant/wrapper-logs/before_lib.log")
128+
#os.remove("/vagrant/wrapper-logs/wrapper.log")
129+
subprocess.call(["get-bc", "-b", "arch/x86/lib/lib.a" ])
130+
subprocess.call(["touch","/vagrant/wrapper-logs/wrapper.log"])
131+
llvm_log=open("/vagrant/wrapper-logs/wrapper.log","r")
132+
assembly_objects=[]
133+
for line in llvm_log.readlines():
134+
if len(line)>=54 and line[:54]=="WARNING:Error reading the .llvm_bc section of ELF file":
135+
assembly_objects.append(line[55:-2])
136+
if assembly_objects:
137+
out.writelines("mkdir -p $build_home/arch/x86/lib/objects \n")
138+
for asf in assembly_objects:
139+
out.writelines("cp "+ asf + " $build_home/arch/x86/lib/objects/ \n")
140+
filename= asf.split('/')[-1]
141+
#link_args.writelines("arch/x86/lib/objects/" +filename+" ") ##commented to keep the order of linked files
142+
out.writelines("cp arch/x86/lib/lib.a.bc $build_home/arch/x86/lib/lib.a.bc \n")
143+
out.writelines("clang -c -no-integrated-as -mcmodel=kernel -o $build_home/arch/x86/lib/lib.a.o $build_home/arch/x86/lib/lib.a.bc \n \n")
144+
145+
#Deal with individual files
146+
out.writelines("cp arch/x86/kernel/vmlinux.lds $build_home \n")
147+
out.writelines("cp .tmp_kallsyms2.o $build_home \n")
148+
for sto in standalone_objects:
149+
out.writelines("cp --parents "+ sto+" $build_home \n")
150+
out.writelines("\n#linking command \n")
151+
152+
out.writelines("cd $build_home \n")
153+
154+
# Final linking command
155+
out.writelines("ld --build-id -T vmlinux.lds --whole-archive ")
156+
for sto in standalone_objects:
157+
out.writelines(sto+" ")
158+
out.writelines("\@link-args ")
159+
out.writelines("--no-whole-archive --start-group lib/lib.a.o arch/x86/lib/lib.a.o arch/x86/lib/objects/* .tmp_kallsyms2.o --end-group -o vmlinux")

0 commit comments

Comments
 (0)