X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Freadelf.c;h=15338062180d6ca693e4186978ac32a9c6c58c13;hb=6ff71e768112317de1236a429e7c88c9d3e32116;hp=06fa8d5ad32da499144e76b771ad5974e30fed62;hpb=c8071705c69a13d237aeca4709bf91deaff7e5cb;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/readelf.c b/binutils/readelf.c index 06fa8d5ad3..1533806218 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -43,9 +43,7 @@ #include "sysdep.h" #include #include -#ifdef HAVE_ZLIB_H #include -#endif #ifdef HAVE_WCHAR_H #include #endif @@ -552,7 +550,7 @@ print_symbol (int width, const char *symbol) to print multibyte characters, it just interprets them as hex values. */ static const char * -printable_section_name (Elf_Internal_Shdr * sec) +printable_section_name (const Elf_Internal_Shdr * sec) { #define MAX_PRINT_SEC_NAME_LEN 128 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1]; @@ -2280,12 +2278,6 @@ decode_ARM_machine_flags (unsigned e_flags, char buf[]) e_flags &= ~ EF_ARM_RELEXEC; } - if (e_flags & EF_ARM_HASENTRY) - { - strcat (buf, ", has entry point"); - e_flags &= ~ EF_ARM_HASENTRY; - } - /* Now handle EABI specific flags. */ switch (eabi) { @@ -3262,8 +3254,13 @@ get_machine_flags (unsigned e_flags, unsigned e_machine) break; case EM_RL78: - if (e_flags & E_FLAG_RL78_G10) - strcat (buf, ", G10"); + switch (e_flags & E_FLAG_RL78_CPU_MASK) + { + case E_FLAG_RL78_ANY_CPU: break; + case E_FLAG_RL78_G10: strcat (buf, ", G10"); break; + case E_FLAG_RL78_G13: strcat (buf, ", G13"); break; + case E_FLAG_RL78_G14: strcat (buf, ", G14"); break; + } if (e_flags & E_FLAG_RL78_64BIT_DOUBLES) strcat (buf, ", 64-bit doubles"); break; @@ -3277,6 +3274,9 @@ get_machine_flags (unsigned e_flags, unsigned e_machine) strcat (buf, ", pid"); if (e_flags & E_FLAG_RX_ABI) strcat (buf, ", RX ABI"); + if (e_flags & E_FLAG_RX_SINSNS_SET) + strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES + ? ", uses String instructions" : ", bans String instructions"); break; case EM_S390: @@ -4238,11 +4238,6 @@ parse_args (int argc, char ** argv) && !do_section_groups && !do_archive_index && !do_dyn_syms) usage (stderr); - else if (argc < 3) - { - warn (_("Nothing to do.\n")); - usage (stderr); - } } static const char * @@ -5163,7 +5158,8 @@ get_elf_section_flags (bfd_vma sh_flags) /* Generic. */ /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") }, /* SPARC specific. */ - /* 19 */ { STRING_COMMA_LEN ("ORDERED") } + /* 19 */ { STRING_COMMA_LEN ("ORDERED") }, + /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") } }; if (do_section_details) @@ -5195,6 +5191,7 @@ get_elf_section_flags (bfd_vma sh_flags) case SHF_GROUP: sindex = 8; break; case SHF_TLS: sindex = 9; break; case SHF_EXCLUDE: sindex = 18; break; + case SHF_COMPRESSED: sindex = 20; break; default: sindex = -1; @@ -5276,6 +5273,7 @@ get_elf_section_flags (bfd_vma sh_flags) case SHF_GROUP: *p = 'G'; break; case SHF_TLS: *p = 'T'; break; case SHF_EXCLUDE: *p = 'E'; break; + case SHF_COMPRESSED: *p = 'C'; break; default: if ((elf_header.e_machine == EM_X86_64 @@ -5363,6 +5361,27 @@ get_elf_section_flags (bfd_vma sh_flags) return buff; } +static unsigned int +get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf) +{ + if (is_32bit_elf) + { + Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf; + chdr->ch_type = BYTE_GET (echdr->ch_type); + chdr->ch_size = BYTE_GET (echdr->ch_size); + chdr->ch_addralign = BYTE_GET (echdr->ch_addralign); + return sizeof (*echdr); + } + else + { + Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf; + chdr->ch_type = BYTE_GET (echdr->ch_type); + chdr->ch_size = BYTE_GET (echdr->ch_size); + chdr->ch_addralign = BYTE_GET (echdr->ch_addralign); + return sizeof (*echdr); + } +} + static int process_section_headers (FILE * file) { @@ -5807,7 +5826,29 @@ process_section_headers (FILE * file) } if (do_section_details) - printf (" %s\n", get_elf_section_flags (section->sh_flags)); + { + printf (" %s\n", get_elf_section_flags (section->sh_flags)); + if ((section->sh_flags & SHF_COMPRESSED) != 0) + { + /* Minimum section size is 12 bytes for 32-bit compression + header + 12 bytes for compressed data header. */ + unsigned char buf[24]; + assert (sizeof (buf) >= sizeof (Elf64_External_Chdr)); + if (get_data (&buf, (FILE *) file, section->sh_offset, 1, + sizeof (buf), _("compression header"))) + { + Elf_Internal_Chdr chdr; + get_compression_header (&chdr, buf); + if (chdr.ch_type == ELFCOMPRESS_ZLIB) + printf (" ZLIB, "); + else + printf (_(" [: 0x%x], "), + chdr.ch_type); + print_vma (chdr.ch_size, LONG_HEX); + printf (", %lu\n", (unsigned long) chdr.ch_addralign); + } + } + } } if (!do_section_details) @@ -11120,6 +11161,42 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc, } break; } + + case EM_RL78: + { + static bfd_vma saved_sym1 = 0; + static bfd_vma saved_sym2 = 0; + static bfd_vma value; + + switch (reloc_type) + { + case 0x80: /* R_RL78_SYM. */ + saved_sym1 = saved_sym2; + saved_sym2 = symtab[get_reloc_symindex (reloc->r_info)].st_value; + saved_sym2 += reloc->r_addend; + return TRUE; + + case 0x83: /* R_RL78_OPsub. */ + value = saved_sym1 - saved_sym2; + saved_sym2 = saved_sym1 = 0; + return TRUE; + break; + + case 0x41: /* R_RL78_ABS32. */ + byte_put (start + reloc->r_offset, value, 4); + value = 0; + return TRUE; + + case 0x43: /* R_RL78_ABS16. */ + byte_put (start + reloc->r_offset, value, 2); + value = 0; + return TRUE; + + default: + break; + } + break; + } } return FALSE; @@ -11592,11 +11669,11 @@ is_none_reloc (unsigned int reloc_type) static void apply_relocations (void * file, - Elf_Internal_Shdr * section, - unsigned char * start) + const Elf_Internal_Shdr * section, + unsigned char * start, bfd_size_type size) { Elf_Internal_Shdr * relsec; - unsigned char * end = start + section->sh_size; + unsigned char * end = start + size; if (elf_header.e_type != ET_REL) return; @@ -11888,7 +11965,7 @@ dump_section_as_bytes (Elf_Internal_Shdr * section, if (relocate) { - apply_relocations (file, section, start); + apply_relocations (file, section, start, section->sh_size); } else { @@ -11962,12 +12039,9 @@ dump_section_as_bytes (Elf_Internal_Shdr * section, /* Uncompresses a section that was compressed using zlib, in place. */ static int -uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED, - dwarf_size_type *size ATTRIBUTE_UNUSED) +uncompress_section_contents (unsigned char **buffer, + dwarf_size_type *size) { -#ifndef HAVE_ZLIB_H - return FALSE; -#else dwarf_size_type compressed_size = *size; unsigned char * compressed_buffer = *buffer; dwarf_size_type uncompressed_size; @@ -12018,7 +12092,6 @@ uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED, || strm.avail_out != 0) goto fail; - free (compressed_buffer); *buffer = uncompressed_buffer; *size = uncompressed_size; return 1; @@ -12028,12 +12101,11 @@ uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED, /* Indicate decompression failure. */ *buffer = NULL; return 0; -#endif /* HAVE_ZLIB_H */ } static int load_specific_debug_section (enum dwarf_section_display_enum debug, - Elf_Internal_Shdr * sec, void * file) + const Elf_Internal_Shdr * sec, void * file) { struct dwarf_section * section = &debug_displays [debug].section; char buf [64]; @@ -12052,16 +12124,36 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, section->size = 0; else { - section->size = sec->sh_size; - if (uncompress_section_contents (§ion->start, §ion->size)) - sec->sh_size = section->size; + unsigned char *start = section->start; + dwarf_size_type size = sec->sh_size; + + if ((sec->sh_flags & SHF_COMPRESSED) != 0) + { + Elf_Internal_Chdr chdr; + unsigned int compression_header_size + = get_compression_header (&chdr, start); + if (chdr.ch_type != ELFCOMPRESS_ZLIB + || chdr.ch_addralign != sec->sh_addralign) + return 0; + start += compression_header_size; + size -= compression_header_size; + } + + if (uncompress_section_contents (&start, &size)) + { + /* Free the compressed buffer, update the section buffer + and the section size if uncompress is successful. */ + free (section->start); + section->start = start; + } + section->size = size; } if (section->start == NULL) return 0; if (debug_displays [debug].relocate) - apply_relocations ((FILE *) file, sec, section->start); + apply_relocations ((FILE *) file, sec, section->start, section->size); return 1; } @@ -16137,6 +16229,11 @@ main (int argc, char ** argv) if (optind < (argc - 1)) show_name = 1; + else if (optind >= argc) + { + warn (_("Nothing to do.\n")); + usage (stderr); + } err = 0; while (optind < argc)