elf backend hook for machine dependent section header flags
Jim Wilson
wilson@cygnus.com
Thu Oct 5 15:43:00 GMT 2000
For ia64-linux, if I assemble a file that uses the sdata section
.section .sdata
.long 10
and then look at the resulting .o file with objdump, it has
3 .sdata 00000004 0000000000000000 0000000000000000 00000040 2**2
CONTENTS, ALLOC, LOAD, DATA
There is no mention of the SMALL_DATA flag. I know the flag is there, because
readelf prints "WAp" for the section header flags, where the 'p' indicates
a machine specific flag is set. If I run the file through "ld -r", the bit is
now gone.
There is a generic bfd problem here in that there is no support for converting
machine dependent section header flags into bfd internal section header flags
when reading an ELF section header.
You can see the same problem with the mips toolchain. It mostly works because
when outputting ELF sections, it checks the section names, and sets the header
flags that are supposed to be set. This solves the ld -r problem, but not
the objdump problem. This also does not work if you want to set the small
data flag on sections other than predefined ones. Something that is supposed
to work in the IA-64 ABI.
So I've added a elf backend hook to solve this problem, and defined the hook
for IA-64. Now objdump says
3 .sdata 00000004 0000000000000000 0000000000000000 00000040 2**2
CONTENTS, ALLOC, LOAD, DATA, SMALL_DATA
and I don't lose the header flag when using ld -r.
This patch was reviewed and approved by Richard Henderson.
2000-10-05 Jim Wilson <wilson@cygnus.com>
* elf-bfd.h (struct elf_backend_data): Add elf_backend_section_flags
field.
* elf.c (_bfd_elf_make_section_from_shdr): Call the
elf_backend_section_flags function.
* elf64-ia64.c (elf64_ia64_section_from_shdr): Delete flag conversion
code.
(elf64_ia64_section_flags): New function containing flag conversion
code.
(elf_backend_section_flags): Define to elf64_ia64_section_flags.
* elfxx-target.h (elf_backend_section_flags): Define.
(elfNN_bed): Initialize elf_backend_section_flags field.
Index: elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.27
diff -p -r1.27 elf-bfd.h
*** elf-bfd.h 2000/08/22 19:33:16 1.27
--- elf-bfd.h 2000/10/05 22:18:45
*************** struct elf_backend_data
*** 391,396 ****
--- 391,401 ----
Elf32_Internal_Shdr *,
char *));
+ /* A function to convert machine dependent section header flags to
+ BFD internal section header flags. */
+ boolean (*elf_backend_section_flags) PARAMS ((flagword *,
+ Elf32_Internal_Shdr *));
+
/* A function to handle unusual program segment types when creating BFD
sections from ELF program segments. */
boolean (*elf_backend_section_from_phdr) PARAMS ((bfd *,
Index: elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.55
diff -p -r1.55 elf.c
*** elf.c 2000/09/30 00:44:49 1.55
--- elf.c 2000/10/05 22:18:45
*************** _bfd_elf_make_section_from_shdr (abfd, h
*** 345,350 ****
--- 345,351 ----
{
asection *newsect;
flagword flags;
+ struct elf_backend_data *bed;
if (hdr->bfd_section != NULL)
{
*************** _bfd_elf_make_section_from_shdr (abfd, h
*** 409,414 ****
--- 410,420 ----
all but one of the sections. */
if (strncmp (name, ".gnu.linkonce", sizeof ".gnu.linkonce" - 1) == 0)
flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+
+ bed = get_elf_backend_data (abfd);
+ if (bed->elf_backend_section_flags)
+ if (! bed->elf_backend_section_flags (&flags, hdr))
+ return false;
if (! bfd_set_section_flags (abfd, newsect, flags))
return false;
Index: elf64-ia64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ia64.c,v
retrieving revision 1.7
diff -p -r1.7 elf64-ia64.c
*** elf64-ia64.c 2000/08/14 20:13:39 1.7
--- elf64-ia64.c 2000/10/05 22:18:45
*************** elf64_ia64_section_from_shdr (abfd, hdr,
*** 946,953 ****
return false;
newsect = hdr->bfd_section;
if (hdr->sh_flags & SHF_IA_64_SHORT)
! newsect->flags |= SEC_SMALL_DATA;
return true;
}
--- 946,966 ----
return false;
newsect = hdr->bfd_section;
+ return true;
+ }
+
+ /* Convert IA-64 specific section flags to bfd internal section flags. */
+
+ /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
+ flag. */
+
+ static boolean
+ elf64_ia64_section_flags (flags, hdr)
+ flagword *flags;
+ Elf64_Internal_Shdr *hdr;
+ {
if (hdr->sh_flags & SHF_IA_64_SHORT)
! *flags |= SEC_SMALL_DATA;
return true;
}
*************** elf64_ia64_print_private_bfd_data (abfd,
*** 4064,4069 ****
--- 4077,4084 ----
#define elf_backend_section_from_shdr \
elf64_ia64_section_from_shdr
+ #define elf_backend_section_flags \
+ elf64_ia64_section_flags
#define elf_backend_fake_sections \
elf64_ia64_fake_sections
#define elf_backend_add_symbol_hook \
Index: elfxx-target.h
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-target.h,v
retrieving revision 1.16
diff -p -r1.16 elfxx-target.h
*** elfxx-target.h 2000/07/02 01:17:52 1.16
--- elfxx-target.h 2000/10/05 22:18:45
*************** Foundation, Inc., 59 Temple Place - Suit
*** 237,242 ****
--- 237,245 ----
#ifndef elf_backend_section_from_shdr
#define elf_backend_section_from_shdr 0
#endif
+ #ifndef elf_backend_section_flags
+ #define elf_backend_section_flags 0
+ #endif
#ifndef elf_backend_section_from_phdr
#define elf_backend_section_from_phdr 0
#endif
*************** static CONST struct elf_backend_data elf
*** 368,373 ****
--- 371,377 ----
elf_backend_get_symbol_type,
elf_backend_section_processing,
elf_backend_section_from_shdr,
+ elf_backend_section_flags,
elf_backend_section_from_phdr,
elf_backend_fake_sections,
elf_backend_section_from_bfd_section,
More information about the Binutils
mailing list