2009-04-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/10074
	* coffcode.h (bfd_pei_p): New.

	* config.bfd: Remove bfd_efi_bsdrv_ia32_vec,
	bfd_efi_rtdrv_ia32_vec, bfd_efi_bsdrv_x86_64_vec,
	bfd_efi_rtdrv_x86_64_vec, bfd_efi_bsdrv_ia64_vec and
	bfd_efi_rtdrv_ia64_vec.  Replace bfd_efi_app_ia32_vec,
	bfd_efi_app_x86_64_vec and bfd_efi_app_ia64_vec with
	i386pei_vec, x86_64pei_vec and bfd_pei_ia64_vec, respectively.

	* configure.in: Remove bfd_efi_bsdrv_ia32_vec,
	bfd_efi_rtdrv_ia32_vec, bfd_efi_bsdrv_x86_64_vec,
	bfd_efi_rtdrv_x86_64_vec,
	bfd_efi_bsdrv_ia64_vec and bfd_efi_rtdrv_ia64_vec.  Replace
	bfd_efi_ia64_vec with bfd_pei_ia64_vec.
	* targets.c: Likewise.

	* configure: Regenerated.
	* libcoff.h: Likewise.
	* Makefile.in: Likewise.

	* efi-app-ia32.c: Removed.
	* efi-app-x86_64.c: Likewise.
	* efi-bsdrv-ia32.c: Likewise.
	* efi-bsdrv-ia64.c: Likewise.
	* efi-bsdrv-x86_64.c: Likewise.
	* efi-rtdrv-ia32.c: Likewise.
	* efi-rtdrv-ia64.c: Likewise.
	* efi-rtdrv-x86_64.c: Likewise.
	* efi-rtdrv-ia32.c: Likewise.

	* efi-app-ia64.c: Moved to ...
	* pei-ia64.c: This.
	(TARGET_SYM): Set to bfd_pei_ia64_vec.
	(TARGET_NAME): Set to pei-ia64.

	* libpei.h (bfd_target_pei_p): Removed.
	(bfd_target_pei_arch): Likewise.
	(bfd_target_efi_app_p): Likewise.
	(bfd_target_efi_app_arch): Likewise.
	(bfd_target_efi_bsdrv_p): Likewise.
	(bfd_target_efi_bsdrv_arch): Likewise.
	(bfd_target_efi_rtdrv_p): Likewise.
	(bfd_target_efi_rtdrv_arch): Likewise.
	(bfd_pe_executable_p): Likewise.

	* Makefile.am (BFD32_BACKENDS): Remove efi-app-ia32.lo,
	efi-bsdrv-ia32.lo and efi-rtdrv-ia32.lo.
	(BFD32_BACKENDS_CFILES): Remove efi-app-ia32.c, efi-bsdrv-ia32.c
	and efi-rtdrv-ia32.c.
	(BFD64_BACKENDS): Remove efi-app-ia64.lo, efi-bsdrv-ia64.lo,
	efi-rtdrv-ia64.lo, efi-app-x86_64.lo, efi-bsdrv-x86_64.lo and
	efi-rtdrv-x86_64.lo. Add pei-ia64.lo.
	(BFD64_BACKENDS_CFILES): Remove efi-app-ia64.c, efi-bsdrv-ia64.c,
	efi-rtdrv-ia64.c, efi-app-x86_64.c, efi-bsdrv-x86_64.c and
	efi-rtdrv-x86_64.c. Add pei-ia64.c.
	(efi-app-ia64.lo): Removed.
	(efi-bsdrv-ia32.lo): Likewise.
	(efi-rtdrv-ia32.lo): Likewise.
	(efi-app-ia64.lo): Likewise.
	(efi-bsdrv-ia64.lo): Likewise.
	(efi-rtdrv-ia64.lo): Likewise.
	(efi-app-x86_64.lo): Likewise.
	(efi-bsdrv-x86_64.lo): Likewise.
	(efi-rtdrv-x86_64.lo): Likewise.
	(pei-ia64.lo): New.

	* peicode.h (coff_swap_scnhdr_in): Replace bfd_pe_executable_p
	with bfd_pei_p.
	(arch_type): Removed.
	(pe_arch): Likewise.
	(pe_bfd_object_p): Just return coff_object_p.

	* peXXigen.c (_bfd_XXi_swap_scnhdr_out): Replace
	bfd_pe_executable_p with bfd_pei_p.

binutils/

