/* plugin_section_reorder.c -- Simple plugin to reorder function sections

   Copyright 2011 Free Software Foundation, Inc.
   Written by Sriraman Tallam <tmsriram@google.com>.

   This file is part of gold.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program 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 for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "plugin-api.h"

static ld_plugin_get_input_section_count get_input_section_count = NULL;
static ld_plugin_get_input_section_type get_input_section_type = NULL;
static ld_plugin_get_input_section_name get_input_section_name = NULL;
static ld_plugin_get_input_section_contents get_input_section_contents = NULL;
static ld_plugin_update_section_order update_section_order = NULL;
static ld_plugin_allow_section_ordering allow_section_ordering = NULL;

enum ld_plugin_status onload(struct ld_plugin_tv *tv);
enum ld_plugin_status claim_file_hook(const struct ld_plugin_input_file *file,
                                      int *claimed);
enum ld_plugin_status all_symbols_read_hook(void);

/* Plugin entry point.  */
enum ld_plugin_status
onload(struct ld_plugin_tv *tv)
{
  struct ld_plugin_tv *entry;
  for (entry = tv; entry->tv_tag != LDPT_NULL; ++entry)
    {
      switch (entry->tv_tag)
        {
        case LDPT_REGISTER_CLAIM_FILE_HOOK:
          assert((*entry->tv_u.tv_register_claim_file) (claim_file_hook) == LDPS_OK);
          break;
	case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
          assert((*entry->tv_u.tv_register_all_symbols_read) (all_symbols_read_hook)
		  == LDPS_OK);
          break;
        case LDPT_GET_INPUT_SECTION_COUNT:
          get_input_section_count = *entry->tv_u.tv_get_input_section_count;
          break;
        case LDPT_GET_INPUT_SECTION_TYPE:
          get_input_section_type = *entry->tv_u.tv_get_input_section_type;
          break;
        case LDPT_GET_INPUT_SECTION_NAME:
          get_input_section_name = *entry->tv_u.tv_get_input_section_name;
          break;
        case LDPT_GET_INPUT_SECTION_CONTENTS:
          get_input_section_contents = *entry->tv_u.tv_get_input_section_contents;
          break;
	case LDPT_UPDATE_SECTION_ORDER:
	  update_section_order = *entry->tv_u.tv_update_section_order;
	  break;
	case LDPT_ALLOW_SECTION_ORDERING:
	  allow_section_ordering = *entry->tv_u.tv_allow_section_ordering;
	  break;
        default:
          break;
        }
    }

  if (get_input_section_count == NULL
      || get_input_section_type == NULL
      || get_input_section_name == NULL
      || get_input_section_contents == NULL
      || update_section_order == NULL
      || allow_section_ordering == NULL)
    {
      fprintf(stderr, "Some interfaces are missing\n");
      return LDPS_ERR;
    }

  return LDPS_OK;
}

inline static int is_prefix_of(const char *prefix, const char *str)
{
  return strncmp(prefix, str, strlen (prefix)) == 0;
}

struct ld_plugin_section section_list[3];
int num_entries = 0;

/* This function is called by the linker for every new object it encounters.  */
enum ld_plugin_status
claim_file_hook(const struct ld_plugin_input_file *file, int *claimed)
{
  static int is_ordering_specified = 0;
  struct ld_plugin_section section;
  unsigned int count = 0;
  unsigned int shndx;

  *claimed = 0;
  if (is_ordering_specified == 0)
    {
      /* Inform the linker to prepare for section reordering.  */
      (*allow_section_ordering)();
      is_ordering_specified = 1;
    }

  (*get_input_section_count)(file->handle, &count);

  for (shndx = 0; shndx < count; ++shndx)
    {
      char *name = NULL;
      int position = 3;

      section.handle = file->handle;
      section.shndx = shndx;
      (*get_input_section_name)(section, &name);

      /* Order is foo() followed by bar() followed by baz()  */
      if (is_prefix_of(".text.", name))
	{
	  if (strstr(name, "_Z3foov") != NULL)
	    position = 0;
	  else if (strstr(name, "_Z3barv") != NULL)
	    position = 1;
	  else if (strstr(name, "_Z3bazv") != NULL)
	    position = 2;
	  else
	    position = 3;
	}
      if (position < 3)
	{
	  section_list[position].handle = file->handle;
	  section_list[position].shndx = shndx;
	  num_entries++;
	}
    }
  return LDPS_OK;
}

/* This function is called by the linker after all the symbols have been read.
   At this stage, it is fine to tell the linker the desired function order.  */

enum ld_plugin_status
all_symbols_read_hook(void)
{
  if (num_entries == 3)
    update_section_order(section_list, num_entries);

  return LDPS_OK;
}

