@@ -44,6 +44,7 @@ impl std::error::Error for RelocError {} |
| 44 | 44 | |
| 45 | 45 | struct ResolveView<'a> { |
| 46 | 46 | sym_table: &'a SymbolTable, |
| 47 | + symbol_name_index: &'a HashMap<String, SymbolId>, |
| 47 | 48 | atom_table: &'a AtomTable, |
| 48 | 49 | atom_addrs: &'a HashMap<crate::resolve::AtomId, u64>, |
| 49 | 50 | atoms_by_input_section: &'a HashMap<(InputId, u8), Vec<crate::resolve::AtomId>>, |
@@ -236,8 +237,10 @@ pub fn apply_layout( |
| 236 | 237 | let atoms_by_input_section = atoms.by_input_section(); |
| 237 | 238 | let section_addrs = input_section_address_map(layout, atoms); |
| 238 | 239 | let synth_addrs = synthetic_address_maps(layout, plan.synthetic_plan); |
| 240 | + let symbol_name_index = build_symbol_name_index(sym_table); |
| 239 | 241 | let resolve = ResolveView { |
| 240 | 242 | sym_table, |
| 243 | + symbol_name_index: &symbol_name_index, |
| 241 | 244 | atom_table: atoms, |
| 242 | 245 | atom_addrs: &atom_addrs, |
| 243 | 246 | atoms_by_input_section: &atoms_by_input_section, |
@@ -556,8 +559,10 @@ pub fn plan_thunks( |
| 556 | 559 | let atoms_by_input_section = atoms.by_input_section(); |
| 557 | 560 | let section_addrs = input_section_address_map(layout, atoms); |
| 558 | 561 | let synth_addrs = synthetic_address_maps(layout, synthetic_plan); |
| 562 | + let symbol_name_index = build_symbol_name_index(sym_table); |
| 559 | 563 | let resolve = ResolveView { |
| 560 | 564 | sym_table, |
| 565 | + symbol_name_index: &symbol_name_index, |
| 561 | 566 | atom_table: atoms, |
| 562 | 567 | atom_addrs: &atom_addrs, |
| 563 | 568 | atoms_by_input_section: &atoms_by_input_section, |
@@ -683,7 +688,7 @@ fn apply_one( |
| 683 | 688 | })? + local_offset as u64; |
| 684 | 689 | match reloc.kind { |
| 685 | 690 | RelocKind::Unsigned => { |
| 686 | | - if dylib_import_symbol_id(obj, reloc.referent, resolve.sym_table).is_some() { |
| 691 | + if dylib_import_symbol_id(obj, reloc.referent, resolve).is_some() { |
| 687 | 692 | if direct_import_bind_supported(reloc) { |
| 688 | 693 | clear_direct_import_slot(bytes, atom, obj, local_offset, reloc) |
| 689 | 694 | } else { |
@@ -801,7 +806,7 @@ fn apply_one( |
| 801 | 806 | ), |
| 802 | 807 | RelocKind::TlvpLoadPageOff12 => { |
| 803 | 808 | let target = resolve_tlvp_pageoff_target(obj, atom, reloc, resolve)?; |
| 804 | | - if dylib_import_symbol_id(obj, reloc.referent, resolve.sym_table).is_some() { |
| 809 | + if dylib_import_symbol_id(obj, reloc.referent, resolve).is_some() { |
| 805 | 810 | patch_pageoff12(bytes, atom, obj, local_offset, reloc, target) |
| 806 | 811 | } else { |
| 807 | 812 | patch_tlvp_pageoff12(bytes, atom, obj, local_offset, reloc, target) |
@@ -826,7 +831,7 @@ fn resolve_branch_target_key( |
| 826 | 831 | reloc: Reloc, |
| 827 | 832 | resolve: &ResolveView<'_>, |
| 828 | 833 | ) -> Result<BranchTargetKey, RelocError> { |
| 829 | | - if let Some(symbol_id) = dylib_import_symbol_id(obj, reloc.referent, resolve.sym_table) { |
| 834 | + if let Some(symbol_id) = dylib_import_symbol_id(obj, reloc.referent, resolve) { |
| 830 | 835 | return Ok(BranchTargetKey::Stub(symbol_id)); |
| 831 | 836 | } |
| 832 | 837 | match reloc.referent { |
@@ -847,11 +852,7 @@ fn resolve_branch_target_key( |
| 847 | 852 | ) |
| 848 | 853 | })?; |
| 849 | 854 | if let Ok(name) = obj.symbol_name(input_sym) { |
| 850 | | - if let Some((symbol_id, _)) = resolve |
| 851 | | - .sym_table |
| 852 | | - .iter() |
| 853 | | - .find(|(_, symbol)| resolve.sym_table.interner.resolve(symbol.name()) == name) |
| 854 | | - { |
| 855 | + if let Some(symbol_id) = resolve.symbol_name_index.get(name).copied() { |
| 855 | 856 | return Ok(BranchTargetKey::Symbol(symbol_id)); |
| 856 | 857 | } |
| 857 | 858 | } |
@@ -1085,7 +1086,7 @@ fn resolve_got_target( |
| 1085 | 1086 | reloc: Reloc, |
| 1086 | 1087 | resolve: &ResolveView<'_>, |
| 1087 | 1088 | ) -> Result<u64, RelocError> { |
| 1088 | | - let Some(symbol_id) = symbol_referent_id(obj, reloc.referent, resolve.sym_table) else { |
| 1089 | + let Some(symbol_id) = symbol_referent_id(obj, reloc.referent, resolve) else { |
| 1089 | 1090 | return Err(reloc_error( |
| 1090 | 1091 | atom, |
| 1091 | 1092 | &obj.path, |
@@ -1108,7 +1109,7 @@ fn resolve_got_target( |
| 1108 | 1109 | } |
| 1109 | 1110 | |
| 1110 | 1111 | fn got_reloc_relaxes_locally(obj: &ObjectFile, reloc: Reloc, resolve: &ResolveView<'_>) -> bool { |
| 1111 | | - match symbol_referent_id(obj, reloc.referent, resolve.sym_table) { |
| 1112 | + match symbol_referent_id(obj, reloc.referent, resolve) { |
| 1112 | 1113 | Some(symbol_id) => match resolve.sym_table.get(symbol_id) { |
| 1113 | 1114 | Symbol::DylibImport { .. } => false, |
| 1114 | 1115 | Symbol::Defined { .. } => true, |
@@ -1124,7 +1125,7 @@ fn resolve_tlvp_target( |
| 1124 | 1125 | reloc: Reloc, |
| 1125 | 1126 | resolve: &ResolveView<'_>, |
| 1126 | 1127 | ) -> Result<u64, RelocError> { |
| 1127 | | - if dylib_import_symbol_id(obj, reloc.referent, resolve.sym_table).is_some() { |
| 1128 | + if dylib_import_symbol_id(obj, reloc.referent, resolve).is_some() { |
| 1128 | 1129 | return resolve_got_target(obj, atom, reloc, resolve); |
| 1129 | 1130 | } |
| 1130 | 1131 | resolve_referent(obj, atom, reloc.kind, reloc.referent, resolve) |
@@ -1136,7 +1137,7 @@ fn resolve_tlvp_pageoff_target( |
| 1136 | 1137 | reloc: Reloc, |
| 1137 | 1138 | resolve: &ResolveView<'_>, |
| 1138 | 1139 | ) -> Result<u64, RelocError> { |
| 1139 | | - if dylib_import_symbol_id(obj, reloc.referent, resolve.sym_table).is_some() { |
| 1140 | + if dylib_import_symbol_id(obj, reloc.referent, resolve).is_some() { |
| 1140 | 1141 | return resolve_got_target(obj, atom, reloc, resolve); |
| 1141 | 1142 | } |
| 1142 | 1143 | resolve_referent(obj, atom, reloc.kind, reloc.referent, resolve) |
@@ -1189,12 +1190,15 @@ fn resolve_symbol_referent( |
| 1189 | 1190 | })?; |
| 1190 | 1191 | |
| 1191 | 1192 | if let Ok(name) = obj.symbol_name(input_sym) { |
| 1192 | | - if let Some((_, symbol)) = resolve |
| 1193 | | - .sym_table |
| 1194 | | - .iter() |
| 1195 | | - .find(|(_, symbol)| resolve.sym_table.interner.resolve(symbol.name()) == name) |
| 1196 | | - { |
| 1197 | | - return resolve_global_symbol(obj, atom, kind, name, symbol, resolve); |
| 1193 | + if let Some(symbol_id) = resolve.symbol_name_index.get(name).copied() { |
| 1194 | + return resolve_global_symbol( |
| 1195 | + obj, |
| 1196 | + atom, |
| 1197 | + kind, |
| 1198 | + name, |
| 1199 | + resolve.sym_table.get(symbol_id), |
| 1200 | + resolve, |
| 1201 | + ); |
| 1198 | 1202 | } |
| 1199 | 1203 | } |
| 1200 | 1204 | |
@@ -1204,27 +1208,35 @@ fn resolve_symbol_referent( |
| 1204 | 1208 | fn dylib_import_symbol_id( |
| 1205 | 1209 | obj: &ObjectFile, |
| 1206 | 1210 | referent: Referent, |
| 1207 | | - sym_table: &SymbolTable, |
| 1211 | + resolve: &ResolveView<'_>, |
| 1208 | 1212 | ) -> Option<SymbolId> { |
| 1209 | | - let symbol_id = symbol_referent_id(obj, referent, sym_table)?; |
| 1210 | | - matches!(sym_table.get(symbol_id), Symbol::DylibImport { .. }).then_some(symbol_id) |
| 1213 | + let symbol_id = symbol_referent_id(obj, referent, resolve)?; |
| 1214 | + matches!(resolve.sym_table.get(symbol_id), Symbol::DylibImport { .. }).then_some(symbol_id) |
| 1211 | 1215 | } |
| 1212 | 1216 | |
| 1213 | 1217 | fn symbol_referent_id( |
| 1214 | 1218 | obj: &ObjectFile, |
| 1215 | 1219 | referent: Referent, |
| 1216 | | - sym_table: &SymbolTable, |
| 1220 | + resolve: &ResolveView<'_>, |
| 1217 | 1221 | ) -> Option<SymbolId> { |
| 1218 | 1222 | let Referent::Symbol(sym_idx) = referent else { |
| 1219 | 1223 | return None; |
| 1220 | 1224 | }; |
| 1221 | 1225 | let input_sym = obj.symbols.get(sym_idx as usize)?; |
| 1222 | 1226 | let name = obj.symbol_name(input_sym).ok()?; |
| 1223 | | - let (symbol_id, symbol) = sym_table |
| 1227 | + resolve.symbol_name_index.get(name).copied() |
| 1228 | +} |
| 1229 | + |
| 1230 | +fn build_symbol_name_index(sym_table: &SymbolTable) -> HashMap<String, SymbolId> { |
| 1231 | + sym_table |
| 1224 | 1232 | .iter() |
| 1225 | | - .find(|(_, symbol)| sym_table.interner.resolve(symbol.name()) == name)?; |
| 1226 | | - let _ = symbol; |
| 1227 | | - Some(symbol_id) |
| 1233 | + .map(|(symbol_id, symbol)| { |
| 1234 | + ( |
| 1235 | + sym_table.interner.resolve(symbol.name()).to_string(), |
| 1236 | + symbol_id, |
| 1237 | + ) |
| 1238 | + }) |
| 1239 | + .collect() |
| 1228 | 1240 | } |
| 1229 | 1241 | |
| 1230 | 1242 | fn resolve_global_symbol( |