global.h
6.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#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_ */