* config/obj-coff-seh.c: Rewrite the entire file.

(symtab, symptr, reltab, relcount, relsize): Remove.
	(seh_ctx_root, seh_ctx): Remove.
	(xdata_seg, xdata_subseg, pdata_seg): New.
	(switch_xdata, switch_pdata): New.
	(verify_context, verify_context_and_target, skip_whitespace_and_comma):
	New parsing functions.  Rewrite all parsing functions to use them.
	(obj_coff_seh_32): Fix != arm thinko.
	(obj_coff_seh_handler): For x64, don't accept handler pointer here,
	only flags.
	(obj_coff_seh_handlerdata): New.
	(do_seh_endproc): Split out of ...
	(obj_coff_seh_endproc): ... here.
	(obj_coff_seh_proc): Use it, if needed.
	(seh_x64_make_prologue_element): Use XRESIZEVEC, symbol_temp_new_now.
	(seh_x64_read_reg): Remove mm_regs alternative.  Tidy integer reg
	alternatives.  Don't slurp commas.
	(seh_read_offset): Remove.
	(obj_coff_seh_pushframe): Split out from obj_coff_seh_push.
	(obj_coff_seh_scope): Remove.
	(obj_coff_seh_save): Decide UWOP_SAVE_* vs _FAR immediately.
	(obj_coff_seh_stackalloc): Decide _SMALL vs _LARGE immediately.
	(out_one, out_two, out_four): New.
	(seh_x64_write_prologue_data, seh_x64_size_prologue_data,
	seh_x64_write_function_xdata, write_function_xdata): Rewrite
	from seh_x64_write_xdata, seh_needed_unwind_info, seh_store_elm_data,
	seh_getelm_data_size, seh_getsize_of_unwind_entry,
	seh_make_unwind_entry, seh_getsize_unwind_data, and
	seh_create_unwind_data.
	(seh_arm_write_function_pdata): Rewrite from seh_arm_create_pdata.
	(write_function_pdata): Rewrite from make_function_entry_pdata.
	(seh_write_text_eh_data, make_function_entry_pdata,
	seh_arm_create_pdata, seh_arm_write_pdata, seh_reloc, save_relocs,
	seh_symbol_init, seh_symbol, quick_section, seh_emit_rva,
	seh_emit_long, seh_make_globl, seh_make_section2, seh_make_section,
	seh_make_xlbl_name, make_seh_text_label, seh_fill_pcsyms,
	seh_needed_unwind_info, seh_store_elm_data, seh_getelm_data_size,
	seh_getsize_of_unwind_entry, seh_make_unwind_entry,
	seh_getsize_unwind_data, seh_create_unwind_data,
	seh_make_function_entry_xdata, seh_x64_makescope_elem): Remove.
	* config/obj-coff-seh.h (SEH_CMDS): Remove seh_savemm, seh_scope.
	Add seh_handlerdata.  Adjust function/what arguments for
	seh_savereg, seh_pushframe, seh_stackalloc.
	(struct seh_prologue_element): Adjust members to closer match
	the elements of the UNWIND_CODE structure.
	(struct seh_scope_elem): Remove.
	(struct seh_context): Replace char* members with symbolS or
	expressionS as appropriate.  Sort members by ARM/x64 applicability.
	Remove obsolete stuff wrt direct symbol and reloc manipulation.
This commit is contained in:
Richard Henderson 2010-08-30 21:51:28 +00:00
parent 03f17ccfe1
commit 681418c21c
3 changed files with 859 additions and 1452 deletions

View file

