This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
PATCH LD octets vs byte support, revised
- To: binutils at sourceware dot cygnus dot com, nickc at cygnus dot com
- Subject: PATCH LD octets vs byte support, revised
- From: Timothy Wall <twall at tiac dot net>
- Date: Thu, 27 Jan 2000 07:27:23 -0500
This patch supersedes the previous one, incorporating Ian's comments on
BYTE behavior for targets where a byte is greater than one octet.
* ld/ld.texinfo: Updated description of BYTE, SHORT, LONG, etc to be
clear about behavior when an octet is smaller than one byte.
* ld/ldlang.c (lang_do_assignments, lang_size_sections): Use the larger
of the directive size or octets_per_byte for the number of octets
allocated in the output section.
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/binutils/binutils/ld/ld.texinfo,v
retrieving revision 1.10
diff -c -3 -p -r1.10 ld.texinfo
*** ld.texinfo 2000/01/07 19:46:04 1.10
--- ld.texinfo 2000/01/27 12:23:23
*************** value of the expression is stored at the
*** 2469,2487 ****
counter.
The @code{BYTE}, @code{SHORT}, @code{LONG}, and @code{QUAD} commands
! store one, two, four, and eight bytes (respectively). After storing the
! bytes, the location counter is incremented by the number of bytes
! stored.
! For example, this will store the byte 1 followed by the four byte value
! of the symbol @samp{addr}:
@smallexample
BYTE(1)
LONG(addr)
@end smallexample
When using a 64 bit host or target, @code{QUAD} and @code{SQUAD} are the
! same; they both store an 8 byte, or 64 bit, value. When both host and
target are 32 bits, an expression is computed as 32 bits. In this case
@code{QUAD} stores a 32 bit value zero extended to 64 bits, and
@code{SQUAD} stores a 32 bit value sign extended to 64 bits.
--- 2469,2488 ----
counter.
The @code{BYTE}, @code{SHORT}, @code{LONG}, and @code{QUAD} commands
! store one, two, four, and eight octets (respectively). After storing the
! octets, the location counter is incremented by the number of target bytes
! stored. If the number of octets to be output is less than the size of a
! target byte, the output is padded to the target byte size.
! For example, this will store one byte with value 1 followed by the four
! octet value of the symbol @samp{addr}:
@smallexample
BYTE(1)
LONG(addr)
@end smallexample
When using a 64 bit host or target, @code{QUAD} and @code{SQUAD} are the
! same; they both store an 8 octet, or 64 bit, value. When both host and
target are 32 bits, an expression is computed as 32 bits. In this case
@code{QUAD} stores a 32 bit value zero extended to 64 bits, and
@code{SQUAD} stores a 32 bit value sign extended to 64 bits.
Index: ld/ldexp.c
===================================================================
RCS file: /cvs/binutils/binutils/ld/ldexp.c,v
retrieving revision 1.2
diff -c -3 -p -r1.2 ldexp.c
*** ldexp.c 1999/07/11 20:08:59 1.2
--- ldexp.c 2000/01/27 12:23:23
*************** fold_name (tree, current_section, alloca
*** 456,466 ****
case SIZEOF:
if (allocation_done != lang_first_phase_enum)
{
lang_output_section_statement_type *os;
os = lang_output_section_find (tree->name.name);
check (os, tree->name.name, "SIZEOF");
! result = new_abs (os->bfd_section->_raw_size);
}
else
result = invalid ();
--- 456,467 ----
case SIZEOF:
if (allocation_done != lang_first_phase_enum)
{
+ int opb = bfd_octets_per_byte (output_bfd);
lang_output_section_statement_type *os;
os = lang_output_section_find (tree->name.name);
check (os, tree->name.name, "SIZEOF");
! result = new_abs (os->bfd_section->_raw_size / opb);
}
else
result = invalid ();
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/binutils/binutils/ld/ldlang.c,v
retrieving revision 1.17
diff -c -3 -p -r1.17 ldlang.c
*** ldlang.c 2000/01/05 14:12:23 1.17
--- ldlang.c 2000/01/27 12:23:24
*************** print_input_section (in)
*** 2168,2174 ****
{
asection *i = in->section;
bfd_size_type size = i->_cooked_size != 0 ? i->_cooked_size : i->_raw_size;
!
if (size != 0)
{
print_space ();
--- 2168,2175 ----
{
asection *i = in->section;
bfd_size_type size = i->_cooked_size != 0 ? i->_cooked_size : i->_raw_size;
! int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
! ldfile_output_machine);
if (size != 0)
{
print_space ();
*************** print_input_section (in)
*** 2192,2198 ****
}
minfo ("0x%V %W %B\n",
! i->output_section->vma + i->output_offset, size,
i->owner);
if (i->_cooked_size != 0 && i->_cooked_size != i->_raw_size)
--- 2193,2199 ----
}
minfo ("0x%V %W %B\n",
! i->output_section->vma + i->output_offset, size / opb,
i->owner);
if (i->_cooked_size != 0 && i->_cooked_size != i->_raw_size)
*************** print_input_section (in)
*** 2214,2220 ****
bfd_link_hash_traverse (link_info.hash, print_one_symbol, (PTR) i);
! print_dot = i->output_section->vma + i->output_offset + size;
}
}
}
--- 2215,2221 ----
bfd_link_hash_traverse (link_info.hash, print_one_symbol, (PTR) i);
! print_dot = i->output_section->vma + i->output_offset + size / opb;
}
}
}
*************** print_data_statement (data)
*** 2234,2239 ****
--- 2235,2242 ----
bfd_vma addr;
bfd_size_type size;
const char *name;
+ int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+ ldfile_output_machine);
for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
print_space ();
*************** print_data_statement (data)
*** 2277,2284 ****
}
print_nl ();
- print_dot = addr + size;
}
/* Print an address statement. These are generated by options like
--- 2280,2288 ----
}
print_nl ();
+
+ print_dot = addr + size / opb;
}
/* Print an address statement. These are generated by options like
*************** print_reloc_statement (reloc)
*** 2302,2307 ****
--- 2306,2313 ----
int i;
bfd_vma addr;
bfd_size_type size;
+ int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+ ldfile_output_machine);
for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
print_space ();
*************** print_reloc_statement (reloc)
*** 2323,2329 ****
print_nl ();
! print_dot = addr + size;
}
static void
--- 2329,2335 ----
print_nl ();
! print_dot = addr + size / opb;
}
static void
*************** print_padding_statement (s)
*** 2332,2337 ****
--- 2338,2345 ----
{
int len;
bfd_vma addr;
+ int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+ ldfile_output_machine);
minfo (" *fill*");
*************** print_padding_statement (s)
*** 2352,2358 ****
print_nl ();
! print_dot = addr + s->size;
}
static void
--- 2360,2366 ----
print_nl ();
! print_dot = addr + s->size / opb;
}
static void
*************** insert_pad (this_ptr, fill, power, outpu
*** 2547,2552 ****
--- 2555,2562 ----
inserting a magic 'padding' statement.
*/
+ int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+ ldfile_output_machine);
unsigned int alignment_needed = align_power (dot, power) - dot;
if (alignment_needed != 0)
*************** insert_pad (this_ptr, fill, power, outpu
*** 2563,2569 ****
new->padding_statement.output_offset =
dot - output_section_statement->vma;
new->padding_statement.fill = fill;
! new->padding_statement.size = alignment_needed;
}
--- 2573,2579 ----
new->padding_statement.output_offset =
dot - output_section_statement->vma;
new->padding_statement.fill = fill;
! new->padding_statement.size = alignment_needed * opb;
}
*************** insert_pad (this_ptr, fill, power, outpu
*** 2572,2580 ****
{
output_section_statement->alignment_power = power;
}
! output_section_statement->_raw_size += alignment_needed;
! return alignment_needed + dot;
}
/* Work out how much this section will move the dot point */
--- 2582,2590 ----
{
output_section_statement->alignment_power = power;
}
! output_section_statement->_raw_size += alignment_needed * opb;
+ return dot + alignment_needed;
}
/* Work out how much this section will move the dot point */
*************** size_input_section (this_ptr, output_sec
*** 2588,2593 ****
--- 2598,2605 ----
{
lang_input_section_type *is = &((*this_ptr)->input_section);
asection *i = is->section;
+ int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+ ldfile_output_machine);
if (is->ifile->just_syms_flag == false)
{
*************** size_input_section (this_ptr, output_sec
*** 2605,2614 ****
/* Mark how big the output section must be to contain this now
*/
if (i->_cooked_size != 0)
! dot += i->_cooked_size;
else
! dot += i->_raw_size;
! output_section_statement->bfd_section->_raw_size = dot - output_section_statement->bfd_section->vma;
}
else
{
--- 2617,2627 ----
/* Mark how big the output section must be to contain this now
*/
if (i->_cooked_size != 0)
! dot += i->_cooked_size / opb;
else
! dot += i->_raw_size / opb;
! output_section_statement->bfd_section->_raw_size =
! (dot - output_section_statement->bfd_section->vma) * opb;
}
else
{
*************** static void
*** 2629,2634 ****
--- 2642,2648 ----
lang_check_section_addresses ()
{
asection * s;
+ int opb = bfd_octets_per_byte (output_bfd);
/* Scan all sections in the output list. */
for (s = output_bfd->sections; s != NULL; s = s->next)
*************** lang_size_sections (s, output_section_st
*** 2692,2697 ****
--- 2706,2714 ----
bfd_vma dot;
boolean relax;
{
+ int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+ ldfile_output_machine);
+
/* Size up the sections from their constituent parts. */
for (; s != (lang_statement_union_type *) NULL; s = s->next)
{
*************** lang_size_sections (s, output_section_st
*** 2805,2823 ****
(void) lang_size_sections (os->children.head, os, &os->children.head,
os->fill, dot, relax);
! /* Ignore the size of the input sections, use the vma and size to
! align against. */
!
! after = ALIGN_N (os->bfd_section->vma +
! os->bfd_section->_raw_size,
/* The coercion here is important, see ld.h. */
(bfd_vma) os->block_value);
if (bfd_is_abs_section (os->bfd_section))
ASSERT (after == os->bfd_section->vma);
else
! os->bfd_section->_raw_size = after - os->bfd_section->vma;
! dot = os->bfd_section->vma + os->bfd_section->_raw_size;
os->processed = true;
/* Update dot in the region ?
--- 2822,2840 ----
(void) lang_size_sections (os->children.head, os, &os->children.head,
os->fill, dot, relax);
! /* put the section within the requested block size, or align at
! the block boundary */
! after = ALIGN_N (os->bfd_section->vma,
! os->bfd_section->_raw_size / opb,
/* The coercion here is important, see ld.h. */
(bfd_vma) os->block_value);
if (bfd_is_abs_section (os->bfd_section))
ASSERT (after == os->bfd_section->vma);
else
! os->bfd_section->_raw_size =
! (after - os->bfd_section->vma) * opb;
! dot = os->bfd_section->vma + os->bfd_section->_raw_size / opb;
os->processed = true;
/* Update dot in the region ?
*************** lang_size_sections (s, output_section_st
*** 2897,2904 ****
size = BYTE_SIZE;
break;
}
!
! dot += size;
output_section_statement->bfd_section->_raw_size += size;
/* The output section gets contents, and then we inspect for
any flags set in the input script which override any ALLOC. */
--- 2914,2922 ----
size = BYTE_SIZE;
break;
}
! if (size < opb)
! size = opb;
! dot += size / opb;
output_section_statement->bfd_section->_raw_size += size;
/* The output section gets contents, and then we inspect for
any flags set in the input script which override any ALLOC. */
*************** lang_size_sections (s, output_section_st
*** 2918,2924 ****
s->reloc_statement.output_section =
output_section_statement->bfd_section;
size = bfd_get_reloc_size (s->reloc_statement.howto);
! dot += size;
output_section_statement->bfd_section->_raw_size += size;
}
break;
--- 2936,2942 ----
s->reloc_statement.output_section =
output_section_statement->bfd_section;
size = bfd_get_reloc_size (s->reloc_statement.howto);
! dot += size / opb;
output_section_statement->bfd_section->_raw_size += size;
}
break;
*************** lang_size_sections (s, output_section_st
*** 3006,3012 ****
new->padding_statement.output_offset =
dot - output_section_statement->bfd_section->vma;
new->padding_statement.fill = fill;
! new->padding_statement.size = newdot - dot;
output_section_statement->bfd_section->_raw_size +=
new->padding_statement.size;
}
--- 3024,3030 ----
new->padding_statement.output_offset =
dot - output_section_statement->bfd_section->vma;
new->padding_statement.fill = fill;
! new->padding_statement.size = (newdot - dot) * opb;
output_section_statement->bfd_section->_raw_size +=
new->padding_statement.size;
}
*************** lang_size_sections (s, output_section_st
*** 3024,3030 ****
pass than it did at this point in the previous pass. */
s->padding_statement.output_offset =
dot - output_section_statement->bfd_section->vma;
! dot += s->padding_statement.size;
output_section_statement->bfd_section->_raw_size +=
s->padding_statement.size;
break;
--- 3042,3048 ----
pass than it did at this point in the previous pass. */
s->padding_statement.output_offset =
dot - output_section_statement->bfd_section->vma;
! dot += s->padding_statement.size / opb;
output_section_statement->bfd_section->_raw_size +=
s->padding_statement.size;
break;
*************** lang_do_assignments (s, output_section_s
*** 3057,3062 ****
--- 3075,3083 ----
fill_type fill;
bfd_vma dot;
{
+ int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+ ldfile_output_machine);
+
for (; s != (lang_statement_union_type *) NULL; s = s->next)
{
switch (s->header.type)
*************** lang_do_assignments (s, output_section_s
*** 3078,3084 ****
dot = os->bfd_section->vma;
(void) lang_do_assignments (os->children.head, os,
os->fill, dot);
! dot = os->bfd_section->vma + os->bfd_section->_raw_size;
}
if (os->load_base)
{
--- 3099,3106 ----
dot = os->bfd_section->vma;
(void) lang_do_assignments (os->children.head, os,
os->fill, dot);
! dot = os->bfd_section->vma + os->bfd_section->_raw_size / opb;
!
}
if (os->load_base)
{
*************** lang_do_assignments (s, output_section_s
*** 3118,3139 ****
if (value.valid_p == false)
einfo (_("%F%P: invalid data statement\n"));
}
! switch (s->data_statement.type)
! {
! case QUAD:
! case SQUAD:
! dot += QUAD_SIZE;
! break;
! case LONG:
! dot += LONG_SIZE;
! break;
! case SHORT:
! dot += SHORT_SIZE;
! break;
! case BYTE:
! dot += BYTE_SIZE;
! break;
! }
break;
case lang_reloc_statement_enum:
--- 3140,3167 ----
if (value.valid_p == false)
einfo (_("%F%P: invalid data statement\n"));
}
! {
! int size;
! switch (s->data_statement.type)
! {
! case QUAD:
! case SQUAD:
! size = QUAD_SIZE;
! break;
! case LONG:
! size = LONG_SIZE;
! break;
! case SHORT:
! size = SHORT_SIZE;
! break;
! case BYTE:
! size = BYTE_SIZE;
! break;
! }
! if (size < opb)
! size = opb;
! dot += size / opb;
! }
break;
case lang_reloc_statement_enum:
*************** lang_do_assignments (s, output_section_s
*** 3147,3153 ****
if (value.valid_p == false)
einfo (_("%F%P: invalid reloc statement\n"));
}
! dot += bfd_get_reloc_size (s->reloc_statement.howto);
break;
case lang_input_section_enum:
--- 3175,3181 ----
if (value.valid_p == false)
einfo (_("%F%P: invalid reloc statement\n"));
}
! dot += bfd_get_reloc_size (s->reloc_statement.howto) / opb;
break;
case lang_input_section_enum:
*************** lang_do_assignments (s, output_section_s
*** 3155,3163 ****
asection *in = s->input_section.section;
if (in->_cooked_size != 0)
! dot += in->_cooked_size;
else
! dot += in->_raw_size;
}
break;
--- 3183,3191 ----
asection *in = s->input_section.section;
if (in->_cooked_size != 0)
! dot += in->_cooked_size / opb;
else
! dot += in->_raw_size / opb;
}
break;
*************** lang_do_assignments (s, output_section_s
*** 3177,3183 ****
break;
case lang_padding_statement_enum:
! dot += s->padding_statement.size;
break;
case lang_group_statement_enum:
--- 3205,3211 ----
break;
case lang_padding_statement_enum:
! dot += s->padding_statement.size / opb;
break;
case lang_group_statement_enum:
*************** lang_set_startof ()
*** 3235,3245 ****
h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true);
if (h != NULL && h->type == bfd_link_hash_undefined)
{
h->type = bfd_link_hash_defined;
if (s->_cooked_size != 0)
! h->u.def.value = s->_cooked_size;
else
! h->u.def.value = s->_raw_size;
h->u.def.section = bfd_abs_section_ptr;
}
--- 3263,3275 ----
h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true);
if (h != NULL && h->type == bfd_link_hash_undefined)
{
+ int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+ ldfile_output_machine);
h->type = bfd_link_hash_defined;
if (s->_cooked_size != 0)
! h->u.def.value = s->_cooked_size / opb;
else
! h->u.def.value = s->_raw_size / opb;
h->u.def.section = bfd_abs_section_ptr;
}
*************** lang_one_common (h, info)
*** 3416,3421 ****
--- 3446,3453 ----
unsigned int power_of_two;
bfd_vma size;
asection *section;
+ int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+ ldfile_output_machine);
if (h->type != bfd_link_hash_common)
return true;
*************** lang_one_common (h, info)
*** 3430,3437 ****
section = h->u.c.p->section;
/* Increase the size of the section. */
! section->_cooked_size = ALIGN_N (section->_cooked_size,
! (bfd_size_type) (1 << power_of_two));
/* Adjust the alignment if necessary. */
if (power_of_two > section->alignment_power)
--- 3462,3469 ----
section = h->u.c.p->section;
/* Increase the size of the section. */
! section->_cooked_size = ALIGN_N ((section->_cooked_size + opb - 1) / opb,
! (bfd_size_type) (1 << power_of_two)) * opb;
/* Adjust the alignment if necessary. */
if (power_of_two > section->alignment_power)
*************** lang_abs_symbol_at_end_of (secname, name
*** 4291,4297 ****
h->u.def.value = 0;
else
h->u.def.value = (bfd_get_section_vma (output_bfd, sec)
! + bfd_section_size (output_bfd, sec));
h->u.def.section = bfd_abs_section_ptr;
}
--- 4323,4330 ----
h->u.def.value = 0;
else
h->u.def.value = (bfd_get_section_vma (output_bfd, sec)
! + bfd_section_size (output_bfd, sec) /
! bfd_octets_per_byte (output_bfd));
h->u.def.section = bfd_abs_section_ptr;
}