/*
 * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */


#ifdef __APPLE__
#include "decoder_machO.hpp"
#include "jvm.h"
#include "memory/allocation.inline.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/permitForbiddenFunctions.hpp"

#include <cxxabi.h>
#include <mach-o/loader.h>
#include <mach-o/nlist.h>


bool MachODecoder::demangle(const char* symbol, char *buf, int buflen) {
  int   status;
  char* result;
  size_t size = (size_t)buflen;
  // Don't pass buf to __cxa_demangle. In case of the 'buf' is too small,
  // __cxa_demangle will call system "realloc" for additional memory, which
  // may use different malloc/realloc mechanism that allocates 'buf'.
  if ((result = abi::__cxa_demangle(symbol, nullptr, nullptr, &status)) != nullptr) {
    jio_snprintf(buf, buflen, "%s", result);
    // call c library's free
    permit_forbidden_function::free(result);
    return true;
  }
  return false;
}

bool MachODecoder::decode(address addr, char *buf,
      int buflen, int *offset, const void *mach_base) {
  if (addr == (address)(intptr_t)-1) {
    // dladdr() in macOS12/Monterey returns success for -1, but that addr value
    // won't work in this function. Should have been handled by the caller.
    ShouldNotReachHere();
    return false;
  }
  struct symtab_command * symt = (struct symtab_command *)
    mach_find_command((struct mach_header_64 *)mach_base, LC_SYMTAB);
  if (symt == nullptr) {
    DEBUG_ONLY(tty->print_cr("no symtab in mach file at 0x%lx", p2i(mach_base)));
    return false;
  }
  uint32_t off = symt->symoff;          /* symbol table offset (within this mach file) */
  uint32_t nsyms = symt->nsyms;         /* number of symbol table entries */
  uint32_t stroff = symt->stroff;       /* string table offset */
  uint32_t strsize = symt->strsize;     /* string table size in bytes */

  // iterate through symbol table trying to match our offset

  uint32_t addr_relative = (uintptr_t) mach_base - (uintptr_t) addr; // offset we seek in the symtab
  void * symtab_addr = (void*) ((uintptr_t) mach_base + off);
  struct nlist_64 *cur_nlist = (struct nlist_64 *) symtab_addr;
  struct nlist_64 *last_nlist = cur_nlist;  // no size stored in an entry, so keep previously seen nlist

  int32_t found_strx = 0;
  int32_t found_symval = 0;

  for (uint32_t i=0; i < nsyms; i++) {
    uint32_t this_value = cur_nlist->n_value;

    if (addr_relative == this_value) {
      found_strx =  cur_nlist->n_un.n_strx;
      found_symval = this_value;
      break;
    } else if (addr_relative > this_value) {
      // gone past it, use previously seen nlist:
      found_strx = last_nlist->n_un.n_strx;
      found_symval = last_nlist->n_value;
      break;
    }
    last_nlist = cur_nlist;
    cur_nlist = cur_nlist + sizeof(struct nlist_64);
  }
  if (found_strx == 0) {
    return false;
  }
  // write the offset:
  *offset = addr_relative - found_symval;

  // lookup found_strx in the string table
  char * symname = mach_find_in_stringtable((char*) ((uintptr_t)mach_base + stroff), strsize, found_strx);
  if (symname) {
      strncpy(buf, symname, buflen);
      buf[buflen - 1] = '\0';
      return true;
  }
  DEBUG_ONLY(tty->print_cr("no string or null string found."));
  return false;
}

void* MachODecoder::mach_find_command(struct mach_header_64 * mach_base, uint32_t command_wanted) {
  // possibly verify it is a mach_header, use magic number.
  // commands begin immediately after the header.
  struct load_command *pos = (struct load_command *) mach_base + sizeof(struct mach_header_64);
  for (uint32_t i = 0; i < mach_base->ncmds; i++) {
    struct load_command *this_cmd = (struct load_command *) pos;
    if (this_cmd->cmd == command_wanted) {
       return pos;
    }
    int cmdsize = this_cmd->cmdsize;
    pos += cmdsize;
  }
  return nullptr;
}

char* MachODecoder::mach_find_in_stringtable(char *strtab, uint32_t tablesize, int strx_wanted) {

  if (strx_wanted == 0) {
    return nullptr;
  }
  char *strtab_end = strtab + tablesize;

  // find the first string, skip over the space char
  // (or the four zero bytes we see e.g. in libclient)
  if (*strtab == ' ') {
      strtab++;
      if (*strtab != 0) {
          DEBUG_ONLY(tty->print_cr("string table has leading space but no following zero."));
          return nullptr;
      }
      strtab++;
  } else {
      if ((uint32_t) *strtab != 0) {
          DEBUG_ONLY(tty->print_cr("string table without leading space or leading int of zero."));
          return nullptr;
      }
      strtab+=4;
  }
  // read the real strings starting at index 1
  int cur_strx = 1;
  while (strtab < strtab_end) {
    if (cur_strx == strx_wanted) {
        return strtab;
    }
    // find start of next string
    while (*strtab != 0) {
        strtab++;
    }
    strtab++; // skip the terminating zero
    cur_strx++;
  }
  DEBUG_ONLY(tty->print_cr("string number %d not found.", strx_wanted));
  return nullptr;
}


#endif


