103 lines
2.0 KiB
Plaintext
103 lines
2.0 KiB
Plaintext
|
#!/usr/bin/tclsh
|
||
|
#########################################################################################
|
||
|
# Parse output from ld_classic that complains about missing symbols and look them
|
||
|
# up in the named object file
|
||
|
#
|
||
|
|
||
|
proc parse_line {line} {
|
||
|
|
||
|
global last_fname
|
||
|
|
||
|
set toks [split $line]
|
||
|
if { ![regexp "ld_classic:" [lindex $toks 0]] } {
|
||
|
puts "ignoring garbage '$line'"
|
||
|
return
|
||
|
}
|
||
|
|
||
|
set fname [lindex $toks 1]
|
||
|
set relent [lindex $toks 7]
|
||
|
set sect [lindex $toks 10]
|
||
|
|
||
|
# strip archive member name if present
|
||
|
set ppos [string last "(" $fname];
|
||
|
if {$ppos != -1} {
|
||
|
set fname [string range $fname 0 [expr $ppos - 1]];
|
||
|
}
|
||
|
|
||
|
#puts "% $fname % $relent % $sect"
|
||
|
|
||
|
set relname [find_sym $fname $relent $sect]
|
||
|
|
||
|
if {$last_fname != $fname} {
|
||
|
puts "$fname:"
|
||
|
set last_fname $fname
|
||
|
}
|
||
|
|
||
|
puts " $relname"
|
||
|
}
|
||
|
|
||
|
proc find_sym {fname relent sect} {
|
||
|
|
||
|
global reloc_$fname
|
||
|
|
||
|
if {![array exists reloc_$fname]} {
|
||
|
get_relocs $fname
|
||
|
}
|
||
|
upvar 0 reloc_$fname relocs
|
||
|
if {[array names relocs -exact $sect:$relent] == ""} {
|
||
|
puts "Don't know reloc $relent for $fname"
|
||
|
exit 1
|
||
|
}
|
||
|
return $relocs($sect:$relent)
|
||
|
}
|
||
|
|
||
|
proc get_relocs {fname} {
|
||
|
|
||
|
global reloc_$fname
|
||
|
upvar 0 reloc_$fname relocs
|
||
|
|
||
|
set body [exec otool -rv $fname]
|
||
|
set lines [split $body "\n"]
|
||
|
|
||
|
set curr_sect "none"
|
||
|
|
||
|
foreach line $lines {
|
||
|
|
||
|
set toks [split [collapse $line]]
|
||
|
|
||
|
if {[lindex $toks 0] == "Relocation"} {
|
||
|
set sect [lindex $toks 2]
|
||
|
set count [lindex $toks 3]
|
||
|
set curr_sect $sect
|
||
|
set counter 0
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
if {[string is xdigit [lindex $toks 0]]} {
|
||
|
if {[llength $toks] == 7} {
|
||
|
set relocs($curr_sect:$counter) [lindex $toks 6]
|
||
|
}
|
||
|
incr counter
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
proc collapse {str} {
|
||
|
|
||
|
set before ""
|
||
|
set after $str
|
||
|
|
||
|
while {$before != $after} {
|
||
|
set before $after
|
||
|
|
||
|
set after [string map [list " " " "] $before]
|
||
|
}
|
||
|
return $after
|
||
|
}
|
||
|
|
||
|
# Suck from standard input
|
||
|
set last_fname ""
|
||
|
while {[gets stdin line] > 0} {
|
||
|
parse_line $line
|
||
|
}
|