fix case where return local without a type was converted to a parameter

This commit is contained in:
Nikita Smith
2026-01-20 14:47:01 -08:00
parent 0c4009c328
commit a51d3fb752
+43 -35
View File
@@ -3437,6 +3437,8 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params)
B32 defrange_target_is_param = 0;
U64 procedure_num = 0;
U64 procedure_base_voff = 0;
U64 regrel_idx = 0;
RDIM_Symbol *curr_proc_symbol = 0;
CV_RecRange *rec_ranges_first = sym->sym_ranges.ranges + sym_rec_range.min;
CV_RecRange *rec_ranges_opl = sym->sym_ranges.ranges + sym_rec_range.max;
typedef struct P2R_ScopeNode P2R_ScopeNode;
@@ -3675,17 +3677,17 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params)
// rjf: build procedure symbol
if(params->subset_flags & (RDIM_SubsetFlag_Procedures|RDIM_SubsetFlag_ProcedureNameMap))
{
RDIM_Symbol *procedure_symbol = rdim_symbol_chunk_list_push(arena, sym_procedures, sym_procedures_chunk_cap);
procedure_symbol->is_extern = (kind == CV_SymKind_GPROC32);
procedure_symbol->name = name;
procedure_symbol->link_name = link_name;
procedure_symbol->type = type;
procedure_symbol->container_symbol = container_symbol;
procedure_symbol->container_type = container_type;
procedure_symbol->root_scope = procedure_root_scope;
curr_proc_symbol = rdim_symbol_chunk_list_push(arena, sym_procedures, sym_procedures_chunk_cap);
curr_proc_symbol->is_extern = (kind == CV_SymKind_GPROC32);
curr_proc_symbol->name = name;
curr_proc_symbol->link_name = link_name;
curr_proc_symbol->type = type;
curr_proc_symbol->container_symbol = container_symbol;
curr_proc_symbol->container_type = container_type;
curr_proc_symbol->root_scope = procedure_root_scope;
if(procedure_root_scope != 0)
{
procedure_root_scope->symbol = procedure_symbol;
procedure_root_scope->symbol = curr_proc_symbol;
}
}
@@ -3701,10 +3703,14 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params)
// rjf: increment procedure counter
procedure_num += 1;
// reset S_REGREL32 index
regrel_idx = 0;
}break;
//- rjf: REGREL32
case CV_SymKind_REGREL32:
{
if(params->subset_flags & RDIM_SubsetFlag_Locals)
{
// TODO(rjf): apparently some of the information here may end up being
@@ -3728,7 +3734,26 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params)
U32 var_off = regrel32->reg_off;
// rjf: determine if this is a parameter
RDI_LocalKind local_kind = RDI_LocalKind_Variable;
RDI_LocalKind local_kind = regrel_idx < curr_proc_symbol->type->count ? RDI_LocalKind_Parameter : RDI_LocalKind_Variable;
// rjf: determine if we need an extra indirection to the value
B32 extra_indirection_to_value = 0;
if(type != 0)
{
switch(arch)
{
case RDI_Arch_X64:
{
extra_indirection_to_value = (local_kind == RDI_LocalKind_Parameter && (type->byte_size > 8 || !IsPow2OrZero(type->byte_size)));
}break;
}
}
// If the return local does not fit in a register MSVC does not assign it a type.
// So we infer the return type from the signature.
//
// rjf: redirect type, if 0, and if outside frame, to the return type of the
// containing procedure
{
B32 is_stack_reg = 0;
switch(arch)
@@ -3738,27 +3763,18 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params)
}
if(is_stack_reg)
{
U32 frame_size = 0xFFFFFFFF;
if(procedure_num != 0 && procedure_frameprocs[procedure_num-1] != 0 && procedure_num <= procedure_frameprocs_count)
{
CV_SymFrameproc *frameproc = procedure_frameprocs[procedure_num-1];
frame_size = frameproc->frame_size;
}
if(var_off > frame_size)
{
local_kind = RDI_LocalKind_Parameter;
}
}
}
// TODO(rjf): is this correct?
// rjf: redirect type, if 0, and if outside frame, to the return type of the
// containing procedure
if(local_kind == RDI_LocalKind_Parameter && regrel32->itype == 0 &&
if(var_off > frameproc->frame_size && regrel32->itype == 0 &&
top_scope_node->scope->symbol != 0 &&
top_scope_node->scope->symbol->type != 0)
{
type = top_scope_node->scope->symbol->type->direct_type;
extra_indirection_to_value = 1;
}
}
}
}
// rjf: build local
@@ -3769,18 +3785,7 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params)
local->type = type;
// rjf: add location info to local
if(type != 0)
{
// rjf: determine if we need an extra indirection to the value
B32 extra_indirection_to_value = 0;
switch(arch)
{
case RDI_Arch_X64:
{
extra_indirection_to_value = (local_kind == RDI_LocalKind_Parameter && (type->byte_size > 8 || !IsPow2OrZero(type->byte_size)));
}break;
}
// rjf: get raddbg register code
RDI_RegCode reg_code = p2r_rdi_reg_code_from_cv_reg_code(arch, cv_reg);
// TODO(rjf): real byte_size & byte_pos from cv_reg goes here
@@ -3793,6 +3798,9 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params)
RDIM_Rng1U64 voff_range = {0, max_U64};
rdim_local_push_location_case(arena, sym_scopes, local, loc2, voff_range);
}
}
regrel_idx += 1;
}break;
//- rjf: LTHREAD32/GTHREAD32