16d528ed9Sopenharmony_ci// Copyright 2023 The Chromium Authors. All rights reserved.
26d528ed9Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
36d528ed9Sopenharmony_ci// found in the LICENSE file.
46d528ed9Sopenharmony_ci
56d528ed9Sopenharmony_ci#include <dlfcn.h>
66d528ed9Sopenharmony_ci#include <mach-o/dyld.h>
76d528ed9Sopenharmony_ci#include <stdlib.h>
86d528ed9Sopenharmony_ci#include <string.h>
96d528ed9Sopenharmony_ci
106d528ed9Sopenharmony_citypedef int (*entry_point)(int, char**);
116d528ed9Sopenharmony_ci
126d528ed9Sopenharmony_cistatic char kMainRelativePath[] = "/Frameworks/HelloMain.framework/HelloMain";
136d528ed9Sopenharmony_ci
146d528ed9Sopenharmony_cistatic char* GetHelloMainPath(void) {
156d528ed9Sopenharmony_ci  uint32_t buffer_size = 0;
166d528ed9Sopenharmony_ci  _NSGetExecutablePath(NULL, &buffer_size);
176d528ed9Sopenharmony_ci  if (buffer_size == 0)
186d528ed9Sopenharmony_ci    return NULL;
196d528ed9Sopenharmony_ci
206d528ed9Sopenharmony_ci  uint32_t suffix_len = sizeof(kMainRelativePath) + 1;
216d528ed9Sopenharmony_ci  if (buffer_size >= UINT32_MAX - suffix_len)
226d528ed9Sopenharmony_ci    return NULL;
236d528ed9Sopenharmony_ci
246d528ed9Sopenharmony_ci  char* buffer = malloc(suffix_len + buffer_size);
256d528ed9Sopenharmony_ci  if (!buffer)
266d528ed9Sopenharmony_ci    return NULL;
276d528ed9Sopenharmony_ci
286d528ed9Sopenharmony_ci  if (_NSGetExecutablePath(buffer, &buffer_size) != 0)
296d528ed9Sopenharmony_ci    return NULL;
306d528ed9Sopenharmony_ci
316d528ed9Sopenharmony_ci  char* last_sep = strrchr(buffer, '/');
326d528ed9Sopenharmony_ci  if (!last_sep)
336d528ed9Sopenharmony_ci    return NULL;
346d528ed9Sopenharmony_ci
356d528ed9Sopenharmony_ci  memcpy(last_sep, kMainRelativePath, suffix_len);
366d528ed9Sopenharmony_ci  return buffer;
376d528ed9Sopenharmony_ci}
386d528ed9Sopenharmony_ci
396d528ed9Sopenharmony_ciint main(int argc, char** argv) {
406d528ed9Sopenharmony_ci  char* hello_main_path = GetHelloMainPath();
416d528ed9Sopenharmony_ci  if (!hello_main_path)
426d528ed9Sopenharmony_ci    return 1;
436d528ed9Sopenharmony_ci
446d528ed9Sopenharmony_ci  void* hello_main_handle = dlopen(hello_main_path, RTLD_NOW);
456d528ed9Sopenharmony_ci  if (!hello_main_handle)
466d528ed9Sopenharmony_ci    return 1;
476d528ed9Sopenharmony_ci
486d528ed9Sopenharmony_ci  free(hello_main_path);
496d528ed9Sopenharmony_ci  hello_main_path = NULL;
506d528ed9Sopenharmony_ci
516d528ed9Sopenharmony_ci  entry_point hello_main_entry = dlsym(hello_main_handle, "hello_main");
526d528ed9Sopenharmony_ci  if (!hello_main_entry)
536d528ed9Sopenharmony_ci    return 1;
546d528ed9Sopenharmony_ci
556d528ed9Sopenharmony_ci  int retcode = hello_main_entry(argc, argv);
566d528ed9Sopenharmony_ci  if (retcode) {
576d528ed9Sopenharmony_ci    return retcode;
586d528ed9Sopenharmony_ci  }
596d528ed9Sopenharmony_ci
606d528ed9Sopenharmony_ci  if (!dlclose(hello_main_handle)) {
616d528ed9Sopenharmony_ci    return 1;
626d528ed9Sopenharmony_ci  }
636d528ed9Sopenharmony_ci
646d528ed9Sopenharmony_ci  return 0;
656d528ed9Sopenharmony_ci}
66