global.h 6.35 KB
#ifndef _CORD_GLOBAL_H_
#define _CORD_GLOBAL_H_

#include <sys/inst.h>
#include <libelf.h>

#include "const.h"

/*==============================================================================
  definitions of global error functions
==============================================================================*/
extern void dump(...);
extern void note(...);
extern void warning(...);
extern void error(...);
extern void sysfatal(...);
extern void print_elf_error (void);

#ifndef NULL
#define NULL 0
#endif

#define ASSERT(EX) ((EX) ? ((void )0) : \
                error("%s:%d ASSERT(EX)", __FILE__, __LINE__))

/*==============================================================================
   global type definitions
==============================================================================*/
typedef union mips_instruction MIPS_Inst;
typedef enum{FALSE, TRUE}  Cord_Boolean;
typedef unsigned 	   Uint32;
typedef signed 	   	   Sint32;
typedef unsigned long long Uint64;
typedef Uint32		   Addr;
typedef unsigned short      Uint16;

typedef struct cord_proc{
    char 	*name;			/* procedure name */
    char	*file_name;		/* file name */
    Addr	begin;			/* starting address */
    Uint32	size;			/* size of procedure */
    Uint32	freq;			/* frequency (cycles or #samples) */
    struct cord_proc *prev;		/* previous procedure */
    struct cord_proc *next;		/* next procedure */
    Cord_Boolean	emitted;	/* the procedure has been emitted */
    Cord_Boolean	tied_to_next;	/* the procedure has to be tied to next */
} Proc;

typedef enum{PIC, CPIC, NON_SHARED}  Cord_exe_type;

#define SIZE_INST       4       /* size of instruction in bytes */

typedef struct {
	/* binary state */
    Cord_exe_type	type;
    enum{BIT64, BIT32}  bit;
    enum{ABI1, ABI2}	abi;
    enum{NONE, MDEBUG, DWARF}   debug_type;

    Proc        	*libstub;	/* libstub (pseudo) procedure */ 
	/* old binary */
    Elf			*elf;
    Addr		text_hi;
    Addr		text_lo;
    Addr		broad_text_hi;
    Addr		broad_text_lo;
    Addr		pixie_addrs_base; /* addrs base in pixie .Addrs file */
    Addr        	entry;          /* program entry point */
    Addr		*text_map;      /* old-new text mapping */
    Uint32		n_instructions;
    MIPS_Inst 		*text;
    Uint32         	gp_value;
    int			dt_local_gotno;
    int			dt_gotsym;
    Uint32		dt_got_base;
    Uint32		dt_flags;
    Uint32		dt_strtab;
    Uint32		dt_timestamp;
    Uint32		timestamp;

    union{
        Elf32_Got       *got32;
        Elf64_Got       *got64;
    }			got;
    Uint32      gotno;

    union{
        Elf32_Sym       *dynsym32;
        Elf64_Sym       *dynsym64;
    }           	dynsym;
    
	/* new binary */
    Elf			*new_elf;
    Uint32         	new_instructions;
    MIPS_Inst 	*new_text;
    Cord_Boolean	need_rpt_post_process;
    Uint32		rpt_post_process_offset;
    Uint32		rpt_post_process_size;
    Uint32		line_post_process_offset;
    Uint32		line_post_process_size;
    Uint32		text_expand_offset;
    Uint32		text_expand_size;

        /* file descriptor */
    int         fd_in;
    int         fd_out;
} Bin;

extern Bin	bin;

/*------------------------------------------------------------------------------  
  Common macros
------------------------------------------------------------------------------*/
#define IS_32BIT()      (bin.bit == BIT32)
#define IS_64BIT()      (bin.bit == BIT64)
#define IS_ABI1()	(bin.abi == ABI1)
#define IS_ABI2()	(bin.abi == ABI2)

#define IN_TEXT(addr)   ( ( (Addr) addr) >= bin.text_lo && \
                ( (Addr) addr) < bin.text_hi)

#define IN_NEW_TEXT(addr)   ( ( (Addr) addr) >= bin.text_lo && \
                ( (Addr) addr) < (bin.text_lo + \
                        (Addr)bin.n_new_instructions*SIZE_INST) )

                /* check whether instruction is in text */
#define IN_BROAD_TEXT(addr)   ( ( (Addr) addr) >= bin.broad_text_lo && \
                ( (Addr) addr) < bin.broad_text_hi)

#define NEW_ADDR(addr)  bin.text_map[(Uint32) \
                (( (Addr) addr)-bin.text_lo)/SIZE_INST]

#define GET_TEXT_BY_ADDR(addr) (bin.text[(Uint32) \
                (((Addr) addr)-bin.text_lo)/SIZE_INST] )

#define GET_NEWTEXT_BY_ADDR(addr) (bin.new_text[(Uint32) \
                (( (Addr) addr)-bin.text_lo)/SIZE_INST])

#define MAX(x,y) ((x>y)?x:y)
#define MIN(x,y) ((x<y)?x:y)

#define ULO(x) ( (x) & 0xffff )
#define UHI(x) ( (x) >> 16 )
#define SLO(x) ( (short) ((x) & 0xffff) )
#define SHI(x) ( (x - SLO(x)) >> 16 )

#define S64_LO(x)       SLO(x)
#define S64_HIGH(x)     ( (short) ((x - SLO(x)) >> 16) & 0xffff )
#define S64_HIGHER(x)   ( (short) ((x - (x & 0xffffffff ))) >> 32 & 0xffff)
#define S64_HIGHEST(x)  ( (short) ((x - (x & 0xffffffffffff ))) >> 48 & 0xffff)

#define IN_SINT16_RANGE(x) ((x) <= 0x7fff && (x) >= -0x8000)

extern void read_orig_binary(int fd);
extern void dwarf_interface (Elf *);
extern void reorder_it(void);
extern void parse_command_line(int, char**);
extern void read_reorder_files(void);
extern void compact_relocation(void);
extern void write_it(void);
extern void post_process_rpt(int, int);
extern void post_process_line(int, int);
extern void bin_copy(int, int);

extern void create_cord_section(Elf *elf);
extern void update_got(Elf *elf);
extern void update_reldyn(Elf *elf);
extern void update_elf_header(Elf *elf);
extern void update_dynamic(Elf *elf);
extern void update_symtab(Elf *elf);
extern void update_dynsym(Elf *elf);
extern void update_compact_rel(Elf *elf);
extern void update_jump(Elf *elf);
extern void check_branch_out_of_procedure(void);
extern void check_merged_procedure(void);
extern void check_procedure_with_no_return(void);
extern void update_rpt(Elf *elf);
extern void update_mdebug(Elf *elf);
extern void update_branch_offset(void);

extern void check_r4000_bug(void);
extern int  check_r4000_bug_per_block(int, Uint32, Uint32, Uint32);

extern Proc *new_proc(void);
extern void dump_procs(void);
extern void mdebug_derive_proc_highpc(void);

extern void duplicate_elf(void);


/*==============================================================================  definitions of gcord stuff
==============================================================================*/
typedef struct gcordSection {
        Elf32_Shdr * old_shdr, * new_shdr;
        Elf_Scn * old_section, * new_section;
        Elf_Data * old_data, * new_data;
        char * name;
        struct gcordSection * next;
} GCORDSECT, *GCORDSECTPTR;

GCORDSECTPTR gcordSectList;

#include "option.h"
#endif /* ifndef _CORD_GLOBAL_H_ */