11use std:: collections:: BTreeMap ;
22use std:: fmt:: Debug ;
3+ use std:: io:: Write ;
34use std:: str:: FromStr ;
45use std:: { mem, str} ;
56
@@ -188,12 +189,11 @@ impl<'a> BreakpadIndex<'a> {
188189 } )
189190 }
190191
191- pub fn serialize_to_bytes ( & self ) -> Vec < u8 > {
192+ fn header_and_total_size ( & self ) -> ( BreakpadSymindexFileHeader , u32 ) {
192193 let header_len = HEADER_SIZE ;
193194 let module_info_offset = header_len;
194195 let module_info_len = self . module_info_bytes . len ( ) as u32 ;
195- let padding_after_module_info = align_to_4_bytes ( module_info_len) - module_info_len;
196- let file_entries_offset = module_info_offset + module_info_len + padding_after_module_info;
196+ let file_entries_offset = module_info_offset + align_to_4_bytes ( module_info_len) ;
197197 let file_count = self . files . len ( ) as u32 ;
198198 let file_entries_len = file_count * FILE_OR_INLINE_ORIGIN_ENTRY_SIZE ;
199199 let inline_origin_entries_offset = file_entries_offset + file_entries_len;
@@ -217,19 +217,37 @@ impl<'a> BreakpadIndex<'a> {
217217 symbol_addresses_offset : symbol_addresses_offset. into ( ) ,
218218 symbol_entries_offset : symbol_entries_offset. into ( ) ,
219219 } ;
220+ ( header, total_file_len)
221+ }
222+
223+ pub fn to_writer < W : Write > ( & self , w : W ) -> std:: io:: Result < ( ) > {
224+ let ( header, _) = self . header_and_total_size ( ) ;
225+ self . to_writer_inner ( w, header)
226+ }
220227
221- let mut vec = Vec :: with_capacity ( total_file_len as usize ) ;
222- vec. extend_from_slice ( header. as_bytes ( ) ) ;
223- vec. extend_from_slice ( self . module_info_bytes ) ;
224- vec. extend ( std:: iter:: repeat ( 0 ) . take ( padding_after_module_info as usize ) ) ;
225- vec. extend_from_slice ( self . files . as_slice ( ) . as_bytes ( ) ) ;
226- vec. extend_from_slice ( self . inline_origins . as_slice ( ) . as_bytes ( ) ) ;
227- vec. extend_from_slice ( self . symbol_addresses . as_bytes ( ) ) ;
228- vec. extend_from_slice ( self . symbol_entries . as_bytes ( ) ) ;
228+ fn to_writer_inner < W : Write > (
229+ & self ,
230+ mut w : W ,
231+ header : BreakpadSymindexFileHeader ,
232+ ) -> std:: io:: Result < ( ) > {
233+ w. write_all ( header. as_bytes ( ) ) ?;
234+ w. write_all ( self . module_info_bytes ) ?;
235+ let padding_after_module_info = header. file_entries_offset . get ( )
236+ - ( header. module_info_offset . get ( ) + header. module_info_len . get ( ) ) ;
237+ w. write_all ( & [ 0 ; 4 ] [ ..padding_after_module_info as usize ] ) ?;
238+ w. write_all ( self . files . as_slice ( ) . as_bytes ( ) ) ?;
239+ w. write_all ( self . inline_origins . as_slice ( ) . as_bytes ( ) ) ?;
240+ w. write_all ( self . symbol_addresses . as_bytes ( ) ) ?;
241+ w. write_all ( self . symbol_entries . as_bytes ( ) ) ?;
229242
230- assert_eq ! ( vec. len( ) , total_file_len as usize ) ;
243+ Ok ( ( ) )
244+ }
231245
232- vec
246+ pub fn serialize_to_bytes ( & self ) -> Vec < u8 > {
247+ let ( header, total_size) = self . header_and_total_size ( ) ;
248+ let mut v = Vec :: with_capacity ( total_size as usize ) ;
249+ self . to_writer_inner ( & mut v, header) . unwrap ( ) ;
250+ v
233251 }
234252}
235253
@@ -583,7 +601,7 @@ impl BreakpadIndexCreator {
583601 line_buffer. consume ( chunk, |offset, line| inner. process_line ( offset, line) ) ;
584602 }
585603
586- pub fn finish ( mut self ) -> Result < Vec < u8 > , BreakpadParseError > {
604+ pub fn finish ( mut self ) -> Result < OwnedBreakpadIndex , BreakpadParseError > {
587605 let inner = & mut self . inner ;
588606 let final_offset = self
589607 . line_buffer
@@ -674,7 +692,10 @@ impl BreakpadIndexCreatorInner {
674692 }
675693 }
676694
677- pub fn finish ( mut self , file_end_offset : u64 ) -> Result < Vec < u8 > , BreakpadParseError > {
695+ pub fn finish (
696+ mut self ,
697+ file_end_offset : u64 ,
698+ ) -> Result < OwnedBreakpadIndex , BreakpadParseError > {
678699 self . finish_pending_func_block ( file_end_offset) ;
679700 let BreakpadIndexCreatorInner {
680701 mut symbols,
@@ -697,20 +718,53 @@ impl BreakpadIndexCreatorInner {
697718
698719 let ( debug_id, os, arch, debug_name) =
699720 module_info. ok_or ( BreakpadParseError :: NoModuleInfoInSymFile ) ?;
700- let index = BreakpadIndex {
701- module_info_bytes : & module_info_bytes ,
702- debug_name ,
721+
722+ Ok ( OwnedBreakpadIndex {
723+ module_info_bytes ,
703724 debug_id,
704- code_id,
705- name,
706- arch,
707725 os,
708- symbol_addresses : & symbol_addresses,
709- symbol_entries : & symbol_entries,
710- files : StringListRef :: new ( & files) ,
711- inline_origins : StringListRef :: new ( & inline_origins) ,
712- } ;
713- Ok ( index. serialize_to_bytes ( ) )
726+ arch,
727+ debug_name,
728+ name,
729+ code_id,
730+ files,
731+ inline_origins,
732+ symbol_addresses,
733+ symbol_entries,
734+ } )
735+ }
736+ }
737+
738+ #[ derive( Debug , Clone , Default ) ]
739+ pub struct OwnedBreakpadIndex {
740+ module_info_bytes : Vec < u8 > ,
741+ debug_name : String ,
742+ debug_id : DebugId ,
743+ arch : String ,
744+ os : String ,
745+ name : Option < String > ,
746+ code_id : Option < CodeId > ,
747+ files : Vec < StringLocation > ,
748+ inline_origins : Vec < StringLocation > ,
749+ symbol_addresses : Vec < U32 < LittleEndian > > ,
750+ symbol_entries : Vec < BreakpadSymbolEntry > ,
751+ }
752+
753+ impl OwnedBreakpadIndex {
754+ pub fn index ( & self ) -> BreakpadIndex < ' _ > {
755+ BreakpadIndex {
756+ module_info_bytes : & self . module_info_bytes ,
757+ debug_name : self . debug_name . clone ( ) ,
758+ debug_id : self . debug_id ,
759+ code_id : self . code_id . clone ( ) ,
760+ name : self . name . clone ( ) ,
761+ arch : self . arch . clone ( ) ,
762+ os : self . os . clone ( ) ,
763+ symbol_addresses : & self . symbol_addresses ,
764+ symbol_entries : & self . symbol_entries ,
765+ files : StringListRef :: new ( & self . files ) ,
766+ inline_origins : StringListRef :: new ( & self . inline_origins ) ,
767+ }
714768 }
715769}
716770
@@ -1194,7 +1248,7 @@ curity/sandbox/chromium/base/strings/safe_sprintf.cc:f150bc1f71d09e1e1941065951f
11941248 for chunk in data. chunks ( 84 ) {
11951249 parser. consume ( chunk) ;
11961250 }
1197- let index_bytes = parser. finish ( ) . unwrap ( ) ;
1251+ let index_bytes = parser. finish ( ) . unwrap ( ) . index ( ) . serialize_to_bytes ( ) ;
11981252 let index = BreakpadIndex :: parse_symindex_file ( & * index_bytes) . unwrap ( ) ;
11991253
12001254 assert_eq ! (
@@ -1230,7 +1284,7 @@ curity/sandbox/chromium/base/strings/safe_sprintf.cc:f150bc1f71d09e1e1941065951f
12301284 parser. consume ( b"\n 2b78e 2 306 0\n 2b790 c 305 0\n 2b79c b 309 0\n 2b7a7 10 660 0\n 2b7b7 2 " ) ;
12311285 parser. consume ( b"661 0\n 2b7b9 11 662 0\n 2b7ca 9 340 0\n 2b7d3 e 341 0\n 2b7e1 c 668 0\n 2b7" ) ;
12321286 parser. consume ( b"ed b 7729 1\n 2b7f8 6 668 0" ) ;
1233- let index_bytes = parser. finish ( ) . unwrap ( ) ;
1287+ let index_bytes = parser. finish ( ) . unwrap ( ) . index ( ) . serialize_to_bytes ( ) ;
12341288 let index = BreakpadIndex :: parse_symindex_file ( & * index_bytes) . unwrap ( ) ;
12351289 assert_eq ! ( & index. debug_name, "firefox.pdb" ) ;
12361290 assert_eq ! (
0 commit comments