Author Topic: Help with Ghidra Memory Mapping / Relocation for a MIPS COFF VxWorks Module  (Read 12069 times)

0 Members and 2 Guests are viewing this topic.

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
Help with Ghidra Memory Mapping / Relocation for a MIPS COFF VxWorks Module (Tektronix Firmware)

Hi everyone,
I'm reverse engineering a Window Manager module (dtwm) from a Tektronix X11-terminal firmware.
The file is in "MIPS Big Endian COFF format" - yep it's neither a modern ELF nor a ECOFF, it's a relocatable object file, likely loaded at runtime by VxWorks via loadModule().

I am tracking down a mismatch between how strings are referenced in the assembly versus where they actually lie in the binary file structure.

I'm importing the file into Ghidra as a "Raw Binary" (because Ghidra does not recognize the file format), but I'm hitting a wall with the memory map alignment.

File Structure (Extracted from COFF Section Headers)
Parsing the raw COFF header, the section layout is reported as follows:

Code: [Select]
Nome     | address    | size       | File Off
---------------------------------------------------------
.text    | 0x00000000 | 0x0028C588 | 0x00000168
.rdata   | 0x0028C588 | 0x00027270 | 0x0028C6F0
.data    | 0x002B37F8 | 0x0002C780 | 0x002B3960
.sdata   | 0x002DFF78 | 0x00000000 | 0x00000000  <--- empty
.lit8    | 0x002DFF78 | 0x00000000 | 0x00000000  <--- empty
.sbss    | 0x002DFF78 | 0x00000000 | 0x00000000  <--- empty
.bss     | 0x002DFF78 | 0x0002F598 | n.a.

Entry Point:   0x00023428