@ -1,3 +1,55 @@
2010-08-30 Richard Henderson <rth@redhat.com>
* config/obj-coff-seh.c: Rewrite the entire file.
(symtab, symptr, reltab, relcount, relsize): Remove.
(seh_ctx_root, seh_ctx): Remove.
(xdata_seg, xdata_subseg, pdata_seg): New.
(switch_xdata, switch_pdata): New.
(verify_context, verify_context_and_target, skip_whitespace_and_comma):
New parsing functions. Rewrite all parsing functions to use them.
(obj_coff_seh_32): Fix != arm thinko.
(obj_coff_seh_handler): For x64, don't accept handler pointer here,
only flags.
(obj_coff_seh_handlerdata): New.
(do_seh_endproc): Split out of ...
(obj_coff_seh_endproc): ... here.
(obj_coff_seh_proc): Use it, if needed.
(seh_x64_make_prologue_element): Use XRESIZEVEC, symbol_temp_new_now.
(seh_x64_read_reg): Remove mm_regs alternative. Tidy integer reg
alternatives. Don't slurp commas.
(seh_read_offset): Remove.
(obj_coff_seh_pushframe): Split out from obj_coff_seh_push.
(obj_coff_seh_scope): Remove.
(obj_coff_seh_save): Decide UWOP_SAVE_* vs _FAR immediately.
(obj_coff_seh_stackalloc): Decide _SMALL vs _LARGE immediately.
(out_one, out_two, out_four): New.
(seh_x64_write_prologue_data, seh_x64_size_prologue_data,
seh_x64_write_function_xdata, write_function_xdata): Rewrite
from seh_x64_write_xdata, seh_needed_unwind_info, seh_store_elm_data,
seh_getelm_data_size, seh_getsize_of_unwind_entry,
seh_make_unwind_entry, seh_getsize_unwind_data, and
seh_create_unwind_data.
(seh_arm_write_function_pdata): Rewrite from seh_arm_create_pdata.
(write_function_pdata): Rewrite from make_function_entry_pdata.
(seh_write_text_eh_data, make_function_entry_pdata,
seh_arm_create_pdata, seh_arm_write_pdata, seh_reloc, save_relocs,
seh_symbol_init, seh_symbol, quick_section, seh_emit_rva,
seh_emit_long, seh_make_globl, seh_make_section2, seh_make_section,
seh_make_xlbl_name, make_seh_text_label, seh_fill_pcsyms,
seh_needed_unwind_info, seh_store_elm_data, seh_getelm_data_size,
seh_getsize_of_unwind_entry, seh_make_unwind_entry,
seh_getsize_unwind_data, seh_create_unwind_data,
seh_make_function_entry_xdata, seh_x64_makescope_elem): Remove.
* config/obj-coff-seh.h (SEH_CMDS): Remove seh_savemm, seh_scope.
Add seh_handlerdata. Adjust function/what arguments for
seh_savereg, seh_pushframe, seh_stackalloc.
(struct seh_prologue_element): Adjust members to closer match
the elements of the UNWIND_CODE structure.
(struct seh_scope_elem): Remove.
(struct seh_context): Replace char* members with symbolS or
expressionS as appropriate. Sort members by ARM/x64 applicability.
Remove obsolete stuff wrt direct symbol and reloc manipulation.
2010-08-25 Alan Modra <amodra@gmail.com> 2010-08-25 Alan Modra <amodra@gmail.com>
* NEWS: Mention ampersand in macro change. * NEWS: Mention ampersand in macro change.

File diff suppressed because it is too large Load diff

View file

