Skip to content

Failing to parse section headers of MIPS LE 32-bit ELF correctly on 64-bit PPC BE host #420

@sajattack

Description

@sajattack

Hello, I seem to have stumbled upon some endian-awareness issues, unless you think I'm somehow misusing the library.

I have this goblin program (simplified from my actual usecase for ease of troubleshooting)

use std::fs;
use goblin::elf32::{header::Header, section_header::SectionHeader, section_header::SHT_REL};

fn main() {
    let elf_bytes = fs::read("psp-cube-example").unwrap();
    let header = Header::parse(&elf_bytes).unwrap();

    let section_headers = SectionHeader::from_bytes(
        &elf_bytes[header.e_shoff as usize..],
        header.e_shnum as usize,
    );

    let reloc_count = section_headers.iter().filter(|sh| sh.sh_type == SHT_REL).count();
    println!("reloc_count: {}", reloc_count);
    println!("section_headers: {:?}", section_headers);
}

and I have this 32-bit MIPS2 LE ELF file (uploaded as zip because github is dumb)
psp-cube-example.zip

When I run this program on x86_64 Little Endian - I get the correct result.
goblin_repro_x86_64.txt

When I run this program on 64-bit PowerPC - I do not.
goblin_repro_ppc64.txt

I am using the default endian_fd feature of goblin.

Here is the output of readelf -S

paul@ps3:~/goblin-repro$ readelf -S psp-cube-example
There are 34 section headers, starting at offset 0x46d44:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000120 00af20 00  AX  0   0 16
  [ 2] .sceStub.text     PROGBITS        0000af20 00b040 0000b8 00   A  0   0  4
  [ 3] .lib.stub.top     PROGBITS        0000afd8 00b0f8 000004 00   A  0   0  4
  [ 4] .lib.stub         PROGBITS        0000afdc 00b0fc 000078 00   A  0   0  4
  [ 5] .lib.stub.btm     PROGBITS        0000b054 00b174 000004 00   A  0   0  4
  [ 6] .lib.ent.top      PROGBITS        0000b058 00b178 000004 00   A  0   0  4
  [ 7] .lib.ent          PROGBITS        0000b05c 00b17c 000010 00   A  0   0  1
  [ 8] .lib.ent.btm      PROGBITS        0000b06c 00b18c 000004 00   A  0   0  4
  [ 9] .eh_frame_hdr     PROGBITS        0000b070 00b190 0005cc 00   A  0   0  4
  [10] .eh_frame         PROGBITS        0000b63c 00b75c 0014d4 00   A  0   0  4
  [11] .rodata.sceR[...] PROGBITS        0000cb10 00cc30 000074 00   A  0   0  4
  [12] .rodata.sceM[...] PROGBITS        0000cb90 00ccb0 000040 00   A  0   0 16
  [13] .rodata.sceNid    PROGBITS        0000cbd0 00ccf0 00005c 00   A  0   0  4
  [14] .rodata           PROGBITS        0000cc30 00cd50 011e22 00 AMS  0   0 16
  [15] .data             PROGBITS        0001ea54 01eb74 000068 00  WA  0   0  4
  [16] .got              PROGBITS        0001eac0 01ebe0 000008 00 WAp  0   0 16
  [17] .gcc_except_table PROGBITS        0001eac8 01ebe8 000dd8 00   A  0   0  4
  [18] .bss              NOBITS          0001f8a0 01f9c0 1030a4 00  WA  0   0 16
  [19] .mdebug.abi32     PROGBITS        00000000 01f9c0 000000 00      0   0  1
  [20] .rel.text         REL             00000000 01f9c0 002f68 08   I 31   1  4
  [21] .pdr              PROGBITS        00000000 022928 0151a0 00      0   0  4
  [22] .rel.pdr          REL             00000000 037ac8 005468 08   I 31  21  4
  [23] .rel.rodata       REL             00000000 03cf30 000f78 08   I 31  14  4
  [24] .rel.rodata.[...] REL             00000000 03dea8 000028 08   I 31  12  4
  [25] .rel.lib.ent      REL             00000000 03ded0 000008 08   I 31   7  4
  [26] .rel.rodata.[...] REL             00000000 03ded8 000010 08   I 31  11  4
  [27] .rel.data         REL             00000000 03dee8 000048 08   I 31  15  4
  [28] .comment          PROGBITS        00000000 03df30 0000bf 01  MS  0   0  1
  [29] .rel.lib.stub     REL             00000000 03dff0 000090 08   I 31   4  4
  [30] .rel.sceStub.text REL             00000000 03e080 000170 08   I 31   2  4
  [31] .symtab           SYMTAB          00000000 03e1f0 002c20 10     33 504  4
  [32] .shstrtab         STRTAB          00000000 040e10 000197 00      0   0  1
  [33] .strtab           STRTAB          00000000 040fa7 005d9b 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), p (processor specific)

Let me know if there's any other details you need, I hope you may be able to reproduce using qemu-system-ppc64, but I have not explored it myself.

For extra background on what I'm actually doing, because it's kind of fun 😄
I'm trying to use rust-psp to compile a psp homebrew app on a ps3 running linux. And I hit this assertion in our psp executable repacker: https://github.com/overdrivenpotato/rust-psp/blob/bfaa487ea4881395cc64fdd82158745885222a29/cargo-psp/src/bin/prxgen.rs#L98

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions