From 44254cbe5ff0af106c38ba9333163d8dd260092a Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 23 Feb 2026 01:58:09 -0700 Subject: [PATCH 1/2] Add symbol kind to diff proto output Expose SymbolKind (Function, Object, Section, Unknown) in the DiffSymbol proto message, allowing CLI oneshot diff consumers to distinguish symbol types without inferring from instruction/data presence. --- objdiff-core/protos/diff.proto | 8 ++++++++ objdiff-core/protos/proto_descriptor.bin | Bin 17936 -> 18346 bytes objdiff-core/src/bindings/diff.rs | 12 ++++++++++++ 3 files changed, 20 insertions(+) diff --git a/objdiff-core/protos/diff.proto b/objdiff-core/protos/diff.proto index 56dfa27..94784d6 100644 --- a/objdiff-core/protos/diff.proto +++ b/objdiff-core/protos/diff.proto @@ -40,6 +40,7 @@ message DiffSymbol { uint64 address = 3; uint64 size = 4; uint32 flags = 5; + DiffSymbolKind kind = 10; // The symbol index in the _other_ object that this symbol was diffed against optional uint32 target_symbol = 6; optional float match_percent = 7; @@ -49,6 +50,13 @@ message DiffSymbol { repeated DiffDataSegment data_diff = 9; } +enum DiffSymbolKind { + SYMBOL_UNKNOWN = 0; + SYMBOL_FUNCTION = 1; + SYMBOL_OBJECT = 2; + SYMBOL_SECTION = 3; +} + // Symbol visibility flags (bitmask) enum DiffSymbolFlag { SYMBOL_NONE = 0; diff --git a/objdiff-core/protos/proto_descriptor.bin b/objdiff-core/protos/proto_descriptor.bin index ac74171896c4bc2f696e72801a953341187e5474..1436db89077261454027119157adbf85bae4562b 100644 GIT binary patch delta 3377 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 aS^=R}fI4wNNT0KWt`#7W5B_WarsID%eg|s+ diff --git a/objdiff-core/src/bindings/diff.rs b/objdiff-core/src/bindings/diff.rs index 9a9c36d..a0d2b65 100644 --- a/objdiff-core/src/bindings/diff.rs +++ b/objdiff-core/src/bindings/diff.rs @@ -112,6 +112,7 @@ impl DiffSymbol { address: symbol.address, size: symbol.size, flags: symbol_flags(&symbol.flags), + kind: DiffSymbolKind::from(symbol.kind) as i32, // Diff information target_symbol: symbol_diff.target_symbol.map(|i| i as u32), match_percent: symbol_diff.match_percent, @@ -121,6 +122,17 @@ impl DiffSymbol { } } +impl From for DiffSymbolKind { + fn from(value: obj::SymbolKind) -> Self { + match value { + obj::SymbolKind::Unknown => DiffSymbolKind::SymbolUnknown, + obj::SymbolKind::Function => DiffSymbolKind::SymbolFunction, + obj::SymbolKind::Object => DiffSymbolKind::SymbolObject, + obj::SymbolKind::Section => DiffSymbolKind::SymbolSection, + } + } +} + fn symbol_flags(flags: &obj::SymbolFlagSet) -> u32 { let mut result = 0u32; if flags.contains(SymbolFlag::Global) { From 1ba07d1edd14b6eff2233771cfc20b90861e2ae2 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 23 Feb 2026 21:04:26 -0700 Subject: [PATCH 2/2] Stop filtering symbols from diff output, replace flags bitmask with message Remove the symbol filter (size == 0 / Ignored) from DiffObject so all symbols are emitted. This fixes target_symbol indices being invalid after filtering. Replace the DiffSymbolFlag bitmask enum + uint32 field with a DiffSymbolFlags message of booleans, adding ignored and size_inferred flags so consumers can filter on their end. --- objdiff-core/protos/diff.proto | 19 +++++++------- objdiff-core/protos/proto_descriptor.bin | Bin 18346 -> 18566 bytes objdiff-core/src/bindings/diff.rs | 31 ++++++++--------------- 3 files changed, 20 insertions(+), 30 deletions(-) diff --git a/objdiff-core/protos/diff.proto b/objdiff-core/protos/diff.proto index 94784d6..afb025a 100644 --- a/objdiff-core/protos/diff.proto +++ b/objdiff-core/protos/diff.proto @@ -39,7 +39,7 @@ message DiffSymbol { optional string demangled_name = 2; uint64 address = 3; uint64 size = 4; - uint32 flags = 5; + DiffSymbolFlags flags = 5; DiffSymbolKind kind = 10; // The symbol index in the _other_ object that this symbol was diffed against optional uint32 target_symbol = 6; @@ -57,14 +57,15 @@ enum DiffSymbolKind { SYMBOL_SECTION = 3; } -// Symbol visibility flags (bitmask) -enum DiffSymbolFlag { - SYMBOL_NONE = 0; - SYMBOL_GLOBAL = 1; - SYMBOL_LOCAL = 2; - SYMBOL_WEAK = 4; - SYMBOL_COMMON = 8; - SYMBOL_HIDDEN = 16; +// Symbol flags +message DiffSymbolFlags { + bool global = 1; + bool local = 2; + bool weak = 3; + bool common = 4; + bool hidden = 5; + bool ignored = 6; + bool size_inferred = 7; } // A single instruction diff row diff --git a/objdiff-core/protos/proto_descriptor.bin b/objdiff-core/protos/proto_descriptor.bin index 1436db89077261454027119157adbf85bae4562b..ce62f84c09b40b29ccf7d12b8f30f0c1c5f52cce 100644 GIT binary patch delta 3372 zcmYjTNpBoQ7@exF?&+zXiQ}^48Mn7~$ZjxZ7lJHaAhwZ`$XJ#!OETCKV`6(E+n8Wk z86+SeAvr*Y1Q0<15tQTrLcVZ70>Pa>fP^@6;KY#w@2jQ5oci^v_v+iKrte&4mp){k z{PXzt-V2=lou1*F#fPMScCk9YTJaN>{>j>+XWv+QxxV-`z1#kaA7_nUm~0wZID7Vg zgldz){9^s(>SBc@>_9kSk!qFxVtp2`xqfYcQc}ELtDdWP`lWs*huQklQhm81jDtb+ z{*{Hfx!N)XM9xncs46nQFuz=1sm)aa%{Zv;k)_pzjoRsj<+HUF;`5p>(#tXXZhJs{ z7Nld*X5qX0WnTHY+@0;;qM!V}PFa+`@VE$+caS$b#DG-UArC0-*#4pUE8d7D7ea|A zb0aL?k(i<+x`YxxPY6h#49hZ-LI|Ey-eIn^4}ec7a0m+z=SvP@kHb5gtqjx=8;sx# zvLjB`;Ec$8(drmemcx}(X;0FGr*dXOET0hom;lsA~^1ayO$j><5Y=>&Ed%w$+N#9M46zDBMnK4e4r9gc%+s9D)4(V=1f zXuIVC=!UcH0_cYGt&W3kxLlEa=#{U;@!T`%wO#ugWPUu1wVh9`8RfUC^j;e!t~7T*fmO z4wvz$*Ku$e-+jm-gff0#zq}WT1xlRAJ)eHqcA!DopRh9*P+}+fF0BASnNIT1AuK#u zFarV(ZYNt>bw~jvcFHyr0J2k=j7IKM!Hg<6$WEb|eW*vkkqMhfA2078z%x`6nTi}I z3TF7hK{c_fO&-!JfXVcO^1dSh_mKUh%^nEZPe$D~UYfqio;?ncYX1TGptgW)D*dP2 z4+|VfZz{8(qdXOv&Vqx*RO~Eh5T{^qP+K6}>GVuxFD!gmOlKA}l+%&94Zy)-T6Nhd zd{|5;y|Q0hV6U0<*UBMS1hAONENDJwG7IX^OlA?lVg?qyXk%W9mvRefUwc=79*bTI zJFt%s`7o!%Y5t0*cLf4>IxNb^iK7-*)Aja82Jnb|s=`bz5SCRV(_kR%Q$>TjwFuN~ z`g?oa$a9+1Sz(SD5HU?=Vt^o;t+dOs7NNa0(G$yLaAp3rrP}hE+lj`sCfZDR`gW<6 z&FJTKuWMc1x>0#*{Jbc~dy{8t=c_B#wRA1sJ&M-|d|sHz1VRk+c36N&gJF>5thEY8;qRP|@O*%<%FsiE-xerkll)svLld-rx8BEtZI{OP)x{Aw% znpdFat?`Cw9uT;-Fp_(Tqp;W0pF4U7@QB^kZS#PzY~79w5O!Nf*!#5z)P=OU^B#yO z#0!~-Lc9=}+Y}r`7uw2tObT>1H`2MzM;ds9Xd@F*6*jV+s6!jrsa@{`uqj&NVlq*q z|MInk`m!lbLAPwvwhRa+n*}pOK%~Q6O(&~BH`+zf5qBm-E7j%Mw9?h_0A3=7i&+eG zFfT@CfWSe1u|3wcl`43P<=#u@x_TRuDe)EyX_*ibwG(eM+)^d{X#?SM2Mis=+P4|* zDa(2UaZwp5$afeoTM|Vi=%lD3Am-0VQAR)vV8dv+5|=!s2A%ZauKQEea3T_(|5Y}v_x3=J`1~L9c7593|r}s z-RFk!h>wvihHHm50K^7c46U^gx-F(U9mED(tS6BVN$ztMe8h5}rmyz&w4J@2Hj@|gmFBOu<%z<36E39`T$ zi7gV6lR$?h0s;ykAP-29U-Fhu;59#yf5^F2)eU}{)Aycp*Q)ZZJM7P&nJsS&{AHiv z>|Hp+uU6JdXQ?oIezm~~*uEXxNqdlO*Ezo>%A2yXKfkmzv9UZ?Dh$BIuae%x^k{Ex zKnHC?g`f{VAxv{kS!Kb0& z{{GWr>2zoK*1MYgyGvI1j%B^sKAif;IZz{0(h)Wnj&JYhZiE<6vNA$8P_@6^;{UoLjzq zg8L*+0HzasM}#;~y4pCxbduK^6H};M6+w8O^dm`tQ(V;oNs4xgtLzDpt=cz|D5X1& zZNsrUj%~xSJB}@UyC;q<;Ml_{^eM_&z_TZgjn4J*I+K(|Nyk_+LB z0qcu!rG9Uj?v%J9cs@*@=H_+r%h zCM;z3m8tqsH>0#2Dr`(Q22;1trZKZ%KyVyOVzW^+5Y)zMY7GshoE{NO476NKqaDa4 z)v}Ncv>XO@0BuCGecKu5nQUuVYRH5K8&Zd80KPpQvuQ8JlWOtEAMEkEdfBPi02ATG zhCL@8ZlenmrVBvm!i3jqGNp}~XzPd&vG(qhpDGE^Cc}3PU68=A?a5d|Kw{F<6NU{E zli5f@Kw=US`;`RJoeGaN?uLW|iK$q^A&XaS;!>NZ{FVqoVk&5tT}lG6ro-PGJIfAF zKw>(UNI+sbmPkNiI+jR4Vj2?d7-zy4XRYs8wl3%?2KnOZ+RFO;TE0{aF3qm2spBk& zeAaD3d?6C9<%@ItysfeUg6*7}lJavh(hkgoYcU79Z~EFN4gE-sgf`T2-T`#mT0^_1YW6mwPT03skQ#au(9%qS%+#e!(d z%HU+r%K7!>#Ud)8ol9`q?gddFA!saQ^ofBD8VfD0YOVXK2ZU$3$Cw9tDt@qcs)uRH8lljaK3n6rv*DA6wJl~fm=xG zu~(c?T`JVp$rjXBLEBv9wb^vgJG;6VlvJyN;r>X8PEIjaq9zrS>hdHiaxLNl+l^dZ zU#wW=aJ0F-%Z1Yl?j@S5OLJZ2Kj^sv!M5sppuk3DtcQ=A+YjL<;;fso0>N$FY#9*Z ztRvyQiUiZ;@W19=AW?FcV-h8I+0#!EY#?2(&!`1*=~!=s-7QDU_zBWROrrWX;z%^5 z4Mb{GkpQlUnrtfgYOzq7pQZKHZE@8Iub2@6LF9^g=zxfar-BZnOPArMXv#JRy(_cD z`S5gO(SZ#v1<1`h<8;oa+5lti*QPD*}?4zcljeuClvgYE^zR7r# zv7(m*BQBZ=n5>Vi;ND~?MN@%pF+8tY7>9shMFc^;#oWpWDreP1E~KBh&A9bbINR1y zBjI?PxvjEh1lVG2fjo@=L~K8C zhglE9fuO65S&BQ%q1Qn;HtFAGJWVV@FamlJL^tlTN;(hZ3u9;sB&4CLh#-7JhKjT= z(645EFcK9I^D3)2*jHdZFqo0+z4y+PA)p#A8R2{Hy)T+@-wYQfPt(*% zphFKBZ!p#1JrECC-xomtpgmwXLUf;de&P|co`t`(HCbm7mNog91!XN zRFfBg@O{Cm_2L6U^95^dQ+1>$;LE55K%fHZ762-%X#pUpFR2Cc2K(C|T0f7prPa+_wuUS&}4v?I;|K0Vr<9`X=JA(iK diff --git a/objdiff-core/src/bindings/diff.rs b/objdiff-core/src/bindings/diff.rs index a0d2b65..0dd22b6 100644 --- a/objdiff-core/src/bindings/diff.rs +++ b/objdiff-core/src/bindings/diff.rs @@ -43,9 +43,6 @@ impl DiffObject { let mut symbols = Vec::with_capacity(obj.symbols.len()); for (symbol_idx, symbol) in obj.symbols.iter().enumerate() { let symbol_diff = &diff.symbols[symbol_idx]; - if symbol.size == 0 || symbol.flags.contains(SymbolFlag::Ignored) { - continue; - } symbols.push(DiffSymbol::new(obj, symbol_idx, symbol, symbol_diff, diff_config)?); } @@ -133,24 +130,16 @@ impl From for DiffSymbolKind { } } -fn symbol_flags(flags: &obj::SymbolFlagSet) -> u32 { - let mut result = 0u32; - if flags.contains(SymbolFlag::Global) { - result |= DiffSymbolFlag::SymbolGlobal as u32; - } - if flags.contains(SymbolFlag::Local) { - result |= DiffSymbolFlag::SymbolLocal as u32; - } - if flags.contains(SymbolFlag::Weak) { - result |= DiffSymbolFlag::SymbolWeak as u32; - } - if flags.contains(SymbolFlag::Common) { - result |= DiffSymbolFlag::SymbolCommon as u32; - } - if flags.contains(SymbolFlag::Hidden) { - result |= DiffSymbolFlag::SymbolHidden as u32; - } - result +fn symbol_flags(flags: &obj::SymbolFlagSet) -> Option { + Some(DiffSymbolFlags { + global: flags.contains(SymbolFlag::Global), + local: flags.contains(SymbolFlag::Local), + weak: flags.contains(SymbolFlag::Weak), + common: flags.contains(SymbolFlag::Common), + hidden: flags.contains(SymbolFlag::Hidden), + ignored: flags.contains(SymbolFlag::Ignored), + size_inferred: flags.contains(SymbolFlag::SizeInferred), + }) } impl DiffInstructionRow {