//
// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
//  
//  SPDX-License-Identifier: BSD-2-Clause-Patent
//

  ENTRY &ram_start &ram_size

  ;If system is running then stop the execution so we can load symbols.
  break
  
  ;Reset all windows
  WINPAGE.RESET
  
  AREA.Reset
  AREA.Create SYMBOL 300. 100.
  AREA.View SYMBOL
  AREA.Select SYMBOL
  SYS.Option BE OFF
 
  ; Added based on suggestion from Lauterbach support.
  MMU.TABLEWALK ON
  MMU.ON

  GOSUB load_symbols &ram_start &ram_size

  ;Open some windows.
  WINPOS 83.125 29.063 48. 9. 0. 0. W003
  Register

  WINPOS 83.25 10. 48. 9. 0. 1. W002
  Var.Local
  
  END

find_system_table:
  ENTRY &mem_start &mem_size
  &mem_ptr=&mem_start+&mem_size
  RPT    
  (
    &mem_ptr=&mem_ptr-0x400000  // 4 MB
    &word1=Data.LONG(D:&mem_ptr)
    &word2=Data.LONG(D:&mem_ptr+0x04)
    IF &word1==0x20494249
    (
      IF &word2==0x54535953
      (
        &result=Data.LONG(D:&mem_ptr+0x08)
        RETURN &result
      )
    )
  )
  WHILE &mem_ptr>&mem_start
  &result=0
  RETURN &result

compare_guid:
  ENTRY &guid
  IF Data.LONG(D:&guid)==0x49152E77
  (
    IF Data.LONG(D:&guid+0x04)==0x47641ADA
    (
      IF Data.LONG(D:&guid+0x08)==0xFE7AA2B7
      (
        IF Data.LONG(D:&guid+0x0C)==0x8B5ED9FE
        (
          RETURN 0
        )
      )
    )
  )
  RETURN 1  

find_debug_info_table_header:
  ENTRY &system_table
  &config_table_entries=Data.LONG(D:&system_table+0x40)
  &config_table_pointer=Data.LONG(D:&system_table+0x44)
  RPT &config_table_entries
  (
    GOSUB compare_guid &config_table_pointer
    ENTRY &result
    IF &result==0
    (
      &result=Data.LONG(D:&config_table_pointer+0x10)
      RETURN &result
    )  
    &config_table_pointer=&config_table_pointer+0x14
  )
  RETURN 0;

valid_pe_header:
  ENTRY &header
  IF Data.BYTE(D:&header+0x00)==0x4D
  (
    IF Data.BYTE(D:&header+0x01)==0x5A
    (
      IF Data.BYTE(D:&header+0x80)==0x50
      (
        IF Data.BYTE(D:&header+0x81)==0x45
        (
          RETURN 1
        )
      )
    )
  )
  RETURN 0

get_file_string:
  ENTRY &stringOffset

  local &string
  
  &more_string=data.string(d:&stringOffset)

  if (string.len("&more_string")>=128.)
  (
    &string="&string"+"&more_string"
    &stringOffset=&stringOffset+string.len("&more_string")

    //Get remaining file string
    GOSUB get_file_string &stringOffset
    ENTRY &more_string
    &string="&string"+"&more_string"
  )
  else
  (
    &string="&string"+"&more_string"
    &more_string=""
  )
  RETURN &string
 
load_symbol_file:
  ENTRY &header &load_address
  GOSUB valid_pe_header &header
  ENTRY &result
 
  IF &result==1
  (
    &debugOffset=Data.LONG(D:&header+0x0128)
    &stringOffset=&header+&debugOffset+0x002C
    
    &stringOffset=&stringOffset+11.

    GOSUB get_file_string &stringOffset
    ENTRY &filestring
  
    &filestring="c:"+"&filestring"

    PRINT "&filestring 0x" &load_address
    Data.load.elf &filestring &load_address /nocode /noclear
  )
  RETURN

pe_headersize:
  ENTRY &header;
  RETURN Data.LONG(D:&header+0x00AC)

load_symbols:
  ENTRY &mem_start &mem_size
  GOSUB find_system_table &mem_start &mem_size
  ENTRY &system_table
  GOSUB find_debug_info_table_header &system_table
  ENTRY &debug_info_table_header
  &debug_info_table=Data.LONG(D:&debug_info_table_header+0x08)
  &debug_info_table_size=Data.LONG(D:&debug_info_table_header+0x04)
  &index=0
  RPT &debug_info_table_size
  (
    &debug_image_info=Data.LONG(D:&debug_info_table+&index)
    IF &debug_image_info==0
      RETURN        
    &loaded_image_protocol=Data.LONG(D:&debug_image_info+0x04);
    &image_base=Data.LONG(D:&loaded_image_protocol+0x20);
    GOSUB pe_headersize &image_base
    ENTRY &header_size
    &image_load_address=&image_base+&header_size
    GOSUB load_symbol_file &image_base &image_load_address
    &index=&index+0x4
  )
    
  RETURN
  