Class: Itools::LinkMap
- Inherits:
-
Object
- Object
- Itools::LinkMap
- Defined in:
- lib/itools/link_map.rb
Overview
———————————LinkMap class———————————
Instance Attribute Summary collapse
-
#l_arch ⇒ Object
包含的属性.
-
#l_dead_stripped_symbols ⇒ Object
包含的属性.
-
#l_name ⇒ Object
包含的属性.
-
#l_obj_files ⇒ Object
包含的属性.
-
#l_path ⇒ Object
包含的属性.
-
#l_sections ⇒ Object
包含的属性.
-
#l_sym_map ⇒ Object
包含的属性.
-
#l_symbols ⇒ Object
包含的属性.
Class Method Summary collapse
-
.parser(path_para) ⇒ Object
对linkmap进行解析,然后输出结果.
-
.parser_by_folder(args) ⇒ Object
根据linkmap && folder计算占用 第一个参数为linkmap路径,第二个参数为要分析的项目文件夹.
- .traverse_dir(sort_by_obj_files_map, file_path, results, size_files, space_index) ⇒ Object
Instance Method Summary collapse
-
#get_arch(str) ⇒ Object
get arch.
-
#get_o_name(str) ⇒ Object
得到o_ame 有待优化,可以使用正则表达式处理TODO.
-
#get_path(str) ⇒ Object
得到path.
-
#handle_l_sym_map ⇒ Object
处理symbols的数组,把symbols转换成hashmap.
-
#handle_map ⇒ Object
处理link map file.
-
#handle_ojbect_files(str) ⇒ Object
处理object文件.
-
#handle_sections(str) ⇒ Object
处理sections.
-
#handle_symbols(str) ⇒ Object
处理Symbols.
-
#initialize(fName) ⇒ LinkMap
constructor
初始化方法.
Constructor Details
#initialize(fName) ⇒ LinkMap
初始化方法
41 42 43 44 45 46 47 |
# File 'lib/itools/link_map.rb', line 41 def initialize(fName) @l_name = fName @l_obj_files = [] @l_symbols = [] @l_sections = [] @l_dead_stripped_symbols = [] end |
Instance Attribute Details
#l_arch ⇒ Object
包含的属性
39 40 41 |
# File 'lib/itools/link_map.rb', line 39 def l_arch @l_arch end |
#l_dead_stripped_symbols ⇒ Object
包含的属性
39 40 41 |
# File 'lib/itools/link_map.rb', line 39 def l_dead_stripped_symbols @l_dead_stripped_symbols end |
#l_name ⇒ Object
包含的属性
39 40 41 |
# File 'lib/itools/link_map.rb', line 39 def l_name @l_name end |
#l_obj_files ⇒ Object
包含的属性
39 40 41 |
# File 'lib/itools/link_map.rb', line 39 def l_obj_files @l_obj_files end |
#l_path ⇒ Object
包含的属性
39 40 41 |
# File 'lib/itools/link_map.rb', line 39 def l_path @l_path end |
#l_sections ⇒ Object
包含的属性
39 40 41 |
# File 'lib/itools/link_map.rb', line 39 def l_sections @l_sections end |
#l_sym_map ⇒ Object
包含的属性
39 40 41 |
# File 'lib/itools/link_map.rb', line 39 def l_sym_map @l_sym_map end |
#l_symbols ⇒ Object
包含的属性
39 40 41 |
# File 'lib/itools/link_map.rb', line 39 def l_symbols @l_symbols end |
Class Method Details
.parser(path_para) ⇒ Object
对linkmap进行解析,然后输出结果
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/itools/link_map.rb', line 155 def self.parser(path_para) start_time = Time.now.to_i #程序开始执行时间(以毫秒为单位) # 获取link map file's name link_map_file_name = path_para puts "获取的文件路径为:#{link_map_file_name}" if link_map_file_name.nil? puts "请按照如下命令执行该脚本:" puts "\033[31mitools parse **.txt \033[0m" puts "**指代Link Map File的名字,例如LinkMapApp-LinkMap-normal-x86_64.txt,parse后面为绝对路径" return end if File.exist?(link_map_file_name) puts "\033[32m获取LinkMap文件: #{link_map_file_name}成功,开始分析数据...\033[0m" else puts "\033[31m#{link_map_file_name}文件不存在,请重新输入文件 \033[0m" return end link_map = LinkMap.new(link_map_file_name) link_map.handle_map #处理文件为对象,然后继续后续操作 link_map.handle_l_sym_map #处理symbols为hashmap sizeResultArr = [] link_map.l_obj_files.each do |obj| temp_file_name = obj.file_name.split("(")[0] last_file = sizeResultArr.last if last_file && temp_file_name.eql?(last_file.file_name) last_file.file_serial_numers << obj.serial_number else sz_obj = SizeResult.new sz_obj.file_name = temp_file_name sz_obj.file_serial_numers << obj.serial_number sizeResultArr << sz_obj end end data_analyze_time = Time.now.to_i puts "\033[32m数据分析完成,耗时#{data_analyze_time - start_time}秒。开始计算结果\033[0m" # 计算赋值size,此处耗时较长 total_size = 0 sizeResultArr.each do |obj| # 处理方法2 obj.file_serial_numers.each do |s_number| begin link_map.l_sym_map[s_number].each do |symb| obj.size = obj.size + symb.s_size.hex total_size = total_size +symb.s_size.hex #统计总大小 end rescue => exception end end # 处理方法1 太过耗时 # link_map.l_symbols.each do |symb| # if obj.file_serial_numers.include?(symb.s_file_serial_number) # obj.size = obj.size + symb.s_size.hex # end # end # puts "正在计算#{obj.file_name}的大小..." end data_handle_time = Time.now.to_i #处理数据时间 puts "\033[32m数据处理完成,耗时#{data_handle_time - data_analyze_time}秒。开始对结果进行大小排序(从大到小)...\033[0m" # 按照从大到小排序 sizeResultArr.sort_by!{|obj|[-obj.size]} sort_handle_time = Time.now.to_i #排序耗时 puts "\033[32m数据排序完成,耗时#{sort_handle_time - data_handle_time}秒。开始输出结果:\033[0m" puts "\033[32m--------------------------------\033[0m" # 判断文件是否存在 save_file_path = SizeResult.getSaveFileName(path_para) if File.exist?(save_file_path) File.delete(save_file_path) end # 创建要保存数据的文件 save_file = File.new(save_file_path,"w+") # 打印结果 sizeResultArr.each do |obj| puts "#{obj.file_name} " + SizeResult.handleSize(obj.size) save_file.puts("#{obj.file_name} #{SizeResult.handleSize(obj.size)}(#{obj.size})") end save_file.puts("总大小为:#{SizeResult.handleSize(total_size)}") save_file.close puts "总大小为(仅供参考):#{SizeResult.handleSize(total_size)}" puts "\033[32m--------------------------------\033[0m" end_time = Time.now.to_i #程序执行结束时间 puts "分析结果已经保存为文件,位置为:\n\033[32m#{save_file_path}\033[0m" puts " " puts "\033[32m整个程序执行时间为:#{end_time - start_time}秒\033[0m" end |
.parser_by_folder(args) ⇒ Object
根据linkmap && folder计算占用 第一个参数为linkmap路径,第二个参数为要分析的项目文件夹
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/itools/link_map.rb', line 249 def self.parser_by_folder(args) link_map_file_name = args[0] #linkmap文件路径 project_folder = args[1] #项目文件夹 # 对参数进行校验 if File::directory?(project_folder) puts "获取的项目目录路径为:#{project_folder}" else puts "\033[31m#{project_folder}文件夹不存在,请重新输入 \033[0m" return end if File.exist?(link_map_file_name) puts "获取的linkmap文件路径为:#{link_map_file_name}" puts "\033[32m获取LinkMap文件: #{link_map_file_name}成功,开始分析数据...\033[0m" else puts "\033[31m#{link_map_file_name}文件不存在,请重新输入 \033[0m" return end # 开始处理数据 link_map = LinkMap.new(link_map_file_name) link_map.handle_map #处理文件为对象,然后继续后续操作 link_map.handle_l_sym_map #处理symbols为hashmap # 所有的文件 link_map.l_obj_files # 所有的symbols link_map.l_symbols # 处理得到每个obj_file的大小 link_map.l_obj_files.each do |obj| if link_map.l_sym_map[obj.serial_number] link_map.l_sym_map[obj.serial_number].each do |symb| obj.o_size = obj.o_size + symb.s_size.hex end end end # key为文件名,value为ojbect sort_by_obj_files_map = link_map.l_obj_files.group_by(&:o_name) # save_file_path = SizeResult.getSaveFileName(project_folder) # save_file = File.new(save_file_path,"w+") # sort_by_obj_files_map.keys.each do |sss| # save_file.puts("#{sort_by_obj_files_map[sss][0].o_name} #{sort_by_obj_files_map[sss][0].o_size}") # end # save_file.close # exit size_results = [] #盛放计算结果 size_files = [] space_index = 0 puts "计算开始" traverse_dir(sort_by_obj_files_map,project_folder,size_results,size_files,space_index) size_results.reverse! # 存储为文件 save_file_path = SizeResult.getSaveFileName(project_folder) if File.exist?(save_file_path) File.delete(save_file_path) end save_file = File.new(save_file_path,"w+") o_index = 2 size_results.each do |o| result_str = "#{' ' * o.space_count}├── #{o.folder_name.split('/').last} #{SizeResult.handleSize(o.size)}(#{o.size})" save_file.puts(result_str) end save_file.close puts "分析结果已经保存为文件,位置为:\n\033[32m#{save_file_path}\033[0m" end |
.traverse_dir(sort_by_obj_files_map, file_path, results, size_files, space_index) ⇒ Object
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/itools/link_map.rb', line 317 def self.traverse_dir(sort_by_obj_files_map,file_path,results,size_files,space_index) s_result = SizeResult.new s_result.folder_name = file_path space_index = space_index + 2 file_name_arr = [] #盛放计算过的类 Find.find(file_path) do |file| # 不包含图片 if File.file?(file) && !(File.extname(file) =~ /(png|gif|jpg|bmp|jpeg)/) file_name = File.basename(file,".*") if !file_name_arr.include?(file_name) && sort_by_obj_files_map[file_name] #没有已经计算过 s_result.size = s_result.size + sort_by_obj_files_map[file_name][0].o_size file_name_arr << file_name end elsif File::directory?(file) && file != file_path traverse_dir(sort_by_obj_files_map,file,results,size_files,space_index) end end if s_result.size > 0 && !size_files.include?(s_result.folder_name) s_result.space_count = space_index results << s_result size_files << s_result.folder_name end end |
Instance Method Details
#get_arch(str) ⇒ Object
get arch
87 88 89 90 |
# File 'lib/itools/link_map.rb', line 87 def get_arch(str) splitparam = str.split(" ") @l_arch = splitparam.last end |
#get_o_name(str) ⇒ Object
得到o_ame 有待优化,可以使用正则表达式处理TODO
66 67 68 69 70 71 72 73 |
# File 'lib/itools/link_map.rb', line 66 def get_o_name(str) temp_arr = str.split("(") if temp_arr.size > 1 temp_arr[1].split(".o)")[0] else return temp_arr[0].split(".o")[0] end end |
#get_path(str) ⇒ Object
得到path
49 50 51 52 |
# File 'lib/itools/link_map.rb', line 49 def get_path(str) splitparam = str.split(" ") @l_path = splitparam.last end |
#handle_l_sym_map ⇒ Object
处理symbols的数组,把symbols转换成hashmap
116 117 118 119 120 121 122 |
# File 'lib/itools/link_map.rb', line 116 def handle_l_sym_map @l_sym_map = @l_symbols.group_by(&:s_file_serial_number) if @l_sym_map.include?(-1) puts "移除无用元素" @l_sym_map.delete(-1) end end |
#handle_map ⇒ Object
处理link map file
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/itools/link_map.rb', line 124 def handle_map handle_method_name = "" File.read(@l_name).each_line do |line| if line[0] == "#" if line.include?("Path:") handle_method_name = "get_path" puts "处理path..." elsif line.include?("Arch:") handle_method_name = "get_arch" puts "处理Arch..." elsif line.include?("Object files") handle_method_name = "handle_ojbect_files" puts "处理Object files..." elsif line.include?("Sections") handle_method_name = "handle_sections" puts "处理Sections..." elsif line.include?("Symbols:") #symbols:和Dead Stripped Symbols处理一样 # 这里不处理Dead Stripped Symbols if line.delete('#').strip.include?("Dead Stripped Symbols") puts "不处理处理#{line.delete('#').strip}..." break end puts "处理#{line.delete('#').strip}..." handle_method_name = "handle_symbols" end end self.send(handle_method_name, line) end end |
#handle_ojbect_files(str) ⇒ Object
处理object文件
54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/itools/link_map.rb', line 54 def handle_ojbect_files(str) tempSplit = str.split("]") if tempSplit.size > 1 obj_file = ObjectFile.new obj_file.serial_number = tempSplit[0].delete("[").strip.to_i #设置serial_number obj_file.file_path = tempSplit[1].strip obj_file.file_name = tempSplit[1].split("/").last.chomp obj_file.o_name = get_o_name(tempSplit[1].split("/").last.chomp) l_obj_files << obj_file end end |
#handle_sections(str) ⇒ Object
处理sections
75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/itools/link_map.rb', line 75 def handle_sections(str) sectionSplit = str.split(" ") if sectionSplit.size == 4 section = Sections.new section.address = sectionSplit[0] section.size = sectionSplit[1] section.segment = sectionSplit[2] section.section = sectionSplit[3] l_sections << section end end |
#handle_symbols(str) ⇒ Object
处理Symbols
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/itools/link_map.rb', line 92 def handle_symbols(str) # 字符编码产生的异常处理 begin symbolsSplit = str.split("\t") rescue => exception return end if symbolsSplit.size > 2 symbol = Symbols.new symbol.s_address = symbolsSplit[0] symbol.s_size = symbolsSplit[1] # 获取编号和名字 serial_name_str = symbolsSplit[2] file_and_name_split = serial_name_str.split("]") if file_and_name_split.size > 1 symbol.s_file_serial_number = file_and_name_split[0].delete("[").strip.to_i #设置文件编号 symbol.s_name = file_and_name_split[1] end l_symbols << symbol else end end |