Class: Omnizip::Filters::BcjPpc
- Inherits:
-
FilterBase
- Object
- FilterBase
- Omnizip::Filters::BcjPpc
- Defined in:
- lib/omnizip/filters/bcj_ppc.rb
Overview
BCJ filter for PowerPC executables.
This filter preprocesses PowerPC machine code by converting relative addresses in B/BL (Branch/Branch and Link) instructions to absolute addresses. PowerPC uses 4-byte aligned instructions with big-endian encoding.
The filter improves compression by making branch targets position-independent.
Constant Summary collapse
- OPCODE_BASE =
PPC B/BL instruction base (0x48000000)
0x48000000- OPCODE_MASK =
Mask for checking B/BL instructions
0xFC000003- OPCODE_PATTERN =
Expected pattern for B/BL with link bit (0x48000001)
0x48000001- INSTRUCTION_SIZE =
Size of PPC instruction (4 bytes, big-endian)
4- OFFSET_MASK =
Offset mask (26-bit offset in instruction)
0x03FFFFFC
Class Method Summary collapse
-
.metadata ⇒ Hash
Get metadata about this filter.
Instance Method Summary collapse
-
#decode(data, position = 0) ⇒ String
Decode (postprocess) PowerPC executable data after decompression.
-
#encode(data, position = 0) ⇒ String
Encode (preprocess) PowerPC executable data for compression.
Class Method Details
.metadata ⇒ Hash
Get metadata about this filter.
129 130 131 132 133 134 135 136 137 |
# File 'lib/omnizip/filters/bcj_ppc.rb', line 129 def { name: "BCJ-PPC", description: "Branch converter for PowerPC executables", architecture: "PowerPC", alignment: 4, endian: "big", } end |
Instance Method Details
#decode(data, position = 0) ⇒ String
Decode (postprocess) PowerPC executable data after decompression.
Reverses the encoding by converting absolute addresses back to relative addresses.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/omnizip/filters/bcj_ppc.rb', line 94 def decode(data, position = 0) return data.dup if data.bytesize < INSTRUCTION_SIZE result = data.b size = data.bytesize & ~(INSTRUCTION_SIZE - 1) i = 0 pc = position - INSTRUCTION_SIZE while i < size instruction = extract_uint32_be(result, i) pc += INSTRUCTION_SIZE # Check for B/BL instruction if (instruction & OPCODE_MASK) == OPCODE_PATTERN # Extract absolute address absolute = instruction & OFFSET_MASK # Convert to relative offset offset = absolute - pc # Encode back new_instruction = OPCODE_BASE | (offset & OFFSET_MASK) | 1 write_uint32_be(result, i, new_instruction) end i += INSTRUCTION_SIZE end result end |
#encode(data, position = 0) ⇒ String
Encode (preprocess) PowerPC executable data for compression.
Scans for B/BL instructions (0x48xxxxxx) and converts relative addresses to absolute addresses.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/omnizip/filters/bcj_ppc.rb', line 54 def encode(data, position = 0) return data.dup if data.bytesize < INSTRUCTION_SIZE result = data.b size = data.bytesize & ~(INSTRUCTION_SIZE - 1) i = 0 pc = position - INSTRUCTION_SIZE while i < size instruction = extract_uint32_be(result, i) pc += INSTRUCTION_SIZE # Check for B/BL instruction (0x48xxxxxx with proper flags) if (instruction & OPCODE_MASK) == OPCODE_PATTERN # Extract 24-bit offset (bits 6-29), sign-extend offset = instruction & OFFSET_MASK offset = sign_extend_26(offset) # Convert to absolute address absolute = offset + pc # Encode back new_instruction = OPCODE_BASE | (absolute & OFFSET_MASK) | 1 write_uint32_be(result, i, new_instruction) end i += INSTRUCTION_SIZE end result end |