diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 1770d702..fca7e3e5 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -381,8 +381,8 @@ Address,Quality,Size,Name 0x0000007100009d70,U,000372,PlayerOrEnemy::rtti1impl 0x0000007100009ee4,U,000140, 0x0000007100009f70,U,000140, -0x0000007100009ffc,U,000140,_ZNK4sead15RuntimeTypeInfo6DeriveINS_4HeapEE9isDerivedEPKNS0_9InterfaceE -0x000000710000a088,U,000140,_ZNK4sead15RuntimeTypeInfo6DeriveINS_15ResourceFactoryEE9isDerivedEPKNS0_9InterfaceE +0x0000007100009ffc,U,000140, +0x000000710000a088,U,000140, 0x000000710000a114,U,000316,CookResult::construct 0x000000710000a250,O,000384,_ZN4ksys8CookItemC1Ev 0x000000710000a3d0,U,000532, @@ -506,7 +506,7 @@ Address,Quality,Size,Name 0x0000007100012610,O,000468,_ZNK4sead14SafeStringBaseIcE9findIndexERKS1_ 0x00000071000127e4,U,000336,_ZN4sead18Matrix34CalcCommonIfE7inverseERNS_9BaseMtx34IfEERKS3_ 0x0000007100012934,O,000004,_ZN4sead21FormatFixedSafeStringILi128EED0Ev -0x0000007100012938,O,000240,_ZN4sead15FixedSafeStringILi128EEaSERKNS_14SafeStringBaseIcEE +0x0000007100012938,U,000240, 0x0000007100012a28,U,000600, 0x0000007100012c80,U,000068,Enemy::construct 0x0000007100012cc4,U,000044, @@ -1008,7 +1008,7 @@ Address,Quality,Size,Name 0x0000007100031314,U,000204, 0x00000071000313e0,U,000092, 0x000000710003143c,U,000204, -0x0000007100031508,U,000092,_ZNK4sead14MainFileDevice18getRuntimeTypeInfoEv +0x0000007100031508,U,000092, 0x0000007100031564,U,000104, 0x00000071000315cc,U,000004,j_nullsub_62 0x00000071000315d0,U,000036,_ZN3agl3pfx12DepthOfFieldD0Ev @@ -2400,7 +2400,7 @@ Address,Quality,Size,Name 0x00000071000800bc,O,000240,_ZN4sead19FixedSafeStringBaseIcLi256EEaSERKNS_14SafeStringBaseIcEE 0x00000071000801ac,U,000060,_ZN4sead18HeapSafeStringBaseIcED0Ev 0x00000071000801e8,U,000004,j__ZdlPv_31 -0x00000071000801ec,U,000240,_ZN4sead15FixedSafeStringILi32EEaSERKNS_14SafeStringBaseIcEE +0x00000071000801ec,U,000240,_ZN4sead15FixedSafeStringILi128EEaSERKNS_14SafeStringBaseIcEE 0x00000071000802dc,U,000024, 0x00000071000802f4,U,000140, 0x0000007100080380,U,000104,HavokActiveObject::construct @@ -4913,7 +4913,7 @@ Address,Quality,Size,Name 0x00000071000e1d48,O,000288,_ZNK5uking6action16ControllerRumble27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE 0x00000071000e1e68,O,000092,_ZNK5uking6action16ControllerRumble18getRuntimeTypeInfoEv 0x00000071000e1ec4,O,000052,_ZN5uking6action16ControllerRumbleD0Ev -0x00000071000e1ef8,O,000356,_ZNK4ksys3act2ai10ActionBase19getDynamicParamImplIPiEEbPT_RKN4sead14SafeStringBaseIcEEMNS1_9ParamPackEKFbS6_SB_ES6_ +0x00000071000e1ef8,U,000356, 0x00000071000e205c,U,000060, 0x00000071000e2098,O,000076,_ZN5uking6action18CopyMapPinPositionC1ERKN4ksys3act2ai10ActionBase7InitArgE 0x00000071000e20e4,O,000020,_ZN5uking6action18CopyMapPinPositionD1Ev @@ -13053,7 +13053,7 @@ Address,Quality,Size,Name 0x00000071001ed4a8,O,000288,_ZNK5uking6action26Msg2CameraResetInterpolate27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE 0x00000071001ed5c8,O,000092,_ZNK5uking6action26Msg2CameraResetInterpolate18getRuntimeTypeInfoEv 0x00000071001ed624,O,000052,_ZN5uking6action26Msg2CameraResetInterpolateD0Ev -0x00000071001ed658,O,000356,_ZNK4ksys3act2ai10ActionBase19getDynamicParamImplIPfEEbPT_RKN4sead14SafeStringBaseIcEEMNS1_9ParamPackEKFbS6_SB_ES6_ +0x00000071001ed658,U,000356, 0x00000071001ed7bc,U,000060, 0x00000071001ed7f8,O,000048,_ZN5uking6action24Msg2CameraResetNoConnectC1ERKN4ksys3act2ai10ActionBase7InitArgE 0x00000071001ed828,U,000108,_ZN5uking6action24Msg2CameraResetNoConnect8oneShot_Ev @@ -18224,7 +18224,7 @@ Address,Quality,Size,Name 0x00000071002a5908,U,000088, 0x00000071002a5960,U,000088, 0x00000071002a59b8,U,000088, -0x00000071002a5a10,O,000356,_ZNK4ksys3act2ai10ActionBase19getDynamicParamImplIPbEEbPT_RKN4sead14SafeStringBaseIcEEMNS1_9ParamPackEKFbS6_SB_ES6_ +0x00000071002a5a10,U,000356, 0x00000071002a5b74,U,000060, 0x00000071002a5bb0,U,000356, 0x00000071002a5d14,U,000060, @@ -46194,14 +46194,14 @@ Address,Quality,Size,Name 0x00000071007151dc,U,000092, 0x0000007100715238,U,000428,octarockTypeEnum_text 0x00000071007153e4,U,000004,j__ZdlPv_308 -0x00000071007153e8,U,000240,_ZN4sead15FixedSafeStringILi16EEaSERKNS_14SafeStringBaseIcEE +0x00000071007153e8,U,000240, 0x00000071007154d8,U,000004,j__ZdlPv_309 -0x00000071007154dc,U,000240,_ZN4sead15FixedSafeStringILi224EEaSERKNS_14SafeStringBaseIcEE +0x00000071007154dc,U,000240, 0x00000071007155cc,U,000428,octarockWigTypeEnum_text 0x0000007100715778,U,000004,j__ZdlPv_310 -0x000000710071577c,U,000240,_ZN4sead19FixedSafeStringBaseIcLi224EEaSERKNS_14SafeStringBaseIcEE +0x000000710071577c,U,000240, 0x000000710071586c,U,000004,j__ZdlPv_311 -0x0000007100715870,U,000240,_ZN4sead15FixedSafeStringILi1024EEaSERKNS_14SafeStringBaseIcEE +0x0000007100715870,U,000240, 0x0000007100715960,U,000124, 0x00000071007159dc,U,000068, 0x0000007100715a20,U,000284, @@ -49439,9 +49439,9 @@ Address,Quality,Size,Name 0x00000071007d0304,U,000008,uking::StageSelect::moveReenter 0x00000071007d030c,U,000428,_ZN4sead16RegionLanguageID5text_Ei 0x00000071007d04b8,U,000004,j__ZdlPv_354 -0x00000071007d04bc,O,000240,_ZN4sead15FixedSafeStringILi24EEaSERKNS_14SafeStringBaseIcEE +0x00000071007d04bc,U,000240, 0x00000071007d05ac,U,000004,j__ZdlPv_355 -0x00000071007d05b0,U,000240,_ZN4sead15FixedSafeStringILi96EEaSERKNS_14SafeStringBaseIcEE +0x00000071007d05b0,U,000240, 0x00000071007d06a0,U,000004,j__ZdlPv_356 0x00000071007d06a4,U,000040, 0x00000071007d06cc,U,000024, @@ -52900,7 +52900,7 @@ Address,Quality,Size,Name 0x000000710089c240,U,000012, 0x000000710089c24c,U,000008, 0x000000710089c254,U,000076, -0x000000710089c2a0,U,000204,_ZNK4sead13CalculateTask27checkDerivedRuntimeTypeInfoEPKNS_15RuntimeTypeInfo9InterfaceE +0x000000710089c2a0,U,000204, 0x000000710089c36c,U,000092, 0x000000710089c3c8,U,000004,j__ZdlPv_384 0x000000710089c3cc,U,000140, @@ -54547,7 +54547,7 @@ Address,Quality,Size,Name 0x00000071009160bc,U,000300, 0x00000071009161e8,U,000476, 0x00000071009163c4,U,000420, -0x0000007100916568,U,000224,_ZN4sead21FormatFixedSafeStringILi64EEC2EPKcz +0x0000007100916568,U,000224,_ZN4sead21FormatFixedSafeStringILi96EEC2EPKcz 0x0000007100916648,U,000384, 0x00000071009167c8,U,000044,SaveSystem::setGdmFlagsBeforeStageGen 0x00000071009167f4,U,000004,SaveSystem::noop @@ -61772,11 +61772,11 @@ Address,Quality,Size,Name 0x0000007100aa9ac4,U,000168, 0x0000007100aa9b6c,U,005076, 0x0000007100aaaf40,U,000004,j__ZdlPv_576 -0x0000007100aaaf44,U,000244,_ZN4sead15FixedSafeStringILi168EEaSERKNS_14SafeStringBaseIcEE +0x0000007100aaaf44,U,000244, 0x0000007100aab038,U,000004,j__ZdlPv_577 -0x0000007100aab03c,U,000244,_ZN4sead19FixedSafeStringBaseIcLi168EEaSERKNS_14SafeStringBaseIcEE +0x0000007100aab03c,U,000244, 0x0000007100aab130,U,000004,j__ZdlPv_578 -0x0000007100aab134,U,000244,_ZN4sead15FixedSafeStringILi12EEaSERKNS_14SafeStringBaseIcEE +0x0000007100aab134,U,000244, 0x0000007100aab228,U,000004,nullsub_3124 0x0000007100aab22c,U,000080, 0x0000007100aab27c,U,001404,getSoundNumberForStage @@ -63797,7 +63797,7 @@ Address,Quality,Size,Name 0x0000007100b1cac4,O,000092,_ZN4sead7Color4f4lerpERKS0_S2_f 0x0000007100b1cb20,O,000060,_ZN4sead7Color4fpLERKS0_ 0x0000007100b1cb5c,O,000060,_ZN4sead7Color4fmLERKS0_ -0x0000007100b1cb98,m,000044,_ZN4seadmlERKNS_8Color4u8Ef +0x0000007100b1cb98,U,000044, 0x0000007100b1cbc4,O,000036,_ZN4seadplERKNS_7Color4fES2_ 0x0000007100b1cbe8,O,000036,_ZN4seadmlERKNS_7Color4fES2_ 0x0000007100b1cc0c,O,000032,_ZN4seadmlERKNS_7Color4fEf @@ -67871,7 +67871,7 @@ Address,Quality,Size,Name 0x0000007100be2ee0,U,000036, 0x0000007100be2f04,U,000208, 0x0000007100be2fd4,U,000004,j__ZdlPv_759 -0x0000007100be2fd8,U,000244,_ZN4sead19FixedSafeStringBaseIcLi24EEaSERKNS_14SafeStringBaseIcEE +0x0000007100be2fd8,U,000244, 0x0000007100be30cc,U,000092,_ZN3eui9PictureExC2EPKN2nn4ui2d10ResPictureES5_RKNS2_11BuildArgSetE 0x0000007100be3128,U,000064,_ZN3eui8WindowExC1ERKS0_ 0x0000007100be3168,U,000036, @@ -69228,7 +69228,7 @@ Address,Quality,Size,Name 0x0000007100c2cb2c,U,000012, 0x0000007100c2cb38,U,000012, 0x0000007100c2cb44,U,000260, -0x0000007100c2cc48,U,000200,_ZN3agl3utl14ParameterCurveILj1EE4copyERKNS0_13ParameterBaseE +0x0000007100c2cc48,U,000200, 0x0000007100c2cd10,U,000192, 0x0000007100c2cdd0,U,000344, 0x0000007100c2cf28,U,000008, @@ -71107,7 +71107,7 @@ Address,Quality,Size,Name 0x0000007100cb2208,L,000068,_ZNK2nn3nex7qResult7IsErrorEv 0x0000007100cb224c,L,000008, 0x0000007100cb2254,L,000288, -0x0000007100cb2374,L,000008,_ZN4sead5Mutex6unlockEv +0x0000007100cb2374,L,000008, 0x0000007100cb237c,L,000020,_ZN2nn3nex9Condition6NotifyEv 0x0000007100cb2390,L,000068,_ZN2nn3nex10RootObjectnwEmPKcj 0x0000007100cb23d4,L,000024,_ZN2nn3nex11LockCheckerD0Ev diff --git a/tools/viking/src/functions.rs b/tools/viking/src/functions.rs index db9830ed..36385ad1 100644 --- a/tools/viking/src/functions.rs +++ b/tools/viking/src/functions.rs @@ -1,7 +1,10 @@ use crate::repo; use anyhow::{bail, ensure, Context, Result}; use rustc_hash::FxHashMap; -use std::path::{Path, PathBuf}; +use std::{ + collections::HashSet, + path::{Path, PathBuf}, +}; pub enum Status { Matching, @@ -84,6 +87,7 @@ pub fn get_functions_for_path(csv_path: &Path) -> Result> { let mut result = Vec::with_capacity(110_000); let mut record = csv::StringRecord::new(); let mut line_number = 1; + let mut num_names = 0; if reader.read_record(&mut record)? { // Verify that the CSV has the correct format. ensure!(record.len() == 4, "invalid record; expected 4 fields"); @@ -98,12 +102,36 @@ pub fn get_functions_for_path(csv_path: &Path) -> Result> { } while reader.read_record(&mut record)? { - result.push( - parse_function_csv_entry(&record) - .with_context(|| format!("failed to parse CSV record at line {}", line_number))?, - ); + let entry = parse_function_csv_entry(&record) + .with_context(|| format!("failed to parse CSV record at line {}", line_number))?; + + if !entry.name.is_empty() { + num_names += 1; + } + + result.push(entry); line_number += 1; } + + // Check for duplicate names in the CSV. + let mut known_names = HashSet::with_capacity(num_names); + let mut duplicates = Vec::new(); + for entry in &result { + if entry.is_decompiled() && entry.name.is_empty() { + bail!( + "function at {:016x} is marked as O/M/m but has an empty name", + entry.addr | ADDRESS_BASE + ); + } + + if !entry.name.is_empty() && !known_names.insert(&entry.name) { + duplicates.push(&entry.name); + } + } + if !duplicates.is_empty() { + bail!("found duplicates: {:#?}", duplicates); + } + Ok(result) }