9 SECTION
=".discard.retpoline_safe"
11 # Form an associative lookup for the symbol numbers in the ELF symbol table.
12 # Uses 8 character 0 expanded hexadecimal key for ease of consumption.
15 readelf
-W --syms "$1" |
16 awk '($4 == "SECTION" && $1 ~ /^[0-9]*:/) { printf("%08x %08x\n", int($1), int($7)); }' | \
17 while read symbol_num section_num
19 echo "symbolmap_$symbol_num='$section_num'"
24 eval $
(__symbolmap_init
"$1")
28 eval RET
="\$symbolmap_$1"
29 if [ "$RET" = '' ]; then
30 echo "symbolmap: $1: invalid section" 1>&2
35 # Form an associative lookup for the section numbers in the ELF symbol table.
36 # Uses 8 character 0 expanded hexadecimal key for ease of consumption.
39 readelf
-W --headers "$1" | \
41 { sub("\\[", ""); sub("\\]", ""); }
42 ($1 ~ /^[0-9][0-9]*/) { printf("%08x %s %s %s\n", int($1), $2, $3, $4); }
45 while read section_num section_name section_type section_vma
47 echo "sectionmap_$section_num='$section_name'"
48 echo "sectionvma_$section_num='$section_vma'"
49 case "$section_type" in
50 REL|RELA
) section_relocation
="$section_type" ;;
53 echo "section_relocation='$section_relocation'"
58 eval $
(__sectionmap_init
"$1")
62 eval RET
="\$sectionmap_$1"
63 if [ "$RET" = '' ]; then
64 echo "sectionmap: $1: invalid section" 1>&2
70 eval RET
="\$sectionvma_$1"
71 if [ "$RET" = '' ]; then
72 echo "sectionvma: $1: invalid section" 1>&2
77 # Read and parse the hex-dump output.
79 hex_8
="$hex$hex$hex$hex$hex$hex$hex$hex"
81 hexspc_8
="$hexspc$hexspc$hexspc$hexspc$hexspc$hexspc$hexspc$hexspc"
85 readelf
--hex-dump "$2" "$1" 2>/dev
/null |
87 -e '/^Hex/d' -e '/^$/d' -e '/^ *NOTE/d' \
88 -e 's/ *[^ ][^ ]* *\('"$hex_8"'\) \('"$hexspc_8"'\) \('"$hexspc_8"'\) \('"$hexspc_8"'\) .*/\1 \2 \3 \4 /' \
89 -e 's/\('"$hex$hex"'\)\('"$hex$hex"'\)\('"$hex$hex"'\)\('"$hex$hex"'\) /\4\3\2\1 /g' \
90 -e 's/ $//g' -e 's/ /\n/g'
92 #-e 's/\([^ ][^ ][^ ][^ ][^ ][^ ][^ ][^ ]\) \([^ ][^ ][^ ][^ ][^ ][^ ][^ ][^ ]\) /\2\1 /g' \
96 #file="$(basename "$1")"
99 # Read relocation information for a 64bit binary. Each relocation entry
100 # is 3 long longs so we collect 6 quads here. Note that the dump is in
101 # listed in increasing byte order not withstanding the quad split.
103 # The record says to take the value of <symbol> add <symbol offset> and
104 # shove that into <write offset> in the segment of the <symbol>.
107 # <write offset> 64 bits
108 # <symbol number> 32 bits
109 # <relocation type> 32 bits
110 # <symbol offset> 64 bits
111 raw32
"$1" ".rela$SECTION" | \
113 a1
=''; a2
=''; a3
=''; a4
=''; a5
=''
116 [ "$a1" = '' ] && { a1
="$a6"; continue; }
117 [ "$a2" = '' ] && { a2
="$a6"; continue; }
118 [ "$a3" = '' ] && { a3
="$a6"; continue; }
119 [ "$a4" = '' ] && { a4
="$a6"; continue; }
120 [ "$a5" = '' ] && { a5
="$a6"; continue; }
122 #echo ">$a1< >$a2< >$a3< >$a4< >$a5< >$a6<" 1>&2
123 #echo "type<$a3> symbol<$a4> offset<$a2$a1> addr<$a6a5>" 1>&2
125 symbolmap
"$a4"; section_num
="$RET"
126 #echo "section_num<$section_num>" 1>&2
128 sectionmap
"$section_num"; section
="$RET"
129 sectionvma
"$section_num"; vma
="$RET"
130 #echo "section<$section> vma<$vma>" 1>&2
132 # Adjust the segment addressing by the segment offset.
133 printf -v addr
"%u" "0x$a6$a5"
134 printf -v vma
"%u" "0x$vma"
135 let offset
="$addr + $vma"
136 printf -v offset
"%x" "$offset"
138 echo "$file-$section-$offset"
140 a1
=''; a2
=''; a3
=''; a4
=''; a5
=''
142 } |
sed -e 's/-00*\([0-9a-f]\)/-\1/'
145 # Form an associative lookup for the raw contents for an ELF section.
146 # Uses 8 character 0 expanded hexadecimal key for ease of consumption.
149 raw32
"$1" "$2" >"$tmp.cm"
153 printf -v offset_hex
"%08x" $offset
154 eval contentmap_
$offset_hex=\'$value\'
156 let offset
="$offset + 4"
162 eval RET
="\$contentmap_$1"
163 if [ "$RET" = '' ]; then
164 echo "contentmap: $1: invalid offset" 1>&2
171 # Load up the current contents of the $SECTION segment
172 # as the offsets (see below) are recorded there and we will need
173 # those to calculate the actuall address.
174 contentmap_init
"$1" "$SECTION"
176 #file="$(basename "$1")"
179 # Read relocation information for a 32bit binary. Each relocation entry
180 # is 3 longs so we collect 3 quads here. Note that the dump is in
181 # listed in increasing byte order not withstanding the quad split.
183 # The record says to take the value of <symbol> and add that to the
184 # existing contents of <write offset> in the segment of the <symbol>.
187 # <write offset> 32 bits
188 # <symbol number> 24 bits
189 # <relocation type> 8 bits
190 raw32
"$1" ".rel$SECTION" | \
195 [ "$a1" = '' ] && { a1
="$a2"; continue; }
198 contentmap
"$a1"; offset
="$RET"
199 symbolmap
"00${a2%??}"; section_num
="$RET"
201 sectionmap
"$section_num"; section
="$RET"
202 sectionvma
"$section_num"; vma
="$RET"
203 #echo ">$a1< >$a2< >$offset< >$section<"
205 echo "$file-$section-$offset"
209 } |
sed -e 's/-00*\([0-9a-f]\)/-\1/'
212 tmp
="/tmp/retpoline-extract.$$"
214 # Accumulate potentially vunerable indirect call/jmp sequences. We do this
215 # by examining the raw disassembly for affected forms, recording the location
219 *) disassemble_as
='--disassembler-options=i8086' ;;
221 objdump
$disassemble_as --disassemble --no-show-raw-insn "$object" | \
223 BEGIN { file="'"$object"'"; src="'"$src"'"; }
224 /Disassembly of section/ { segment=$4; sub(":", "", segment); }
225 /^[0-9a-f][0-9a-f]* <.*>:/ { tag=$0; sub(".*<", "", tag); sub(">.*", "", tag); }
226 $0 ~ /(call|jmp)q? *\*.*%/ {
228 if (segment != ".init.text") {
231 print(file "-" segment "-" offset " " src " " segment " " $0);
234 ' |
sort -k 1b
,1 >"$object.ur-detected"
235 [ ! -s "$object.ur-detected" ] && rm -f "$object.ur-detected"
237 # Load up the symbol table and section mappings.
238 symbolmap_init
"$object"
239 sectionmap_init
"$object"
241 # Accumulate annotated safe indirect call/jmp sequences. We do this by examining
242 # the $SECTION sections (and their associated relocation information),
243 # each entry represents the address of an instruction which has been marked
245 case "$section_relocation" in
246 REL
) rel
"$object" ;;
247 RELA
) rela
"$object" ;;
248 esac |
sort -k 1b
,1 >"$object.ur-safe"
249 [ ! -s "$object.ur-safe" ] && rm -f "$object.ur-safe"
251 # We will perform the below join on the summarised and sorted fragments
252 # formed above. This is performed in retpoline-check.
253 #join -v 1 -j 1 "$tmp.extracted" "$tmp.safe" | sed -s 's/[^ ]* *//'