@ -45,7 +45,9 @@
The pseudos: The pseudos:
.seh_proc <fct_name> .seh_proc <fct_name>
.seh_endprologue .seh_endprologue
.seh_handler <handler>[,<handler-data>]] .seh_handler <handler>[,@unwind][,@except] (x64)
.seh_handler <handler>[,<handler_data>] (others)
.seh_handlerdata
.seh_eh .seh_eh
.seh_32/.seh_no32 .seh_32/.seh_no32
.seh_endproc .seh_endproc
@ -53,106 +55,76 @@
.seh_stackalloc .seh_stackalloc
.seh_pushreg .seh_pushreg
.seh_savereg .seh_savereg
.seh_savemm
.seh_savexmm .seh_savexmm
.seh_pushframe .seh_pushframe
.seh_scope */
*/
/* architecture specific pdata/xdata handling. */ /* architecture specific pdata/xdata handling. */
#define SEH_CMDS \ #define SEH_CMDS \
{"seh_proc", obj_coff_seh_proc, 0}, \ {"seh_proc", obj_coff_seh_proc, 0}, \
{"seh_endproc", obj_coff_seh_endproc, 0}, \ {"seh_endproc", obj_coff_seh_endproc, 0}, \
{"seh_pushreg", obj_coff_seh_push, 0}, \ {"seh_pushreg", obj_coff_seh_pushreg, 0}, \
{"seh_savereg", obj_coff_seh_save, 0}, \ {"seh_savereg", obj_coff_seh_save, 1}, \
{"seh_savemm", obj_coff_seh_save, 1}, \
{"seh_savexmm", obj_coff_seh_save, 2}, \ {"seh_savexmm", obj_coff_seh_save, 2}, \
{"seh_pushframe", obj_coff_seh_push, 1}, \ {"seh_pushframe", obj_coff_seh_pushframe, 0}, \
{"seh_endprologue", obj_coff_seh_endprologue, 0}, \ {"seh_endprologue", obj_coff_seh_endprologue, 0}, \
{"seh_setframe", obj_coff_seh_setframe, 0}, \ {"seh_setframe", obj_coff_seh_setframe, 0}, \
{"seh_stackalloc", obj_coff_seh_stack_alloc, 0}, \ {"seh_stackalloc", obj_coff_seh_stackalloc, 0}, \
{"seh_handler", obj_coff_seh_handler, 0}, \
{"seh_eh", obj_coff_seh_eh, 0}, \ {"seh_eh", obj_coff_seh_eh, 0}, \
{"seh_32", obj_coff_seh_32, 1}, \ {"seh_32", obj_coff_seh_32, 1}, \
{"seh_no32", obj_coff_seh_32, 0}, \ {"seh_no32", obj_coff_seh_32, 0}, \
{"seh_scope", obj_coff_seh_scope, 0}, {"seh_handler", obj_coff_seh_handler, 0}, \
{"seh_handlerdata", obj_coff_seh_handlerdata, 0},
/* Type definitions. */ /* Type definitions. */
typedef struct seh_prologue_element typedef struct seh_prologue_element
{ {
int code;
int info;
offsetT off;
symbolS *pc_addr; symbolS *pc_addr;
char *pc_symbol;
int kind;
int reg;
bfd_vma offset;
} seh_prologue_element; } seh_prologue_element;
typedef struct seh_scope_elem {
char *begin_addr;
char *end_addr;
char *handler_addr;
char *jump_addr;
} seh_scope_elem;
typedef struct seh_context typedef struct seh_context
{ {
struct seh_context *next; struct seh_context *next;
/* Was record alread processed. */
int done;
/* Function name. */ /* Function name. */
char *func_name; char *func_name;
/* BeginAddress. */ /* BeginAddress. */
char *start_symbol;
symbolS *start_addr; symbolS *start_addr;
bfd_vma start_offset;
/* EndAddress. */ /* EndAddress. */
char *end_symbol;
symbolS *end_addr; symbolS *end_addr;
bfd_vma end_offset; /* Unwind data. */
symbolS *xdata_addr;
/* PrologueEnd. */ /* PrologueEnd. */
char *endprologue_symbol;
symbolS *endprologue_addr; symbolS *endprologue_addr;
bfd_vma endprologue_offset;
/* ExceptionHandler. */ /* ExceptionHandler. */
char *handler_name; expressionS handler;
/* ExceptionHandlerData. */ /* ExceptionHandlerData. (arm, mips) */
char *handler_data_name; expressionS handler_data;
/* ARM .seh_eh directive seen. */
int handler_written; int handler_written;
/* WinCE specific data. */ /* WinCE specific data. */
int use_instruction_32; int use_instruction_32;
/* Was record already processed. */
int done;
/* x64 flags for the xdata header. */
int handler_flags;
int subsection;
/* the bfd to store data within. */
bfd *abfd;
/* the current section to generate data within. */
asection *section;
/* Relocations for section. */
unsigned int count_reloc;
/* Symbols within section. */
unsigned int count_syms;
/* Iterator for text lable generation. */
unsigned int tlbl_count;
/* Iterator for xdata lable generation. */
unsigned int xlbl_count;
/* The name of the first xdata label. */
char *xdata_first;
/* FIelds used for x64 generation of chained information. */
char **xdata_names;
char **xdata_pcsyms;
int *xdata_elm_start;
/* Size and offset within current generated xdata section. */
size_t xdata_sz;
size_t xdata_offset;
/* x64 framereg and frame offset information. */ /* x64 framereg and frame offset information. */
int framereg; int framereg;
bfd_vma frameoff; int frameoff;
/* Information about x64 specific unwind data fields. */ /* Information about x64 specific unwind data fields. */
size_t elems_count; int elems_count;
size_t elems_max; int elems_max;
seh_prologue_element *elems; seh_prologue_element *elems;
size_t scope_max;
size_t scope_count;
seh_scope_elem *scopes;
} seh_context; } seh_context;
typedef enum seh_kind { typedef enum seh_kind {
@ -163,21 +135,18 @@ typedef enum seh_kind {
} seh_kind; } seh_kind;
/* Forward declarations. */ /* Forward declarations. */
static void obj_coff_seh_stack_alloc (int); static void obj_coff_seh_stackalloc (int);
static void obj_coff_seh_setframe (int); static void obj_coff_seh_setframe (int);
static void obj_coff_seh_endprologue (int); static void obj_coff_seh_endprologue (int);
static void obj_coff_seh_save (int); static void obj_coff_seh_save (int);
static void obj_coff_seh_push (int); static void obj_coff_seh_pushreg (int);
static void obj_coff_seh_pushframe (int);
static void obj_coff_seh_endproc (int); static void obj_coff_seh_endproc (int);
static void obj_coff_seh_eh (int); static void obj_coff_seh_eh (int);
static void obj_coff_seh_32 (int); static void obj_coff_seh_32 (int);
static void obj_coff_seh_proc (int); static void obj_coff_seh_proc (int);
static void obj_coff_seh_handler (int); static void obj_coff_seh_handler (int);
static void obj_coff_seh_scope (int); static void obj_coff_seh_handlerdata (int);
static int seh_read_offset (const char *, bfd_vma *);
static int seh_x64_read_reg (const char *, int, int *);
static void seh_x64_make_prologue_element (int, int, bfd_vma);
static void make_function_entry_pdata (seh_context *c);
#define UNDSEC (asection *) &bfd_und_section #define UNDSEC (asection *) &bfd_und_section