2009-04-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/10074
	* objcopy.c: Include coff/i386.h and coff/pe.h.
	(pe_file_alignment): New.
	(pe_heap_commit): Likewise.
	(pe_heap_reserve): Likewise.
	(pe_image_base): Likewise.
	(pe_section_alignment): Likewise.
	(pe_stack_commit): Likewise.
	(pe_stack_reserve): Likewise.
	(pe_subsystem): Likewise.
	(pe_major_subsystem_version): Likewise.
	(pe_minor_subsystem_version): Likewise.
	(set_pe_subsystem): Likewise.
	(convert_efi_target): Likewise.
	(command_line_switch): Add OPTION_FILE_ALIGNMENT,
	OPTION_HEAP, OPTION_IMAGE_BASE, OPTION_SECTION_ALIGNMENT,
	OPTION_STACK and OPTION_SUBSYSTEM.
	(copy_options): Likewise.
	(copy_usage): Add --file-alignment, --heap, --image-base,
	--section-alignment, --stack and --subsystem.
	(copy_object): Set up PE parameters.
	(copy_main): Process Add OPTION_FILE_ALIGNMENT,
	OPTION_HEAP, OPTION_IMAGE_BASE, OPTION_SECTION_ALIGNMENT,
	OPTION_STACK and OPTION_SUBSYSTEM.   Convert EFI target to
	PEI target.

	* NEWS: Mention --file-alignment, --heap, --image-base,
	--section-alignment, --stack and --subsystem command line
	options for objcopy.

	* doc/binutils.texi: Document --file-alignment, --heap,
	--image-base, --section-alignment, --stack and --subsystem
	command line options for objcopy.
This commit is contained in:
H.J. Lu
2009-04-17 13:46:18 +00:00
parent 69c5861ee1
commit 92dd451149
25 changed files with 510 additions and 632 deletions

View File

