arch/mips_symbolization

MIPS architecture-specific rules for symbolization

MIPS Symbolic Operand Attributes

  1. %hi(symbol) / %lo(symbol)

  • Used to form full 32-bit addresses in non-PIC code.

  • Represents the high and low 16-bit parts of a symbol’s address.

  • Generates R_MIPS_HI16 and R_MIPS_LO16 relocations.

E.g.,

lui $t0, %hi(foo) # $t0 gets the upper 16 bits of foo lw $t1, %lo(foo)($t0) # Add the lower 16 bits of foo to $t0

# and load from the address.

  1. %got(symbol)

  • Used to access a symbol’s address through GOT.

  • The assembler emits an offset from $gp to the GOT entry for the symbol, which the dynamic linker resolves at runtime.

  • Generates an R_MIPS_GOT16 relocation.

E.g,

lw $t9, %got(foo)($gp) # Load address of foo via GOT

  1. %pcrel_hi(symbol) / %pcrel_lo(symbol)

  • Used in PIC to compute PC-relative addresses.

  • Generates R_MIPS_PCHI16 and R_MIPS_PCLO16 relocations.

E.g.,

lui $t0, %pcrel_hi(foo) lw $t1, %pcrel_lo(foo)($t0)

  1. %got_page(symbol) / %got_ofst(symbol)

  • Used in PIC to compute GOT-relative addresses more efficiently.

  • %got_page(symbol) gives the GOT entry page base and %got_ofst(symbol) gives the offset within that page.

  • Generates R_MIPS_GOT_PAGE and R_MIPS_GOT_OFST relocations.

E.g.,

lw $t0, %got_page(foo)($gp) # $t0 gets the GOT page base for foo addiu $t1, $t0, %got_ofst(foo) # Add the offset to get the address of foo

gp_relative_operand(src:address, index:operand_index, dest:address)

Instructions with an indirect operand with GP(Global Pointer)-relative address

got_reference_mips_global(Got_entry:address, Symbol:symbol)

MIPS-specific got_reference using MIPS_GOTSYM and MIPS_LOCAL_GOTNO

The main reason for this is to avoid potential issues in stratification. Some generic versions of got_reference rely on symbolic_expr, which can lead to cyclic negation or cyclic aggregation.

hi_load(ea:address, reg:register, upper:number)

hi_load_prop(reg_restore_ea:address, ea:address, reg:register, upper:number, type:symbol)

HI load propagation to recover hi_load value from stack or simple data-flow

split_load_candidate(ea_hi:address, ea_lo:address, dest:address, type:symbol)

split_load_point(ea:address, nextea:address, dest:address, type:symbol, point:number, why:symbol)

split_load_conflict(ea:address, nextea:address, dest:address, type:symbol, ea2:address, nextea2:address, dest2:address, type2:symbol)

split_load_total_points(ea:address, nextea:address, dest:address, type:symbol, points:number)

discarded_split_load(ea:address, nextea:address, dest:address, type:symbol, points:number)

split_load(ea:address, nextea:address, dest:address, type:symbol)

split_loadstore(ea:address, nextea:address, dest:address)

valid_address(EA:address)

WARNING: Predicate not present in compiled Datalog program (Dead Code)

symbol_type(Addr:address, Type:symbol)

WARNING: Predicate not present in compiled Datalog program (Dead Code)

base_addr_offset_operand_candidate(EA:address, NextEA:address, Index2:operand_index, Reg:register, Dest_addr:address, SymType:symbol, Got_entry:address, Offset:number, Type:symbol)

got_page / got_fst instructions pairs

EA: Instruction for got_page NextEA: Instruction for got_ofst Index2: Operand index for got_ofst Reg: Base register in NextEA Dest_addr: Target symbol address SymType: Type of target symbol (either “code” or “data”) Got_entry: GOT entry containing page base Offset: Raw offset in NextEA Index2 operand Type: Type of got_ofst instruction (either ADDIU or LoadStore)

base_addr_offset_operand(EA:address, NextEA:address, Index2:operand_index, Dest_addr:address, SymType:symbol, Type:symbol)

base_addr_offset_operand_point(EA:address, NextEA:address, Index2:operand_index, Points:number, Why:symbol)

base_addr_offset_operand_total_points(EA:address, NextEA:address, Index2:operand_index, Points:number)

base_addr_load(EA:address, NextEA:address, Reg:register, Reg2:register, Got_entry:address, BaseAddr:address)

mips_page_base_in_got(Got_entry:address)

match_symbol_dest_addr(Dest_addr:address)

WARNING: Predicate not present in compiled Datalog program (Dead Code)

symbolic_operand_mips_candidate(ea:address, index:operand_index, dest:address)

inferred_symbol_mips(EA:address, SymbolName:symbol, Scope:symbol, Visibility:symbol, Type:symbol, Pos:symbol_position)

MIPS-specific inferred_symbol:

The MIPS assembler requires any symbol referenced by a GOT-related relocation to be global; otherwise, assembly fails (e.g., with an error that local symbols cannot use %got).

However, in a fully linked shared object, symbols originally accessed via %got(sym) may appear as local in the ELF symbol table. This happens because the linker performs symbol binding reduction – localizing symbols that are not exported – even if they were originally global during assembly and relocation processing.

As a result, some GOT entries correspond to symbols that now appear local, and reassembling such code would fail because the assembler rejects %got references to local symbols.

This discrepancy arises from the difference between what the assembler allows and what the linker produces.

To resolve this issue, we create a new inferred symbol with GLOBAL binding and HIDDEN visibility for such cases. ——————————————————————————-

mips_stubs_section(name:symbol)

mips_stubs_entry(Block:address, Function:symbol)

plt_entry_candidate(EA:address, GotIndex:unsigned)

mips_attribute_target_to_mid_function(EA:address, Dest_addr:address, Attribute:symbol)

Some relocations may reference labels inside the body of a function, not just function entry points. Log any symbolic operands with attribute whose target lies in the middle of function.