2010-05-03  Tristan Gingold  <gingold@adacore.com>

	* vms-alpha.c: Add comments.
	(struct vms_private_data_struct): Remove image_autoextend field.
	(dst_check_allocation): Removed.
	(image_write): Remove call to dst_check_allocation.
	(vms_slurp_debug): Do not set image_autoextend.  Adjust section
	size.
	(_bfd_vms_slurp_object_records): Remove useless new_type variable.
	(alpha_vms_write_exec): Use dst_section to get the dst section.
	Write the dmt section.
	(evax_bfd_print_image): Also print the dst size in hexa.  Fix typo.
	(alpha_vms_read_sections_content): Do not set image_autoextend.

include/vms/
2010-05-03  Tristan Gingold  <gingold@adacore.com>

	* dmt.h: Improve comments.
This commit is contained in:
Tristan Gingold 2010-05-03 12:16:46 +00:00
parent ab94b07c4b
commit 44273c5bcc
4 changed files with 150 additions and 51 deletions

View File

@ -1,3 +1,17 @@
2010-05-03 Tristan Gingold <gingold@adacore.com>
* vms-alpha.c: Add comments.
(struct vms_private_data_struct): Remove image_autoextend field.
(dst_check_allocation): Removed.
(image_write): Remove call to dst_check_allocation.
(vms_slurp_debug): Do not set image_autoextend. Adjust section
size.
(_bfd_vms_slurp_object_records): Remove useless new_type variable.
(alpha_vms_write_exec): Use dst_section to get the dst section.
Write the dmt section.
(evax_bfd_print_image): Also print the dst size in hexa. Fix typo.
(alpha_vms_read_sections_content): Do not set image_autoextend.
2010-05-03 Tristan Gingold <gingold@adacore.com> 2010-05-03 Tristan Gingold <gingold@adacore.com>
* vms-lib.c (_bfd_vms_lib_archive_p): Adjust for a possible empty * vms-lib.c (_bfd_vms_lib_archive_p): Adjust for a possible empty

View File