Code: [Select]
00000000   60 01 00 07  00 00 00 00  00 47 9F 94  00 00 01 13  00 38 00 06  01 0B 00 D6  00 28 C5 88  00 05 39 F0  `........G.......8.......(....9.
00000020   00 02 F5 98  00 02 34 28  00 00 00 00  00 28 C5 88  00 2D FF 78  00 01 AC AA  00 00 00 00  00 00 09 92  ......4(.....(...-.x............
00000040   00 00 2D 31  00 00 00 00  00 00 00 00  2E 74 65 78  74 00 00 00  00 00 00 00  00 00 00 00  00 28 C5 88  ..-1.........text............(..
00000060   00 00 01 68  00 30 F6 78  00 47 9F 94  AC AA 00 00  00 00 00 20  2E 72 64 61  74 61 00 00  00 28 C5 88  ...h.0.x.G......... .rdata...(..
00000080   00 28 C5 88  00 02 72 70  00 28 C6 F0  00 45 0E 70  00 00 00 00  09 92 00 00  00 00 01 00  2E 64 61 74  .(....rp.(...E.p.............dat
000000A0   61 00 00 00  00 2B 37 F8  00 2B 37 F8  00 02 C7 80  00 2B 39 60  00 45 81 48  00 00 00 00  2D 31 00 00  a....+7..+7......+9`.E.H....-1..
000000C0   00 00 00 40  2E 73 64 61  74 61 00 00  00 2D FF 78  00 2D FF 78  00 00 00 00  00 00 00 00  00 00 00 00  [email protected]............
000000E0   00 00 00 00  00 00 00 00  00 00 02 00  2E 6C 69 74  38 00 00 00  00 2D FF 78  00 2D FF 78  00 00 00 00  .............lit8....-.x.-.x....
00000100   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  08 00 00 00  2E 73 62 73  73 00 00 00  00 2D FF 78  .....................sbss....-.x
00000120   00 2D FF 78  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 04 00  2E 62 73 73  .-.x.........................bss
00000140   00 00 00 00  00 2D FF 78  00 2D FF 78  00 02 F5 98  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  .....-.x.-.x....................
00000160   00 00 00 80  00 00 00 00  27 BD FF E0  AF BF 00 18  AF B1 00 14  AF B0 00 10  00 80 88 21  8E 25 00 28  ........'..................!.%.(
00000180   00 00 00 00  10 A0 00 16  00 00 00 00  8E 22 00 3C  00 00 00 00  8C 42 04 28  00 00 00 00  14 A2 00 07  .............".<.....B.(........
000001A0   00 00 00 00  3C 04 00 00  8C 84 00 60  0C 00 00 00  00 00 00 00  08 00 00 1E  00 00 00 00  3C 10 00 00  ....<......`................<...
000001C0   26 10 00 60  8E 04 00 00  0C 09 6D 56  00 00 00 00  8E 04 00 00  8E 25 00 28  0C 00 00 00  00 00 00 00  &..`......mV.........%.(........
000001E0   8E 22 00 3C  00 00 00 00  8C 45 04 28  00 00 00 00  10 A0 00 09  00 00 00 00  8E 22 00 28  00 00 00 00  .".<.....E.(.............".(....
00000200   10 45 00 05  00 00 00 00  3C 04 00 00  8C 84 00 60  0C 00 00 00  00 00 00 00  8E 23 00 3C  8E 22 00 28  .E......<......`.........#.<.".(
(hexedit ... )

The Assembly Discrepancy
Inside the .text section, a string pointer is being passed to a printf-like function (FUN_00000000) using raw, absolute-looking values, completely bypassing any $gp (Global Pointer) indirect referencing:

MIPS Assembler
Code: [Select]
0002347c 8c 44 00 cc:    lw        a0, 0xcc(v0)
00023480 3c 05 00 00:    lui       a1, 0x0
00023484 24 a5 13 50:    addiu     a1, a1, 0x1350 <------- WTF??!? 0x00001350 doesn not point to .rdata!!!!
00023488 0c 00 00 00:    jal       FUN_00000000 <------- this "should be" a kind of "printf()" or something ...
0002348c 00 00 00 00:    nop

According to this raw, un-relocated assembly on disk, the code expects the target string to be at RAM address 0x00001350

The Conflict
However, by checking the file with a hex editor / strings -t x, the target string actually resides at physical File Offset 0x0028D520.

If we calculate the relative offset of the string inside the .rdata section:
Code: [Select]
.text{Offset inside .rdata} = 0x0028D520 - 0x0028C6F0 = 0x000E30
If .rdata were to be mapped in RAM starting at 0x00000520 (or if we account for typical 32-byte alignment/padding of literal pools), the string would land exactly at 0x00001350, matching the addiu offset perfectly.

So, W____T____F____?  :o :o :o :o :o

The Question:
Since VxWorks normally handles relocations at runtime via its dynamic loader (patching the lui placeholders), Ghidra's raw import leaves the lui at 0x0.
If I try to map .rdata to start at 0x00000000 in Ghidra to satisfy the addiu constraint, Ghidra obviously rejects it due to a memory block conflict with .text (which spans from 0x0 up to 0x0028C588).

What is the best workflow in Ghidra to properly map these old MIPS COFF relocatable modules so that local internal code references (jal to local functions) and text/literal references (0x1350) both resolve correctly without clipping each other?

Is there a known loader extension or an elegant scripting trick to apply these static COFF relocations?

Thanks in advance!  :D
« Last Edit: May 23, 2026, 08:34:34 pm by DiTBho »
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 5745
  • Country: Earth
The missing loader extension is located between the keyboard and the chair.  ;D
 

Offline abeyer

  • Frequent Contributor
  • **
  • Posts: 955
  • Country: us
There should be a relocation table for your .text section (referenced from s_relptr and s_nreloc fields in the section header) with entries that each contain an offset into the .text section, an offset into the symbol table, and a type that tells the loader how to combine them to do the relocation.

gnu binutils can handle them (easiest if you can get something like the debian -multiarch build, that has all targets/architectures compiled in... otherwise you may have to mess around with building against one architecture on another, which I recall being painful last time I had to do it.) If you ask for both relocation and disassembly from objdump, it will annotate the relocations inline with the instructions. You'll likely see a REFHI and REFLO relocation on the lui and addiu instructions in your example.

The easiest fix is likely to do a loader script that walks that table and patches the bytes in .text as it's loaded. If you don't care about proper support for everything, that simplifies it, as you can scan the relocation types used in your binary and just support those specific ones rather than all the possibilities. The logic for them all can be found in binutil's bfd definitions in https://git.sr.ht/~sourceware/binutils-gdb/tree/master/item/bfd/coff-mips.c
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
There should be a relocation table for your .text section (referenced from s_relptr and s_nreloc fields in the section header) with entries that each contain an offset into the .text section, an offset into the symbol table, and a type that tells the loader how to combine them to do the relocation.

gnu binutils can handle them (easiest if you can get something like the debian -multiarch build, that has all targets/architectures compiled in... otherwise you may have to mess around with building against one architecture on another, which I recall being painful last time I had to do it.) If you ask for both relocation and disassembly from objdump, it will annotate the relocations inline with the instructions. You'll likely see a REFHI and REFLO relocation on the lui and addiu instructions in your example.

The easiest fix is likely to do a loader script that walks that table and patches the bytes in .text as it's loaded. If you don't care about proper support for everything, that simplifies it, as you can scan the relocation types used in your binary and just support those specific ones rather than all the possibilities. The logic for them all can be found in binutil's bfd definitions in https://git.sr.ht/~sourceware/binutils-gdb/tree/master/item/bfd/coff-mips.c

thanks!
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
can't find any binutils supporting "MIPS-COFF"!
binutils v2.7 (1998) and binutils v2.12 (2003) only support "MIPS-eCOFF"

Code: [Select]
my_hack/Ghidra/tekxpress-v8.1 # mips-sony-bsd-objdump -r guineapig/dtwm
mips-sony-bsd-objdump: guineapig/dtwm: File format not recognized

"eCOFF" is not the same as "COFF"  :-// :-// :-//


The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline gerbay

  • Regular Contributor
  • *
  • Posts: 90
  • Country: tr
Can you share the file?
 

Offline abeyer

  • Frequent Contributor
  • **
  • Posts: 955
  • Country: us
Code: [Select]
my_hack/Ghidra/tekxpress-v8.1 # mips-sony-bsd-objdump -r guineapig/dtwm
mips-sony-bsd-objdump: guineapig/dtwm: File format not recognized

"eCOFF" is not the same as "COFF"  :-// :-// :-//

From what I've seen "ecoff" is actually a bunch of things, as there seemed to be a few conflicting definitions of some of the core stuff, and every architecture and os added its own implementation specific definitions within fields/sections/tables, sometimes in incompatible or conflicting ways. That quote looks like you're using a build that's expecting a bsd ecoff which isn't what all/most mips code is likely to be. Also, I vaguely suspect that all mips coffs are actually ecoff in some sense... could be wrong there, but not sure I've ever seen a truly correct pure coff file for mips. Regardless, the changes to ecoff are largely around the symbol table: you should be able to use the same process described above regardless of the content of the symbol table, tho, as the relocations table references and entries themselves are the same. In a lot mips code I've seen, since the relocations are also usually combined with existing immediate value offsets, the relocation symbol references commonly all point at the beginning of a section anyway. So in that case you can potentially just ignore the symbol table altogether while doing relocation and just use the base addresses of each section, and the coff vs ecoff question becomes moot.

Did you try a multiarch build of binutils with all the targets and architectures enabled, as I suggested? I'd do that before assuming it won't work.

Also, either the binary itself as mentioned, or at least what a modern version of `file` says about it, would be interesting to see.
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
That quote looks like you're using a build that's expecting a bsd ecoff

That one yes, it's eCOFF, but this one is "COFF"

Code: [Select]
00000000  60 01 00 07 00 00 00 00  00 08 46 d0 00 00 00 b4  |`.........F.....|
00000010  00 38 00 06 01 0b 00 d6  00 04 be a8 00 00 c6 50  |.8.............P|
00000020  00 00 24 00 00 01 12 e0  00 00 00 00 00 04 be a8  |..$.............|
00000030  00 05 84 f8 00 00 32 a3  00 00 00 00 00 00 01 0f  |......2.........|
00000040  00 00 04 02 00 00 00 00  00 00 00 00 2e 74 65 78  |.............tex|
00000050  74 00 00 00 00 00 00 00  00 00 00 00 00 04 be a8  |t...............|
00000060  00 00 01 68 00 05 aa 60  00 00 00 00 32 a3 00 00  |...h...`....2...|
00000070  00 00 00 20 2e 72 64 61  74 61 00 00 00 04 be a8  |... .rdata......|
00000080  00 04 be a8 00 00 9c 30  00 04 c0 10 00 08 0a 04  |.......0........|
00000090  00 00 00 00 01 0f 00 00  00 00 01 00 2e 64 61 74  |.............dat|
000000a0  61 00 00 00 00 05 5a d8  00 05 5a d8 00 00 2a 20  |a.....Z...Z...* |
000000b0  00 05 5c 40 00 08 16 b8  00 00 00 00 04 02 00 00  |..\@............|
000000c0  00 00 00 40 2e 73 64 61  74 61 00 00 00 05 84 f8  |[email protected]......|
000000d0  00 05 84 f8 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000000e0  00 00 00 00 00 00 00 00  00 00 02 00 2e 6c 69 74  |.............lit|
000000f0  38 00 00 00 00 05 84 f8  00 05 84 f8 00 00 00 00  |8...............|
00000100  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000110  08 00 00 00 2e 73 62 73  73 00 00 00 00 05 84 f8  |.....sbss.......|
00000120  00 05 84 f8 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000130  00 00 00 00 00 00 00 00  00 00 04 00 2e 62 73 73  |.............bss|
00000140  00 00 00 00 00 05 84 f8  00 05 84 f8 00 00 24 00  |..............$.|
00000150  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000160  00 00 00 80 00 00 00 00  27 bd ff d0 af bf 00 28  |........'......(|
00000170  af b1 00 24 af b0 00 20  00 80 80 21 08 00 00 0d  |...$... ...!....|
00000180  00 a0 88 21 00 05 2e 00  0c 00 00 00 00 05 2e 03  |...!............|
00000190  14 40 00 07 02 00 10 21  26 10 00 01 82 02 00 00  |.@.....!&.......|
000001a0  92 05 00 00 14 40 ff f7  02 20 20 21 00 00 10 21  |.....@...  !...!|
000001b0  8f bf 00 28 8f b1 00 24  8f b0 00 20 03 e0 00 08  |...(...$... ....|
000001c0  27 bd 00 30 27 bd ff e0  af bf 00 1c af b2 00 18  |'..0'...........|
000001d0  af b1 00 14 af b0 00 10  00 80 80 21 16 00 00 0b  |...........!....|
000001e0  00 a0 90 21 3c 02 00 00  8c 42 00 f8 00 00 00 00  |...!<....B......|
000001f0  14 40 00 06 00 40 80 21  24 02 00 16 3c 01 00 00  |.@...@.!$...<...|
00000200  ac 22 00 00 08 00 00 43  00 00 10 21 02 00 20 21  |.".....C...!.. !|

Code: [Select]
macmini2 devchain-baremetal-2022-2025/mybuilder-2025 # ./mybuild binutils mipsecoff
building mipsecoff-binutils-2.12 ...
binutils/2.12, checking source ... ok
binutils/2.12, checking build ... touching ... success
binutils/2.12, machine=mips-ecoff
binutils/2.12, preparing myconfigure ... success
binutils/2.12, configuring#2 ... success
binutils/2.12, building() ... success
binutils/2.12, installing ... success
binary fixing(mips)  no file
mips-ecoff-binutils, checking binaries ... success

I am on a GNU/Linux Gentoo/x86-64bit mac-mini
Last year I wrote a toolchain builder able to build "mips-ecoff-binutils".
Unfortunately it cannot build any "mips-coff-binutils": not supported.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
what a modern version of `file` says about it, would be interesting to see.

Code: [Select]
# file guineapig/*
guineapig/olwm.coff: data
guineapig/mwm.ecoff: MIPSEB ECOFF executable (impure) not stripped - version 2.11
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
Can you share the file?

Sure, but I can only share the "demo" version.
Attached here, it's a MIPS-BE "coff" file for VxWorks v5.

* xpwm.zip (45.02 kB - downloaded 24 times.)
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
Code: [Select]
macmini2 # mips-ecoff-objdump -i
BFD header file version 2.12
ecoff-bigmips
 (header big endian, data big endian)
  mips
ecoff-littlemips
 (header little endian, data little endian)
  mips
srec
 (header endianness unknown, data endianness unknown)
  mips
symbolsrec
 (header endianness unknown, data endianness unknown)
  mips
tekhex
 (header endianness unknown, data endianness unknown)
  mips
binary
 (header endianness unknown, data endianness unknown)
  mips
ihex
 (header endianness unknown, data endianness unknown)
  mips

               ecoff-bigmips ecoff-littlemips srec symbolsrec tekhex binary
          mips ecoff-bigmips ecoff-littlemips srec symbolsrec tekhex binary

               ihex
          mips ihex

ok, this is the last built mips-ecoff-binutils, and what it supports.

Code: [Select]
my_hack/Ghidra # mips-ecoff-objdump -h guineapig/olwm.coff
mips-ecoff-objdump: cavia/olwm.coff: File format not recognized

Code: [Select]
my_hack/Ghidra # mips-ecoff-objdump -h guineapig/mwm.ecoff

guineapig/mwm.ecoff:     file format ecoff-bigmips

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00188e20  00000000  00000000  000000f0  2**4
                  CONTENTS, ALLOC, LOAD, RELOC, CODE
  1 .rdata        0002a850  00188e20  00188e20  00188f10  2**4
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
  2 .data         0000f0e0  001b3670  001b3670  001b3760  2**4
                  CONTENTS, ALLOC, LOAD, RELOC, DATA
  3 .bss          00007744  001c2750  001c2750  00000000  2**4
                  ALLOC

The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline abeyer

  • Frequent Contributor
  • **
  • Posts: 955
  • Country: us
Sure, but I can only share the "demo" version.
Attached here, it's a MIPS-BE "coff" file for VxWorks v5.

actually that looks different from what you showed of the other one you were looking at... and in fact doesn't seem valid at all.

The magic number in the first two bytes is byte swapped like it's little endian, and file in fact recognizes it as such, reporting it as what I interpret as a big endian mips executable stored in a little endian file ( :scared: ) :
Code: [Select]
xpwm.coff: MIPSEB-LE ECOFF executable not stripped - version -42.0

But looking at subsequent fields in the header, they do not appear to be byte swapped, and are somewhat valid coff in many place, but not quite (version 0.-42  or 0.214 !?) in others. If I manually flip the first two bytes, so its interpreted as a regular big endian file, objdump will succeed for some basic stuff:
Code: [Select]
~/tmp/tekxp$ objdump -h xpwm

xpwm:     file format ecoff-bigmips

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         000153f0  00000000  00000000  00000168  2**4
                  CONTENTS, ALLOC, LOAD, RELOC, CODE
  1 .rdata        00000cc8  000153f0  000153f0  00015558  2**4
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
  2 .data         00000bd8  000160b8  000160b8  00016220  2**4
                  CONTENTS, ALLOC, LOAD, RELOC, DATA
  3 .sdata        00000000  00016c90  00016c90  00000000  2**4
                  ALLOC, LOAD, DATA, SMALL_DATA
  4 .lit8         00000000  00016c90  00016c90  00000000  2**4
                  ALLOC, LOAD, READONLY, DATA, SMALL_DATA
  5 .sbss         00000000  00016c90  00016c90  00000000  2**4
                  ALLOC, SMALL_DATA
  6 .bss          000004b8  00016c90  00016c90  00000000  2**4
                  ALLOC


...but will still give up if you try to do anything with the symbol table, which it doesn't like.

Kinda looks to me like maybe a developer was making up their own thing that's vaguely coff-shaped, but perhaps vxworks specific, and not really following anyone else's standard.
 

Offline abeyer

  • Frequent Contributor
  • **
  • Posts: 955
  • Country: us
I poked a bit more at the binary you shared, and it seems to have a normal coff symbol table, but the relocation table is not typical for either coff nor mips ecoff that I've seen before. Normal coff has 10 byte entries, mips ecoff packs the fields into 8 bytes, that file has 12 bytes per entry.

They look like it could just be extending the type field which is typically a short to a long or possibly adding some flags to it... but how to interpret those extra bytes would be a bit of an exploratory thing you'd have to mess with.
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
Code: [Select]
00000000   01 60 00 07  00 00 00 00  00 01 F3 14  00 00 00 A1  00 38 00 06  01 0B 00 D6  00 01 53 F0  00 00 18 A0  00 00 04 B8  00 00 03 54  .`...............8........S............T
00000028   00 00 00 00  00 01 53 F0  00 01 6C 90  00 00 09 ED  00 00 00 00  00 00 00 50  00 00 00 76  00 00 00 00  00 00 00 00  2E 74 65 78  ......S...l............P...v.........tex
00000050   74 00 00 00  00 00 00 00  00 00 00 00  00 01 53 F0  00 00 01 68  00 01 72 B0  00 00 00 00  09 ED 00 00  00 00 00 20  2E 72 64 61  t.............S....h..r............ .rda
00000078   74 61 00 00  00 01 53 F0  00 01 53 F0  00 00 0C C8  00 01 55 58  00 01 E9 CC  00 00 00 00  00 50 00 00  00 00 01 00  2E 64 61 74  ta....S...S.......UX.........P.......dat
000000A0   61 00 00 00  00 01 60 B8  00 01 60 B8  00 00 0B D8  00 01 62 20  00 01 ED 8C  00 00 00 00  00 76 00 00  00 00 00 40  2E 73 64 61  a.....`...`.......b .........v.....[member=123300].[/member]sda
(xpwm.coff.hacked is "xpwm.coff" with the first two byte swapped, swap(byte0, byte1))


Code: [Select]
my_hack/Ghidra/guineapig # mips-ecoff-objdump -b ecoff-bigmips -m mips -x xpwm.coff.hacked

xpwm.coff.hacked:     file format ecoff-bigmips
xpwm.coff.hacked
architecture: mips:3000, flags 0x00000133:
HAS_RELOC, EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED
start address 0x00000354

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         000153f0  00000000  00000000  00000168  2**4
                  CONTENTS, ALLOC, LOAD, RELOC, CODE
  1 .rdata        00000cc8  000153f0  000153f0  00015558  2**4
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
  2 .data         00000bd8  000160b8  000160b8  00016220  2**4
                  CONTENTS, ALLOC, LOAD, RELOC, DATA
  3 .sdata        00000000  00016c90  00016c90  00000000  2**4
                  ALLOC, LOAD, DATA
  4 .lit8         00000000  00016c90  00016c90  00000000  2**4
                  ALLOC, LOAD, READONLY, DATA
  5 .sbss         00000000  00016c90  00016c90  00000000  2**4
                  ALLOC
  6 .bss          000004b8  00016c90  00016c90  00000000  2**4
                  ALLOC
mips-ecoff-objdump: xpwm.coff.hacked: Bad value

umm, progress ...  :-//
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
I'm wondering if any retired engineers who worked for Tektronix in the 1990s read this forum, and if so, if they can help me with the xterminals.

I also posted on the VCF forum, but couldn't find anyone  :-// :-// :-//
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline abeyer

  • Frequent Contributor
  • **
  • Posts: 955
  • Country: us
It might help if people understood the goal/question, too... so far here you shared one binary and output on a few others, but they didn't all seem to be the same format, and sounded like maybe none of them were the one you actually cared about but couldn't share.

Is this still part of your trying to get a browser to run locally but write its files to a remote system without nfs?
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
It might help if people understood the goal/question, too...

The purpose is perfectly explained in the first post of topic: understanding the the old VxWorks COFF binary format.

The first post reports a hexdump, which over time I discovered to be of a different format.
However, in the topic this matter has been clarified (see (1)), and an example of binary is provided

so far here you shared one binary and output on a few others, but they didn't all seem to be the same format

I shared an example of the old VxWorks COFF binary format.

and sounded like maybe none of them were the one you actually cared about but couldn't share.

I can't share any "commercial binaries," especially if they're covered by a legal license. Okay, so it's about 30 years old (1995-2026), probably expired, but...

So I shared a "demo" version, which is the same VxWorks COFF binary format I'm trying to figure out.

(1)
If anything, we've discovered that newer versions of the NCD firmware do not use the same binary format used by Tektronix.
  • Tektronix uses a custom VxWorks COFF format <------ my target
  • NCD uses a standard eCOFF format (the header was hexdumped in the first post)

Is this still part of your trying to get a browser to run locally but write its files to a remote system without nfs?

Here I am trying to reverse engineering the old VxWorks COFF binaries.

NFS-v2 is a different problem, and has nothing to deal with this topic.
I've written 90% of the code, which is ad-hoc, not generic, but still enough to boot the terminal via NFS-v2.
I've written a userspace server; there are still some things that don't work, but they're a good starting point.

The problem here is that I'm trying to solve a major problem: to use Ghidra and reconstruct what the various software modules do, so as to fix it.

The TFTP part used by Netscape for the primitive filesystems... I don't understand what it does, but it does the wrong things...
In any case, to fix the root of the problem, I need to get the "Netscape v4 sources" so I can rewrite parts.

The problem is that Tektronix uses a proprietary VxWorks COFF format on the firmware and applications (Netscape for Xpress), and, as I mentioned in the first post, VxWorks dynamically patches the binaries it needs to load.

So, if I can't get the relocation table, I can't set up Ghidra sessions to work on.
I get a jumble of things that, instead of helping me, complicate my life, and the Netscape binary is already quite complex and big (5Mbyte of binary!!!!)
Besides this, there are also modules I'd like to hack because they're broken, especially if they don't have licenses.
For example, My XP417 has an MPEG HW module and an AUDIO interface, but no license for the audio server.
Result? There's no audio, you can play an MPEG1 video... but it's silent.
« Last Edit: June 09, 2026, 10:12:54 pm by DiTBho »
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline abeyer

  • Frequent Contributor
  • **
  • Posts: 955
  • Country: us
If anything, we've discovered that newer versions of the NCD firmware do not use the same binary format used by Tektronix.
  • Tektronix uses a custom VxWorks COFF format <------ my target
  • NCD uses a standard eCOFF format (the header was hexdumped in the first post)

Ah, ok, that helps clarify the background about why we were seeing different formats.
 

Offline Renate

  • Super Contributor
  • ***
  • Posts: 1774
  • Country: de
    • Renate's Android Page
I've worked with Qualcomm xbl's (Android) which have lots of segments.
I just "flatten" them to a single contiguous image internally padded with zeroes where necessary.
Then you can analyze the single raw image using the correct offset.
(I don't use Ghidra much.)
Code: [Select]
C:\>hexcalc 168+153f0
0x15558

C:\>hexcalc 168+153f0+cc8
0x16220

C:\>hexcalc 168+153f0+cc8+bd8
0x16df8
So your 3 segments are already packed contiguously as they would be loaded into memory.

Take your coff and copy from 0x168 to 0x16df8 (size 0x16c90)
Then you have your memory image.
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
I've worked with Qualcomm xbl's (Android) which have lots of segments.
I just "flatten" them to a single contiguous image internally padded with zeroes where necessary.
Then you can analyze the single raw image using the correct offset.
(I don't use Ghidra much.)
Code: [Select]
C:\>hexcalc 168+153f0
0x15558

C:\>hexcalc 168+153f0+cc8
0x16220

C:\>hexcalc 168+153f0+cc8+bd8
0x16df8
So your 3 segments are already packed contiguously as they would be loaded into memory.

Take your coff and copy from 0x168 to 0x16df8 (size 0x16c90)
Then you have your memory image.

Read the first post of this topic, The Assembly Discrepancy (relocation table) IS the problem here!
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Renate

  • Super Contributor
  • ***
  • Posts: 1774
  • Country: de
    • Renate's Android Page
Ok, so where are the relocation entries then?
It can't indiscriminately modify every lui.
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
Ok, so where are the relocation entries then?

This is exactly what we need to understand about that format and/or the VxWorks loader (v5.5).

The eCOFF (not used by Tektronix, but used by NCD) there's a specific area containing symbols and addresses, which the VxWorks V5.5.3 loader uses to modify the binary at runtime.

This means I can write a C program that "emulates" what the loader does and then pass the modified binary to Ghidra, with all the references (function addresses, constant addresses, string addresses, etc.) in the correct place.

In the COFF format... I don't understand where they are, and they're necessary because all the function calls point to address zero, the same for strings, constant, etc, which is incorrect and a big problem for Ghidra because then the references are no longer returned, and it's a mess.

What I see with the eCOFF format is that the binary contains the "relocation table", which tells me at what address to modify the "numeric" field of the assembly instructions (e.g., load xxxx, jump_to_subroutine xxxx).

If I apply all those changes, what I get makes perfect sense to Ghidra.

Obviously, Ghidra does not directly understand the "eCOFF" format, so you need to import the binary as "raw," then create a custom "memory map" using all the information from (binutils) objdump, where you specify where each session begins, its size, and, in the case of "initialized" sessions, the offset toward the binary file.

I automated everything in a script, and with the NCD's "eCOFF" format there is no problem.
Indeed, at the moment I'm rebuilding the C sources for Navio, from its binary, a much simpler browser than Netscape... so great for training with Ghidra.

The problem is that damned Tektronix's "COFF" format... I am lost with it.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
I'm wondering if any retired engineers who worked for Tektronix in the 1990s read this forum, and if so, if they can help me with the xterminals.

I also posted on the VCF forum, but couldn't find anyone  :-// :-// :-//

I'm wondering if any retired engineers who worked for Tektronix in the 1990s read a forum, social, and if so, where in the internet.

There's a lot of missing information, and it seems like no one cares about these xterminals ...
... except for some "creepy dudes" on eBay asking 300-600-1000 euros for something that

                  "oh, it (the green led on the front) turns on ..."

that hasn't even been seriously tested  :palm: :palm: :palm:
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline abeyer

  • Frequent Contributor
  • **
  • Posts: 955
  • Country: us
and it seems like no one cares about these xterminals ...
... except for some "creepy dudes" on eBay asking 300-600-1000 euros

Sounds about right for ebay stuff that has no practical use but appeals to hobbyists/collectors with plenty of money to spend.
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
Sounds about right for ebay stuff that has no practical use but appeals to hobbyists/collectors with plenty of money to spend.

umm, sounds nobody buys.
I won't for sure for that crazy price.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

-->