@ -35,6 +35,22 @@
#include "coff/internal.h"
#include "libcoff.h"
/* FIXME: See bfd/peXXigen.c for why we include an architecture specific
header in generic PE code. */
#include "coff/i386.h"
#include "coff/pe.h"
static bfd_vma pe_file_alignment = (bfd_vma) -1;
static bfd_vma pe_heap_commit = (bfd_vma) -1;
static bfd_vma pe_heap_reserve = (bfd_vma) -1;
static bfd_vma pe_image_base = (bfd_vma) -1;
static bfd_vma pe_section_alignment = (bfd_vma) -1;
static bfd_vma pe_stack_commit = (bfd_vma) -1;
static bfd_vma pe_stack_reserve = (bfd_vma) -1;
static short pe_subsystem = -1;
static short pe_major_subsystem_version = -1;
static short pe_minor_subsystem_version = -1;
struct is_specified_symbol_predicate_data
{
const char *name;
@ -280,7 +296,13 @@ enum command_line_switch
OPTION_PURE,
OPTION_IMPURE,
OPTION_EXTRACT_SYMBOL,
OPTION_REVERSE_BYTES
OPTION_REVERSE_BYTES,
OPTION_FILE_ALIGNMENT,
OPTION_HEAP,
OPTION_IMAGE_BASE,
OPTION_SECTION_ALIGNMENT,
OPTION_STACK,
OPTION_SUBSYSTEM
};
/* Options to handle if running as "strip". */
@ -394,6 +416,12 @@ static struct option copy_options[] =
{"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
{"wildcard", no_argument, 0, 'w'},
{"writable-text", no_argument, 0, OPTION_WRITABLE_TEXT},
{"file-alignment", required_argument, 0, OPTION_FILE_ALIGNMENT},
{"heap", required_argument, 0, OPTION_HEAP},
{"image-base", required_argument, 0 , OPTION_IMAGE_BASE},
{"section-alignment", required_argument, 0, OPTION_SECTION_ALIGNMENT},
{"stack", required_argument, 0, OPTION_STACK},
{"subsystem", required_argument, 0, OPTION_SUBSYSTEM},
{0, no_argument, 0, 0}
};
@ -515,6 +543,15 @@ copy_usage (FILE *stream, int exit_status)
--prefix-alloc-sections <prefix>\n\
Add <prefix> to start of every allocatable\n\
section name\n\
--file-alignment <num> Set PE file alignment to <num>\n\
--heap <reserve>[,<commit>] Set PE reserve/commit heap to <reserve>/\n\
<commit>\n\
--image-base <address> Set PE image base to <address>\n\
--section-alignment <num> Set PE section alignment to <num>\n\
--stack <reserve>[,<commit>] Set PE reserve/commit stack to <reserve>/\n\
<commit>\n\
--subsystem <name>[:<version>]\n\
Set PE subsystem to <name> [& <version>]\n]\
-v --verbose List all object files modified\n\
@<file> Read options from <file>\n\
-V --version Display this program's version number\n\
@ -1448,6 +1485,58 @@ copy_object (bfd *ibfd, bfd *obfd)
return FALSE;
}
if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
&& bfd_pei_p (obfd))
{
/* Set up PE parameters. */
pe_data_type *pe = pe_data (obfd);
if (pe_file_alignment != (bfd_vma) -1)
pe->pe_opthdr.FileAlignment = pe_file_alignment;
else
pe_file_alignment = PE_DEF_FILE_ALIGNMENT;
if (pe_heap_commit != (bfd_vma) -1)
pe->pe_opthdr.SizeOfHeapCommit = pe_heap_commit;
if (pe_heap_reserve != (bfd_vma) -1)
pe->pe_opthdr.SizeOfHeapCommit = pe_heap_reserve;
if (pe_image_base != (bfd_vma) -1)
pe->pe_opthdr.ImageBase = pe_image_base;
if (pe_section_alignment != (bfd_vma) -1)
pe->pe_opthdr.SectionAlignment = pe_section_alignment;
else
pe_section_alignment = PE_DEF_SECTION_ALIGNMENT;
if (pe_stack_commit != (bfd_vma) -1)
pe->pe_opthdr.SizeOfStackCommit = pe_stack_commit;
if (pe_stack_reserve != (bfd_vma) -1)
pe->pe_opthdr.SizeOfStackCommit = pe_stack_reserve;
if (pe_subsystem != -1)
pe->pe_opthdr.Subsystem = pe_subsystem;
if (pe_major_subsystem_version != -1)
pe->pe_opthdr.MajorSubsystemVersion = pe_major_subsystem_version;
if (pe_minor_subsystem_version != -1)
pe->pe_opthdr.MinorSubsystemVersion = pe_minor_subsystem_version;
if (pe_file_alignment > pe_section_alignment)
{
char file_alignment[20], section_alignment[20];
sprintf_vma (file_alignment, pe_file_alignment);
sprintf_vma (section_alignment, pe_section_alignment);
non_fatal (_("warning: file alignment (0x%s) > section alignment (0x%s)"),
file_alignment, section_alignment);
}
}
if (isympp)
free (isympp);
@ -2928,6 +3017,117 @@ strip_main (int argc, char *argv[])
return status;
}
/* Set up PE subsystem. */
static void
set_pe_subsystem (const char *s)
{
const char *version, *subsystem;
size_t i;
static const struct
{
const char *name;
const char set_def;
const short value;
}
v[] =
{
{ "native", 0, IMAGE_SUBSYSTEM_NATIVE },
{ "windows", 0, IMAGE_SUBSYSTEM_WINDOWS_GUI },
{ "console", 0, IMAGE_SUBSYSTEM_WINDOWS_CUI },
{ "posix", 0, IMAGE_SUBSYSTEM_POSIX_CUI },
{ "wince", 0, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI },
{ "efi-app", 1, IMAGE_SUBSYSTEM_EFI_APPLICATION },
{ "efi-bsd", 1, IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER },
{ "efi-rtd", 1, IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER },
{ "efi-rom", 1, IMAGE_SUBSYSTEM_EFI_ROM },
{ "xbox", 0, IMAGE_SUBSYSTEM_XBOX }
};
short value;
char *copy;
int set_def = -1;
/* Check for the presence of a version number. */
version = strchr (s, ':');
if (version == NULL)
subsystem = s;
else
{
int len = version - s;
copy = xstrdup (s);
subsystem = copy;
copy[len] = '\0';
version = copy + 1 + len;
pe_major_subsystem_version = strtoul (version, &copy, 0);
if (*copy == '.')
pe_minor_subsystem_version = strtoul (copy + 1, &copy, 0);
if (*copy != '\0')
non_fatal (_("%s: bad version in PE subsystem"), s);
}
/* Check for numeric subsystem. */
value = (short) strtol (subsystem, &copy, 0);
if (*copy == '\0')
{
for (i = 0; i < ARRAY_SIZE (v); i++)
if (v[i].value == value)
{
pe_subsystem = value;
set_def = v[i].set_def;
break;
}
}
else
{
/* Search for subsystem by name. */
for (i = 0; i < ARRAY_SIZE (v); i++)
if (strcmp (subsystem, v[i].name) == 0)
{
pe_subsystem = v[i].value;
set_def = v[i].set_def;
break;
}
}
switch (set_def)
{
case -1:
fatal (_("unknown PE subsystem: %s"), s);
break;
case 0:
break;
default:
if (pe_file_alignment == (bfd_vma) -1)
pe_file_alignment = PE_DEF_FILE_ALIGNMENT;
if (pe_section_alignment == (bfd_vma) -1)
pe_section_alignment = PE_DEF_SECTION_ALIGNMENT;
break;
}
}
/* Convert EFI target to PEI target. */
static void
convert_efi_target (char *efi)
{
efi[0] = 'p';
efi[1] = 'e';
efi[2] = 'i';
if (strcmp (efi + 4, "ia32") == 0)
{
/* Change ia32 to i386. */
efi[5]= '3';
efi[6]= '8';
efi[7]= '6';
}
else if (strcmp (efi + 4, "x86_64") == 0)
{
/* Change x86_64 to x86-64. */
efi[7] = '-';
}
}
static int
copy_main (int argc, char *argv[])
{
@ -3466,6 +3666,59 @@ copy_main (int argc, char *argv[])
break;
}
case OPTION_FILE_ALIGNMENT:
pe_file_alignment = parse_vma (optarg, "--file-alignment");
break;
case OPTION_HEAP:
{
char *end;
pe_heap_reserve = strtoul (optarg, &end, 0);
if (end == optarg
|| (*end != '.' && *end != '\0'))
non_fatal (_("%s: invalid reserve value for --heap"),
optarg);
else if (*end != '\0')
{
pe_heap_commit = strtoul (end + 1, &end, 0);
if (*end != '\0')
non_fatal (_("%s: invalid commit value for --heap"),
optarg);
}
}
break;
case OPTION_IMAGE_BASE:
pe_image_base = parse_vma (optarg, "--image-base");
break;
case OPTION_SECTION_ALIGNMENT:
pe_section_alignment = parse_vma (optarg,
"--section-alignment");
break;
case OPTION_SUBSYSTEM:
set_pe_subsystem (optarg);
break;
case OPTION_STACK:
{
char *end;
pe_stack_reserve = strtoul (optarg, &end, 0);
if (end == optarg
|| (*end != '.' && *end != '\0'))
non_fatal (_("%s: invalid reserve value for --stack"),
optarg);
else if (*end != '\0')
{
pe_stack_commit = strtoul (end + 1, &end, 0);
if (*end != '\0')
non_fatal (_("%s: invalid commit value for --stack"),
optarg);
}
}
break;
case 0:
/* We've been given a long option. */
break;
@ -3505,6 +3758,59 @@ copy_main (int argc, char *argv[])
if (output_target == NULL)
output_target = input_target;
/* Convert input EFI target to PEI target. */
if (input_target != NULL
&& strncmp (input_target, "efi-", 4) == 0)
{
char *efi;
efi = xstrdup (output_target + 4);
if (strncmp (efi, "bsdrv-", 6) == 0
|| strncmp (efi, "rtdrv-", 6) == 0)
efi += 2;
else if (strncmp (efi, "app-", 4) != 0)
fatal (_("unknown input EFI target: %s"), input_target);
input_target = efi;
convert_efi_target (efi);
}
/* Convert output EFI target to PEI target. */
if (output_target != NULL
&& strncmp (output_target, "efi-", 4) == 0)
{
char *efi;
efi = xstrdup (output_target + 4);
if (strncmp (efi, "app-", 4) == 0)
{
if (pe_subsystem == -1)
pe_subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION;
}
else if (strncmp (efi, "bsdrv-", 6) == 0)
{
if (pe_subsystem == -1)
pe_subsystem = IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;
efi += 2;
}
else if (strncmp (efi, "rtdrv-", 6) == 0)
{
if (pe_subsystem == -1)
pe_subsystem = IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
efi += 2;
}
else
fatal (_("unknown output EFI target: %s"), output_target);
if (pe_file_alignment == (bfd_vma) -1)
pe_file_alignment = PE_DEF_FILE_ALIGNMENT;
if (pe_section_alignment == (bfd_vma) -1)
pe_section_alignment = PE_DEF_SECTION_ALIGNMENT;
output_target = efi;
convert_efi_target (efi);
}
if (binary_architecture != NULL)
{
if (input_target && strcmp (input_target, "binary") == 0)