@ -89,6 +89,7 @@
#define ALPHA_R_BSR 15 #define ALPHA_R_BSR 15
#define ALPHA_R_LDA 16 #define ALPHA_R_LDA 16
#define ALPHA_R_BOH 17 #define ALPHA_R_BOH 17
/* These are used with DST_S_C_LINE_NUM. */ /* These are used with DST_S_C_LINE_NUM. */
#define DST_S_C_LINE_NUM_HEADER_SIZE 4 #define DST_S_C_LINE_NUM_HEADER_SIZE 4
@ -291,7 +292,6 @@ struct vms_private_data_struct
/* Content reading. */ /* Content reading. */
asection *image_section; /* section for image_ptr */ asection *image_section; /* section for image_ptr */
file_ptr image_offset; /* Offset for image_ptr. */ file_ptr image_offset; /* Offset for image_ptr. */
bfd_boolean image_autoextend; /* Resize section if necessary. */
struct module *modules; /* list of all compilation units */ struct module *modules; /* list of all compilation units */
@ -1383,30 +1383,6 @@ dst_retrieve_location (bfd *abfd, unsigned int loc)
return PRIV (dst_ptr_offsets)[loc]; return PRIV (dst_ptr_offsets)[loc];
} }
/* Check that the DST section is big enough for the specified
amount of bytes. */
static void
dst_check_allocation (bfd *abfd, unsigned int size)
{
asection *section = PRIV (image_section);
section->size += size;
/* Grow the section as necessary */
if (section->size <= section->rawsize)
return;
do
{
if (section->rawsize == 0)
section->rawsize = 1024;
else
section->rawsize *= 2;
}
while (section->size > section->rawsize);
section->contents = bfd_realloc (section->contents, section->rawsize);
}
/* Write multiple bytes to section image. */ /* Write multiple bytes to section image. */
static bfd_boolean static bfd_boolean
@ -1418,9 +1394,6 @@ image_write (bfd *abfd, unsigned char *ptr, int size)
_bfd_hexdump (9, ptr, size, 0); _bfd_hexdump (9, ptr, size, 0);
#endif #endif
if (PRIV (image_autoextend))
dst_check_allocation (abfd, size);
if (PRIV (image_section)->contents != NULL) if (PRIV (image_section)->contents != NULL)
{ {
asection *sec = PRIV (image_section); asection *sec = PRIV (image_section);
@ -1667,6 +1640,10 @@ alpha_vms_fix_sec_rel (bfd *abfd, struct bfd_link_info *info,
return vma + sec->vma; return vma + sec->vma;
} }
/* Read an ETIR record from ABFD. If INFO is not null, put the content into
the output section (used during linking).
Return FALSE in case of error. */
static bfd_boolean static bfd_boolean
_bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
{ {
@ -2263,11 +2240,11 @@ vms_slurp_debug (bfd *abfd)
PRIV (image_section) = section; PRIV (image_section) = section;
PRIV (image_offset) = section->size; PRIV (image_offset) = section->size;
PRIV (image_autoextend) = FALSE;
if (!_bfd_vms_slurp_etir (abfd, NULL)) if (!_bfd_vms_slurp_etir (abfd, NULL))
return FALSE; return FALSE;
section->size = PRIV (image_offset);
return TRUE; return TRUE;
} }
@ -2279,7 +2256,7 @@ _bfd_vms_slurp_edbg (bfd *abfd)
{ {
vms_debug2 ((2, "EDBG\n")); vms_debug2 ((2, "EDBG\n"));
abfd->flags |= (HAS_DEBUG | HAS_LINENO); abfd->flags |= HAS_DEBUG | HAS_LINENO;
return vms_slurp_debug (abfd); return vms_slurp_debug (abfd);
} }
@ -2334,21 +2311,20 @@ _bfd_vms_slurp_eeom (bfd *abfd)
static bfd_boolean static bfd_boolean
_bfd_vms_slurp_object_records (bfd * abfd) _bfd_vms_slurp_object_records (bfd * abfd)
{ {
int err, new_type, type = -1; bfd_boolean err;
int type;
do do
{ {
vms_debug2 ((7, "reading at %08lx\n", (unsigned long)bfd_tell (abfd))); vms_debug2 ((7, "reading at %08lx\n", (unsigned long)bfd_tell (abfd)));
new_type = _bfd_vms_get_object_record (abfd); type = _bfd_vms_get_object_record (abfd);
if (new_type < 0) if (type < 0)
{ {
vms_debug2 ((2, "next_record failed\n")); vms_debug2 ((2, "next_record failed\n"));
return FALSE; return FALSE;
} }
type = new_type;
switch (type) switch (type)
{ {
case EOBJ__C_EMH: case EOBJ__C_EMH:
@ -2598,6 +2574,8 @@ alpha_vms_file_position_block (bfd *abfd)
PRIV (file_pos) -= (PRIV (file_pos) % VMS_BLOCK_SIZE); PRIV (file_pos) -= (PRIV (file_pos) % VMS_BLOCK_SIZE);
} }
/* Convert from internal structure SRC to external structure DST. */
static void static void
alpha_vms_swap_eisd_out (struct vms_internal_eisd_map *src, alpha_vms_swap_eisd_out (struct vms_internal_eisd_map *src,
struct vms_eisd *dst) struct vms_eisd *dst)
@ -2636,6 +2614,9 @@ alpha_vms_append_extra_eisd (bfd *abfd, struct vms_internal_eisd_map *eisd)
PRIV (gbl_eisd_tail) = eisd; PRIV (gbl_eisd_tail) = eisd;
} }
/* Create an EISD for shared image SHRIMG.
Return FALSE in case of error. */
static bfd_boolean static bfd_boolean
alpha_vms_create_eisd_for_shared (bfd *abfd, bfd *shrimg) alpha_vms_create_eisd_for_shared (bfd *abfd, bfd *shrimg)
{ {
@ -2677,6 +2658,9 @@ alpha_vms_create_eisd_for_shared (bfd *abfd, bfd *shrimg)
return TRUE; return TRUE;
} }
/* Create an EISD for section SEC.
Return FALSE in case of failure. */
static bfd_boolean static bfd_boolean
alpha_vms_create_eisd_for_section (bfd *abfd, asection *sec) alpha_vms_create_eisd_for_section (bfd *abfd, asection *sec)
{ {
@ -2732,6 +2716,9 @@ alpha_vms_create_eisd_for_section (bfd *abfd, asection *sec)
return TRUE; return TRUE;
} }
/* Layout executable ABFD and write it to the disk.
Return FALSE in case of failure. */
static bfd_boolean static bfd_boolean
alpha_vms_write_exec (bfd *abfd) alpha_vms_write_exec (bfd *abfd)
{ {
@ -2743,7 +2730,9 @@ alpha_vms_write_exec (bfd *abfd)
struct vms_internal_eisd_map *first_eisd; struct vms_internal_eisd_map *first_eisd;
struct vms_internal_eisd_map *eisd; struct vms_internal_eisd_map *eisd;
asection *dst; asection *dst;
asection *dmt;
/* Build the EIHD. */
PRIV (file_pos) = EIHD__C_LENGTH; PRIV (file_pos) = EIHD__C_LENGTH;
memset (&eihd, 0, sizeof (eihd)); memset (&eihd, 0, sizeof (eihd));
@ -2821,9 +2810,8 @@ alpha_vms_write_exec (bfd *abfd)
eihi->imgbid[0] = 0; eihi->imgbid[0] = 0;
/* Alloc EIHS. */ /* Alloc EIHS. */
dst = bfd_get_section_by_name (abfd, "$DST$"); dst = PRIV (dst_section);
if (dst == NULL || dst->size == 0) dmt = bfd_get_section_by_name (abfd, "$DMT$");
dst = bfd_get_section_by_name (abfd, "$TBT$");
if (dst != NULL && dst->size != 0) if (dst != NULL && dst->size != 0)
{ {
eihs = (struct vms_eihs *)((char *) &eihd + PRIV (file_pos)); eihs = (struct vms_eihs *)((char *) &eihd + PRIV (file_pos));
@ -2840,7 +2828,7 @@ alpha_vms_write_exec (bfd *abfd)
bfd_putl32 (0, eihs->dmtsize); bfd_putl32 (0, eihs->dmtsize);
} }
/* One per section. */ /* One EISD per section. */
for (sec = abfd->sections; sec; sec = sec->next) for (sec = abfd->sections; sec; sec = sec->next)
{ {
if (!alpha_vms_create_eisd_for_section (abfd, sec)) if (!alpha_vms_create_eisd_for_section (abfd, sec))
@ -2920,6 +2908,12 @@ alpha_vms_write_exec (bfd *abfd)
{ {
bfd_putl32 ((dst->filepos / VMS_BLOCK_SIZE) + 1, eihs->dstvbn); bfd_putl32 ((dst->filepos / VMS_BLOCK_SIZE) + 1, eihs->dstvbn);
bfd_putl32 (dst->size, eihs->dstsize); bfd_putl32 (dst->size, eihs->dstsize);
if (dmt != NULL)
{
bfd_putl32 ((dmt->filepos / VMS_BLOCK_SIZE) + 1, eihs->dmtvbn);
bfd_putl32 (dmt->size, eihs->dmtsize);
}
} }
/* Write EISD in hdr. */ /* Write EISD in hdr. */
@ -7362,8 +7356,8 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
(unsigned)bfd_getl32 (eihs.minorid)); (unsigned)bfd_getl32 (eihs.minorid));
dst_vbn = bfd_getl32 (eihs.dstvbn); dst_vbn = bfd_getl32 (eihs.dstvbn);
dst_size = bfd_getl32 (eihs.dstsize); dst_size = bfd_getl32 (eihs.dstsize);
fprintf (file, _(" debug symbol table : vbn: %u, size: %u\n"), fprintf (file, _(" debug symbol table : vbn: %u, size: %u (0x%x)\n"),
dst_vbn, dst_size); dst_vbn, dst_size, dst_size);
gst_vbn = bfd_getl32 (eihs.gstvbn); gst_vbn = bfd_getl32 (eihs.gstvbn);
gst_size = bfd_getl32 (eihs.gstsize); gst_size = bfd_getl32 (eihs.gstsize);
fprintf (file, _(" global symbol table: vbn: %u, records: %u\n"), fprintf (file, _(" global symbol table: vbn: %u, records: %u\n"),
@ -7499,7 +7493,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
} }
count = bfd_getl16 (dmth.psect_count); count = bfd_getl16 (dmth.psect_count);
fprintf (file, fprintf (file,
_(" module address: 0x%08x, size: 0x%08x, (%u psect)\n"), _(" module address: 0x%08x, size: 0x%08x, (%u psects)\n"),
(unsigned)bfd_getl32 (dmth.modbeg), (unsigned)bfd_getl32 (dmth.modbeg),
(unsigned)bfd_getl32 (dmth.size), count); (unsigned)bfd_getl32 (dmth.size), count);
dmt_size -= sizeof (dmth); dmt_size -= sizeof (dmth);
@ -7745,7 +7739,7 @@ vms_bfd_print_private_bfd_data (bfd *abfd, void *ptr)
/* Linking. */ /* Linking. */
/* Slurp an ordered set of VMS object records. */ /* Slurp ETIR/EDBG/ETBT VMS object records. */
static bfd_boolean static bfd_boolean
alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info) alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info)
@ -7758,8 +7752,6 @@ alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info)
if (bfd_seek (abfd, 0, SEEK_SET) != 0) if (bfd_seek (abfd, 0, SEEK_SET) != 0)
return FALSE; return FALSE;
PRIV (image_autoextend) = FALSE;
cur_section = NULL; cur_section = NULL;
cur_offset = 0; cur_offset = 0;
@ -7769,6 +7761,7 @@ alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info)
{ {
if (info->strip == strip_all || info->strip == strip_debugger) if (info->strip == strip_all || info->strip == strip_debugger)
{ {
/* Discard the DST section. */
dst_offset = 0; dst_offset = 0;
dst_section = NULL; dst_section = NULL;
} }
@ -7805,9 +7798,7 @@ alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info)
continue; continue;
PRIV (image_section) = dst_section; PRIV (image_section) = dst_section;
PRIV (image_offset) = dst_offset; PRIV (image_offset) = dst_offset;
PRIV (image_autoextend) = TRUE;
res = _bfd_vms_slurp_etir (abfd, info); res = _bfd_vms_slurp_etir (abfd, info);
PRIV (image_autoextend) = FALSE;
dst_offset = PRIV (image_offset); dst_offset = PRIV (image_offset);
break; break;
case EOBJ__C_EEOM: case EOBJ__C_EEOM:
@ -8372,6 +8363,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
asection *fixupsec; asection *fixupsec;
bfd_vma base_addr; bfd_vma base_addr;
bfd_vma last_addr; bfd_vma last_addr;
asection *dst;
bfd_get_outsymbols (abfd) = NULL; bfd_get_outsymbols (abfd) = NULL;
bfd_get_symcount (abfd) = 0; bfd_get_symcount (abfd) = 0;
@ -8415,7 +8407,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
} }
#endif #endif
/* Find entry point. */ /* Find the entry point. */
if (bfd_get_start_address (abfd) == 0) if (bfd_get_start_address (abfd) == 0)
{ {
bfd *startbfd = NULL; bfd *startbfd = NULL;
@ -8454,7 +8446,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
} }
} }
/* Allocate content. */ /* Allocate contents. */
base_addr = (bfd_vma)-1; base_addr = (bfd_vma)-1;
last_addr = 0; last_addr = 0;
for (o = abfd->sections; o != NULL; o = o->next) for (o = abfd->sections; o != NULL; o = o->next)
@ -8474,6 +8466,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
} }
} }
/* Create the fixup section. */
fixupsec = bfd_make_section_anyway_with_flags fixupsec = bfd_make_section_anyway_with_flags
(info->output_bfd, "$FIXUP$", (info->output_bfd, "$FIXUP$",
SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_LINKER_CREATED); SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_LINKER_CREATED);
@ -8524,6 +8517,91 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
if (!alpha_vms_build_fixups (info)) if (!alpha_vms_build_fixups (info))
return FALSE; return FALSE;
/* Compute the DMT. */
dst = PRIV (dst_section);
if (dst != NULL && dst->size == 0)
dst = NULL;
if (dst != NULL)
{
asection *dmt;
int pass;
unsigned char *contents = NULL;
dmt = bfd_make_section_anyway_with_flags
(info->output_bfd, "$DMT$",
SEC_DEBUGGING | SEC_HAS_CONTENTS | SEC_LINKER_CREATED);
if (dmt == NULL)
return FALSE;
/* In pass 1, compute the size. In pass 2, write the DMT contents. */
for (pass = 0; pass < 2; pass++)
{
unsigned int off = 0;
/* For each object file (ie for each module). */
for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
{
asection *sub_dst;
struct vms_dmt_header *dmth = NULL;
unsigned int psect_count;
/* Skip this module if it has no DST. */
sub_dst = PRIV2 (sub, dst_section);
if (sub_dst == NULL || sub_dst->size == 0)
continue;
if (pass == 1)
{
/* Write the header. */
dmth = (struct vms_dmt_header *)(contents + off);
bfd_putl32 (sub_dst->output_offset, dmth->modbeg);
bfd_putl32 (sub_dst->size, dmth->size);
}
off += sizeof (struct vms_dmt_header);
psect_count = 0;
/* For each section (ie for each psect). */
for (o = sub->sections; o != NULL; o = o->next)
{
/* Only consider interesting sections. */
if (!(o->flags & SEC_ALLOC))
continue;
if (o->flags & SEC_LINKER_CREATED)
continue;
if (pass == 1)
{
/* Write an entry. */
struct vms_dmt_psect *dmtp;
dmtp = (struct vms_dmt_psect *)(contents + off);
bfd_putl32 (o->output_offset + o->output_section->vma,
dmtp->start);
bfd_putl32 (o->size, dmtp->length);
psect_count++;
}
off += sizeof (struct vms_dmt_psect);
}
if (pass == 1)
bfd_putl32 (psect_count, dmth->psect_count);
}
if (pass == 0)
{
contents = bfd_zalloc (info->output_bfd, off);
if (contents == NULL)
return FALSE;
dmt->contents = contents;
dmt->size = off;
}
else
{
BFD_ASSERT (off == dmt->size);
}
}
}
return TRUE; return TRUE;
} }

View File

@ -1,3 +1,7 @@
2010-05-03 Tristan Gingold <gingold@adacore.com>
* dmt.h: Improve comments.
2010-04-30 Tristan Gingold <gingold@adacore.com> 2010-04-30 Tristan Gingold <gingold@adacore.com>
* lbr.h (struct vms_kbn): New structure. * lbr.h (struct vms_kbn): New structure.

View File

@ -25,10 +25,10 @@
struct vms_dmt_header struct vms_dmt_header
{ {
/* Address of the module. */ /* Offset in the DST of the module. */
unsigned char modbeg[4]; unsigned char modbeg[4];
/* Size of the module. */ /* Size of the DST chunk for this module. */
unsigned char size[4]; unsigned char size[4];
/* Number of psect for this module. */ /* Number of psect for this module. */
@ -39,7 +39,10 @@ struct vms_dmt_header
struct vms_dmt_psect struct vms_dmt_psect
{ {
/* Address of the psect. */
unsigned char start[4]; unsigned char start[4];
/* Length of the psect. */
unsigned char length[4]; unsigned char length[4];
}; };
#endif /* _VMS_DMT_H */ #endif /* _VMS_DMT_H */